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 两类一致性算法(操作原 ...
随机推荐
- Yolov5代码详解——detect.py
首先执行扩展包的导入: import argparse import os import platform import sys from pathlib import Path import t ...
- 我为什么选择Wiki.js记笔记?
很长一段时间里,我都被困扰着,感觉陷入了笔记的泥潭,而积累的如此多的笔记也没有形成我自己的知识体系. 之前的记笔记方式 笔记的来源 微信公众号 技术博客 纸质书籍 官网文档 PDF 自己的零散想法 网 ...
- 鸿蒙HarmonyOS实战-ArkUI组件(Menu)
一.Menu组件 Menu组件是一种常见的用户界面(UI)控件,用于在移动应用程序中显示可选项列表.它通常由一系列链接或按钮组成,以帮助用户导航和选择所需的操作.Menu组件可以在水平或垂直方向上呈现 ...
- Python阿里云消息推送调用API
很多公司测试APP推送时候,应该也是很头疼:推送环境:测试.正式,稍不注意就把测试的push到正式上,导致所有用户都收到 例子很多: 其实阿里.极光都有推送Api,直接调用API就ok,特别是有的公司 ...
- JavaScript如何判断一个元素是否在可视区域中?
一.用途 可视区域即我们浏览网页的设备肉眼可见的区域,如下图 在日常开发中,我们经常需要判断目标元素是否在视窗之内或者和视窗的距离小于一个值(例如 100 px),从而实现一些常用的功能,例如: 图片 ...
- 记一次 Go 调用系统命令出现的问题分析
首先在程序中封装了下面一个函数用来执行系统命令: // 执行系统命令 func executeCommand(command string, output, outerr io.Writer) err ...
- Django框架——ORM执行SQL语句、神奇的双下划线、外键字段的创建、跨表查询、进阶操作
ORM执行SQL语句 有时候ORM的操作效率可能偏低 我们是可以自己编写SQL的 方式一: models.User.objects.raw('select * from app01_user') 方式 ...
- 力扣69(java&python)-x的平方根(简单)
题目: 给你一个非负整数 x ,计算并返回 x 的 算术平方根 . 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 . 注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0. ...
- 力扣383(java&python)-赎金信(简单)
题目: 给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成. 如果可以,返回 true :否则返回 false . m ...
- 力扣18(java)-四数之和(中等)
题目: 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target .请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d ...