通过python递归来解决孔明棋问题
孔明棋大家应该都不陌生。(好吧可能不一定)
简单来讲,是一种规则简单,但是过程并不见得容易,可以一个人玩的棋。
他有还一个有趣的名字:法国跳棋独立钻石。
我上手的是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递归来解决孔明棋问题相关推荐
- Go语言解决孔明棋的玩法(加深对for循环的认识)
对于for循环,在 Go语言零基础入门,捕获错误.slice切片.for循环.test 中也有介绍,大家都很熟悉,一般是三部分组成:初始化,条件表达式,后置语句,如下: func main() {fo ...
- Python小游戏——孔明棋
Python小游戏--孔明棋 规则简介 孔明棋又叫法国独立钻石,是一种单人棋,下法规则简单,棋子只能跳过相邻的棋子到空位上,并且把被跳过的棋子吃掉.棋子可以沿格线横.纵方向跳,但是不能斜跳,当棋盘内所 ...
- Triangle Peg Solitaire(孔明棋)
孔明棋,是法国跳棋独立钻石在中国的别称,也有人叫它跳弹珠,或者叫它「Pegged」.一般流传的玩法是先取去中央的那个棋子,便可以展开游戏.游戏时,是将棋子跳过邻近的棋子,到达一个旁边空着的位置,被跳过 ...
- python 递归调用
2019独角兽企业重金招聘Python工程师标准>>> 解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的. ...
- [转载] Python 递归 深入理解递归 Python递归剖析,绝对让你看懂!
参考链接: Python | print()中的结束参数 目录 递归剖析 递归的两个过程 return 返回值 详解 递归思路二分法和递归尾递归递归练习题 递归剖析 递归真的很重要,之前学的时候,学的 ...
- python递归求5!_Python | 递归
说起递归,我觉得其实大部分人应该是不陌生的,递归广泛存在于生活中. 比如: The woman in this image holds an object that contains a smalle ...
- python递归遍历目录_Python实现递归遍历文件夹并删除文件
思路: 遍历文件夹下面的文件夹 如果文件夹名称等于".svn",则修改文件夹的属性(因为".svn"的文件都是只读的,你不能直接删除) 删除此文件夹 如果文件夹 ...
- python递归编程题_Python数据结构与算法41:递归编程练习题4:铺瓷砖
注:本文如涉及到代码,均经过Python 3.7实际运行检验,保证其严谨性. 本文阅读时间约为8分钟. 递归编程练习题4:铺瓷砖 给定一个长度为N的区域,及4种不同长度的瓷砖:灰瓷砖(长为1格).红瓷 ...
- python递归是什么意思_Python——谈谈递归的深度问题
前言: 用过python递归的同学可能都碰到过:RecursionError: maximum recursion depth exceeded while getting the str of an ...
最新文章
- Web前端框架与类库的思考
- PHP框架编写和应用知识点,写PHP框架需要具备那些知识?
- python环境变量配置_21 python环境的配置
- 七天学会SALTSTACK自动化运维 (3)
- 宏定义和内联函数的学习
- 程序员的创业困境 谁来帮助出出主意?
- andriod 新建 Activity_ Form (详细设置)
- 【ACDU】国产数据库有奖征文活动开始啦!发原创奖京东卡,最高可领1000元!...
- android学习--TabHost选项卡组件
- python浏览器怎么设置_怎么设置jupyter的默认浏览器
- R中Matrix and TMB package version issues
- C++指针delete后赋值为NULL的一些问题
- 超好用的数学公式识别软件mathpix!
- Ubuntu20.4安装gnuradio艰辛之路
- apm、pixhawk、pixhack飞控航拍后pos数据提取流程
- struggle for English college test band 6
- word英文大写问题解决方案
- 树莓派机器人小车(创乐博)修炼指南(一)
- ThingsBoard使用规则链将设备信息转发至外部mqtt
- Python语言零基础入门教程(一)