Python中的Peg跳跃谜题



嗨,大家好,我遇到了一个关于使用python解决peg jump难题的问题,并从谷歌搜索过,但没有任何有用的。有各种各样的谜题,包括在一个有孔图案的板上的钉子。拼图板是一排规则间隔的孔。孔的数量可以变化。拼图开始时,一些洞被钉子占据,一些洞是空的。玩家通过一系列跳跃继续前进。在跳跃中,一个木桩越过[最近的]木桩进入一个空洞。跳过的钉子被移走了。这个谜题的目标是找到一个跳跃的序列,这样棋盘最终只有一个钉子,所有其他的洞都是空的。对于这个项目,游戏板的起始位置是一个Python字符串,如下所示:

XoXoooXXoo

,其中X表示一个钉子,o表示一个空洞。有效跳转的示例如下:

XooXX

:

XoXoo

,其中最右边的挂钩跳到左边,从最后一个挂钩移走了第二个挂钩。

目标是编写一个Python函数pegsSolution(gameBoard),它返回一个跳跃序列,结果是一个带有单个peg的板。跳转序列应该是一个Python列表,如下所示:

[(3"L"),(5‘R’),(4 ' L ')],上面的示例解决方案[(4,"L"),(0,' R ')],结果是oooox。

,其中列表中的每个项目都是一对,指示跳跃的peg的位置(从板左边的0开始计数)和方向(左或右的L或R)。如果不存在能够赢得游戏的跳跃序列,那么你的函数应该返回None。

任何建议和帮助将不胜感激,谢谢。

我面临一个关于使用python解决peg jump难题的问题,并从谷歌搜索,但没有任何有用的。

有一个完整的解决方案,并附有注释:

https://github.com/macfreek/puzzle-code/blob/master/puzzle.py

三角钉拼图模型如下:

class TriPuzzle:
pos = '011111111111111'
goal = '100000000000000'
triples = [[0,1,3], [1,3,6], [3,6,10], [2,4,7], [4,7,11], [5,8,12],
[10,11,12], [11,12,13], [12,13,14], [6,7,8], [7,8,9], [3,4,5],
[0,2,5], [2,5,9], [5,9,14], [1,4,8], [4,8,13], [3,7,12]]
def __init__(self, pos = None):
if pos: self.pos = pos
def produce( self, t, sub ):
return self.pos[:t[0]] + sub[0] + self.pos[t[0]+1:t[1]] + sub[1] + self.pos[t[1]+1:t[2]] + sub[2] + self.pos[t[2]+1:]
def __iter__( self ):
for t in self.triples:
if self.pos[t[0]]=='1' and self.pos[t[1]]=='1' and self.pos[t[2]]=='0':
yield self.__class__(self.produce(t,'001'))
if self.pos[t[0]]=='0' and self.pos[t[1]]=='1' and self.pos[t[2]]=='1':
yield self.__class__(self.produce(t,'100'))
def __str__( self ):
return '        %sn      %s   %sn    %s   %s   %sn  %s   %s   %s   %sn%s   %s   %s   %s   %sn' % tuple(self.pos)

默认的起始位置是在顶部有一个打开的挂钩:

>> start_pos = TriPuzzle()
>>> print(start_pos)
0
1   1
1   1   1
1   1   1   1
1   1   1   1   1

最有趣的方法是__iter__,它从当前位置生成所有可能的移动:

>>> for next_pos in start_pos:
...     print(next_pos)

1
0   1
0   1   1
1   1   1   1
1   1   1   1   1
1
1   0
1   1   0
1   1   1   1
1   1   1   1   1

Puzzle类的其余部分实现了一个简单的搜索器,它探索移动直到找到所需的解决方案。

我将首先实现以下函数来定义游戏规则:

from typing import List, Optional, Tuple
Move = Tuple[int, str]  # e.g. (4, 'L') to jump board[4] to the left
def possible_moves(board: str) -> List[Move]:
"""Return all possible moves given a board position."""
raise NotImplementedError
def apply_move(board: str, move: Move) -> str:
"""Apply given Move to the board and return the new board."""
raise NotImplementedError
def is_winning_board(board) -> bool:
"""Defines whether a given board has reached the win condition."""
return board.count("X") == 1
# Some simple unit tests
assert possible_moves("XooXX") == [(4, 'L')]
assert apply_move("XooXX", (4, 'L')) == "XoXoo"
assert not is_winning_board("XoXoo")
有了这些辅助函数后,编写递归DFS来查找解决方案应该很容易,如下所示:
def pegs_solution(board: str) -> Optional[List[Move]]:
"""Return a list of moves that results in a board with a single peg."""
if is_winning_board(board):
return []  # win condition
for move in possible_moves(board):
solution = pegs_solution(apply_move(board, move))
if solution is not None:
return [move] + solution
return None  # lose condition

最新更新