棋盘和棋子采用GDI+画上去的。棋盘18*18。棋子是用DrawElipse画的,白棋和黑棋分两个List集合存储,方便判断五子连线的情况。
主要说一下,五子连线的思路,把集合按行和按列以及按正斜和反斜进行分组。然后在依次遍历被分组的集合,如果其中有一个集合出现了5子相连的情况就胜利。而五子相连的判断是:通过判断前一个和后一个棋子的距离是否是等于棋盘的格子宽度。按行列分组好判断,就 x y相等的分别分组。但是正斜和反斜的分组,我接用的是一元一次方程来做的。详细如代码所示:

private bool IsWin(List<Point> pt)
{
bool isWin = false;
//横
var yGroup=pt.GroupBy(p => p.Y);
foreach (var h in yGroup)
{
var lst = h.ToList().Select(a => a.X).ToList();
lst.Sort(); if (lst.Count < 5)
{
continue;
}
int hasCount = 1; for (int j = 0; j < lst.Count; j++)
{
var x=lst[j];
for (int m = j+1; m <lst.Count&&m< j+5; m++)
{ var xNext=lst[m]; if (xNext - x <= 30*(hasCount))
{
hasCount++;
}
else
{
hasCount = 1;
break;
} if (hasCount == 5)
{
return true;
} } if (hasCount != 5)
{
hasCount = 1;
}
} } //纵
var xGroup=pt.GroupBy(p => p.X);
foreach (var z in xGroup)
{
var lst = z.ToList().Select(a => a.Y).ToList();
lst.Sort(); if (lst.Count < 5)
{
continue;
}
int hasCount = 1; for (int j = 0; j < lst.Count; j++)
{
var y = lst[j];
for (int m = j + 1; m < lst.Count && m < j + 5; m++)
{ var yNext = lst[m]; if (yNext - y <= 30 * (hasCount))
{
hasCount++;
}
else
{
hasCount = 1;
break;
} if (hasCount == 5)
{
return true;
} } if (hasCount != 5)
{
hasCount = 1;
}
} } for (int b = -30*18; b < 30*18; b+=30)
{
var lst = pt.Where(a => -1 * a.Y == -1 * a.X + b).Select(a => a.X).ToList();
lst.Sort(); if (lst.Count < 5)
{
continue;
}
int hasCount = 1; for (int j = 0; j < lst.Count; j++)
{
var y = lst[j];
for (int m = j + 1; m < lst.Count && m < j + 5; m++)
{ var yNext = lst[m]; if (yNext - y <= 30 * (hasCount))
{
hasCount++;
}
else
{
hasCount = 1;
break;
} if (hasCount == 5)
{
return true;
} } hasCount = 1;
}
} //右斜 for (int mq=1;mq<18*18;mq++)
{
int b = mq * -10;
var lst = pt.Where(a =>-1*a.Y == a.X + b).Select(a => a.X).ToList();
lst.Sort(); if (lst.Count < 5)
{
continue;
}
int hasCount = 1; for (int j = 0; j < lst.Count; j++)
{
var y = lst[j];
for (int m = j + 1; m < lst.Count && m < j + 5; m++)
{ var yNext = lst[m]; if (yNext - y <= 30 * (hasCount))
{
hasCount++;
}
else
{
hasCount = 1;
break;
} if (hasCount == 5)
{
return true;
} } hasCount = 1;
}
}
return isWin; }
 
这是简单的适合人和人玩的方法。
目前,想加入人机,想采用极大极小alphabat剪枝的博弈算法来做机器人,但对我来说,有点复杂,肯定要花很多时间的,我没有信心完成,所以就没做了。还想做局域网对战,以前做过一次五子棋局域网的,记得是在18年的时候,是用button作为棋子,下个子要等很久,而且五连判断还没写好。比起那时候自己做的五子棋,这次这个要好很多了。
我发现在网络里,能发现无数个比自己厉害的人,特别是在B站,博客园什么的,很多厉害的人,他们在大学时候甚至才高中,初中,小学,就已经实现了我现在想实现的五子棋功能。我觉得,自己虽然已毕业多年,但在编程方面确实要下功夫才行。

