-
결!합! C++로 만들기-결!합! 시스템게임개발 2021. 5. 10. 21:03
타이틀을 만들었고, 게임 진행 부분을 만들기 전에 게임판을 만들고, '합'을 찾고, 몇 가지 그래픽적인 사항을 먼저 구현할 필요가 있었다. 그렇기에 오늘은 이것을 다루도록 하겠다.
우선, 게임판을 만들어야 하는데, space, txt, shape라는 3*3 배열 3개를 만들었다. 이는 각각 배경색, 글자색, 모양을 의미한다.
int space[3][3], txt[3][3], shape[3][3];
makenewboard 함수를 호출하면, 저 3개의 배열이 랜덤으로 지정된다. 각각 종류가 3개이므로, 0~2의 값이 들어간다. 또한, 중복을 피하기 위한 코드도 작성한다.
void makenewboard() { srand((int)time(NULL)); bool b; int k; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { b = true; while (b) { b = false; space[i][j] = rand() % 3; txt[i][j] = rand() % 3; shape[i][j] = rand() % 3; for (k = 0; k < 3 * i + j; k++) { if (space[k / 3][k % 3] == space[i][j] && txt[k / 3][k % 3] == txt[i][j] && shape[k / 3][k % 3] == shape[i][j])b = true; } } } } }
게임판을 만들면, 그 판에서 합을 모두 찾아야 한다. 합은 3개의 칸의 번호로 표현되는데, 이를 표현하기 위한 클래스를 만들었다(구조체로 해도 된다)
class hap { public: int a, b, c; hap() { a = 0; b = 0; c = 0; } hap(int A, int B, int C) { a = A; b = B; c = C; } bool operator <(const hap& h)const { if (a != h.a)return a < h.a; if (b != h.b)return b < h.b; return c < h.c; } };
operator <가 정의된 이유는, 셋으로 합들을 관리하기 위해서다. 합을 관리할 셋과, 참조를 위한 iterator를 만들어준다.
set<hap>answer; set<hap>::iterator hit;
또한, 사용자가 고른 칸들을 저장하기 위해서 셋을 미리 만들어두자. 역시, iterator도 만들어준다.
set<int>user; set<int>::iterator it;
이제, 모든 합을 찾아서 셋에 넣어주자.
void findhap() { user.clear(); answer.clear(); int i, j, k; for (i = 0; i < 9; i++) { for (j = i + 1; j < 9; j++) { for (k = j + 1; k < 9; k++) { if (ishap(i, j, k))answer.insert(hap(i, j, k)); } } } }
한 줄이 길어지는 것을 막기 위해 ishap이라는 함수를 사용하였다.
bool ishap(int a, int b, int c) { return ishapminimum(space[a / 3][a % 3], space[b / 3][b % 3], space[c / 3][c % 3]) && ishapminimum(txt[a / 3][a % 3], txt[b / 3][b % 3], txt[c / 3][c % 3]) && ishapminimum(shape[a / 3][a % 3], shape[b / 3][b % 3], shape[c / 3][c % 3]); }
모두 같거나 모두 다른지를 ishapminimum 함수를 통해 전달받는다.
bool ishapminimum(int x, int y, int z) { if (x == y && y == z)return true; if (x != y && y != z && z != x)return true; return false; }
이제 생성된 게임판을 화면에 출력해야 한다. 그 전에, 각 배경색, 모양 색의 코드(색 지정 함수에 전달할 인수)를 spacenum, txtnum이라는 배열에 저장했고, 3개의 모양 역시 spacenum 배열에 저장하였다.
int spacenum[3] = { 0,8,15 }; int txtnum[3] = { 12,10,9 }; string shapenum[3] = { "●","▲","■" };
배경색은 순서대로 검정/회색/흰색이고, 모양 색은 순서대로 빨강/초록/파랑이다.
게임판 출력은 printboard함수가 해 준다.
void printboard() { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 16 * spacenum[space[i][j]] + txtnum[txt[i][j]]); gotoxy(10 * j + 2, 5 * i + 1); printf(" "); gotoxy(10 * j + 2, 5 * i + 2); strpr(" " + shapenum[shape[i][j]] + " "); gotoxy(10 * j + 2, 5 * i + 3); printf(" "); } } SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15); gotoxy(0, 15); }
10*5 공간 하나 당 한 칸을 차지하며, 배경은 그 안에 6*3 공간에 채워진다(이렇게 말하면 가로로 길쭉한 것 같지만, 1*1 공간은 스페이스 키 한 번 누르는 공간이기 때문에 1*1이 세로로 길쭉하다). 그리고, 그 중심에 도형이 그 색에 맞게 그려진다.
사용자가 특정 칸을 선택하면 주변으로 노란 테두리가 생기는데, gridline이라는 함수가 이 일을 한다.
void gridline(int x, int y, int z) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 224 * z); gotoxy(10 * x, 5 * y); printf(" "); gotoxy(10 * x, 5 * y + 4); printf(" "); for (int i = 1; i < 4; i++) { gotoxy(10 * x, 5 * y + i); printf(" "); gotoxy(10 * x + 8, 5 * y + i); printf(" "); } SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15); gotoxy(0, 15); }
이제 모든 준비가 끝났다. 이 기능들을 이용하여, 이제 게임을 시작하자.
'게임개발' 카테고리의 다른 글
결!합! C++로 만들기-게임 플레이 (0) 2021.07.14 결!합! C++로 만들기-로비, 게임 설명/설정 (2) 2021.04.02 게임개발 1-많이 쓰는 기능들 (0) 2021.02.27