#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#include <string.h>
#define SIZE 8
const char comp_c = 'X';
const char player_c = 'O';
void display(char board[][SIZE]);
int valid_moves(char board[][SIZE],bool moves[][SIZE],char player);
void make_move(char board[][SIZE],int row,int col,char player);
void computer_move(char board[][SIZE],bool moves[][SIZE],char player);
int best_move(char board[][SIZE],bool moves[][SIZE],char player);
int get_score(char board[][SIZE],char player);
int main(void)
{
char board[SIZE][SIZE] = {0};
bool moves[SIZE][SIZE] = { false };
int row = 0;
int col = 0;
int no_of_games = 0;
int no_of_moves = 0;
int invalid_moves = 0;
int comp_score = 0;
int user_score = 0;
char y = 0;
int x = 0;
char again = 0;
bool next_player = true;
do
{
next_player = !next_player;
no_of_moves = 4;
for (row=0;row<SIZE;row++)
for (col=0;col<SIZE;col++)
board[row][col] = ' ';
int mid = SIZE/2;
board[mid-1][mid-1] = board[mid][mid] = player_c;
board[mid-1][mid] = board[mid][mid-1] = comp_c;
do
{
display(board);
if(next_player = !next_player)
{
//玩家下棋
if(valid_moves(board,moves,player_c))
{
//invalid_moves = 0;
for(;;)
{
printf("输入下子位置:\n");
scanf("%d%c",&x,&y);
y = tolower(y) - 'a';
x--;
if(x>=0 && y>=0 && x<SIZE && y<SIZE && moves[x][y])
{
make_move(board,x,y,player_c);
no_of_moves++;
break;
}
else
{
printf("下子位置错误,请重新输入.\n");
}
}
}
else
{
if(++invalid_moves<2)
{
printf("无可落子位置,按回车结束本回合.\n");
//scanf("%c",&again);
}
else
printf("双方无子可落,游戏结束.\n");
}
}
else
{
//电脑落子
if(valid_moves(board,moves,comp_c))
{
invalid_moves = 0;
computer_move(board,moves,comp_c);
no_of_moves++;
}
else
{
if(++invalid_moves<2)
printf("无可落子位置,交换回合.\n");
else
printf("双方无子可落,游戏结束.\n");
}
}
}while(no_of_moves<SIZE*SIZE && invalid_moves<2);
display(board);
comp_score = user_score = 0;
for(row=0;row<SIZE;row++)
for(col=0;col<SIZE;col++)
{
comp_score += board[row][col]== comp_c;
user_score += board[row][col]== player_c;
}
printf("The final score is:\n");
printf("Computer:%d\nUser:%d\n\n",comp_score,user_score);
printf("Want play again(y/n):");
fflush(stdin);
scanf("%c",&again);
}while(tolower(again)=='y');
printf("\nGoodbye\n");
system("pause");
return 0;
}
int valid_moves(char board[][SIZE],bool moves[][SIZE],char player) //求可落子位置
{
int rowdelta = 0;
int coldelta = 0;
int x = 0;
int y = 0;
int no_of_moves = 0;
char opponent = (player==player_c)? comp_c : player_c;
//逻辑棋盘初始化
for (int row=0;row<SIZE;row++)
for (int col=0;col<SIZE;col++)
moves[row][col] = false;
//遍历棋盘所有位置
for (int row=0;row<SIZE;row++)
for (int col=0;col<SIZE;col++)
{
if(board[row][col]!=' ')
continue;
for(rowdelta = -1;rowdelta <=1; rowdelta++)
for(coldelta = -1;coldelta <=1;coldelta++) //遍历八个方向是否有对方棋子
{
if(row+rowdelta<0||row+rowdelta>=SIZE||
col+coldelta<0||col+coldelta>=SIZE||
(rowdelta==0 && coldelta==0))
continue;
if(board[row+rowdelta][col+coldelta]==opponent)
{
x = row + rowdelta;
y = col + coldelta;
for(;;)
{
x += rowdelta;
y += coldelta;
if(x<0 || x>=SIZE || y<0 || y>=SIZE)
break;
if(board[x][y]==' ')
break;
if(board[x][y]==player)
{
moves[row][col] = true;
no_of_moves++;
break; //跳出周围棋子检查 ,继续遍历剩余可下子位置
}
}
}
}
}
return no_of_moves;
}
void display(char board[][SIZE])
{
char col_label = 'a';
printf("\n ");
for(int col=0;col<SIZE;col++)
printf(" %c",col_label+col);
printf("\n");
for (int row=0;row<SIZE;row++)
{
printf(" +");
for (int col=0;col<SIZE;col++)
printf("---+");
printf("\n%2d|",row+1);
for (int col=0;col<SIZE;col++)
printf(" %c |",board[row][col]);
printf("\n");
}
printf(" +");
for (int col=0;col<SIZE;col++)
printf("---+");
printf("\n");
}
void make_move(char board[][SIZE],int row ,int col, char player)
{
int rowdelta = 0;
int coldelta = 0;
int x = 0 ;
int y = 0;
char opponent = (player==player_c) ? comp_c:player_c;
board[row][col] = player;
for (rowdelta=-1;rowdelta<2;rowdelta++)
for (coldelta=-1;coldelta<2;coldelta++)
{
if(row+rowdelta<0||row+rowdelta>=SIZE||
col+coldelta<0||col+coldelta>=SIZE||
(rowdelta==0&&coldelta==0))
continue;
if(board[row+rowdelta][col+coldelta]==opponent)
{
x = row + rowdelta;
y = col + coldelta;
for(;;)
{
x += rowdelta;
y += coldelta;
if(x<0||x>=SIZE||y<0||y>=SIZE)
break;
if(board[x][y]==' ')
break;
if(board[x][y] == player)
{
while(board[x-=rowdelta][y-=coldelta] == opponent)
board[x][y] = player;
break;
}
}
}
}
}
int get_score(char board[][SIZE],char player)
{
int score = 0;
char opponent = (player == player_c)? comp_c : player_c;
for(int row=0; row < SIZE ;row++)
for(int col=0; col < SIZE ;col++)
{
score -= board[row][col]==opponent;
score += board[row][col]==player;
}
return score;
}
int best_move(char board[][SIZE],bool moves[][SIZE],char player)
{
char opponent = (player == player_c)? comp_c : player_c;
char new_board[SIZE][SIZE] = {0};
int score = 0;
int new_score = 0;
for(int row=0;row<SIZE;row++)
for(int col=0;col<SIZE;col++)
{
if(!moves[row][col])
continue;
memcpy(new_board,board,sizeof(new_board));
make_move(new_board,row,col,player);
new_score = get_score(new_board,player);
if(score<new_score)
score = new_score;
}
return score;
}
void computer_move(char board[][SIZE],bool moves[][SIZE],char player)
{
int best_row = 0;
int best_col = 0;
int new_score = 0;
int score = 100;
char temp_board[SIZE][SIZE];
bool temp_moves[SIZE][SIZE];
char opponent = (player == player_c)? comp_c : player_c;
for(int row=0;row<SIZE;row++)
for(int col=0;col<SIZE;col++)
{
if(!moves[row][col])
continue;
memcpy(temp_board,board,sizeof(temp_board));
make_move(temp_board,row,col,player);
valid_moves(temp_board,temp_moves,opponent);
new_score = best_move(temp_board,temp_moves,opponent);
if(new_score<score)
{
score = new_score;
best_row = row;
best_col = col;
}
}
make_move(board,best_row,best_col,player);
}
C黑白棋
最新推荐文章于 2021-05-24 17:35:58 发布