C# winform GDI+ 五子棋 (一):基本界面和胜负判断的更多相关文章

  1. 五子棋(无AI winform gdi+)

    之前无意间在博客园看到一篇用深度学习玩马里奥的文章,于是就想做这个小东西来测试人工智能算法(准备用PYTHON的库,对神经网络的梦已经做了好多年了,但是太难了,一直懒得动它),本来是想用WPF做UI, ...

  2. c# winform编程之多线程ui界面资源修改总结篇【转】

    c# winform编程之多线程ui界面资源修改总结篇 单线程的winfom程序中,设置一个控件的值是很easy的事情,直接 this.TextBox1.value = "Hello Wor ...

  3. Winform GDI+

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

  4. WinForm GDI+ 资料收集

    UI(User Interface)编程在整个项目开发过程中是个颇为重要的环节,任何好的解决方案若没有良好的用户界面呈现给最终用户,那么就算包含了最先进的技术也不能算是好程序.UI编程体现在两个方面, ...

  5. WinForm GDI+自定义控件总结(一)

    前言 由于项目的原因好久没写博客了,也正是项目的原因开始系统的学习WinForm,从而接触到自定义控件的开发.自定义控件的开发有一定的难度,对开发者要求比较高,需要了解Windows运行的机制,熟悉w ...

  6. C#winform自定义控件模拟设计时界面鼠标移动和调节大小、选中效果

    要想玩转Winform自定义控件需要对GDI+非常熟悉,对常用的控件有一些了解,好选择合适的基类控件来简化. 要点说明及代码 1)定义接口: using System; using System.Wi ...

  7. C# Winform设计运行时,界面模糊

    程序在Visual Studio设计的很清晰的菜单和界面,运行的时候菜单和控件上字体变得很模糊,界面大小也发生了变化 解决方法是:更改程序的配置文件,使程序运行时自动检测屏幕分辨率,在高分屏时禁用系统 ...

  8. C#-WinForm跨线程修改UI界面

    待解决的问题 在我做WinForm开发的过程中,经常会遇到耗时操作或阻塞操作.他们会引发软件的卡顿甚至假死,严重影响软件的使用. 因此,这类耗时或阻塞的操作一般都会使用异步的方式去执行,不影响主线程( ...

  9. Winform GDI+ 绘图一:绘制2D电池

    winform桌面软件开发,在工业控制领域的使用还是很广泛的,打算好好学习一下GDI+绘图.以前都是用别人的轮子,自己也打算封装一些工业控制领域常用的控件. 今天要将的是,利用缓动函数动态绘制电池. ...

  10. c# winform编程之多线程ui界面资源修改总结篇

    单线程的winfom程序中,设置一个控件的值是很easy的事情,直接 this.TextBox1.value = "Hello World!";就搞定了,但是如果在一个新线程中这么 ...

随机推荐

  1. C#的AOP(最经典实现)

    (适用于.NET/.NET Core/.NET Framework) [目录]0.前言1.第一个AOP程序2.Aspect横切面编程3.一个横切面程序拦截多个主程序4.多个横切面程序拦截一个主程序5. ...

  2. HarmonyOS应用侧与前端页面数据通道建立

    一.  应用侧调用前端页面函数 应用侧可以通过runJavaScript()方法调用前端页面的JavaScript相关函数.在下面的示例中,点击应用侧的"runJavaScript" ...

  3. 重新整理数据结构与算法(c#)—— 树的节点删除[十八]

    前言 你好这里的一个删除,指的是如果删除的叶子节点则直接删除,如果删除的是非叶子节点,则删除的是这颗子树. 这样删除的场景并不多,这种删除方式了解即可. 十七和十六没有放树图,把树图放一下. 正文 节 ...

  4. WPF随笔收录-实时绘制心率曲线

    一.前言 在自己的项目中,涉及到实时心率曲线的绘制,项目上的曲线绘制,一般很难找到能直接用的第三方库,而且有些还是定制化的功能,所以还是自己绘制比较方便.很多人一听到自己画就害怕,感觉很难,今天就分享 ...

  5. python 多进程jieba分词,高效分词,multiprocessing

    自然语言任务经常使用jieba分词,数据量大时怎么加速,jieba分词不支持使用asyncio异步加速,使用multiprocessing还是可以的 import jieba import jieba ...

  6. .net core的依赖注入学习

    依赖注入(Dependency Injection,DI),简称DI,它可以降低各模块之间的耦合 首先需要安装两个Nuget包: Microsoft.Extensions.DependencyInje ...

  7. NIFI简介

    NIFI简介 首先是官网地址:Apache NiFi,不过会百度的估计都能搜到 因为后面的工作一定会用到,所以大致的听了一下讲解操作之类的 大概感觉就是NIFI是个web端的一种控制数据走向的工具?可 ...

  8. eclipse 汉化语言包/中文补丁/简中设置/中英互换

    eclipse 汉化语言包/中文补丁/简中设置/中英互换 汉化很简单,使用eclipse内置的软件下载就可以,不需要下载压缩包 官方的说明 Open the install wizard with ' ...

  9. 力扣670(java)-最大交换(中等)

    题目: 给定一个非负整数,你至多可以交换一次数字中的任意两位.返回你能得到的最大值. 示例 1 : 输入: 2736输出: 7236解释: 交换数字2和数字7.示例 2 : 输入: 9973输出: 9 ...

  10. OceanBase初体验之部署生产标准的三节点分布式集群

    前置条件 OceanBase 数据库集群至少由三个节点组成,所以先准备好3台服务器: IP 配置 操作系统 x.x.x.150 Intel x86 12C 64G内存 1T SSD CentOS 7. ...