VC实现五子棋游戏的一个算法示例_C 语言

本文讲述了VC实现五子棋游戏的一个算法示例,该算法采用极大极小剪枝博弈算法,感兴趣的读者可以对程序中不完善的部分进行修改与完善。

该设计主要包括:数据结构、估值函数、胜负判断、搜索算法

程序运行界面如下:

具体实现步骤如下:

1、数据结构

//记录每步棋,可以建立链表用来进行悔棋、后退(本程序没有实现)
struct Step
{
 int x,y; //棋子坐标
 int ball; //表示下子方{BLACK,WHITE}
};
//记录棋盘情况,用于搜索过程
class CBoardSituation
{
 public:
 int nArrBoard[15][15]; //棋盘情况
 struct Step machineStep; //AI所下的那一步
 long value; //盘面所打的分数
};
//当前棋盘,用于棋盘显示
int nArrBoard[15][15];

2、估值函数

分析当前棋盘上黑白双方棋型:五连、活四、冲四、双活三、单活三、眠三、活二、眠二,然后根据五子棋规则给棋盘打分,
具体分值可以根据经验自己确定。本程序中:五连=9999(极值),活四=9990,冲四=9980,双活三=9970,多活三加2000,
单活三加200,每个眠三加10,每个活二加4,每个眠二加1。其中打分时还要根据当前下棋方情况进行打分。

3、胜负判断

这个比较简单,根据最后落子情况从水平、垂直、左斜、右斜四个方向检查是否存在五个连续棋子即可。

4、搜索算法

算法采用极大极小值博弈算法,它的主要思想为:预测后N步下棋情况,对预测的后N个棋盘进行打分。轮到自己下棋时选分值最大的,轮到对方下时选分值最小的。选出我们认为最优的作为下一步走法。本程序算法基本思想如下(算法语言表示):

