Skip to content

Instantly share code, notes, and snippets.

@kamiyaowl
Created September 5, 2014 16:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kamiyaowl/d637e6d308a5dff34166 to your computer and use it in GitHub Desktop.
Save kamiyaowl/d637e6d308a5dff34166 to your computer and use it in GitHub Desktop.
reversi kai
#include<stdio.h>
#define WIDTH 8
#define HEIGHT 8
#define EMPTY 0
#define BLACK 1
#define WHITE 2
#define TRUE 1
#define FALSE 0
int reversi_play_turn;
int reversi_player;
int reversi_gameover;
int field[HEIGHT][WIDTH];
//### initialize a game ###
void reversi_init(int player) {
int i,j;
for(j = 0 ; j < HEIGHT ; ++j){
for(i = 0 ; i < WIDTH ; ++i){
field[j][i] = EMPTY;
}
}
//initialize position
field[HEIGHT / 2 - 1][WIDTH / 2 - 1] = BLACK;
field[HEIGHT / 2 ][WIDTH / 2 - 1] = WHITE;
field[HEIGHT / 2 - 1][WIDTH / 2 ] = WHITE;
field[HEIGHT / 2 ][WIDTH / 2 ] = BLACK;
//other properties
reversi_player = player;
reversi_gameover = FALSE;
reversi_play_turn = 0;
}
// ### print a game status ###
void reversi_print(){
int i,j;
printf("<---------- turn %d ---------->\n",reversi_play_turn);
/* header */
printf(" |");
for(i = 0 ; i < WIDTH ; ++i){
printf("%2d |",i);
}
printf("\n");
/* field */
for(j = 0 ; j < HEIGHT ; ++j){
printf("%2d |",j);
for(i = 0 ; i < WIDTH ; ++i){
switch(field[j][i]){
case EMPTY:
printf(" |");
break;
case BLACK:
printf(" B |");
break;
case WHITE:
printf(" W |");
break;
default:
break;
}
}
printf("\n");
}
}
// ### check and reverse stone (recursive function) ###
// bw : BLACK or WHITE
// reverse_it : reverse stone if can reverse it
// x : location x
// y : location y
// dx : reverse direction x
// dy : reverse direction y
// return value : can reverse it
int reversi_reverse(int reverse_it,int bw,int x,int y,int dx,int dy){
if(x < 0 || WIDTH <= x) return FALSE;
if(y < 0 || HEIGHT <= y) return FALSE;
if(field[y][x] == EMPTY) return FALSE;
if(field[y][x] == bw) return TRUE;
else {
if(reversi_reverse(reverse_it,bw,x + dx,y + dy, dx, dy)){
if(reverse_it) field[y][x] = bw;
return TRUE;
} else return FALSE;
}
}
// ### check between same color stone and reverse
// bw : BLACK or WHITE
// x : put location x
// y : put location y
// return value : can reverse direction count
int reversi_reverse_others(int bw,int x,int y){
int dir_count = 0;
dir_count += reversi_reverse(TRUE, bw,x, y - 1, 0, -1);//up
dir_count += reversi_reverse(TRUE, bw,x, y + 1, 0, 1);//down
dir_count += reversi_reverse(TRUE, bw,x - 1, y, -1, 0);//left
dir_count += reversi_reverse(TRUE, bw,x + 1, y, 1, 0);//right
dir_count += reversi_reverse(TRUE, bw,x - 1, y - 1, -1, -1);//up left
dir_count += reversi_reverse(TRUE, bw,x + 1, y - 1, 1, -1);//up right
dir_count += reversi_reverse(TRUE, bw,x - 1, y + 1, -1, 1);//down left
dir_count += reversi_reverse(TRUE, bw,x + 1, y + 1, 1, 1);//down right
return dir_count;
}
// ### check can put a stone
// bw : BLACK or WHITE
// return value : can put
int reversi_can_put(int bw){
int x,y;
for(y = 0 ; y < HEIGHT ; ++y){
for(x = 0 ; x < WIDTH ; ++x){
if(field[y][x] != EMPTY) continue;
if(reversi_reverse(FALSE, bw,x, y - 1, 0, -1)) return TRUE;//up
if(reversi_reverse(FALSE, bw,x, y + 1, 0, 1)) return TRUE;//down
if(reversi_reverse(FALSE, bw,x - 1, y, -1, 0)) return TRUE;//left
if(reversi_reverse(FALSE, bw,x + 1, y, 1, 0)) return TRUE;//right
if(reversi_reverse(FALSE, bw,x - 1, y - 1, -1, -1)) return TRUE;//up left
if(reversi_reverse(FALSE, bw,x + 1, y - 1, 1, -1)) return TRUE;//up right
if(reversi_reverse(FALSE, bw,x - 1, y + 1, -1, 1)) return TRUE;//down left
if(reversi_reverse(FALSE, bw,x + 1, y + 1, 1, 1)) return TRUE;//down right
}
}
return FALSE;
}
// ### put a stone ###
//bw : put stone is black or white?
//x : put location x
//y : put location y
//return value : can put stone.
int reversi_put(int x,int y){
/* area check */
if(x < 0 || WIDTH <= x) return FALSE;
if(y < 0 || HEIGHT <= y) return FALSE;
/* already put */
if(field[y][x] != EMPTY) return FALSE;
/* put */
if(reversi_reverse_others(reversi_player,x,y) > 0){
field[y][x] = reversi_player;
reversi_play_turn++;
/* change player */
reversi_player = reversi_player == BLACK ? WHITE : BLACK;
if(!reversi_can_put(reversi_player)){
//skip next player
reversi_player = reversi_player == BLACK ? WHITE : BLACK;
if(!reversi_can_put(reversi_player)){
reversi_gameover = TRUE;
}
}
return TRUE;
} else return FALSE;
}
// ### output a game result ###
void reversi_result(){
int i,j;
int black_count = 0,white_count = 0;
for(j = 0 ; j < HEIGHT ; ++j){
for(i = 0 ; i < WIDTH ; ++i){
switch(field[j][i]){
case BLACK:
black_count++;
break;
case WHITE:
white_count++;
break;
default:
break;
}
}
}
printf("<===== %d =====>\n",reversi_play_turn);
printf("BLACK %d : WHITE %d\n",black_count,white_count);
printf("Winner %s\n",black_count < white_count ? "WWHITE" : "BLACK");
}
int main(void) {
int put_x,put_y;
/* initialize reversi */
reversi_init(WHITE);
reversi_print();
while(!reversi_gameover) {
printf("%s's turn>",reversi_player == WHITE ? "WHITE" : "BLACK");
/* user input */
scanf("%d %d",&put_x, &put_y);
/* put */
if(reversi_put(put_x, put_y)){
reversi_print();
} else {
/* miss */
printf("cannot put a stone.\n");
}
}
reversi_result();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment