Silverlight版井字棋,附解释-[Silverlight开发 ]

本文探讨了井字棋的最佳开局策略,详细分析了为何首步占据角落是取胜的关键,并介绍了如何利用该策略引导对手落入必败的局面。此外,还简要介绍了作者使用Silverlight实现井字棋程序的过程。

Tic-tac-toe, also spelled tick tack toe, or noughts and crosses/Xs and Os as it is known in the UK, Australia and New Zealand, is a pencil-and-paper game for two players, X and O, who take turns marking the spaces in a 3×3 grid.

井字棋可能是最简单的棋类游戏了,它简单到了成年人之间玩几乎总是平局的地步。因此,这个游戏貌似最多只能哄哄小孩子。对井字棋突然感兴趣是看到一张图片,里面解释了最佳的首选策略,然后在网上查看了下具体的说明(原文章)。井字棋可以算是决策树最简单的游戏之一了。在历史上,对井字棋的类似分析很大程度上启发了人们对组合游戏的认识,在博弈论中起着举足轻重的作用。兴致一来,就想着用Silverlight简单的实现下。

简单的实现效果

需要安装Silverlight环境。



为什么第一步走在角上才是最佳的策略

首先看下面这张图,点击查看:http://xkcd.com/832/ & 声明:以下为转载,版权归原作者所有:matrix67


题外话:自己很喜欢这种科普性的文章,像果壳,像松树科学会等都有很多这种类型的文章,可以激发下自己对事物新的看法,挺好的。

先手先占角


游戏开始后,二话不说先占上一个角(比如左下角吧),那么对方总共有五种本质不同的应对策略:占据靠近你的那条边,占据靠近你的那个角,占据远离你的那条边,占据远离你的那个角(即对角),以及占据正中央的位置。不可思议的是,在这五种策略中,前面四种都是陷阱——如果对方不慎选择了前面四种策略中的任意一种,他就必然输掉。


上图显示了在这四种情况下你可以如何把对方一步步逼上绝路。假设对方走正下方,占据了一个靠近你的边(最左边的那个图),你就可以占据正中央来应对,逼迫对方不得不走右上角。这时,只需要在左上角放下一子,你就赢定了——图中出现了两条只差一子的连线,对方不可能兼顾得了。右边几个图显示了对方第一步棋的其它几种走法。选择合适的位置应对他,都可以在下一步迫使对方只剩一种走法,接下来你便可以下出“一箭双雕”的棋,让对方无法彻底封杀你。也就是说,当你占据棋盘一角后,在对方下一步棋的八个可选位置中,其中七个位置都是必输的,陷阱摆满了几乎整个棋盘。在面对“先走一角”的诡异开局时,你的朋友说不准就会慌了手脚,没能冷静地占住中间,决定了必败的命运。


对方要是真的走了正中间,你仍然有赢的机会。你可以占住右上角的位置(如上图)。如果对方不幸走了剩下的两个角中的一个(上图左),你便能故技重施,再次取得胜利。只有对方选择了边上的位置(上图右),才能躲过这一系列的陷阱,最终变成平局。

后手先占角



作为后行者,你遇到的往往是“先走中间”的经典开局。此时,千万别忘了,先占角仍然是一条金科玉律。如果你不慎走了某条边的位置,对方可就赢定了!对方可以向上面的第一幅图那样,在正右方下子应对,逼迫你把下一步棋落在正左方。此时,对方便可占据右上方的位置,同时产生出两条仅差一子的连线。右边三幅图则显示,如果你在角上应对,最终总会是一盘和棋。

本程序背后算法简单说明

其实背后的算法很简单的, 只是简单的模拟一下人类想问题的思路而已,并且很有可能不是最佳的实现方式。

首先定义两个矩阵,一个表示棋盘上的9个位置,另外一个是权重矩阵。解释下权重矩阵,这里的权重是指电脑在思考下一步的过程中得到的,哪个位置权重高点,就先下在那个位置上。所以这里就涉及到权重大小的判断问题,按照正常来说,"求胜"的权重是最大,也就是说电脑在计算的过程中,如果可以获胜就下那个位置,然后到防止对方获胜,也就是当玩家有两个棋子和一个空位置时就堵那个位置。这是基本的两点,然后就到基本位置的判断问题。如下面的代码就是设置"求胜"的权重。

if  (sMatrix[i,  0 +  sMatrix[i,  1 ] + stMatrix[i,  2 ==   2 )
              weightMatrix[i, j] 
+=   6 ;
// 如果可以连成线,则胜利


一开始我设置电脑在中点下子的权重更高,看到文章的分析,就设置在边角的权重更高些,可能由于游戏本来简单,看不出这两者有什么区别。然后,最后一个权重需要考虑的地方就是最好能构成两个连起来的棋子,最后自己得到的权重比例应该是:"获胜">"防止玩家获胜">"边角下子">"中心下子">"连成两个棋子",最后,权重都一样的话就随机找个空的位置下子。

其中,在每次的下子过后都调用一个函数来检查游戏是否结束,这些都是小细节而已。简单的说明就到这里呵。

转载于:https://www.cnblogs.com/wpdev/archive/2011/04/15/tic-tac-toe.html

Ymodem协议是一种在串行通信中用于数据传输的机制,起源于早期的Xmodem协议。该协议具备处理大容量数据文件的能力,支持数据校验、文件属性传递以及多文件批量传输。Qt是一个面向C++的跨平台开发框架,适用于构建图形界面程序及后台服务类应用。当结合Qt实现Ymodem协议时,能够开发出适用于多种设备的通信程序,包括桌面系统、嵌入式设备和移动终端。 在Qt中实现Ymodem协议,需要掌握Qt的信号与槽机制、串口通信模块(如QSerialPort)以及线程管理技术。实现过程中通常包含以下主要环节: 1. 连接初始化:在通信双方确认状态后,启动数据传输流程。 2. 数据块传输:协议支持多种数据块大小,如128字节或1024字节。每个数据块需包含数据内容、编号及校验信息。接收端需对数据进行校验以保证完整性。 3. 序列管理与响应机制:通过编号确保数据顺序,发送端在收到确认信号后继续下一块传输。若未收到有效响应,则需重传。 4. 文件元信息传输:在正式传输前,发送方需传递文件名称及大小等信息,以便接收方进行存储准备。 5. 批量传输模式:支持多个文件的连续传输,需在数据中区分不同文件的块。 6. 传输结束机制:通常通过发送空数据块来终止通信过程。 在Qt中实现Ymodem协议的代码,通常需要创建多个类来封装串口通信逻辑及协议处理功能,同时需考虑异常处理和数据恢复策略。代码涉及对QSerialPort的配置、数据流的监控、事件循环的管理等。此外,为提升用户体验,开发人员可能在代码中加入进度显示、传输速率计算等功能。 Qt的跨平台特性使得基于其开发的Ymodem协议实现具备良好的可移植性,可在不同操作系统上运行。开发此类程序需要开发者对Ymodem协议有深入了解,并熟悉Qt框架的使用,包括信号机制、多线程及串口通信等技术。高质量的代码实现能够确保协议在不同运行环境下的稳定性与可靠性。 Ymodem协议的实现常出现在开源项目中,为开发者提供了参考和借鉴,有助于技术交流与社区发展。根据文件名“SerialPortYmodem”推测,该文件可能用于处理与串口通信相关的Ymodem逻辑。开发者在使用时应仔细查阅文档,理解各模块功能,以便正确集成和应用。 综上,Qt实现Ymodem协议的开发涉及对协议机制与Qt框架的深入理解,能够构建出满足多种串行通信需求的程序。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值