孔明棋大家应该都不陌生。(好吧可能不一定)

简单来讲,是一种规则简单,但是过程并不见得容易,可以一个人玩的棋。

他有还一个有趣的名字:法国跳棋独立钻石。

我上手的是vx某小程序。玩法比最经典的32颗棋子多一些。

(经典玩法如下)

一颗棋子可以跳过邻近一颗棋子(只包含上下左右,而没有斜向),被跳过的棋子就被拿开。

当然如果,跳过后的空位被占了的话,也是无法跳的。如果一颗棋子上下左右都没有棋子的话那就无法移动。当整个棋盘只剩一个棋子就成功了。

棋子越多自由度就越高,每一步的选择就更多,失败的走法总体上比成功地走法多得多,所以成功不算太容易。

所以为了,为了获得一种解法,或者理论上的所有解法,我决定写这样的一个程序。

简单的思路是先建立一个坐标系,如下:

然后定义棋子空格,移动规则等等。

同样由于没必要实现全自动操作,所以采用一些麻烦但可以接受的方式输入棋盘数据。

如图操作:

用0代表空缺,用1来代表棋子,用2来代表棋盘上无法到达的部分。

7*7部分只是为了检验和输入方便,需要的是下面那一行。

运行示例如下:

为了提高速度,只返回了一种可能的解决方案。

大列表中的小列表代表移动,第一个坐标是被移动的棋子的位置,第二个则是被跳过(取走)的棋子的位置。值得一提的是,再返回结果中为了方便,将原坐标系的横纵坐标加一。

如下:

代码如下:


class Square():def __init__(self,position,num):self.position = position #定义位置self.num = numdef __str__(self):return '[%s,%s]'% (self.position,self.num)def getaline(self):linelist = []for each in wholepart:if each.position[1] == self.position[1]:linelist.append(each)return linelistdef getarow(self):rowlist = []for each in wholepart:if each.position[0] == self.position[0]:rowlist.append(each)return rowlistdef getchance():chancelist = []for each in wholepart:if each.num == [1]:try:for eacharound in wholepart:if eacharound.num == [1] and \eacharound.position[0] == each.position[0] \and abs(eacharound.position[1]-each.position[1])==1:if toplace([each,eacharound]).num == []:chancelist.append([each,eacharound])if eacharound.num == [1] and \eacharound.position[1] == each.position[1] \and abs(eacharound.position[0]-each.position[0])==1:if toplace([each,eacharound]).num == []:chancelist.append([each,eacharound])except AttributeError:passreturn chancelistdef move(chance):square1 = chance[0]square2 = chance[1]if square1.position[0]==square2.position[0]:for each in square1.getarow():if each.position[1] == 2*square2.position[1]\-square1.position[1]:each.num = [1]square1.num = []square2.num = []elif square1.position[1]==square2.position[1]:for each in square1.getaline():if each.position[0] == 2*square2.position[0]\-square1.position[0]:each.num = [1]square1.num = []square2.num = []def unmove(chance):square1 = chance[0]square2 = chance[1]if square1.position[0] == square2.position[0]:for each in square1.getarow():if each.position[1] == 2 * square2.position[1] \- square1.position[1]:each.num = []square1.num = [1]square2.num = [1]elif square1.position[1] == square2.position[1]:for each in square1.getaline():if each.position[0] == 2 * square2.position[0] \- square1.position[0]:each.num = []square1.num = [1]square2.num = [1]def toplace(choice):square1 = choice[0]square2 = choice[1]if square1.position[1] == square2.position[1]:for each in square1.getaline():if each.position[0] == 2 * square2.position[0] \- square1.position[0]:return eachif square1.position[0] == square2.position[0]:for each in square1.getarow():if each.position[1] == 2 * square2.position[1] \- square1.position[1]:return each# 生成整个棋局
wholepart = []
for row in range(7):for line in range(7):example = Square((row,line),[])wholepart.append(example)replacelist = []
tolist = []
times = 0
enter = input('please enter:')
for i in enter:if i != '0':tolist.append(int(i))replacelist.append(times)times = times + 1h = dict(zip(replacelist,tolist))
for known,t in h.items():wholepart[known].num.append(t)def main():global goif not go:returnalist = getchance()if alist == []:times = 0for each in wholepart:if each.num == [1]:times += 1if times != 1:returnelif times == 1:print('success')for h in testlist2:print('[(%s,%s),(%s,%s)]'%(h[0][0]+1,h[0][1]+1\,h[1][0]+1,h[1][1]+1),end='')print()go = Falsereturnfor eachway in alist:move(eachway)testlist2.append([eachway[0].position,eachway[1].position])main()unmove(eachway)testlist2.remove([eachway[0].position, eachway[1].position])testlist2 = []
go = True
main()

文本如下:

2200022
2201022
0011100
0001000
0001000
2200022
2200022

2200022220102200111000001000000100022000222200022

下面提供几个示例:

please enter:2201022221112201111100001000000100022111222211122
success
[(2,3),(3,3)][(2,5),(3,5)][(7,3),(6,3)][(5,3),(4,3)][(3,3),(3,4)][(1,4),(2,4)][(3,5),(3,4)][(3,2),(3,3)][(4,4),(3,4)][(6,5),(6,4)][(7,5),(7,4)][(7,3),(6,3)][(5,3),(5,4)][(5,5),(4,5)][(3,6),(3,5)][(2,4),(3,4)]Process finished with exit code 0

