人机大战五子棋

· · 休闲·娱乐

#include <bits/stdc++.h>
using namespace std;

const int BOARD_SIZE=15;
enum Piece {EMPTY,HUMAN,AI};

class Gomoku
{
    private:
        vector<vector<Piece>> board;
    public:
        Gomoku():board(BOARD_SIZE, vector<Piece>(BOARD_SIZE, EMPTY)){}

        void printBoard()
        {
            cout<<"  ";
            for (int i=0;i<BOARD_SIZE;++i) cout<<i%10<<" ";
            cout<<endl;

            for (int i=0;i<BOARD_SIZE;++i)
            {
                cout<<i%10<<" ";
                for(int j=0;j<BOARD_SIZE;++j)
                {
                    char c;
                    switch(board[i][j])
                    {
                        case HUMAN:c='X';break;
                        case AI:c='O';break;
                        default:c='.';break;
                    }
                    cout<<c<<" ";
                }
                cout<<endl;
            }
        }

        // 判断胜负
        bool checkWin(int row, int col, Piece player)
        {
            vector<pair<int, int>> direction={{1,0}, {0,1}, {1,1}, {1,-1}};
            for(auto& dir:direction)
            {
                int count=1;
                int dx=dir.first,dy=dir.second;

                for(int i=1;;i++)
                {
                    int x=row+dx*i;
                    int y=col+dy*i;
                    if (x<0 || x>=BOARD_SIZE || y<0 || y>=BOARD_SIZE || board[x][y]!=player) break;
                    count++;
                }
                for(int i=1;;i++)
                {
                    int x=row-dx*i;
                    int y=col-dy*i;
                    if (x<0 || x>=BOARD_SIZE || y<0 || y>=BOARD_SIZE || board[x][y]!=player) break;
                    count++;
                }

                if(count>=5) return true;
            }
            return false;
        }

        // 评估位置得分
        int Score(int row, int col, Piece player)
        {
            int score=0;
            vector<pair<int,int>> direction={{1,0}, {0,1}, {1,1}, {1,-1}};

            for(auto& dir:direction)
            {
                int dx=dir.first,dy=dir.second;
                int consecutive=1;
                int openEnds=0;

                bool blocked=false;
                for (int i=1;i<5;i++)
                {
                    int x=row+dx*i;
                    int y=col+dy*i;
                    if (x<0 || x>=BOARD_SIZE || y<0 || y>=BOARD_SIZE)
                    {
                        blocked=true;
                        break;
                    }
                    if (board[x][y]==player)
                    {
                        consecutive++;
                    }
                    else
                    {
                        if(board[x][y]==EMPTY) openEnds++;
                        break;
                    }
                }
                for(int i=1;i<5;i++)
                {
                    int x=row-dx*i;
                    int y=col-dy*i;
                    if(x<0 || x>=BOARD_SIZE || y<0 || y>=BOARD_SIZE)
                    {
                        blocked=true;
                        break;
                    }
                    if(board[x][y]==player)
                    {
                        consecutive++;
                    }
                    else
                    {
                        if(board[x][y]==EMPTY) openEnds++;
                        break;
                    }
                }

                // 评分规则
                if (consecutive>=5) score+=100000;
                else if (consecutive==4 && openEnds>=1) score+=10000;
                else if (consecutive==3 && openEnds>=2) score+=1000;
                else if (consecutive==2 && openEnds>=2) score+=100;
            }
            return score;
        }

        // AI决策
        pair<int,int> aiMove()
        {
            int bestScore=-1e9;
            pair<int,int> bestMove;

            for(int i=0;i<BOARD_SIZE;++i)
            {
                for(int j=0;j<BOARD_SIZE;++j)
                {
                    if(board[i][j]==EMPTY)
                    {
                        int Score1=Score(i, j, AI); // 进攻得分
                        int Score2=Score(i, j, HUMAN); // 防守得分
                        int Score3=Score1+Score2*0.7;
                        if (Score3>bestScore)
                        {
                            bestScore=Score3;
                            bestMove={i, j};
                        }
                    }
                }
            }
            return bestMove;
        }

        void startGame()
        {
            bool flot=1;
            while(1)
            {
                printBoard();
                if(flot)
                {
                    int row,col;
                    cout<<"please enter the coordinates(0-14):";
                    while(!(cin>>row>>col) || row<0 || row>=BOARD_SIZE || col<0 || col>=BOARD_SIZE || board[row][col]!=EMPTY)
                    {
                        cin.clear();
                        cin.ignore(1e9,'\n');
                        cout<<"Invalid input, please re-enter:";
                    }
                    board[row][col]=HUMAN;
                    if(checkWin(row,col,HUMAN))
                    {
                        printBoard();
                        cout<<"You Win!"<<endl;
                        break;
                    }
                }
                else
                {
                    cout<<"AI is thinking..."<<endl;
                    auto move=aiMove();
                    board[move.first][move.second]=AI;
                    cout<<"AI's coordinate:"<<move.first<<" "<<move.second<<endl;
                    if (checkWin(move.first, move.second, AI))
                    {
                        printBoard();
                        cout<<"AI Win!"<<endl;
                        break;
                    }
                }
                flot=!flot;
            }
        }
};

int main()
{
    Gomoku game;
    game.startGame();
    return 0;
}