지난번 글에서는 move() 함수는 'move'답게 만들고
다른 함수가 move()를 반복하여 한 판을 조정하여,
main()에서는 판을 반복하게 했습니다.
물론 제가 five_in_a_row()에 단 주석과 약간 다릅니다.
제 주석에 따르면 플레이어가 재경기를 원할 때 재경기를 시켜 줘야 합니다.
게다가 원래 게임과도 약간 달라져 버렸지요.
그.러.나.
그 점은 미뤄 두고, 일단 다른 부분을 시작하도록 하죠. (-_-ㅗ;;)
이번에는 판을 그리는 부분을 바꾸어 보겠습니다.
switch-case 부분이 너무 길어서 저 내부를 한 함수로 빼낼 수 있으면 좋겠군요.
#define BOARD_SIZE 19 void board_write(int x, int y) { x *= 2; gotoxy(x, y); if (x == 0) { if (y == 0) puts("┌"); else if (y == (BOARD_SIZE - 1)) puts("└"); else puts("├"); } else if (x == (BOARD_SIZE - 1) * 2) { if (y == 0) puts("┐"); else if (y == (BOARD_SIZE - 1)) puts("┘"); else puts("┤"); } else { if (y == 0) puts("┬"); else if (y == (BOARD_SIZE - 1)) puts("┴"); else puts("┼"); } }
판 크기는 맨 위에 따로 정의한 후,
전각 문자의 크기로 인한 문제는 board_write()에서 해결하도록 합니다.
move()에서는 x도 한 칸씩만 움직이게 해야겠습니다.
그러면 check()에서도 돌이 일렬로 있는지 검사하기 위해 x를 1씩만 움직여도 되고,
코드를 오히려 줄일 수 있습니다.
또한 move()의 switch-case의 각 방향키 case 안에서,
필요 없는 연산을 수행하고 있습니니다.
예를 들자면,
y += 1;
oldy = y - 1;
이 있겠습니다. 이런 건,
oldy = y;
y++;
(더 줄여서 oldy = y++;)
로 만들 수 있습니다.
이런 식으로 코드를 2차 개선하면 five_in_a_row.h는 아래와 같이 바뀝니다.
/* five_in_a_row.h * by ZFanta & UNique */ #ifndef FIVE_IN_A_ROW #define FIVE_IN_A_ROW #include "tool.h" #define UP 72 #define DOWN 80 #define LEFT 75 #define RIGHT 77 #define ENTER 13 #define BOARD_SIZE 19 int x = 0, y = 0; int oldx = 0, oldy = 0; int board[BOARD_SIZE][BOARD_SIZE]; int turn = 1; char who[3][3] = {"", "흑", "백"}; char stone[3][3] = {"", "○", "●"}; int check(int x, int y, int turn) { int px, py; int count; // 가로로 오목이 있는지 검사 px = x; py = y; count = 0; while(px > 1 && board[px-1][y] == turn) px--; while(px < BOARD_SIZE && board[px][y] == turn) { px++; count++; } if(count == 5) return 1; // 세로로 오목이 있는지 검사 px = x; py = y; count = 0; while(py > 0 && board[x][py-1] == turn) py--; while(py < BOARD_SIZE && board[x][py++] == turn) count++; if(count == 5) return 1; // 좌상우하로 오목이 있는지 검사 px = x; py = y; count = 0; while(px > 0 && py > 0 && board[px-1][py-1] == turn) px--, py--; while(px < BOARD_SIZE && py < BOARD_SIZE && board[px][py++] == turn) { px++; count++; } if(count == 5) return 1; // 우상좌하로 오목이 있는지 검사 px = x; py = y; count = 0; while(px < BOARD_SIZE && py > 0 && board[px+1][py-1] == turn) px++, py--; while(px >= 0 && py < BOARD_SIZE && board[px][py++] == turn) { px--; count++; } if(count == 5) return 1; return 0; } int knock(int x, int y) { if(board[x][y] != 0) { gotoxy(x * 2, y); puts(stone[board[x][y]]); return 0; } else return 1; } void board_write(int x, int y) { x *= 2; gotoxy(x, y); if (x == 0) { if (y == 0) puts("┌"); else if (y == (BOARD_SIZE - 1)) puts("└"); else puts("├"); } else if (x == (BOARD_SIZE - 1) * 2) { if (y == 0) puts("┐"); else if (y == (BOARD_SIZE - 1)) puts("┘"); else puts("┤"); } else { if (y == 0) puts("┬"); else if (y == (BOARD_SIZE - 1)) puts("┴"); else puts("┼"); } } void draw() { int i, j; for (i = 0; i < BOARD_SIZE; i++) for (j = 0; j < BOARD_SIZE; j++) board_write(i, j); } int move() { char input = 0; input = getch(); switch(input) { case UP : if(y > 0) { oldy = y--; gotoxy(x * 2, y); puts("⊙"); if(knock(x, oldy)) board_write(x, oldy); } return 1; break; case DOWN : if(y < BOARD_SIZE - 1) { oldy = y++; gotoxy(x * 2, y); puts("⊙"); if(knock(x, oldy)) board_write(x, oldy); } return 1; break; case LEFT : if(x > 0) { oldx = x--; gotoxy(x * 2, y); puts("⊙"); if(knock(oldx, y)) board_write(oldx, y); } return 1; break; case RIGHT : if(x < BOARD_SIZE - 1) { oldx = x++; gotoxy(x * 2, y); puts("⊙"); if(knock(oldx, y)) board_write(oldx, y); } return 1; break; case ENTER : if(board[x][y] == 0) { board[x][y] = turn; gotoxy(x * 2, y); puts(stone[turn]); if(check(x, y, turn)) { return 0; } turn++; if(turn == 3) turn = 1; } return 1; break; } return 1; } int five_in_a_row() { /* If user wants to re-match, returns 0; or not, returns 1. * (only if one game successfully ended) */ int i, j; system("CLS"); draw(); for (i = 0; i < BOARD_SIZE; i++) for (j = 0; j < BOARD_SIZE; j++) board[i][j] = 0; while (move()); system("CLS"); printf("%s 승리\n", who[turn]); system("PAUSE"); return 0; } #endif
뭐 내친 김에 draw()도 write_board()를 이용하도록 바꾸어 버렸습니다.
이번에 move() 바꾸는 게 가장 중요한 작업인데 어느 정도 성공입니다.
지난번 20줄 정도 늘렸던 게 이번에 거기서 110줄 정도 줄었군요.
뭐 C 파일에서 분리하고, 헤더 하나 더 만든 것까지 포함하면 아직 멀었지만...
다음에는 check()을 좀 바꿔 봐야겠습니다.
'Sablog Models > 자작자작' 카테고리의 다른 글
환타 오목 게임 재구성. (5) (0) | 2009.11.12 |
---|---|
C 언어로 .cdic 파일을 xml로 만드는 프로그램 만드는 중. (0) | 2009.09.21 |
환타 오목 게임 재구성. (4) (0) | 2009.09.17 |
환타 오목 게임 재구성. (3) (1) | 2009.06.13 |
환타 오목 게임 재구성. (1) (1) | 2009.06.06 |