please enter:2200022220102200111000111110111111122000222200022
success
[(3,4),(2,4)][(4,3),(3,3)][(4,5),(5,5)][(5,7),(5,6)][(6,5),(5,5)][(4,6),(4,5)][(5,4),(4,4)][(4,4),(3,4)][(1,4),(2,4)][(3,5),(3,4)][(2,3),(3,3)][(4,3),(5,3)][(5,1),(5,2)][(6,3),(5,3)][(4,2),(4,3)]Process finished with exit code 0

写在最后:代码有很多不足。对于不同的情况,算法所花的时间差别很大,从几秒到几分钟都可能。可能等我学的更多一些才能优化了。

通过python递归来解决孔明棋问题相关推荐

  1. Go语言解决孔明棋的玩法(加深对for循环的认识)

    对于for循环,在 Go语言零基础入门,捕获错误.slice切片.for循环.test 中也有介绍,大家都很熟悉,一般是三部分组成:初始化,条件表达式,后置语句,如下: func main() {fo ...

  2. Python小游戏——孔明棋

    Python小游戏--孔明棋 规则简介 孔明棋又叫法国独立钻石,是一种单人棋,下法规则简单,棋子只能跳过相邻的棋子到空位上,并且把被跳过的棋子吃掉.棋子可以沿格线横.纵方向跳,但是不能斜跳,当棋盘内所 ...

  3. Triangle Peg Solitaire(孔明棋)

    孔明棋,是法国跳棋独立钻石在中国的别称,也有人叫它跳弹珠,或者叫它「Pegged」.一般流传的玩法是先取去中央的那个棋子,便可以展开游戏.游戏时,是将棋子跳过邻近的棋子,到达一个旁边空着的位置,被跳过 ...

  4. python 递归调用

    2019独角兽企业重金招聘Python工程师标准>>> 解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的. ...

  5. [转载] Python 递归 深入理解递归 Python递归剖析,绝对让你看懂!

    参考链接: Python | print()中的结束参数 目录 递归剖析 递归的两个过程 return 返回值 详解 递归思路二分法和递归尾递归递归练习题 递归剖析 递归真的很重要,之前学的时候,学的 ...

  6. python递归求5!_Python | 递归

    说起递归,我觉得其实大部分人应该是不陌生的,递归广泛存在于生活中. 比如: The woman in this image holds an object that contains a smalle ...

  7. python递归遍历目录_Python实现递归遍历文件夹并删除文件

    思路: 遍历文件夹下面的文件夹 如果文件夹名称等于".svn",则修改文件夹的属性(因为".svn"的文件都是只读的,你不能直接删除) 删除此文件夹 如果文件夹 ...

  8. python递归编程题_Python数据结构与算法41:递归编程练习题4:铺瓷砖

    注:本文如涉及到代码,均经过Python 3.7实际运行检验,保证其严谨性. 本文阅读时间约为8分钟. 递归编程练习题4:铺瓷砖 给定一个长度为N的区域,及4种不同长度的瓷砖:灰瓷砖(长为1格).红瓷 ...

  9. python递归是什么意思_Python——谈谈递归的深度问题

    前言: 用过python递归的同学可能都碰到过:RecursionError: maximum recursion depth exceeded while getting the str of an ...

最新文章

  1. Web前端框架与类库的思考
  2. PHP框架编写和应用知识点,写PHP框架需要具备那些知识?
  3. python环境变量配置_21 python环境的配置
  4. 七天学会SALTSTACK自动化运维 (3)
  5. 宏定义和内联函数的学习
  6. 程序员的创业困境 谁来帮助出出主意?
  7. andriod 新建 Activity_ Form (详细设置)
  8. 【ACDU】国产数据库有奖征文活动开始啦!发原创奖京东卡,最高可领1000元!...
  9. android学习--TabHost选项卡组件
  10. python浏览器怎么设置_怎么设置jupyter的默认浏览器
  11. R中Matrix and TMB package version issues
  12. C++指针delete后赋值为NULL的一些问题
  13. 超好用的数学公式识别软件mathpix!
  14. Ubuntu20.4安装gnuradio艰辛之路
  15. apm、pixhawk、pixhack飞控航拍后pos数据提取流程
  16. struggle for English college test band 6
  17. word英文大写问题解决方案
  18. 树莓派机器人小车(创乐博)修炼指南(一)
  19. ThingsBoard使用规则链将设备信息转发至外部mqtt
  20. Python语言零基础入门教程(一)

热门文章

  1. ref和reactive的区别
  2. (二十五)struts2.x中的转换器
  3. java计算机毕业设计ssm智慧小区团购系统4x45g(附源码、数据库)
  4. 怎么让图片动起来?教你让图片动起来的方法
  5. android 语言选则,应用内切换语言不重启应用的方法。
  6. Web服务(02)——Web服务器中间件
  7. 淘宝客月赚3000元的简单方法
  8. 为什么使用指针变量时一定要申请空间?
  9. cesium 实战记录(六)地图通用工具方法的封装
  10. 软考网络管理员教程精讲之文件链接命令