首先说什么是十字翻转棋,十字翻转棋又叫开窗游戏,游戏规则如下:

在n*n的方格中随机分布着一些关着的窗子,当你打开或关闭一个窗子时,它的上下左右四个方向的窗子开关状态也会翻转。目标是将这些关着的窗子都打开,游戏结束。

这里有一个我自己编写的html5开窗游戏,大家可以先去玩一下:

开窗游戏

游戏相对还比较简单,只是一个3*3的难度,当游戏维度增加后,难度也会加大。下面我们来探讨一下如何快速找出一个最优解。

玩几次游戏发现如下两个规律:

1.任何一个位置我们点击1次和点击3次结果是相同的,因为每点一下,这个点击所影响的窗子是固定的,所以如果一个位置需要点击,我们只点击一下就可以了。

2.任何一个位置的窗子状态只和它上中下左右5个位置的点击状态有关系,和他们的点击顺序无关。

由1,2分析可知,在n*n的格子中,达到win状态时这n*n个格子每个格子只有是否被点击两种状态,而与达到这两种状态的点击次数无关,和点击顺序也无关。这个大家可以自己思考一下。

也就是说最后我们只需确定哪些格子需要点,哪些格子不需要点。

我们就拿3*3的难度来推理一下。

c1 c2 c3
c4 c5 c6
c7 c8 c9

假设格子的原始状态为 {cn}, cn有两个值 0代表开着的,1代表关着的 那么要把所有窗子都开着就是要把所有数字都变成0

x1 x2 x3
x4 x5 x6
x7 x8 x9

假设最终格子的点击状态为 {xn},xn也有两种状态 1代表要点击,0代表不点击

我们假设 运算f(x,c)   {x=0,1}{c=0,1}

x表示是否受点击影响 0代表不受点击影响,1代表受点击影响

c表示格子原始状态 0表示开启状态,1表示关闭状态

f(x,c)    表示作用后对应格子的状态

经过分析, f有如下特点:

f(1,0)=1;    //受点击影响 将原先1变为0

f(1,1)=0;    //受点击影响 将原先0变成1

f(0,1)=1;    //不受点击影响,保持原来的1

f(0,0)=0;    //不受点击影响,保持原来的0

聪明的你应该发现,这其实是异或运算^

再来分析第一个格子,

它的原始状态是c1,分析发现能够影响它的点击状态是x1,x2,x4 而其他x对它皆没有影响,而目标最终的状态是0,所以我们得到下面的式子:

f(x4 , f(x2 , f(x1 , c1))) = 0

而我们又知道 f 是异或运算,所以上面的式子可以写成

x4^x2^x1^c1=0

又因为异或服从交换律,且两边同时异或c1 得到下面的变形

x1^x2^x4=c1;

依次类推我们可以写出其他的式子,最后整理好的式子如下:

x1^x2^   x4                = c1x1^x2^x3^   x5             = c2x2^x3^      x6          = c3x1^      x4^x5^   x7       = c4x2^   x4^x5^x6^   x8    = c5x3^   x5^x6^      x9 = c6x4^      x7^x8    = c7x5^   x7^x8^x9 = c8x6^   x8^x9 = c9

将其写成矩阵形式:

 1 1 0 1 0 0 0 0 0    x1     c1      (1)1 1 1 0 1 0 0 0 0    x2     c2      (2)0 1 1 0 0 1 0 0 0    x3     c3      (3)1 0 0 1 1 0 1 0 0    x4     c4      (4)0 1 0 1 1 1 0 1 0    x5     c5      (5)0 0 1 0 1 1 0 0 1    x6     c6      (6)0 0 0 1 0 0 1 1 0    x7     c7      (7)0 0 0 0 1 0 1 1 1    x8     c8      (8)0 0 0 0 0 1 0 1 1    x9     c9      (9)

最终问题划归为求解这个异或矩阵方程~

我们把左边那个矩阵定义为A  使用向量的写法

AX=C

只不过这里矩阵乘法中对应的加法运算要改为异或运算。

线性代数里面有一类问题叫线性方程组的求解,最终划归出来的矩阵形式和这个一模一样。所以我们可以采用解线性方程组的那套算法来解这个方程。

最基本的原则是销元,算法描述如下:

1.用 (1)^(2)  可以得到一个没有x1的等式替代(2),同样用(1)^(3)替代(3) 依次类推,可以得到8个没有x1的等式。

2.再用(2)^(3) 可以得到一个没有x2的等式替代(3);

