메뉴
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);
}



결과