Mega Code Archive
REVERSI An Othello type game
/*
Beginning C, Third Edition
By Ivor Horton
ISBN: 1-59059-253-0
Published: Apr 2004
Publisher: apress
*/
#include
#include
#define SIZE 6 /* Board size - must be even */
/* Function prototypes */
void display(char board[][SIZE]);
int valid_moves(char board[][SIZE], int moves[][SIZE], char player);
void make_move(char board[][SIZE], int row, int col, char player);
void computer_move(char board[][SIZE], int moves[][SIZE], char player);
int best_move(char board[][SIZE], int moves[][SIZE], char player);
int get_score(char board[][SIZE], char player);
void main()
{
char board [SIZE][SIZE] = { 0 }; /* The board */
int moves[SIZE][SIZE] = { 0 }; /* Valid moves */
int row = 0; /* Board row index */
int col = 0; /* Board column index */
int no_of_games = 0; /* Number of games */
int no_of_moves = 0; /* Count of moves */
int invalid_moves = 0; /* Invalid move count */
int comp_score = 0; /* Computer score */
int user_score = 0; /* Player score */
char y = 0; /* Column letter */
int x = 0; /* Row number */
char again = 0; /* Replay choice input */
int player = 0; /* Player indicator */
printf("\nREVERSI\n\n");
printf("You can go first on the first game, then we will take turns.\n");
printf(" You will be white - (O)\n I will be black - (@).\n");
printf("Select a square for your move by typing a digit for the row\n "
"and a letter for the column with no spaces between.\n");
printf("\nGood luck! Press Enter to start.\n");
scanf("%c", &again);
/* Prompt for how to play - as before */
/* The main game loop */
do
{
/* On even games the player starts; */
/* on odd games the computer starts */
player = ++no_of_games % 2;
no_of_moves = 4; /* Starts with four counters */
/* Blank all the board squares */
for(row = 0; row < SIZE; row++)
for(col = 0; col < SIZE; col++)
board[row][col] = ' ';
/* Place the initial four counters in the center */
board[SIZE/2 - 1][SIZE/2 - 1] = board[SIZE/2][SIZE/2] = 'O';
board[SIZE/2 - 1][SIZE/2] = board[SIZE/2][SIZE/2 - 1] = '@';
/* The game play loop */
do
{
display(board); /* Display the board */
if(player++ % 2)
{ /* It is the player's turn */
if(valid_moves(board, moves, 'O'))
{
/* Read player moves until a valid move is entered */
for(;;)
{
fflush(stdin); /* Flush the keyboard buffer */
printf("Please enter your move (row column): ");
scanf("%d%c", &x, &y); /* Read input */
y = tolower(y) - 'a'; /* Convert to column index */
x--; /* Convert to row index */
if( x>=0 && y>=0 && x= SIZE ||
col + coldelta < 0 || col + coldelta >= SIZE ||
(rowdelta==0 && coldelta==0))
continue;
/* Now check the square */
if(board[row + rowdelta][col + coldelta] == opponent)
{
/* If we find the opponent, move in the delta direction */
/* over opponent counters searching for a player counter */
x = row + rowdelta; /* Move to */
y = col + coldelta; /* opponent square */
/* Look for a player square in the delta direction */
for(;;)
{
x += rowdelta; /* Go to next square */
y += coldelta; /* in delta direction*/
/* If we move outside the array, give up */
if(x < 0 || x >= SIZE || y < 0 || y >= SIZE)
break;
/* If we find a blank square, give up */
if(board[x][y] == ' ')
break;
/* If the square has a player counter */
/* then we have a valid move */
if(board[x][y] == player)
{
moves[row][col] = 1; /* Mark as valid */
no_of_moves++; /* Increase valid moves count */
break; /* Go check another square */
}
}
}
}
}
return no_of_moves;
}
/************
* Finds the best move for the computer. This is the move for *
* which the opponent's best possible move score is a minimum. *
* First parameter is the board array. *
* Second parameter is the moves array containing valid moves. *
* Third parameter identifies the computer. *
************/
void computer_move(char board[][SIZE], int moves[][SIZE], char player)
{
int row = 0; /* Row index */
int col = 0; /* Column index */
int best_row = 0; /* Best row index */
int best_col = 0; /* Best column index */
int i = 0; /* Loop index */
int j = 0; /* Loop index */
int new_score = 0; /* Score for current move */
int score = 100; /* Minimum opponent score */
char temp_board[SIZE][SIZE]; /* Local copy of board */
int temp_moves[SIZE][SIZE]; /* Local valid moves array */
char opponent = (player == 'O')? '@' : 'O'; /* Identify opponent */
/* Go through all valid moves */
for(row = 0; row < SIZE; row++)
for(col = 0; col < SIZE; col++)
{
if(moves[row][col] == 0)
continue;
/* First make copies of the board and moves arrays */
for(i = 0; i < SIZE; i++)
for(j = 0; j < SIZE; j++)
temp_board[i][j] = board[i][j];
/* Now make this move on the temporary board */
make_move(temp_board, row, col, player);
/* find valid moves for the opponent after this move */
valid_moves(temp_board, temp_moves, opponent);
/* Now find the score for the opponents best move */
new_score = best_move(temp_board, temp_moves, opponent);
if(new_score= SIZE ||
col + coldelta < 0 || col + coldelta >= SIZE ||
(rowdelta==0 && coldelta== 0))
continue;
/* Now check the square */
if(board[row + rowdelta][col + coldelta] == opponent)
{
/* If we find the opponent, search in the same direction */
/* for a player counter */
x = row + rowdelta; /* Move to opponent */
y = col + coldelta; /* square */
for(;;)
{
x += rowdelta; /* Move to the */
y += coldelta; /* next square */
/* If we are off the board give up */
if(x < 0 || x >= SIZE || y < 0 || y >= SIZE)
break;
/* If the square is blank give up */
if(board[x][y] == ' ')
break;
/* If we find the player counter, go backwards from here */
/* changing all the opponents counters to player */
if(board[x][y] == player)
{
while(board[x-=rowdelta][y-=coldelta]==opponent) /* Opponent? */
board[x][y] = player; /* Yes, change it */
break; /* We are done */
}
}
}
}
}