白棋是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. Git 13 暂存代码

    如果当前分支的功能还没开发完,无法提交代码. 但出现了紧急情况(比如线上BUG),需要立即切换到其他分支进行开发. 此时可以先暂存当前分支代码,等切换回当前分支的时候再恢复. 1.暂存当前分支变更: ...

  2. 踩坑指南:入门OpenTenBase之监控篇

    本次监控将采用Prometheus.Grafana可视化工具以及postgres_exporter对OpenTenBase进行全面监控和优化. 安装监控 Docker安装 1.Docker要求 Cen ...

  3. Java List集合去重、过滤、分组、获取数据、求最值、合并、排序、跳数据和遍历

    前言 请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i. 准备工作:现有一个User类.Student 类和Ticket类,加入相关依赖 @Data public class User { / ...

  4. 双向链表的基本实现【数据结构与算法—TypeScript 实现】

    笔记整理自 coderwhy 『TypeScript 高阶数据结构与算法』课程 双向链表:拥有两个指针方向的链表 DoublyNode 结构: prev:指向上一个节点 value:节点值 next: ...

  5. HarmonyOS元服务开发实践:桌面卡片字典

     本文转载分享自华为开发者论坛<HarmonyOS元服务开发实践:桌面卡片字典>,作者:蛟龙腾飞   一.项目说明 1.DEMO创意为卡片字典. 2.不同卡片显示不同内容:微卡.小卡.中卡 ...

  6. Hive 查看表/分区更新时间

    1.查看分区 hive> show partitions table_name; 2.查看分区更新时间 获取hdfs路径 hive> desc formatted table_name; ...

  7. gRPC入门学习之旅(六)

    gRPC入门学习之旅(一) gRPC入门学习之旅(二) gRPC入门学习之旅(三) gRPC入门学习之旅(四) gRPC入门学习之旅(五) 3.3.客户端编译生成GRPC类 1. 在"解决方 ...

  8. nginx 均衡负载

    前言 在此只介绍一些nginx的简单的负载均衡. 正文 在这篇之前,请看我的nginx反向代理这一篇,是接着上面的例子写的. 我在上个例子中,分别是两个a.html 和 b.html 现在我把他们的名 ...

  9. formdata 的前世今生

    前言 为什么会产生formdata这东西呢? 看下简介: FormData 接口提供了一种表示表单数据的键值对的构造方式,经过它的数据可以使用 XMLHttpRequest.send() 方法送出,本 ...

  10. js 按照字母进行分组

    前言 js 按照字母进行分组的一个实例. 正文 var list = [ { 'name' : '张三', 'py' : 'zhnagsan' }, { 'name' : '李四', 'py' : ' ...