ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 결!합! C++로 만들기-게임 플레이
    게임개발 2021. 7. 14. 11:25

    모든 빌드업이 끝났기 때문에, 이제 게임을 시작할 것이다.

    우선, 긴장감을 유발하기 위한 카운트다운이 시작된다.

    clear();
    printf("3");
    Sleep(1000);
    clear();
    printf("2");
    Sleep(1000);
    clear();
    printf("1");
    Sleep(1000);
    clear();

    그 뒤, 몇 가지 사전 초기화 과정을 거친다.

    findedanswer.clear();
    t = 999;
    score = 0;
    makenewboard();
    findhap();
    printboard();
    gotoxy(0, 15);
    printf("남은 시간:     초\n점수: 0000점");

    게임판 생성, 남은 시간과 점수 초기화 등이 이루어진다. 이제 시간을 점점 줄이면서, 다음 과정이 진행된다.

    while (t > 0) {
    	gotoxy(11, 15);
    	printf("%02d.%d", t / 10, t % 10);

    남은 시간을 초기화해주는 과정이다.

    만약 사용자가 키보드를 눌렀다면, 무엇을 눌렀는지에 따라 행동이 달라진다.

    우선 누른 버튼을 읽어온다.

    if (_kbhit()) {
    	ch = _getch();

     

     

    누른 버튼이 알파벳이라면, '합'에 포함될 칸을 누른 것이므로 다음과 같이 var이라는 변수를 바꾸어 준다.

    if (ch >= 'a' && ch <= 'z') {
    	var = charcode[ch - 'a'];
    }
    else if (ch >= 'A' && ch <= 'Z') {
    	var = charcode[ch - 'A'];
    }

    누른 버튼이 enter(아스키코드: 13)이면 var을 -2로, 의미 없는 다른 문자라면 -1로 설정한다.

    3*3 사각형 내에 있지 않은 문자들에 대해서는 charcode 배열의 값이 -1이다. 즉, var==-1이면 아무 일도 일어나지 않을 것이다.

    else if (ch == 13) {
    	var = -2;
    }
    else {
    	var = -1;
    }

    이제 var값에 따른 분기가 일어난다. 먼저 var이 0 이상이라면, 게임판의 9칸 중 하나를 고른 것이다.

    이 경우, 이미 고른 칸이라면 선택을 해제하고, 고르지 않은 칸이라면 새롭게 선택해야 한다.

    if (var >= 0) {
    	it = user.find(var);
    	if (it == user.end()) {
    		user.insert(var);
    		gridline(var % 3, var / 3, 1);
    	}
    	else {
    		user.erase(it);
    		gridline(var % 3, var / 3, 0);
    	}

    만약 선택한 칸이 3개라면, '합'을 외친 것으로 간주하여 합인지 체크한다.

    if (user.size() == 3) {
    	it = user.begin();
    	h.a = (*it);
    	it++;
    	h.b = (*it);
    	it++;
    	h.c = (*it);
    	hit = answer.find(h);

    h에 합을 저장하고, answer이라는 합 set에서 h를 찾는다.

    이 합이 없다면, 점수를 1점 감점하고, 사용자에게 "오답! -1점"을 보여준다.

    if (hit == answer.end()) {
    	gotoxy(6, 16);
    	score--;
    	if (score < 0) {
    		printf("-%03d", -score);
    	}
    	else {
    		printf("%04d", score);
    	}
    	gotoxy(0, 17);
    	printf("오답! -1점");
    	Sleep(1000);
    	gotoxy(0, 17);
    	printf("          ");
    	gotoxy(0, 17);
    }

    멍청한!

    이 합이 있다면, 합 목록에서 이것을 삭제하고(중복된 답을 말하면 안 되기 때문), 점수를 1점 늘리고, 지금까지 찾은 합 목록에 이것을 추가한 뒤 "정답! +1점"을 보여준다.

    else {
    	answer.erase(hit);
    	gotoxy(6, 16);
    	score++;
    	if (score < 0) {
    		printf("-%03d", -score);
    	}
    	else {
    		printf("%04d", score);
    	}
    	gotoxy(0, 17);
    	printf("정답! +1점");
    	findedanswer.push_back(h);
    	gotoxy(0, 17 + findedanswer.size());
    	printf("%d %d %d", h.a + 1, h.b + 1, h.c + 1);
    	Sleep(1000);
    	gotoxy(0, 17);
    	printf("          ");
    	gotoxy(0, 17);
    }

    합을 맞힌!

    그리고 선택한 3개에 부여된 하이라이트 효과를 제거하고, 사용자가 선택한 3개의 칸에 대한 정보도 삭제한다.

    for (it = user.begin(); it != user.end(); it++) {
    	gridline((*it) % 3, (*it) / 3, 0);
    }
    user.clear();

    이제 '합'을 외쳤을 때의 처리가 끝났으며, 9칸 중 하나를 선택했을 때의 처리도 끝났다.

    '결'을 외쳤을 때의 처리를 알아보자. 이 경우에는 남은 답이 있는지 없는지에 따라 그 후의 처리가 달라질 것이다.

    else if (var == -2) {

    만약 남은 답이 있다면, 점수를 1점 줄이고 "오답! -1점"을 보여준다.

    if (answer.size()) {
    	gotoxy(6, 16);
    	score--;
    	if (score < 0) {
    		printf("-%03d", -score);
    	}
    	else {
    		printf("%04d", score);
    	}
    	gotoxy(0, 17);
    	printf("오답! -1점");
    	Sleep(1000);
    	gotoxy(0, 17);
    	printf("          ");
    	gotoxy(0, 17);
    }

    아쉬운!

    남은 답이 없다면, 결을 성공한 것이므로 점수를 3점 늘리고, "정답! +3점"을 보여주고, 새로운 판을 만든다. 저 긴 출력문은 지금까지 발견된 합을 지우는 용도이다.

    else {
    	gotoxy(6, 16);
    	score += 3;
    	if (score < 0) {
    		printf("-%03d", -score);
    	}
    	else {
    		printf("%04d", score);
    	}
    	gotoxy(0, 17);
    	printf("정답! +3점");
    	Sleep(1000);
    	gotoxy(0, 17);
    	printf("          \n     \n     \n     \n     \n     \n     \n     \n     \n     \n     \n     \n     \n     \n     \n     \n     \n     \n     \n     \n     \n     ");
    	findedanswer.clear();
    	gotoxy(0, 17);
    	makenewboard();
    	findhap();
    	printboard();
    }

    결을 실패하는 확률은...거의 없어요

    이제 키보드를 누름으로써 발생하는 이벤트는 모두 끝났다. 이제 0.1초의 딜레이를 주고, 남은 시간을 줄이기만 하면 끝이다.

    Sleep(100);
    t--;

    게임이 끝나면, 현재 모드와 점수를 보여준다.

    clear();
    printf("모드:");
    strpr(mode[mode_num] + "\n");
    str = "게임 종료\n점수: ";
    oneprint();
    printf("%d\n", score);
    str = "메인 화면으로: m\n다시 시작: r\n게임 종료: o";
    oneprint();

    사용자가 키보드를 클릭하면 그 뒤 행동이 달라진다.

    while (1) {
    	ch = _getch();
    	switch (ch) {
    	case 'm':
    	case 'M':
    		goto title;
    	case 'r':
    	case 'R':
    		goto start;
    	case 'o':
    	case 'O':
    		goto ended;
    	default:
    		break;
    	}
    }

    원라이프와 아케이드 모드는 다음 글에서 다루겠다.

    댓글

Designed by Tistory.