void DFAI()
{
 long value=-MAXINT; //对初始根节点的value赋值
 CBoardSituation currentBoard;
 //获取当前机器新棋面情况
 for(int i=0;i<15;i++)
 for(int j=0;j<15;j++)
  currentBoard.nArrBoard[i][j]=nArrBoard[i][j];
 currentBoard.machineStep.ball=ComputerBall;
 currentBoard.machineStep.x=gnRow;
 currentBoard.machineStep.y=gnColumn;
 currentBoard.value=Eveluate(currentBoard.nArrBoard,BLACK);
 //选取几个最好的下法(贪婪法)-->CountList;
 GetSeveralGoodPlace(¤tBoard,WHITE);
 CountList.RemoveAll();
 POSITION pos=templist.GetHeadPosition();
 for(int j=0;j {
 CountList.AddTail(templist.GetNext(pos));
 }
 pos=CountList.GetHeadPosition();
 CBoardSituation *pBoard;
 //对这些盘面做进一步深度搜索
 for(i=0;i {
 pBoard= &(CountList.GetNext(pos));
 pBoard->value=Search(pBoard,BLACK,value,0);
 value=Select(value,pBoard->value,WHITE); //找出最大的分值
 }
 //回到链表头
 pos=CountList.GetHeadPosition();
 for(i=0;i {
 pBoard= &(CountList.GetNext(pos));
 if (value==pBoard->value) //找出得到最高分的盘面
 {
  value=pBoard->value;
  gnRow=pBoard->machineStep.x;
  gnColumn=pBoard->machineStep.y;
  bPlayerDo=TRUE; //当前下子方改为人
  break;
 }
 }
 //其他处理
}
其中Search()函数如下:
//算法搜索函数
long Search(CBoardSituation *board,int mode,long &oldvalue, int depth)
{
 CList m_DeepList;
 long value;
 if(depthnArrBoard,mode))<8000)
 {
 value=(mode==WHITE)?-MAXINT:MAXINT;
 //选择几个最好的搜索目标
 GetSeveralGoodPlace(board,mode);
 POSITION pos=templist.GetHeadPosition();
 for(int j=0;j {
  m_DeepList.AddTail(templist.GetNext(pos));
 }
 pos=m_DeepList.GetHeadPosition();
 CBoardSituation successorBoard;
 for(int i=0;i {
  successorBoard= m_DeepList.GetNext(pos);
  //是否进行继续深度搜索(剪枝):极大极小值法
  if((mode==WHITE && value<=oldvalue) || (mode==BLACK && value>=oldvalue))
  {
  if(mode==WHITE)
   value=Select(value,Search(&successorBoard,BLACK,value,depth+1),WHITE);
  else//mode==BLACK
   value=Select(value,Search(&successorBoard,WHITE,value,depth+1),BLACK);
  }
 }
 return value;
 }
 else//搜索结束条件
 {
 return Eveluate(board->nArrBoard,mode);//棋面打分
 }
 return 0;
} 

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索算法
, 五子棋
, 游戏
vc
五子棋算法 c语言代码、c语言五子棋算法、c语言剪枝算法五子棋、五子棋算法、五子棋人机对战算法,以便于您获取更多的相关知识。

时间: 2025-01-27 03:55:21

VC实现五子棋游戏的一个算法示例_C 语言的相关文章

C语言实现基于最大堆和最小堆的堆排序算法示例_C 语言

堆定义堆实际上是一棵完全二叉树,其任何一非叶节点满足性质: Key[i]<=key[2i+1]&&Key[i]<=key[2i+2](小顶堆)或者:Key[i]>=Key[2i+1]&&key>=key[2i+2](大顶堆) 即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字. 堆排序的思想利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单. 最大堆:所有节点的子节点比其自身

C++快速幂与大数取模算法示例_C 语言

一.快速幂 其实就是求(a^b)% p ,(其中a,b,p都比较大在int范围内)这类问题. 首先要知道取余的公式: (a*b)%p=(a%p*b%p)%p . 那么幂不就是乘机的累积吗,由此给出代码: int fast(int a,int b,int p) { long long a1=a,t=1; while(b>0) { if(b&1) /如果幂b是奇数多乘一次,因为后边会除2变偶数,(7/2=3) t=(t%p)*(a1%p)%p; a1=(a1%p)*(a1%p)%p; b/=2;

c语言实现冒泡排序、希尔排序等多种算法示例_C 语言

实现以下排序 插入排序O(n^2) 冒泡排序 O(n^2) 选择排序 O(n^2) 快速排序 O(n log n) 堆排序 O(n log n) 归并排序 O(n log n) 希尔排序 O(n^1.25) 1.插入排序 O(n^2) 一般来说,插入排序都采用in-place在数组上实现.具体算法描述如下:⒈ 从第一个元素开始,该元素可以认为已经被排序⒉ 取出下一个元素,在已经排序的元素序列中从后向前扫描⒊ 如果该元素(已排序)大于新元素,将该元素移到下一位置⒋ 重复步骤3,直到找到已排序的元素

VC++实现选择排序算法简单示例_C 语言

本文以一个非常简单的实例说明VC++选择排序算法的实现方法,对n个记录进行n-1趟简单选择排序,在无序区中选取最小记录. 具体实现代码如下: #include<iostream> using namespace std; //简单选择排序 void SelectSort(int r[ ], int n) { int i; int j; int index; int temp; for (i=0; i<n-1; i++) //对n个记录进行n-1趟简单选择排序 { index=i; for

桶排序算法的理解及C语言版代码示例_C 语言

理解:桶排序是计数排序的变种,把计数排序中相邻的m个"小桶"放到一个"大桶"中,在分完桶后,对每个桶进行排序(一般用快排),然后合并成最后的结果.基本思想:桶排序假设序列由一个随机过程产生,该过程将元素均匀而独立地分布在区间[0,1)上.我们把区间[0,1)划分成n个相同大小的子区间,称为桶.将n个记录分布到各个桶中去.如果有多于一个记录分到同一个桶中,需要进行桶内排序.最后依次把各个桶中的记录列出来记得到有序序列.效率分析:桶排序的平均时间复杂度为线性的O(N+C

C语言解决螺旋矩阵算法问题的代码示例_C 语言

赶集网校招就采用了螺旋输出矩阵作为程序题,要求将矩阵螺旋输出如: 图中6*6矩阵线条所示为输出顺序,如果输出正确的话应该输出1~36有序数字.  我想的是这么做的: #include <stdio.h> //#define LEN 1 //#define LEN 2 //#define LEN 3 #define LEN 4 void printClock(int a[][LEN]){//输出函数 int t; int i = 0, m = 0; int j = LEN, n = LEN; w

C/C++实现八大排序算法汇总_C 语言

概述排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短: 1. 插入排序-直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已

VC获取当前路径及程序名的实现代码_C 语言

一.获取当前运行目录的绝对路径 1.使用GetCurrentDirectory函数 假设程序路径为D:\Test\tst.exe,执行GetCurrentDirectory函数 char pBuf[MAX_PATH]; GetCurrentDirectory(MAX_PATH,pBuf); pBuf="D:\Test" 但是如果使用CFileDialog.CFile::Open等函数后,设置不当则会导致再次获取当前路径值改变.所以,如要避免当前路径改变,如果使用CFileDialog,

C语言实现选择排序、冒泡排序和快速排序的代码示例_C 语言

选择和冒泡 #include<stdio.h> void maopao(int a[],int len){ int i,j,temp; for(i = 0;i < len - 1 ; i ++){//从第一个到倒数第二个 for (j = 0 ; j < len - 1 - i ; j ++)//排在后的是已经排序的 { if (a[j] > a[j + 1])//大的数换到后面去 { temp = a[j]; a[j] = a[j + 1]; a [j + 1] = tem