C黑白棋

#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);   
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
黑白棋,又叫反棋(Reversi)、奥赛罗棋(Othello)、苹果棋或翻转棋。黑白棋在西方和日本很流行。游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负。 棋子:黑白棋棋子每颗由黑白两色组成,一面白,一面黑,共64个(包括棋盘中央的4个)。棋子呈圆饼形。    棋盘:黑白棋棋盘由64格的正方格组成,游戏进行时棋子要下在格内。棋盘可分为“角”、“边”以及黑白棋“中腹”。现今的棋盘多以8x8较为普遍。 棋钟:正式的比赛中可以使用棋钟对选手的时间进行限制。非正式的对局中一般不使用棋钟。 黑白棋的棋盘是一个有8*8方格的棋盘。下棋时将棋下在空格中间,而不是像围棋一样下在交叉点上。开始时在棋盘正中有两白两黑四个棋子交叉放置,黑棋总是先下子。    下子的方法把自己颜色的棋子放在棋盘的空格上,而当自己放下的棋子在横、竖、斜八个方向内有一个自己的棋子,则被夹在中间的全部翻转会成为自己的棋子。 并且,只有在可以翻转棋子的地方才可以下子。  如果玩家在棋盘上没有地方可以下子,则该玩家对手可以连下。双方都没有棋子可以下时棋局结束,以棋子数目来计算胜负,棋子多的一方获胜。在棋盘还没有下满时,如果一方的棋子已经被对方吃光,则棋局也结束。将对手棋子吃光的一方获胜。     每个“翻转棋”游戏开始时,棋盘上已经交叉放好了四颗棋子。其中两颗是黑棋,另两颗是白棋。黑棋总是先走。    当您的棋子在某一直线方向包围了对手的棋子时,就可以翻转这些棋子的颜色,使它们成为您方的颜色。例如,如果您执黑棋,并且看到在一排白棋的某一端是一颗黑棋,那么当您将一颗黑棋放在这一排的另一端时,所有的白棋都将翻转并变为黑棋!   所有的直线方向均有效:水平、垂直和斜线方向。    走棋的唯一规则是只能走包围并翻转对手的棋子。每一回合都必须至少翻转一颗对手的棋子。    按规则不能再走棋时,这一回合弃权。计算机会自动将控制权交给对方。 得分 “翻转棋”的计分方法非常简单。游戏过程中随时都显示黑棋数与白棋数。结束时棋数最多的一方就是赢家。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值