孔明棋大家应该都不陌生。(好吧可能不一定)
简单来讲,是一种规则简单,但是过程并不见得容易,可以一个人玩的棋。
他有还一个有趣的名字:法国跳棋独立钻石。
我上手的是vx某小程序。玩法比最经典的32颗棋子多一些。
(经典玩法如下)
一颗棋子可以跳过邻近一颗棋子(只包含上下左右,而没有斜向),被跳过的棋子就被拿开。
当然如果,跳过后的空位被占了的话,也是无法跳的。如果一颗棋子上下左右都没有棋子的话那就无法移动。当整个棋盘只剩一个棋子就成功了。
棋子越多自由度就越高,每一步的选择就更多,失败的走法总体上比成功地走法多得多,所以成功不算太容易。
所以为了,为了获得一种解法,或者理论上的所有解法,我决定写这样的一个程序。
简单的思路是先建立一个坐标系,如下:
然后定义棋子空格,移动规则等等。
同样由于没必要实现全自动操作,所以采用一些麻烦但可以接受的方式输入棋盘数据。
如图操作:
用0代表空缺,用1来代表棋子,用2来代表棋盘上无法到达的部分。
7*7部分只是为了检验和输入方便,需要的是下面那一行。
运行示例如下:
为了提高速度,只返回了一种可能的解决方案。
大列表中的小列表代表移动,第一个坐标是被移动的棋子的位置,第二个则是被跳过(取走)的棋子的位置。值得一提的是,再返回结果中为了方便,将原坐标系的横纵坐标加一。
如下:
代码如下:
class Square():
def __init__(self,position,num):
self.position = position #定义位置
self.num = num
def __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 linelist
def getarow(self):
rowlist = []
for each in wholepart:
if each.position[0] == self.position[0]:
rowlist.append(each)
return rowlist
def 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:
pass
return chancelist
def 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 each
if 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 + 1
h = dict(zip(replacelist,tolist))
for known,t in h.items():
wholepart[known].num.append(t)
def main():
global go
if not go:
return
alist = getchance()
if alist == []:
times = 0
for each in wholepart:
if each.num == [1]:
times += 1
if times != 1:
return
elif 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 = False
return
for 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
写在最后:代码有很多不足。对于不同的情况,算法所花的时间差别很大,从几秒到几分钟都可能。可能等我学的更多一些才能优化了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。