一、实验题目
五子棋游戏算法设计,方法不限。
以两人为一组,分为甲方和乙方对弈。各自设计自己的算法: 针对对方下的每一步骤棋落子,由算法给出相应的本方落子,最终胜者只有一个。
二、实验环境
Windows 10,Visual Studio 2019,编程语言C++
三、实验原理
【实验说明】
- 本实验所实现的五子棋为简易的人机交互版本
- 为简单处理,我们假定人为黑手,即黑棋先下
- 不考虑禁手等规则
【核心算法】
本实验核心算法是五元组评价算法。基本思路如下:
评估当前棋局中所有位置得分,机器落在得分最高的位置。
五子棋取胜条件是哪方5个棋子先连成线,哪方获胜。那么我们将五个相连的位置称为五元组。以15 * 15的棋盘为例,有572个五元组。
针对五元组中黑子和白子的数量情况的不同(不考虑相对位置,只看数量,共10种情况),对该五元组评分,如下表。每一个位置的得分就是包含这个位置的所有五元组的得分之和。评价表的好坏一定程度上决定了实验结果,本实验所采用的是一个比较出色的评价表,经过测试,所带来的结果也比较好。
以评价横向的五元组为例,部分代码如下:
//1、扫描横向的15行
for (int i = 0; i < size; i++) //对于每一行来说
{
for (int j = 0; j < size - 4; j++)
{
int k = j;
while (k < j + 5) //统计每个五元组的黑白棋数量
{
if (ChessBoard[i][k] == black)
bn++;
else if (ChessBoard[i][k] == white)
wn++;
k++;
}
//五元组中白子黑子中对应的数量的打分
tupleScoreTmp = scoreTable(bn, wn);
//为该五元组的5个位置添加分数
for (k = j; k < j + 5; k++)
score[i][k] += tupleScoreTmp;
//计数器们清零
bn = 0;
wn = 0;
tupleScoreTmp = 0;
}
}
【五子棋流程图】
四、实验结果
【初始棋盘】【说明:若输入2 5,则表示第2行、第5列】
【机器(白手)胜】
【人(黑手)胜】
五、完整代码
#include <iostream>
using namespace std;
#include <string>
#include <Windows.h>
#define size 15 //棋盘大小
//核心 【五元组评分算法】
string ChessBoard[size][size]; //棋盘,二维数组实现
int score[size][size]; //评分表
string white = "-●"; //白棋 由于控制台是黑色的,所以反着
string black = "-○"; //黑棋
string board = "-┼-"; //棋盘线 表示无子落下
void initBoard(); //初始化棋盘
void printBoard(); //打印棋盘
int scoreTable(int w, int b); //五元组评分
bool machine(int& goalX, int& goalY); //机器落子
int judge(int flag, int x, int y); //判断输赢
int cnt = 0;
int main()
{
//初始化棋盘
initBoard();
printBoard();
cout << "【说明】若输入2 5,则表示第2行,第5列" << endl;
while (1) //设置一个无限循环
{
//简单版 始终让人类执黑手
cout << "人(黑手)落子:";
int hx, hy;
cin >> hx >> hy;
//判断人的落子是否合法 因为人先手 所以是否平局只在机器落子中判断即可
while (1)
{
if (hx >= 1 && hx <= size && hy >= 1 && hy <= size && ChessBoard[hx - 1][hy - 1] == board)
break; //输入合法,跳出循环
else
{
cout << "人(黑手)落子不合法,请重新输入:";
cin >> hx >> hy;
}
}
//更新棋盘
ChessBoard[hx - 1][hy - 1] = black;
printBoard();
cout << "人(黑手)落子完成" << endl << endl;
//判断棋局胜负
if (judge(1,hx - 1,hy - 1))
{
cout << "人(黑手)胜出!!!" << endl;
break;
}
//人落子处理完成
/********************************************************************/
//开始处理机器落子
//机器 白手
int wx, wy;
//白手落子
if