专栏文章

人机大战五子棋

休闲·娱乐参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miq9kowt
此快照首次捕获于
2025/12/04 01:11
3 个月前
此快照最后确认于
2025/12/04 01:11
3 个月前
查看原文
CPP
#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;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...