3.照这样做下去,可以得到一组上三角矩阵。

4.此时的(9)式就只有x9一个变量,而对应的c9则也就是x9的值。

5.然后将x9代入(8)式可以解出x8

6.继续将 x8,x9代入(7)式可以解出x7

依次类推,可以解出xn  也就是我们要的解。

还记得这种方法应该叫做 高斯消元法。

另一种解法和这个解法类似,只是不用回代:

1.用 (1)^(2)  可以得到一个没有x1的等式替代(2),同样用(1)^(3)替代(3) 依次类推,可以得到8个没有x1的等式。(第一步相同)

2.用(2)^(1) 可以得到一个没有x2的等式替代(1),(2)^(3)-->(3);(2)^(4)-->(4);...(2)^(9)-->(9);   (第二步有所不同,是同样用(2)式将(1)式中的x2消除)

3.同样的(3)^(1)-->(1);    (3)^(2)-->(2);   ...   (3)^(9)-->(9);

照这样做下去,可以得到一组对角矩阵,或者可以说是单位矩阵

而此时cn对应的就是方程组的解。

扩展到n*n的规模,我们发现只是对应的矩阵A变化了,其他算法不变。

针对问题本身,cn是一个参数,是传入值,矩阵A根据不同规模不同,但也是有规律的,可以用程序生成,具体的生成算法这里就不说了。

以下是我用JavaScript写的一个算法,针对3*3的规模解法:

