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 两类一致性算法(操作原 ...
随机推荐
- RabbitMQ 05 直连模式-Spring Boot操作
Spring Boot集成RabbitMQ是现在主流的操作RabbitMQ的方式. 官方文档:https://docs.spring.io/spring-amqp/docs/current/refer ...
- TeamViewer 9发布-在Linux下安装运行
TeamViewer 9发布-在Linux下安装运行 来源:Linux中国 作者:未知 关注我们: 这篇指南介绍了怎么样在 RedHat. CentOS. Fedora 和 Debian. U ...
- 开源相机管理库Aravis例程学习(二)——连续采集multiple-acquisition-main-thread
目录 简介 例程代码 函数说明 arv_camera_set_acquisition_mode arv_camera_create_stream arv_camera_get_payload arv_ ...
- Effective Python:简介
作者:布雷特·斯拉特金 本书的大部分范例代码都遵循Python 3.7版本的语法规范,Python 3.7发布于2018年6月.另外,书里还会给出一些采用Python 3.8语法规范所写的范例,让大家 ...
- MySQL 分析查询与来源机器
当前分析针对版本:MariaDB 10.5 线上出现报错:can't create more than max_prepared_stmt_count statements.造成这个错误的直接原因就是 ...
- Flink Standalone集群jobmanagers高可用配置
上篇文章简单叙述了Flink standalone集群的基础部署,在生产环境中假如只有1个jobmanager的话,那么这个节点一旦挂掉,所有运行的task都会中断,带来的影响比较大,因此在生产环境至 ...
- .Net与AI的强强联合:AntSK知识库项目中Rerank模型的技术突破与实战应用
随着人工智能技术的飞速发展,.Net技术与AI的结合已经成为了一个新的技术热点.今天,我要和大家分享一个令人兴奋的开源项目--AntSK,这是一个基于.net平台构建的开源离线AI知识库项目.在这个项 ...
- 全方位事件监控管理,阿里云日志服务Kubernetes事件中心正式上线
2020年2月21日,阿里云日志服务Kubernetes事件中心正式上线,为Kubernetes事件提供集中化采集.存储.分析.可视化.告警等能力,帮助Kubernetes使用者快速构建准实时.高可靠 ...
- 与容器服务 ACK 发行版的深度对话第二弹:如何借助 hybridnet 构建混合云统一网络平面
简介:本次采访我将继续为大家详细讲解我的好伙伴:阿里巴巴的开源 Kubernetes 容器网络解决方案 hybridnet,以及我是如何借助它来构建混合云统一网络平面. 作者:若禾.昱晟.瑜佳 记者: ...
- iofsstat:帮你轻松定位 IO 突高,前因后果一目了然 | 龙蜥技术
简介:磁盘被打满到底是真实的业务需求量上来了呢?还是有什么野进程在占用 IO? iofsstat 帮你精准定位. 编者按:sysAK(system analyse kit),是龙蜥社区系统运维 SI ...