2025. 6. 15. 14:23ㆍ게임 개발 공부 기록/게임을 만들고 싶은 이유
1. 배열의 요소 iArray [0]을 옮기자
배열 과제로 cin 입력을 통해 0의 위치를 옮기는 코드를 작성했었는데, 대각선 방향으로 움직일 수 있도록 리팩토링을 하다가 갑자기 머릿속에 재미있는 생각이 떠올랐다. 처음에는 위에서 -1이 비처럼 내려오고 입력을 통해 슉슉 피하는 게임을 구상했었는데, cin은 블로킹 함수인지라 코드의 흐름을 멈추기 때문에 위에서 내려오는 -1 역시 멈출 것이었다. 이건 내가 의도한 바와는 달랐다.
내가 구현하고 싶었던 게임은 사용자의 입력을 기다리는 중에도 -1은 계속 내려오는 게임이었다.
(1) cin 대신 _kbhit, _getch?
사용자의 입력을 기다리는 동안 코드의 흐름이 멈추지 않고 계속 진행되게 하려면 입력을 하자마자 바로 인식해서 0이 이동하도록 만들고 그 동안에도 -1은 계속 내려오게 구현하면 동시에 진행되는 것 '처럼' 구현할 수 있지 않을까 생각했다. 너무 빨리 반복되지 않도록 중간중간에 지연시간을 추가해주면 어느 정도 의도한 대로 되지 않을까 하는 생각이었다. 하지만 구조를 곰곰이 생각하다 보니 kbhit와 getch만으로는 동시에 진행되는 게임을 구현하기는 어려울 것 같았다.
(2) 멀티 스레드?
두 번째로 찾아본 방법은 바로 멀티 스레드였다. 아직 배우지 않은 개념이라 어떻게 사용해야 하는지도 몰랐지만 구글에 이것저것 검색해보면서 시도해보았다. cin을 꼭 써야한다면, 사용자 입력을 기다리는 도중에도 다른 스레드가 계속 -1을 떨어뜨리도록 해보자는 생각이었다.
결과는 대실패. 내가 작성한 코드가 너무 미흡한 수준이었을까? 액세스를 위반했다는 에러가 거듭해서 발생했다.
에러에 대해 알아보니 배열을 읽고 쓰는 과정에서 에러가 발생할 위험이 높은 것 같았다. 현재 내 게임은 iArray 배열의 요소를 계속 바꿈으로써 0이 이동하고, 이걸 cout으로 계속 그려서 진행되는 게임이다. 즉, iArray의 값을 읽고 쓰는 과정이 매우 많이 발생한다는 것. 단순히 값을 변경하거나 cout으로 배열을 콘솔 창에 그리는 것 이외에도, 여러 가지 함수와 if문 등에서 iArray 배열의 요소를 계속 검사하는 과정이 이루어지고 있을 것이기 때문이다.
결과적으로 -1을 만들어내고 그 값을 배열의 높은 인덱스와 계속 교환하면서 -1을 떨어뜨리고 그걸 cout으로 그려내는 A 스레드와, 루프를 돌면서 기존의 배열 그리기 및 0 이동을 처리하는 B 스레드가 충돌하지 않을래야 않을 수 없는 상황. 즉 공유 자원 동시 접근 문제였다.
(3) mutex-lock 을 활용해보자
복잡한 게임들은 이런 상황일 때 어떻게 스레드 간 충돌 없이 프로그램을 진행시키는걸까 알아보았더니, 1차적으로 mutex라는 라이브러리를 활용해 스레드 간 동시 접근을 어느 정도 해결할 수 있는 것 같았다. A 스레드가 특정 공유 자원을 사용 중일 때 lock을 걸어 B 스레드가 동시에 같은 자원에 접근하지 못하도록 막는 개념인 것 같았다.
결과는 또 대실패였다. iArray라는 배열 하나만 가지고 진행되는 게임이어서, lock을 어디서부터 어디까지 걸어줘야 하는지 너무 많은 경우의 수가 있었다. 값을 쓰는 것 이외에도 읽을 때에도 lock을 걸어주는게 안전할 것 같은데, 코드 내내 계~속 읽고 쓰고 읽고 검사하고 이러는 와중에 다른 스레드에서 그 사이사이에 타이밍이 겹치지 않게 iArray에 접근해 -1을 만들어내고, 그걸 그리고, 이동시켜야 하는 것 같았다.
나름 촘촘하게 lock을 걸어주었다고 생각했지만 함수에서 다른 함수를 호출하는 과정에서 둘 다 lock이 걸려있어서 lcok이 영원히 풀리지 않는 이중 잠금도 발생하고, while문 내부에서 lock을 걸어버려서 또 영원히 풀리지 않는 Deadlock이 발생했다. 그렇게 몇 시간 멀티 스레드와 씨름을 하다 보니 지금 내 수준에서 이 방법으로 코드를 짜는건 무리라고 느껴졌다.
그렇게 포기하고 얼른 다른 공부나 이어서 할까 생각이 들었는데(놀고 있는 듯한 느낌이 들었다) 그래도 다른 방식으로 구현해볼 수 있을 것 같은 느낌이 들었다. -1이 위에서 내려오게 하는게 어렵다면 배열 군데군데에서 -1이 생겨나는 방식이라면 어떨까 떠올려 본 것이다.
결과는 꽤 나쁘지 않았다! cin 입력을 기다리는 동안에는 -1이 생성되지 않으니, 한 번에 너무 많은 -1이 생겨나는 일도 없었고 사용자가 입력을 한 번 할 때 똑같이 -1도 한 번 생겨나는 일종의 턴의 개념처럼 작용했다.
rand를 활용해서 -1을 생성하는데, rand에 % 나머지 연산자를 사용할 때의 특성상 나누는 수와 비슷한 크기의 수가 잘 나오지 않는다는 점 때문에 -1이 위쪽에서 주로 생겨났고, 목적지인 아래쪽 인덱스가 시작하자마자 -1로 도배되는 경우도 잘 없었던 것이다.
굉장히 미숙하고 간단한 프로그램이지만 잘 작동하는 걸 보니 엄청 뿌듯했다. 하루종일 이걸 잡고 씨름했는데 공부는 뒷전으로 하고 흥미에 정신이 팔려서 놀아버린게 아닐까 살짝 마음이 무겁기까지 했다.
그러나 냉정하게 생각해보아도 학습 효과(?)도 엄연히 있었던 것 같다! 구조체를 배운지 얼마 되지 않아서 구조체를 어떻게 활용해야 할까 어려움이 느껴졌었는데, -1 피하기를 만들면서 구조체 변수를 생성하고 그걸 함수끼리 인자로 넘겨주면서 일어나는 과정을 자연스럽게 반복하고 문법을 조금 더 익히게 된 것 같았다. 아직 코드의 구조를 설계할 때 논리적으로 짜는게 어려워서 자꾸만 같은 코드가 반복되고 함수의 재사용성이 떨어지는 문제가 발생하는데, 구조체를 조금 더 잘 다룰 수 있게 되면서 비슷한 기능을 하는 함수들을 하나로 합치고 불필요한 코드를 줄이는 법을 조금 더 익힐 수 있었다!!
아직 논리적 사고나 추론, 디버깅 능력 등이 전체적으로 너무 부족해서 벽에 부딪히고 막막하고 답답한 느낌이 들 때가 정말 많지만 가끔씩 이렇게 해보고 싶은 것이 생기거나, 게임에 활용해 볼 수 있는 내용이라고 직접적으로 느껴지거나 할 때 정말 재밌고 동기 부여가 된다. -1 피하기도 이렇게 만들어보면 재밌겠는데? 라고 생각이 들자마자 머릿속에서 뭔가 빡하고 강하게 오면서 관련된 내용을 정신없이 찾아보고 결국 활용하진 못했지만 -1을 생성하고 밑으로 움직이게 하는 코드도 연속적으로 열심히 만들어냈다. 이럴 때마다 끝까지 버티면 끝끝내 퀄리티 높은 게임을 만들어낼 수 있을 거라고 기대하면서 공부를 이어나갈 힘을 얻는다 ㅎㅎ
'게임 개발 공부 기록 > 게임을 만들고 싶은 이유' 카테고리의 다른 글
<Vector> 배우다 살면서 처음으로 공부로 쾌감 느낀 날 (1) | 2025.07.09 |
---|---|
강의 듣다 아이템 체크 로직 들었는데 졸음이 깼다 (1) | 2025.05.31 |
도전이라는 이름의 도박 (0) | 2025.05.21 |
게임 '개발'을 좋아하는게 맞아? (1) | 2025.05.21 |
실패와 포기의 연속, 열정은 소모품 (0) | 2025.04.17 |