📅  最后修改于: 2023-12-03 15:06:41.976000             🧑  作者: Mango
传教士和食人者(Missionaries and Cannibals)是一种经典的智力游戏,需要玩家运用逻辑思维解决问题。该游戏的玩法是将三个传教士和三个食人者通过一条小船运到对岸,但是小船只能坐两个人,而且传教士人数不能少于食人者人数,否则传教士将会被食人者吃掉。
以下是使用 Python 写的传教士和食人者游戏源代码:
# 写得不好,请不要在意
import copy
class Node:
def __init__(self, m, c, b):
self.m = m # 左岸传教士数量
self.c = c # 左岸食人者数量
self.b = b # 0 表示船在左岸,1 表示船在右岸
self.parent = None # 父节点
def is_valid(self):
if self.m < 0 or self.c < 0 or self.m > 3 or self.c > 3:
return False
if self.m > 0 and self.m < self.c:
return False
if self.m < 3 and self.m + self.c > 3:
return False
return True
def is_final(self):
if self.m == 0 and self.c == 0 and self.b == 1:
return True
return False
def successors(self):
children = []
if self.b == 0: # 船在左岸
# 移动一个传教士
n = Node(self.m - 1, self.c, 1)
if n.is_valid():
n.parent = self
children.append(n)
# 移动一个食人者
n = Node(self.m, self.c - 1, 1)
if n.is_valid():
n.parent = self
children.append(n)
# 移动一个传教士和一个食人者
n = Node(self.m - 1, self.c - 1, 1)
if n.is_valid():
n.parent = self
children.append(n)
# 移动两个传教士
n = Node(self.m - 2, self.c, 1)
if n.is_valid():
n.parent = self
children.append(n)
# 移动两个食人者
n = Node(self.m, self.c - 2, 1)
if n.is_valid():
n.parent = self
children.append(n)
else: # 船在右岸
# 移动一个传教士
n = Node(self.m + 1, self.c, 0)
if n.is_valid():
n.parent = self
children.append(n)
# 移动一个食人者
n = Node(self.m, self.c + 1, 0)
if n.is_valid():
n.parent = self
children.append(n)
# 移动一个传教士和一个食人者
n = Node(self.m + 1, self.c + 1, 0)
if n.is_valid():
n.parent = self
children.append(n)
# 移动两个传教士
n = Node(self.m + 2, self.c, 0)
if n.is_valid():
n.parent = self
children.append(n)
# 移动两个食人者
n = Node(self.m, self.c + 2, 0)
if n.is_valid():
n.parent = self
children.append(n)
return children
def print_solution(node):
n = node
path = []
while n is not None:
path.append(n)
n = n.parent
path.reverse()
for node in path:
print("M" + str(node.m) + "C" + str(node.c), end='')
if node.b == 0:
print(" -> ", end='')
else:
print(" <- ", end='')
print("")
def bfs():
init = Node(3, 3, 0)
if init.is_final():
print_solution(init)
return
queue = []
queue.append(init)
visited = set()
visited.add((init.m, init.c, init.b))
while queue:
n = queue.pop(0)
for child in n.successors():
if (child.m, child.c, child.b) not in visited:
if child.is_final():
print_solution(child)
return
queue.append(child)
visited.add((child.m, child.c, child.b))
bfs()
除了 Python,传教士和食人者还可以使用其他编程语言来实现。例如,下面是使用 JavaScript 写的传教士和食人者游戏:http://codepen.io/cybercase/pen/odBpJW。