var AI = AI||{};
AI.resolve = function(cArray){var rect33 = [[1,1,0,1,0,0,0,0,0],[1,1,1,0,1,0,0,0,0],[0,1,1,0,0,1,0,0,0],[1,0,0,1,1,0,1,0,0],[0,1,0,1,1,1,0,1,0],[0,0,1,0,1,1,0,0,1],[0,0,0,1,0,0,1,1,0],[0,0,0,0,1,0,1,1,1],[0,0,0,0,0,1,0,1,1],];function resolveRect(rect,cArray){var length = rect.length;for(var i=0;i<length;i++){for(var j=i+1;j<length;j++){var r1 = rect[i];var r2 = rect[j];if(r2[i]==1){if(r1[i]==1){//销元addRect(r1,r2);var c1 = cArray[i];var c2 = cArray[j];cArray[j] = addRect(c1,c2);}else{//交换var temp = rect[i];rect[i]=rect[j];rect[j]=temp;temp = cArray[i];cArray[i]=cArray[j];cArray[j]=temp;}}}if(rect[i][i]!=1){throw "无解!!";return;}else{for(var j=0;j<i;j++){var r1 = rect[i];var r2 = rect[j];if(r2[i]==1){addRect(r1,r2);var c1 = cArray[i];var c2 = cArray[j];cArray[j] = addRect(c1,c2);}}}}}function addRect(r1,r2){if(typeof r2 == "number")return r2^r1;var len = r2.length;for(var i=0;i<len;i++){r2[i]=r2[i]^r1[i];}}resolveRect(rect33,cArray);console.log(rect33);console.log(cArray);
}

可以推算这个解法的时间复杂度是n^2  空间复杂度也是n^2 当然空间上是可以优化的,因为有大部分的0是不需要存储的,优化的问题就不讲了。

顺带说一下,关于这个h5游戏是怎么做出来的,之后会有专门的文章或者视频来讲,敬请期待

另外游戏的源码和解法的源码都可以访问github地址:git@github.com:gagaprince/gaga_c.git

里面有一个叫 game_kaichuang 的分支。

转载请注明出处:http://gagalulu.wang/blog/detail/10 您的支持是我最大的动力!

关于十字翻转棋的解法研究相关推荐

  1. c语言翻转棋ai算法,黑白棋游戏(也叫翻转棋)(AI 版)

    黑白棋(也叫翻转棋)的棋盘是一个有8*8方格的棋盘.下棋时将棋下在空格中间,而不是像围棋一样下在交叉点上.开始时在棋盘正中有两白两黑四个棋子交叉放置,黑棋总是先下子. 下子的方法:把自己颜色的棋子放在 ...

  2. 使用js实现黑白翻转棋

    声明:之下代码是来自CSDN中的一个博客 主页:HaQiaME 黑白翻转棋:黑白棋,又叫翻转棋(Reversi).奥赛罗棋(Othello).苹果棋或反棋(Anti reversi). 黑白棋在西方和 ...

  3. uva 220 - Othello(黑白翻转棋)

    习题4-3 黑白棋(Othello, ACM/ICPC World Finals 1992, UVa220) 你的任务是模拟黑白棋游戏的进程.黑白棋的规则为:黑白双方轮流放棋子,每次必须 让新放的棋子 ...

  4. 洛谷 P1985 翻转棋

    P1985 翻转棋 题目描述 农夫约翰知道,聪明的奶牛可以产更多的牛奶.他为奶牛设计了一种智力游戏,名叫翻转棋. 翻转棋可以分成 M × N 个格子,每个格子有两种颜色,一面是黑的,一面是白的. 一旦 ...

  5. 黑白棋,又叫翻转棋(Reversi)、苹果棋或奥赛罗棋(Othello)。棋盘共有8行8列共64格。开局时,棋盘正中央的4格先置放黑白相隔的4枚棋子。双方轮流落子,只要落子和棋盘上任一枚己方的棋子

    黑白棋,又叫翻转棋(Reversi).苹果棋或奥赛罗棋(Othello).棋盘共有8行8列共64格. 开局时,棋盘正中央的4格先置放黑白相隔的4枚棋子.双方轮流落子,只要落子和棋盘上任一枚己方的棋子在 ...

  6. 南邮 OJ 1652 翻转棋

    翻转棋 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte 总提交 : 41            测试通过 : 20  比赛 ...

  7. [Python] 黑白棋(翻转棋)小游戏

    [Python] 黑白棋(翻转棋)小游戏 游戏介绍 黑白棋(Reversi or Othello)在西方和日本很流行.游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负. 规则 黑白棋的每颗 ...

  8. python 黑白棋_python实现翻转棋游戏(othello)

    利用上一篇的框架,再写了个翻转棋的程序,为了调试minimax算法,花了两天的时间. 几点改进说明: 拆分成四个文件:board.py,player.py,ai.py,othello.py.使得整个结 ...

  9. 黑白翻转棋原理及实现链接

    黑白翻转棋(奥赛罗棋)的一些原理讲解和实现代码的链接,都是博主参考过的. 等有时间会自己写一篇原理介绍及代码实现. 以下是参考网站链接: 貌似是某个学校布置作业的网站,有详细专业的java源码 有原理 ...

  10. python翻转棋_奥赛罗棋reverse

    作者,持牌照消费金融模型经理,发明国家算法专利,国内大型医药数据中心担任过数据库负责人.和中科院,清华大学,百度,腾讯,爱奇艺等平台保持长期项目合作.擅长python 机器学习,应用于游戏,医疗,金融 ...

最新文章

  1. 基于Python的完全监督机器学习教程 Complete Supervised Machine Learning With Python
  2. consolez设置
  3. xp snapshot.
  4. reactor设计模式 1
  5. 爬虫从入门到放弃——爬虫的基本原理
  6. python 减少可调用对象的参数个数
  7. 用poi-3.6-20091214.jar 实现java给excel资料加密
  8. Android Uri to Path
  9. 分值展示时,只显示评委分数,但不显示评委名称或评委编号等标识,如何进行前期准备操作?
  10. linux info命令详解,Linux info 命令简介
  11. swiper控制页面切换
  12. 【图文并茂】U盘重装Win10方法教程
  13. 提高教育效率:教师如何制作智能学生成绩在线查询系统?
  14. VVC帧内预测(六)MIP
  15. java 中 Native.loadLibrary 不能加载 jar 包中库文件的解决方案
  16. jmeter性能测试1-录制脚本
  17. π=4*atan(1.0);
  18. Win10 / Win11 wifi 已连接但是却依然显示小地球
  19. wifi分析仪怎么看哪个信道好_(一百零四)探讨WiFi分析仪如何获取信道的?
  20. flutter用英语怎么说_我想你了用英语怎么说

热门文章

  1. C#操作Access数据库(查询,更新,插入)
  2. 为什么算法工程师也叫调参狗?
  3. 第十三届蓝桥杯省赛模拟赛
  4. H3C AP当无线路由器静态IP上网配置
  5. 关于 Pycharm 2019.2 版本出现等宽字体对不齐的问题的解决方法
  6. AMS1117-5.0-ASEMI低压差线性稳压IC详细解析
  7. Emscripten 单词_英语48个音标与单词字母组合拼读发音教程
  8. 红外避障小车的代码编写
  9. 【优化求解】狼群优化算法matlab源码
  10. 转载--多核DSP快速入门