Omok Game (Connect-5 Game; 오목)
22 FEBRUARY 2012
개요
아래 코드는 바둑판 위에 랜덤하게 바둑돌을 배치했을 때,
전체 바둑판에서 오목의 개수가 각각 몇개인지 세는 프로그램이다.
이미 체크한 바둑돌을 다시 체크하지 않게 하기 위해서,
각 방향(가로, 세로, 대각선)별로 각각 한번만 지나가면서 체크하도록 했다.
오목이외의 6목 7목... 등도 찾도록 했고, if문만 걸어주면 '오목'만 찾도록 할 수 있다.
발견 지점을 좌표로 표기하도록 했고, 코드의 양을 최소화하는데 목적을 두고 코딩했다.
코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | #include <stdio.h> #include <stdlib.h> #define MAX 19 void draw_MAP( int oMAP[][MAX], int NUM_STONE); void result ( int w, int b); void initialize ( int d[]); void find5 ( int a[][MAX], int i, int j, int d[]) ; void check_HV ( int a[][MAX], int *w, int *b); void check_D ( int a[][MAX], int *w, int *b); void printf_MAP ( int a[][MAX]); void main() { int w=0,b=0; int oMAP[MAX][MAX]; int USER_INPUT,NUM_STONE; do { printf ( " Input any integer 0 ~ 2147483647 to generate map > " ); scanf_s( "%d" ,&USER_INPUT); } while (USER_INPUT<0 || USER_INPUT>2147483647); // Get user input for a random seed do { printf ( " Input any integer number of stones 50 ~ 150 > " ); scanf_s( "%d" ,&NUM_STONE); } while (NUM_STONE<50 || NUM_STONE>150); // Get user input for the number of each stone srand (USER_INPUT); draw_MAP(oMAP,NUM_STONE*2); // Draw the 'omok' map printf_MAP(oMAP); // Print the map check_HV (oMAP,&w,&b); // Check Horizontal check_D (oMAP,&w,&b); // Check Diagonal result(w,b); // Print result } void draw_MAP( int oMAP[][MAX], int NUM_STONE){ int i,j,k; for (i=0;i<MAX;i++) for (j=0;j<MAX;j++) oMAP[i][j] = 0; // Initialize for (i=0;i<NUM_STONE;){ j= rand ()%MAX; k= rand ()%MAX; // Get random location if (oMAP[j][k] == 0){ oMAP[j][k] = i%2 + 1; i++;} // Check Duplication // If it is duplicated, find another location } } void initialize ( int d[]){ if (d[0]>=5) {d[4]=(d[3]*2-3)*d[0];} // Check the counter if counter is 5, 5-set-complete has color information. d[0]=0; d[3]=0; // Initialize counter and color information. } void find5 ( int a[][MAX], int i, int j, int d[]) { /********************************************************* For the array 'd' 0: counter, 1: X_before, 2: Y_before, 3: COLOR_before, 4: 5-or-more-set-complete, 5: BLACK_counter, 6:WHITE_counter, 7, 8: Coordinate Offset. *********************************************************/ if (d[3] == a[i][j] && a[i][j]>0) { // if current color is same as before, counter is increased. d[0]++; } else { // if it is different, counter becomes 1. if (d[0]>=5) {d[4]=(d[3]*2-3)*d[0];} // Check the counter if counter is 5, 5-set-complete has color information. d[0]=1; } if (d[4] <= -5) { printf ( " (%d-White at (x,y): (%2d,%2d)~(%2d,%2d))\n" ,d[4]*(-1),d[2]+(d[7]*(d[4]+1)*(-1)+1),d[1]+(d[8]*(d[4]+1)*(-1)+1),d[2]+1,d[1]+1); d[5]++; // Increase Black counter d[4]=0; // Initialize 5-or-more-set-complete } if (d[4] >= 5) { printf ( " (%d-Black at (x,y): (%2d,%2d)~(%2d,%2d))\n" ,d[4],d[2]+(d[7]*(d[4]-1)+1),d[1]+(d[8]*(d[4]-1)+1),d[2]+1,d[1]+1); d[6]++; // Increase White counter d[4]=0; // Initialize 5-or-more-set-complete } // Print out 5-or-more-set-complete color and the information of its location. // And then initialize color information and increase the COLOR counter. d[1]=i; d[2]=j; d[3]=a[i][j]; // Save current i, j, color information for the next pass. } void result ( int w, int b){ // Print the result printf ( " [ RESULT ] White: %d, Black: %d ----- " ,w,b); (w>b) ? printf ( "White Win!" ) : ((w==b)? printf ( "Draw!" ) : printf ( "Black Win!" )); printf ( "\n\n" ); } void check_HV ( int a[][MAX], int *w, int *b) { int i,j; int d[11] = {0,0,0,0,0,0,0,-1,0}; // horizontal int e[11] = {0,0,0,0,0,0,0,0,-1}; // vertical // 0: counter, 1: X_before, 2: Y_before, 3: COLOR_before, // 4: 5-or-more-set-complete, 5: BLACK_counter, 6:WHITE_counter, // 7, 8: Coordinate Offset. for (i=0;i<MAX;i++){ initialize (d); // For a new row of horizontal check, Do initialize initialize (e); // Same as vertical cols. for (j=0;j<MAX;j++){ find5(a, i, j, d); // find 5-or-more-set-complete of horizontal find5(a, j, i, e); // find 5-or-more-set-complete of vertical } } find5(a, i, j, d); // find 5-or-more-set-complete of horizontal for the last several stones find5(a, j, i, e); // find 5-or-more-set-complete of vertical for the last several stones printf ( " [ Horizontal ] White: %d, Black: %d\n" ,d[5],d[6]); printf ( " [ Vertical ] White: %d, Black: %d\n\n" ,e[5],e[6]); // print partial results *w += d[5]+e[5]; *b += d[6]+e[6]; // 'w' and 'b' for the final result } void check_D ( int a[][MAX], int *w, int *b) { int i,j,k; int d[11] = {0,0,0,0,0,0,0,-1,1}; // diagonal ↗ËO int e[11] = {0,0,0,0,0,0,0,1,1}; // diagonal ↘ËU for (i=0,j=0,k=0;i<MAX*MAX;i++){ if (j>=0 && k<MAX) { // For NOT out of range find5(a, j, k, d); // find 5-or-more-set-complete of diagonal ↗ find5(a, j, MAX-1-k, e); // find 5-or-more-set-complete of diagonal ↘ j--; k++; // Next move } if (j<0 || k==MAX) { // Check out of range initialize (d); // Initialize initialize (e); if (k==MAX) { k=j+k-MAX+2; j=MAX-1; } else { j=j+k+1; k=0; } // Set next location } } printf ( " [ Diagonal↗ ] White: %d, Black: %d\n" ,d[5],d[6]); printf ( " [ Diagonal↘ ] White: %d, Black: %d\n\n" ,e[5],e[6]); // print partial results *w += d[5]+e[5]; *b += d[6]+e[6]; // 'w' and 'b' for the final result } void printf_MAP ( int a[][MAX]) { int i,j,k,l=0,m=0; char base[9][4] = { "┌" , "┬" , "┐" , "├" , "┼" , "┤" , "└" , "┴" , "┘" }; // An Array for Omok board printf ( "\n " ); for (i=0;i<MAX;i++){ printf ( "%2d" ,i+1); // print col numbers } printf ( "\n" ); for (i=0;i<MAX;i++){ printf ( " %2d " ,i+1); // print row numbers for (j=0;j<MAX;j++){ if (a[i][j] == 0) { k=0; if (i > 0 && i<MAX-1) k+=3; // Middle rows if (i==MAX-1) k+=6; // Border of bottom if (j > 0 && j<MAX-1) k+=1; // Middle cols if (j ==MAX-1) k+=2; // Border of right printf ( "%s" ,base[k]); // Print board shape } else if (a[i][j] == 1) { printf ( "○" ); l++; // Counter for white stones } else if (a[i][j] == 2) { printf ( "●" ); m++; // Counter for black stones } } printf ( "\n" ); } printf ( "\n Check the number of stones >\n White: %d, Black: %d\n\n" ,l,m); } |
결과