C# winform GDI+ 五子棋 (二):根据博弈算法写的人机AI(抄的别人的)


class GameAI
{
/// <summary>
/// 符合条件的落子点(周围有棋子)
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private bool hasne(int x, int y)
{
for (int i = (x - 2 > 0 ? x - 2 : 0); i <= x + 2 && i < 18; ++i)
for (int j = (y - 2 > 0 ? y - 2 : 0); j <= y + 2 && j < 18; ++j)
// if (i != 0 || j != 0)
if (CheckBoard.ChessPieces[i][j] != 0)
return true;
return false;
}
/// <summary>
/// 生成待分析数组
/// </summary>
private void generatepoint()
{
CheckBoard.BlankPieces.Clear();
for (int i = 0; i < 18; ++i)
for (int j = 0; j < 18; ++j)
if (CheckBoard.ChessPieces[i][j] == 0 && hasne(i, j))
{
CheckBoard.BlankPieces.Add(new Piece(i, j));
}
}
/// <summary>
/// 分数评估
/// </summary>
/// <param name="number"></param>
/// <param name="empty1"></param>
/// <returns></returns>
private int scoretable(int number, int empty1)
{
if (number >= 5) return 100000;
else if (number == 4)
{
if (empty1 == 2) return 10000;//活
else if (empty1 == 1) return 1000;//死
}
else if (number == 3)
{
if (empty1 == 2) return 1000;
else if (empty1 == 1) return 100;
}
else if (number == 2)
{
if (empty1 == 2) return 100;
else if (empty1 == 1) return 10;
}
else if (number == 1 && empty1 == 2) return 10;
return 0;
}
/// <summary>
/// 正斜线、反斜线、横、竖,均转成一维数组来计算
/// </summary>
/// <param name="pieces"></param>
/// <param name="flag"></param>
/// <returns></returns>
private int countscore(Piece[] pieces, int flag)
{
int scoretmp = 0;
int empty1 = 0;//死活
int number = 0;
//1:黑子 2:白子
if (pieces[0].Flag == 0) ++empty1;
else if (pieces[0].Flag == flag) number++;
for (int i = 1; i < pieces.Length; i++)
{
if (pieces[i] == null) break;
if (pieces[i].Flag == flag)
{
number++;
}
else if (pieces[i].Flag == 0)
{
if (number == 0) empty1 = 1;
else
{
scoretmp += scoretable(number, empty1 + 1);
empty1 = 1;
number = 0;
}
}
else
{
scoretmp += scoretable(number, empty1);
empty1 = 0;
number = 0;
}
} scoretmp += scoretable(number, empty1);
return scoretmp; } /// <summary>
/// 评估函数
/// </summary>
/// <returns></returns>
public int evaluate_minmax_noalphabeta()
{
int scorecomputer = 0;
int scorehumber = 0; //横排们
for (int j = 0; j < 18; j++)
{
Piece[] pieces = new Piece[18];
for (int i = 0; i < 18; ++i)
pieces[i] = new Piece(i, j);
scorecomputer += countscore(pieces, 2);
scorehumber += countscore(pieces, 1);
}
//竖排们
for (int i = 0; i < 18; i++)
{
Piece[] pieces = new Piece[18];
for (int j = 0; j < 18; j++)
pieces[j] = new Piece(i, j);
scorecomputer += countscore(pieces, 2);
scorehumber += countscore(pieces, 1);
} //上半正斜线们
for (int i = 0; i < 18; ++i)
{
Piece[] pieces = new Piece[18];
for (int x = i, y = 0; x < 18 && y < 18; x++, y++)
pieces[y] = new Piece(x, y);
scorecomputer += countscore(pieces, 2);
scorehumber += countscore(pieces, 1);
}
//下半正斜线们
for (int j = 1; j < 18; ++j)
{
Piece[] pieces = new Piece[18];
for (int x = 0, y = j; x < 18 && y < 18; y++, x++)
pieces[x] = new Piece(x, y);
scorecomputer += countscore(pieces, 2);
scorehumber += countscore(pieces, 1);
}
//上半反斜线们
for (int i = 0; i < 18; i++)
{
Piece[] pieces = new Piece[18];
for (int y = i, x = 0; y >= 0 && x < 18; y--, x++)
pieces[x] = new Piece(x, y);
scorecomputer += countscore(pieces, 2);
scorehumber += countscore(pieces, 1);
} //下半反斜线们
for (int i = 1; i < 18; i++)
{
Piece[] pieces = new Piece[18];
for (int y = i, x = 14; y < 18 && x >= 0; x--, y++)
pieces[14 - x] = new Piece(y, x);
scorecomputer += countscore(pieces, 2);
scorehumber += countscore(pieces, 1);
} return scorecomputer - scorehumber;
} /// <summary>
/// 当max(电脑)走步时,max(电脑)应该考虑最好的情况
/// </summary>
/// <param name="depth">递归深度</param>
/// <returns></returns>
private int max_noalphabeta(int depth)
{
int res = evaluate_minmax_noalphabeta();
int best = res;
if (depth <= 0)
{
return res;
}
else
{
for (int i = 0; i < CheckBoard.BlankPieces.Count; i++)
{
Piece p = CheckBoard.BlankPieces[i];
CheckBoard.ChessPieces[p.X][p.Y] = 1;
if (CheckBoard.isover(p.X, p.Y))
{
CheckBoard.ChessPieces[p.X][ p.Y] = 0;
return int.MaxValue;
}
RemoveBlankPiece(p);
int temp = min_noalphabeta(--depth);
if (temp > best) best = temp;
CheckBoard.BlankPieces.Insert(i, p);
CheckBoard.ChessPieces[p.X][ p.Y] = 0;
}
return best;
}
} /// <summary>
/// 当min(人)走步时,人的最好情况
/// </summary>
/// <param name="depth">递归深度</param>
/// <returns></returns>
private int min_noalphabeta(int depth)
{
int res = evaluate_minmax_noalphabeta();
int best = res;
if (depth <= 0)
{
return res;
}
else
{
for (int i = 0; i < CheckBoard.BlankPieces.Count; i++)
{
Piece p = CheckBoard.BlankPieces[i];
CheckBoard.ChessPieces[p.X][ p.Y] = 1;
if (CheckBoard.isover(p.X, p.Y))
{
CheckBoard.ChessPieces[p.X][p.Y] = 0;
return int.MinValue;
}
RemoveBlankPiece(p);
int temp = max_noalphabeta(--depth);
if (temp < best) best = temp;
CheckBoard.BlankPieces.Insert(i, p);
CheckBoard.ChessPieces[p.X][ p.Y] = 0;
}
return best;
}
} /// <summary>
/// 人机博弈
/// </summary>
/// <param name="depth">递归深度</param>
/// <returns></returns>
public List<Piece> Machine_Man_Game(int depth)
{
generatepoint();
List<Piece> bftPieces = new List<Piece>();
int AI_best = int.MinValue;
for (int i = 0; i < CheckBoard.BlankPieces.Count; i++)
{
Piece p = CheckBoard.BlankPieces[i];
CheckBoard.ChessPieces[p.X][p.Y] = 2;
if (CheckBoard.isover(p.X, p.Y))
{
CheckBoard.ChessPieces[p.X][p.Y] = 0;
bftPieces.Add(p);
return bftPieces;
}
RemoveBlankPiece(p);
int temp = min_noalphabeta(depth - 1);
if (temp == AI_best)
bftPieces.Add(p);
if (temp > AI_best)
{
AI_best = temp;
bftPieces.Clear();
bftPieces.Add(p);
}
CheckBoard.BlankPieces.Insert(i, p);
CheckBoard.ChessPieces[p.X][ p.Y] = 0;
}
return bftPieces;
}
/// <summary>
/// 消除空子队列中的一个
/// </summary>
/// <param name="p"></param>
private void RemoveBlankPiece(Piece p)
{
for (int i = 0; i < CheckBoard.BlankPieces.Count; i++)
{
if (p.X == CheckBoard.BlankPieces[i].X && p.Y == CheckBoard.BlankPieces[i].Y)
CheckBoard.BlankPieces.RemoveAt(i);
}
} }
C# winform GDI+ 五子棋 (二):根据博弈算法写的人机AI(抄的别人的)的更多相关文章
- Winform GDI+绘图二:绘制旋转太极图
大家好,今天有时间给大家带来Winform自绘控件的第二部分,也是比较有意思的一个控件:旋转太极图. 大家可以停下思考一下,如果让你来绘制旋转的太极图,大家有什么样的思路呢?我今天跟大家展示一下,我平 ...
- Wellner 自适应阈值二值化算法
参考文档: Adaptive Thresholding for the DigitalDesk.pdf Adaptive Thresholding Using the Integral I ...
- Winform GDI+
什么是GDI+ GDI (Graphics Device Interface), 是属于绘图方面的 API (Application Programming Interface). 因为应用程序不能直 ...
- SNF开发平台WinForm之十二-发送手机短信功能调用-金笛-SNF快速开发平台3.3-Spring.Net.Framework
1.调用前组装参数 2.调用发送信息服务脚本 .调用前组装参数: BaseSendTaskEntity entity = new BaseSendTaskEntity(); entity.Mess ...
- php面试题之二——数据结构和算法(高级部分)
二.数据结构和算法 1.使对象可以像数组一样进行foreach循环,要求属性必须是私有.(Iterator模式的PHP5实现,写一类实现Iterator接口)(腾讯) <?php class T ...
- 人机ai五子棋 ——五子棋AI算法之Java实现
人机ai五子棋 下载:chess.jar (可直接运行) 源码:https://github.com/xcr1234/chess 其实机器博弈最重要的就是打分,分数也就是权重,把棋子下到分数大的地方, ...
- 从分布式一致性到共识机制(二)Raft算法
春秋五霸说开 春秋五霸,是指东周春秋时期相继称霸主的五个诸侯,“霸”,意为霸主,即是诸侯之领袖.典型的比如齐桓公,晋文公,春秋时期诸侯国的称霸,与今天要讨论的Raft算法很像. 一.更加直观的Raft ...
- C# 最大二叉堆算法
C#练习二叉堆算法. namespace 算法 { /// <summary> /// 最大堆 /// </summary> /// <typeparam name=&q ...
- JVM(二)GC算法和垃圾收集器
前言 垃圾收集器(Garbage Collection)通常被成为GC,诞生于1960年MIT的Lisp语言.上一篇介绍了Java运行时区域的各个部分,其中程序计数器.虚拟机栈.本地方法栈3个区域随线 ...
- 分布式理论系列(二)一致性算法:2PC 到 3PC 到 Paxos 到 Raft 到 Zab
分布式理论系列(二)一致性算法:2PC 到 3PC 到 Paxos 到 Raft 到 Zab 本文介绍一致性算法: 2PC 到 3PC 到 Paxos 到 Raft 到 Zab 两类一致性算法(操作原 ...
随机推荐
- 《苏丹的复仇》携手华为HMS生态,实现用户、收入双增长
中国出海中东和北非地区的策略类手游<苏丹的复仇>(Revenge of Sultans,ROS)和华为HMS生态深度合作,为本地用户带来创新游戏体验,成为当地广受欢迎的游戏之一,下载量居应 ...
- CentOS编译安装Nginx1.5.2+PHP5.5.1+ MySQL 5.6.10
CentOS编译安装Nginx1.5.2+PHP5.5.1+ MySQL 5.6.10 时间:2013-11-15 23:39 来源:blog.s135.com 作者:张宴的博客 举报 点击:1 ...
- 重学c#系列——缓存[盛派源码分析cache](九)
前言 以前整理过缓存的东西在: https://www.cnblogs.com/aoximin/p/12727659.html 只是粗略的例子,因为真的要去介绍缓存这个东西,要从内存开始,是一个有时间 ...
- MMDeploy部署实战系列【第二章】:mmdeploy安装及环境搭建
MMDeploy部署实战系列[第二章]:mmdeploy安装及环境搭建 这个系列是一个随笔,是我走过的一些路,有些地方可能不太完善.如果有那个地方没看懂,评论区问就可以,我给补充. 版权声明:本文为博 ...
- leetcode:1337. 方阵中战斗力最弱的 K 行
1337. 方阵中战斗力最弱的 K 行 给你一个大小为 m * n 的方阵 mat,方阵由若干军人和平民组成,分别用 0 和 1 表示. 请你返回方阵中战斗力最弱的 k 行的索引,按从最弱到最强排序. ...
- iOS的cer、p12格式证书解析监控
之前博客写过直接解析ipa包获取mobileprovision文件来监控APP是否过期来,但APP的推送证书还没有做, 大家都知道,iOS的推送证书不会放到ipa包里,只能通过直接解析p12或cer. ...
- 浅谈TypeScript对业务可维护性的影响
前言 笔者认为, TypeScript是服务于业务的, 核心就是提高代码的可维护性. TypeScript是把双刃剑, 如果类型系统使用的不好, 反而会阻碍开发, 甚至最后就变成了anyScript. ...
- 构建RAG应用-day01: 词向量和向量数据库 文档预处理
词向量和向量数据库 词向量(Embeddings)是一种将非结构化数据,如单词.句子或者整个文档,转化为实数向量的技术. 词向量搜索和关键词搜索的比较 优势1:词向量可以语义搜索 比如百度搜索,使用的 ...
- 深入探讨下SSR与CSR有啥不同
随着互联网技术的迅速发展,用户对网页的加载速度和交互体验有了更高的期待.作为开发者,我们常常需要在服务器端渲染(SSR)与客户端渲染(CSR)之间做出选择.这两种渲染方式各有特点,适用于不同的场景和需 ...
- 跨全端SDK技术演进
简介: 细想,团队进行跨平台开发已有三年有余,也是集团里面C++方向里比较早涉及该领域的部门之一,伴随业界跨平台技术发展与演进,我们也沉淀了一整套基于C++的跨平台技术体系,本文将以消息SDK为例,详 ...