白棋是ai,最后ai走赢了。
根据博弈算法的一个AI。遍历深度6层,下子很慢。其实我是从别人的代码里复制的算法,改到自己上面用了。
这个博弈算法

 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(抄的别人的)的更多相关文章

  1. Winform GDI+绘图二:绘制旋转太极图

    大家好,今天有时间给大家带来Winform自绘控件的第二部分,也是比较有意思的一个控件:旋转太极图. 大家可以停下思考一下,如果让你来绘制旋转的太极图,大家有什么样的思路呢?我今天跟大家展示一下,我平 ...

  2. Wellner 自适应阈值二值化算法

    参考文档: Adaptive Thresholding for the DigitalDesk.pdf       Adaptive Thresholding Using the Integral I ...

  3. Winform GDI+

    什么是GDI+ GDI (Graphics Device Interface), 是属于绘图方面的 API (Application Programming Interface). 因为应用程序不能直 ...

  4. SNF开发平台WinForm之十二-发送手机短信功能调用-金笛-SNF快速开发平台3.3-Spring.Net.Framework

    1.调用前组装参数 2.调用发送信息服务脚本   .调用前组装参数: BaseSendTaskEntity entity = new BaseSendTaskEntity(); entity.Mess ...

  5. php面试题之二——数据结构和算法(高级部分)

    二.数据结构和算法 1.使对象可以像数组一样进行foreach循环,要求属性必须是私有.(Iterator模式的PHP5实现,写一类实现Iterator接口)(腾讯) <?php class T ...

  6. 人机ai五子棋 ——五子棋AI算法之Java实现

    人机ai五子棋 下载:chess.jar (可直接运行) 源码:https://github.com/xcr1234/chess 其实机器博弈最重要的就是打分,分数也就是权重,把棋子下到分数大的地方, ...

  7. 从分布式一致性到共识机制(二)Raft算法

    春秋五霸说开 春秋五霸,是指东周春秋时期相继称霸主的五个诸侯,“霸”,意为霸主,即是诸侯之领袖.典型的比如齐桓公,晋文公,春秋时期诸侯国的称霸,与今天要讨论的Raft算法很像. 一.更加直观的Raft ...

  8. C# 最大二叉堆算法

    C#练习二叉堆算法. namespace 算法 { /// <summary> /// 最大堆 /// </summary> /// <typeparam name=&q ...

  9. JVM(二)GC算法和垃圾收集器

    前言 垃圾收集器(Garbage Collection)通常被成为GC,诞生于1960年MIT的Lisp语言.上一篇介绍了Java运行时区域的各个部分,其中程序计数器.虚拟机栈.本地方法栈3个区域随线 ...

  10. 分布式理论系列(二)一致性算法:2PC 到 3PC 到 Paxos 到 Raft 到 Zab

    分布式理论系列(二)一致性算法:2PC 到 3PC 到 Paxos 到 Raft 到 Zab 本文介绍一致性算法: 2PC 到 3PC 到 Paxos 到 Raft 到 Zab 两类一致性算法(操作原 ...

随机推荐

  1. Mysql之GTID

    一.GTID Mysql5.6引入GTID(Global Transaction IDs),多线程复制: 由服务器的UUID和事务ID号组成唯一标识某一个主机的某个事务的ID号: 每一个事务首部都有G ...

  2. 物联网浏览器(IoTBrowser)-Java快速对接施耐德网络IO网关

    前一段时间有个Java技术栈的朋友联系到我,需要快速对接现有的无人值守称重系统,这里的对接是指替代现有系统,而非软件层面的对接,也就是利用现有的硬件开发一套替代现有软件的自动化系统.主要设备包括地磅秤 ...

  3. Caused by: org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration$ArtifactResolveException: Could not resolve all files for configuration ':classpath'.

    前言 这个错误怎么看呢? 如果你对gradle 不是很了解的话,有一个建议,就是把异常背下来,当然是看这个:ArtifactResolveException哈. 而不是后面的详情. 正文 给我们详情是 ...

  4. 痞子衡嵌入式:在i.MXRT1xxx系列上用NAND型启动设备时可用两级设计缩短启动时间

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在i.MXRT1xxx系列上用NAND型启动设备时可用两级设计缩短启动时间. 去年痞子衡写过一篇骚操作文章 <借助i.MXRT10 ...

  5. 【笔记】go语言--go语言的依赖管理

    [笔记]go语言--go语言的依赖管理 GO语言的依赖管理 依赖的概念,依赖就是第三方的库,即别人已经做好的库 依赖管理的三个阶段 GOPATH,GOVENDOR, go mod 三个阶段 - GOP ...

  6. 【数学】向量点乘、叉乘的理论、应用及代码实现(C++)

    前言 我总结了一下向量点乘,叉乘的概念,以及他们的应用及相关C++代码的实现.blog 这类问题也是技术面试经常碰到的,一次研究透了会有收获. 1 向量 向量具有大小和方向. 共线向量:两个平行的向量 ...

  7. 智能logo免费体验|如何让餐饮logo在点评网站上一眼出众?

    ​简介:一个新的餐饮店铺,还没有人知晓,Logo就是这个重要的"门面",所传递的信息让人快速识别,就能产生记忆点,愿意进一步了解,从而为店铺带来流量和收益.如何让你的餐饮店铺log ...

  8. KubeCon 2020 演讲集锦|《阿里巴巴云原生技术与实践 13 讲》开放下载

    2020 年 7 月 30 日至 8 月 1 日,由 Cloud Native Computing Foundation (CNCF) 主办的云原生技术大会 Cloud Native + Open S ...

  9. 技术干货 | 应用性能提升 70%,探究 mPaaS 全链路压测的实现原理和实施路径

    ​简介: 全链路压测方案下,非加密场景下至少有 70% 的性能提升,加密场景下 10%的性能提升,并在 MGS 扩容完成后可实现大幅的性能提升,调优的结果远超预期. ​ 业务背景 随着移动开发行业的步 ...

  10. Flink 在顺丰的应用实践

    ​简介: 顺丰基于 Flink 建设实时数仓的思路,引入 Hudi On Flink 加速数仓宽表,以及实时数仓平台化建设的实践. 本⽂由社区志愿者苗文婷整理,内容源⾃顺丰科技大数据平台研发工程师龙逸 ...