python-3.x - 如何以新的方式解决八盖特曼问题?
问题描述
我需要编写一个程序来解决著名的八皇后国际象棋问题。可以在https://en.wikipedia.org/wiki/Eight_queens_puzzle找到问题的描述
这个问题有很多解决方案,所以为了让用户有选择的余地,程序一开始会加载其中一个指挥官的位置。然后他会安排剩下的七个人,让他们不会互相攻击。
某些输入可能没有解决方案,因此程序必须为此做好准备。该程序还必须处理不正确的输入。
入口 程序从标准输入中读取代数记法中的指挥官之一的位置。
退出 程序将八名指挥官的位置列表或关于缺乏解决方案的消息输出到标准输出。
示例 输入其中一个皇后的位置:a2 a2 b4 c6 d8 e3 f1 g7 h5
我在这里堆叠:(对角线效果不好,没有完成由“0”发生,我不知道如何将数字交换为字母以继续以某种方式工作)
n = 8
board = [[0] * n for row in range(n)]
def playField(self, area):
area = input('Give position of hetman: ').upper()
x = area[0]
y = area[1]
print(area[0].isdigit())
if x.isdigit() or y.isdigit():
if int(x)>n or int(x)<1 or int(y)>n or int(y)<1:
print("Wrong position, give new one: ")
playField(board, area)
else:
print(area[0],area[1])
for row in range(n):
for column in range(n):
board[row][column] = 1 #complete board "1"
board[int(x)-1][int(y)-1] = 69 #taken place complete "69" for now, later it will be "0"
if board[row][int(y)-1]==69: #check taken row
print("tag",board[row],board[int(y)-1])
board[row][int(y)-1]=0 #complete taken row "0"
print("taken row")
if board[int(x)-1][column]==69: #check taken column
board[int(x)-1][column]=0 #complete taken column "0"
print("taken column")
else:
print('free')
print("row,column: ", row,column)
print("x,y: ", x,y)
for row in range(n):
for column in range(n):
przX = abs(row - int(x))
przY = abs(column - int(y))
if (przX == przY): #check taken diagonal
print("diagonal:", row+1, column+1)
print(board)
for row in range(n):
for column in range(n):
if(board[row][column]==1): #if in place is "1" it means it is result
print("results: ",row,column)
else:
print("wrong")
playField(board, area)
playField(board, n)
我尝试实现此代码,但仍然无法正常工作:
n = 8
board = [[0] * n for row in range(n)]
def play_field(board, n, x, y):
print(x, y)
answers = solve(n,x,y)
first_answer = next(answers)
print(list(enumerate(first_answer, start=1)))
def get_position(n):
"""Prompt a user for a string resembling F2 and return coordinate pair.
Fails for values above 9 / I.""" # docstring; explains what the function
# does and its limitations. Optional.
while True:
position = input('Give position of hetman: ').upper()
if len(position) != 2:
print("Position must be 2 characters long.")
continue # restart the while True: loop
x_str, y_str = position
try: # attempt to run the following code
x = "ABCDEFGHI".index(x_str) # outputs the location in the string
# where the value of x_str can be found
# (starts counting at 0)
except ValueError: # if x_str wasn't in "ABCDEFGHI"
print("The first character must be a letter.")
continue
try:
y = int(y_str) - 1 # Python starts counting at 0, so we need to
# make sure 1 becomes 0, 2 becomes 1 etc.
except ValueError: # if y_str couldn't be converted to an int
print("The second character must be a number.")
continue
if not (0 <= x < n and 0 <= y < n):
print("Values out of range.")
continue
return x, y # return x and y, exiting the loop
def under_attack(col, queens):
return col in queens or \
any(abs(col - x) == len(queens)-i for i,x in enumerate(queens))
def solve(n,x,y):
solutions = [[x,y]]
for row in range(n):
solutions = (solution+[i+1]
for solution in solutions
for i in range(n)
if not under_attack(i+1, solution))
return solutions
x, y = get_position(n)
play_field(board, n, x, y)
解决方案
你的函数真的应该分成几个更小的函数。让我们首先将缩进级别更改为四个空格并重命名playField
为play_field
符合PEP-8,并删除一些空行。我也会修正play_field
's 的论点;它们应该是board
and n
,而不是self
and area
。(按照惯例,self
应该只用于一个类的方法;你这里没有一个类。忽略你现在得到的任何例子。)
n = 8
board = [[0] * n for row in range(n)]
def play_field(board, n):
area = input('Give position of hetman: ').upper()
x = area[0]
y = area[1]
print(area[0].isdigit())
if x.isdigit() or y.isdigit():
if int(x)>n or int(x)<1 or int(y)>n or int(y)<1:
print("Wrong position, give new one: ")
playField(board, area)
else:
print(area[0],area[1])
for row in range(n):
for column in range(n):
board[row][column] = 1
board[int(x)-1][int(y)-1] = 69
if board[row][int(y)-1]==69:
print("tag",board[row],board[int(y)-1])
board[row][int(y)-1]=0
print("taken row")
if board[int(x)-1][column]==69:
board[int(x)-1][column]=0
print("taken column")
else:
print('free')
print("row,column: ", row,column)
print("x,y: ", x,y)
for row in range(n):
for column in range(n):
przX = abs(row - int(x))
przY = abs(column - int(y))
if (przX == przY):
print("slant :", row+1, column+1)
print(board)
for row in range(n):
for column in range(n):
if(board[row][column]==0):
print("results: ",row,column)
else:
print("wrong")
playField(board, area)
play_field(board, n)
现在,要做的第一件事是将“接受输入”代码移到另一个函数中:
def get_position():
area = input('Give position of hetman: ').upper()
x, y = area # pretty much the same as x = area[0]; y = area[1]
print(x.isdigit())
我将在这里停下来,因为这是您的程序目前无法做到的事情。相反,我将重写这个函数:
def get_position(n):
"""Prompt a user for a string resembling F2 and return coordinate pair.
Fails for values above 9 / I.""" # docstring; explains what the function
# does and its limitations. Optional.
while True:
position = input('Give position of hetman: ').upper()
if len(position) != 2:
print("Position must be 2 characters long.")
continue # restart the while True: loop
x_str, y_str = position
try: # attempt to run the following code
x = "ABCDEFGHI".index(x_str) # outputs the location in the string
# where the value of x_str can be found
# (starts counting at 0)
except ValueError: # if x_str wasn't in "ABCDEFGHI"
print("The first character must be a letter.")
continue
try:
y = int(y_str) - 1 # Python starts counting at 0, so we need to
# make sure 1 becomes 0, 2 becomes 1 etc.
except ValueError: # if y_str couldn't be converted to an int
print("The second character must be a number.")
continue
if not (0 <= x < n and 0 <= y < n):
print("Values out of range.")
continue
return x, y # return x and y, exiting the loop
现在我们修改play_field
为接受x
andy
作为参数,并且不检查area
or x
ory
本身:
n = 8
board = [[0] * n for row in range(n)]
def play_field(board, n, x, y):
print(x, y)
for row in range(n):
for column in range(n):
board[row][column] = 1
board[x][y] = 69
if board[row][y]==69:
print("tag",board[row],board[y])
board[row][y]=0
print("taken row")
if board[x][column]==69:
board[x][column]=0
print("taken column")
else:
print('free')
print("row,column: ", row,column)
print("x,y: ", x+1,y+1)
for row in range(n):
for column in range(n):
przX = abs(row - x)
przY = abs(column - y)
if (przX == przY):
print("slant :", row+1, column+1)
print(board)
for row in range(n):
for column in range(n):
if(board[row][column]==0):
print("results: ",row,column)
def get_position(n):
"""Prompt a user for a string resembling F2 and return coordinate pair.
Fails for values above 9 / I.""" # docstring; explains what the function
# does and its limitations. Optional.
while True:
position = input('Give position of hetman: ').upper()
if len(position) != 2:
print("Position must be 2 characters long.")
continue # restart the while True: loop
x_str, y_str = position
try: # attempt to run the following code
x = "ABCDEFGHI".index(x_str) # outputs the location in the string
# where the value of x_str can be found
# (starts counting at 0)
except ValueError: # if x_str wasn't in "ABCDEFGHI"
print("The first character must be a letter.")
continue
try:
y = int(y_str) - 1 # Python starts counting at 0, so we need to
# make sure 1 becomes 0, 2 becomes 1 etc.
except ValueError: # if y_str couldn't be converted to an int
print("The second character must be a number.")
continue
if not (0 <= x < n and 0 <= y < n):
print("Values out of range.")
continue
return x, y # return x and y, exiting the loop
x, y = get_position(n)
play_field(board, n, x, y)
未完待续...
继续...
用这个替换你的solve
函数来解决(双关语幸运事故)问题:
def solve(n,x,y):
solutions = []
for row in range(n):
solutions = (solution+[x if row==y else i+1]
for solution in solutions
for i in range(n)
if not under_attack(i+1, solution))
return solutions
这里的神奇之处在于[x if row==y else i+1]
,它迫使排成一排的皇后y
等于x
。
推荐阅读
- java - this 的 lambda 语法而不是参考语法是什么?
- html - 如何在 HTML 中突出显示某些内容
- fortran - 如何安全正确地为大量内核进行 MPI 发送和接收
- database - 有什么方法可以访问我在 Xamarin.Forms 应用程序中创建的 SQLite 数据库文件?
- ruby - 从 YAML 文件中读取设置并根据 rb 文件的哈希返回
- c++ - openGL 索引渲染问题
- ios - 我想在 Appstore 上发布的 iOS 应用上只向少数个人用户授予访问权限,我该怎么做?
- ios - Swift:使用 CIColorCube 将 LUT(查找表)应用于视频是滞后的
- python - 在脚本中读取 Airflow REST API 传递的 conf
- react-router-dom - 无法返回 React Router v6