반응형
Stack
스택의 구조
스택은 가장 나중에 들어간 데이터가 가장 먼저 나오는 LIFO(Last In First Out) 선입선출 구조이다다.
실생활의 예로는 책을 쌓아둔 더미를 생각하면 된다
맨 위에 있는 책(마지막에 올려둔 책)을 가장 먼저 집을 수 있는 것 처럼
스택 선언 방법
접근지정자 Stack<타입> 변수명 = new Stack<타입>();
private Stack<string> books = new Stack<string>();
스택의 주요 동작
- Push: 새로운 데이터를 스택 맨 위에 추가
- Pop: 스택 맨 위의 데이터를 제거하고 반환
- Peek: 맨 위 데이터를 제거하지 않고 확인만 함
- Count: 스택에 있는 데이터의 개수 확인
- Contains: 스택에 특정 데이터가 있는지 확인
- Clear: 스택의 모든 데이터를 제거
스택의 특징
- 데이터는 한쪽 끝(top)에서만 삽입/삭제 가능
- 중간에 있는 데이터에 직접 접근 불가
- 순서가 중요한 작업에 적합
장점
- 구현이 간단함
- 데이터 저장/접근이 빠름
- 메모리 관리가 효율적
단점
- 크기가 제한적일 수 있음
- 중간 데이터 접근이 어려움
- 데이터 검색이 어려움
스택 사용 예시
// 문자열 뒤집기 예제
string text = "Hello";
Stack<char> charStack = new Stack<char>();
// 문자를 하나씩 스택에 넣기
foreach (char c in text)
{
charStack.Push(c);
}
// 스택에서 꺼내면서 뒤집힌 문자열 만들기
string reversed = "";
while (charStack.Count > 0)
{
reversed += charStack.Pop();
}
Console.WriteLine(reversed); // "olleH" 출력
주의
Stack<int> emptyStack = new Stack<int>();
// emptyStack.Pop(); // 에러 발생!
// 안전한 방법
if (emptyStack.Count > 0)
{
int value = emptyStack.Pop();
}
비어있는 스택에서 Pop이나 Peek을 하면 에러 발생
실제활용예시
무기 교체 시스템
Stack<Weapon> weapons = new Stack<Weapon>();
// 무기 줍기
weapons.Push(new Weapon("기본 검"));
weapons.Push(new Weapon("불의 검"));
// 'Q'키를 누르면 이전 무기로 교체
if (Input.GetKeyDown(KeyCode.Q))
{
Weapon currentWeapon = weapons.Pop(); // 현재 무기는 스택 아래로
weapons.Push(currentWeapon); // 다시 스택 맨 위로
}
카드 게임의 덱 시스템
Stack<Card> cardDeck = new Stack<Card>();
// 덱 셋업
void SetupDeck()
{
// 덱에 카드 추가
cardDeck.Push(new Card("드래곤"));
cardDeck.Push(new Card("마법사"));
cardDeck.Push(new Card("전사"));
}
// 카드 뽑기
void DrawCard()
{
if (cardDeck.Count > 0)
{
Card drawnCard = cardDeck.Pop();
Debug.Log($"{drawnCard.Name} 카드를 뽑았습니다!");
}
}
Queue
큐의 구조
첫 번째로 들어온 데이터가 첫 번째로 나가는 FIFO(First In First Out) 선입 선출 구조이다
실생활에서는 은행 창구 대기줄이나 티켓 예매 대기열 같은 것이 큐의 좋은 예시다.
큐 선언 방법
접근지정자 Queue<타입> 변수명 = new Queue<타입>();
private Queue<string> queue = new Queue<string>();
큐 주요 동작큐 특징
- Enqueue: 새로운 데이터를 큐의 뒤쪽에 추가
- Dequeue: 큐의 앞쪽에서 데이터를 제거하고 반환
- Peek: 첫 번째 데이터를 제거하지 않고 확인만 함
- Count: 큐에 있는 데이터의 개수 확인
- Clear: 큐의 모든 데이터 제거
- Contains: 큐에 특정 데이터가 있는지 확인
장점
- 순서가 보장됨 - 먼저 들어온 데이터가 먼저 처리됨 (FIFO)
- 데이터를 임시로 저장하고 순서대로 처리하기에 적합
- 멀티 스레드 환경에서 데이터를 안전하게 전달하는데 유용
단점
- 중간에 있는 데이터에 직접 접근 불가
- 데이터 검색이 어려움 (순차적으로 찾아야 함)
- 크기가 고정되어 있는 경우, 메모리 낭비 또는 큐가 가득 찰 수 있음
- 이미 제거한 데이터는 다시 접근할 수 없음
큐 사용 예시
Queue<GameEvent> eventQueue = new Queue<GameEvent>();
// 이벤트 등록
eventQueue.Enqueue(new GameEvent("PlayerJump"));
eventQueue.Enqueue(new GameEvent("EnemySpawn"));
eventQueue.Enqueue(new GameEvent("CollectItem"));
// 이벤트 처리
while (eventQueue.Count > 0)
{
GameEvent currentEvent = eventQueue.Dequeue();
ProcessEvent(currentEvent);
}
주의
Queue<int> emptyQueue = new Queue<int>();
// emptyQueue.Dequeue(); // 에러 발생!
// 안전한 방법
if (emptyQueue.Count > 0)
{
int value = emptyQueue.Dequeue();
}
비어있는 큐에서 Dequeue나 Peek 시도시 에러 발생
실제활용예시
턴제 RPG 전투 시스템
Queue<Character> turnQueue = new Queue<Character>();
// 턴 순서 설정
void SetupBattleTurns()
{
// 캐릭터들의 속도에 따라 턴 순서 정하기
turnQueue.Enqueue(new Character("플레이어", 10));
turnQueue.Enqueue(new Character("몬스터1", 8));
turnQueue.Enqueue(new Character("몬스터2", 5));
}
// 턴 진행
void ProcessTurn()
{
if (turnQueue.Count > 0)
{
Character current = turnQueue.Dequeue();
current.TakeTurn();
// 턴을 마친 캐릭터는 다시 큐의 끝으로
turnQueue.Enqueue(current);
}
}
게임 사운드 시스템
Queue<AudioClip> soundQueue = new Queue<AudioClip>();
// 효과음 예약
void AddSound(AudioClip clip)
{
soundQueue.Enqueue(clip);
}
// 사운드 재생 처리
void Update()
{
if (soundQueue.Count > 0 && !audioSource.isPlaying)
{
AudioClip nextSound = soundQueue.Dequeue();
audioSource.PlayOneShot(nextSound);
}
}
반응형
'유니티 > 문법' 카테고리의 다른 글
[Unity] 유니티 C#) 생성자 (0) | 2024.11.26 |
---|---|
[Unity] 유니티 C#) ref 와 out 키워드 (0) | 2024.11.25 |
[Unity] 유니티 C# 인터페이스 ( Interface) (3) | 2024.11.13 |
[Unity] 유니티 C#) 자료구조 딕셔너리(Dictionary) (0) | 2024.10.28 |
[Unity] 유니티 C#) 자료구조 배열(Array),리스트(List) (0) | 2024.10.28 |