ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 결!합! 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);
    }

    합 3 6 9

    이제 모든 준비가 끝났다. 이 기능들을 이용하여, 이제 게임을 시작하자.

    댓글

Designed by Tistory.