/* : Dots and Boxes : : - hiroumauma */ #include #include #include #define ROWS 4 #define COLS 3 void show_field(); void my_cls(); void init_field(); int user_input(); int cpu_input(); int set_hr(unsigned int m, unsigned int n); int set_vt(unsigned int m, unsigned int n); int is_safe_hr(unsigned int m, unsigned int n); int is_safe_vt(unsigned int m, unsigned int n); int zone_mapping(); int set_hr_rand(); int set_vt_rand(); typedef enum { A = 0, B = 1, PLAIN = 2 } User; User now, player; #define SwitchUser(x) x^=1 char *fic[] = { "\x1b[41m AA \x1b[49m", "\x1b[44m BB \x1b[49m", " " }; char *hrc[] = { "\x1b[31m------\x1b[39m", "\x1b[34m------\x1b[39m", " " }; char *vtc[] = { "\x1b[31m|\x1b[39m" , "\x1b[34m|\x1b[39m" , " " }; int hr_edge[ROWS][COLS+1]; int vt_edge[ROWS+1][COLS]; int zone[ROWS][COLS]; int zcnt[ROWS][COLS]; int input[2]; int score[2]; int main() { init_field(); srand((unsigned) time(NULL)); player=(rand()%2); now=A; for(;;SwitchUser(now)) { show_field(); if(player == now){ if( user_input() == 1) break; } else { if( cpu_input() == 1) break; } if(zone_mapping()==1){ SwitchUser(now); } if( (score[0]+score[1]) >= (ROWS*COLS)) break; } show_field(); printf("GAME OVER!\n"); if( score[A] > score[B] ) printf("A win!\n"); if( score[A] < score[B] ) printf("B win!\n"); if( score[A] == score[B] ) printf("drawn!\n"); return 0; } void show_field() { int i,j,c=0; my_cls(); printf("YOU are %c\n","AB"[player]); for(j=0; j<(COLS+1); j++) { for(i=0; i<(ROWS+1); i++) { printf("%2d", c++); if(i!=(ROWS)) printf("%s", hrc[hr_edge[i][j]]); } printf("\n"); if(j!=COLS) { for(i=0; i<(ROWS); i++) printf(" %s%s",vtc[vt_edge[i][j]],fic[zone[i][j]]); printf(" %s\n",vtc[vt_edge[i][j]]); for(i=0; i<(ROWS); i++) printf(" %s%s",vtc[vt_edge[i][j]],fic[zone[i][j]]); printf(" %s\n",vtc[vt_edge[i][j]]); } } printf("SCORE A(%d) vs B(%d)\n", score[A], score[B]); } void my_cls() { setbuf(stdout,NULL); printf("\x1b[2J"); printf("\x1b[1;1H"); } void init_field() { int i,j; for(i=0; i<(ROWS+1); i++) for(j=0; j<(COLS) ; j++) vt_edge[i][j] = PLAIN; for(i=0; i<(ROWS) ; i++) for(j=0; j<(COLS+1); j++) hr_edge[i][j] = PLAIN; for(i=0; i<(ROWS) ; i++) for(j=0; j<(COLS) ; j++){ zone[i][j] = PLAIN; zcnt[i][j] = 0; } input[0] = input[1] = 0; score[0] = score[1] = 0; } int user_input() { char error = 0; int tmp; unsigned int m,n; for(;;) { printf("$"); scanf("%d,%d",&input[0], &input[1]); if( input[0] > input[1]) { tmp = input[1]; input[1] = input[0]; input[0] = tmp; } if( (input[0] >= ((ROWS+1)*(COLS+1))) || (input[0] < 0) || (input[1] >= ((ROWS+1)*(COLS+1))) || (input[1] < 0) ) { printf("input error\n"); continue; } switch( input[1] - input[0] ) { case 1: if(((input[1]) % (ROWS+1)) == 0 ) { printf("input error\n"); continue; } n = (input[0]/(ROWS+1)); m = (input[0]%(ROWS+1)); if( hr_edge[m][n]!=PLAIN ) { printf("input error\n"); continue; } error = set_hr(m,n); break; case (ROWS+1): n = (input[0]/(ROWS+1)); m = (input[0]%(ROWS+1)); if( vt_edge[m][n]!=PLAIN ) { printf("input error\n"); continue; } error = set_vt(m,n); break; default: printf("input error\n"); continue; break; } break; } return error; } int cpu_input() { unsigned int i,j; char error = 0; srand((unsigned) time(NULL)); for(i=0; i<(ROWS) ; i++) for(j=0; j<(COLS) ; j++) { if(zcnt[i][j] == 3) { if(hr_edge[i][j+1]==PLAIN){ return set_hr(i,j+1); } else if(vt_edge[i+1][j]==PLAIN){ return set_vt(i+1,j); } else if(hr_edge[i][j] ==PLAIN){ return set_hr(i,j); } else if(vt_edge[i][j] ==PLAIN){ return set_vt(i,j); } else { return 1; } } } if(rand()%2){ error = set_hr_rand(); if(error==1) error = set_vt_rand(); }else{ error = set_vt_rand(); if(error==1) error = set_hr_rand(); } return error; } int set_hr_rand() { unsigned int i,m,n; srand((unsigned) time(NULL)); m = rand()%(ROWS); n = rand()%(COLS+1); for( i=0; i < (2*(ROWS*(COLS+1))); i++) { switch(is_safe_hr(m,n)) { case 2: if(i < ((ROWS*(COLS+1))-1)) break; case 1: return set_hr(m,n); break; } m++; if(m>(ROWS-1)) { m = 0; n++; if(n>(COLS)) n = 0; } } return 1; } int set_vt_rand() { unsigned int i,m,n; srand((unsigned) time(NULL)); m = rand()%(ROWS+1); n = rand()%(COLS); for( i=0; i < (2*((ROWS+1)*COLS)); i++ ) { switch(is_safe_vt(m,n)) { case 2: if(i < (((ROWS+1)*COLS)-1)) break; case 1: return set_vt(m,n); break; } m++; if(m>(ROWS)) { m = 0; n++; if(n>(COLS-1)) n = 0; } } return 1; } int set_hr(unsigned int m,unsigned int n) { switch(hr_edge[m][n]) { case A: case B: return 1; break; case PLAIN: hr_edge[m][n] = now; if(n==0) { zcnt[m][n]++; } else if(n==COLS){ zcnt[m][n-1]++; } else { zcnt[m][n]++; zcnt[m][n-1]++; } return 0; break; default: break; } return 1; } int set_vt(unsigned int m, unsigned int n) { switch(vt_edge[m][n]) { case A: case B: return 1; break; case PLAIN: vt_edge[m][n] = now; if(m==0) { zcnt[m][n]++; } else if(m==ROWS){ zcnt[m-1][n]++; } else { zcnt[m][n]++; zcnt[m-1][n]++; } return 0; break; default: break; } return 1; } int is_safe_hr(unsigned int m, unsigned int n) { if(hr_edge[m][n]==PLAIN) { if(n==0) { return ( zcnt[m][n] < 2 )? 1 : 2; } else if(n==COLS){ return ( zcnt[m][n-1] < 2 )? 1 : 2; } else { return ( zcnt[m][n] < 2 && zcnt[m][n-1] < 2 )? 1 : 2; } } return 0; } int is_safe_vt(unsigned int m, unsigned int n) { if(vt_edge[m][n]==PLAIN) { if(m==0) { return ( zcnt[m][n] < 2 )? 1 : 2; } else if(m==ROWS){ return ( zcnt[m-1][n] < 2 )? 1 : 2; } else { return ( zcnt[m][n] < 2 && zcnt[m-1][n] < 2 )? 1 : 2; } } return 0; } int zone_mapping() { int i,j,f; f=0; for(i=0; i<(ROWS) ; i++) for(j=0; j<(COLS) ; j++) { if(zcnt[i][j] >= 4) { if(zone[i][j]==PLAIN) { zone[i][j] = now; score[now]++; f++; } } } return f; }