当前位置:   article > 正文

五元组评价算法实现简易五子棋【人工智能】_五子棋五元组

五子棋五元组

一、实验题目

       五子棋游戏算法设计,方法不限。
       以两人为一组,分为甲方和乙方对弈。各自设计自己的算法: 针对对方下的每一步骤棋落子,由算法给出相应的本方落子,最终胜者只有一个。

二、实验环境

       Windows 10,Visual Studio 2019,编程语言C++

三、实验原理

【实验说明】
  • 本实验所实现的五子棋为简易的人机交互版本
  • 为简单处理,我们假定人为黑手,即黑棋先下
  • 不考虑禁手等规则
【核心算法】

本实验核心算法是五元组评价算法。基本思路如下:
       评估当前棋局中所有位置得分,机器落在得分最高的位置。
       五子棋取胜条件是哪方5个棋子先连成线,哪方获胜。那么我们将五个相连的位置称为五元组。以15 * 15的棋盘为例,有572个五元组。
       针对五元组中黑子和白子的数量情况的不同(不考虑相对位置,只看数量,共10种情况),对该五元组评分,如下表。每一个位置的得分就是包含这个位置的所有五元组的得分之和。评价表的好坏一定程度上决定了实验结果,本实验所采用的是一个比较出色的评价表,经过测试,所带来的结果也比较好。

五元组评价表
情况	得分
1	既有黑子又有白子	0
2	既没有黑子也没有白子	7
3	有1个白子	35
4	有2个白子	800
5	有3个白子	15000
6	有4个白子	800000
7	有1个黑子	15
8	有2个黑子	400
9	有3个黑子	1800
10	有4个黑子	100000

以评价横向的五元组为例,部分代码如下:

//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;
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
【五子棋流程图】

在这里插入图片描述

四、实验结果

【初始棋盘】【说明:若输入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 (
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/336433?site
推荐阅读
相关标签
  

闽ICP备14008679号