我认为board
实际上没有任何目的。
您用于将输入解析为黑白片位置的代码看起来不错,并且可能应该被制成一个函数。
对于调试,有一个函数来获取黑白块位置并打印板子会很有用——例如,使用#
黑色、O
白色和.
空白字符。这将帮助您了解您的程序在做什么。
对于每个方向,您应该有一个函数(ie left
)返回下一个位置(或者None
如果它位于棋盘边缘),另一个函数(ie )返回left_lst
该方向上的连续位置列表。所以left(17)
返回16
、left(16)
返回None
和left_lst(19)
返回[18, 17, 16]
。提示:你如何left_lst
实现left
?
然后:对于每个白色块,检查通过向每个方向移动或远离每个方向可以捕获的内容。你知道应该只有一个解决方案,所以一找到就可以退货;如果没有找到,请返回None
。
希望有帮助!
为了乐趣和兴趣,这是我想出的解决方案。希望大家多多学习!
# https://s3.amazonaws.com/iedu-attachments-question/5a989d787772b7fd88c063aff8393d34_1bee2d300c35eec13edf0a3af515a5a5.pdf
NUM_PROBS = 5
# Board looks like
# 1 2 3 4 5
# 6 7 8 9 10
# 11 12 13 14 15
# 16 17 18 19 20
# 21 22 23 24 25
WIDTH = 5
HEIGHT = 5
# display characters for printing:
WHITE = 'O'
BLACK = '#'
EMPTY = '.'
from itertools import product
def parse(s):
"""
Input: string of comma-delimited integers
ex: "3, 12, 17, 22, 3, 9, 14, 10"
format is num_white, *[white locations], num_black, *[black locations]
Output: [white locations], [black locations]
ex: [12, 17, 22], [9, 14, 10]
"""
ints = [int(i) for i in s.split(',')]
num_white = ints[0]
num_black = ints[num_white + 1]
return ints[1:num_white + 1], ints[-num_black:]
def location_to_coords(location):
"""
Given a location on the board,
return 0-based (y,x) coordinates
ex: location_to_coords(16) returns (3, 0)
"""
return divmod(location - 1, WIDTH)
def coords_to_location(y, x):
"""
Given (y, x) coordinates,
return a location on the board
ex: coords_to_location(3, 0) returns 16
"""
return y * WIDTH + x + 1
def print_board(whites, blacks):
# make an empty board
board = [[EMPTY] * WIDTH for row in range(HEIGHT)]
# add white pieces
for location in whites:
y, x = location_to_coords(location)
board[y][x] = WHITE
# add black pieces
for location in blacks:
y, x = location_to_coords(location)
board[y][x] = BLACK
# show the result
print('\n'.join(''.join(row) for row in board))
def make_dir_fn(dy, dx):
"""
Given a direction, make a function
which, given a location, returns
the next location in that direction
(or None if no such location exists)
"""
def dir_fn(location):
y, x = location_to_coords(location)
if 0 <= y + dy < HEIGHT and 0 <= x + dx < WIDTH:
return coords_to_location(y + dy, x + dx)
else:
return None
return dir_fn
def make_lst_fn(dir_fn):
"""
Given a direction function, make a function
which, given a location, returns a list
of all consecutive locations in that direction
to the edge of the board
"""
def lst_fn(location):
result = []
while True:
location = dir_fn(location)
if location is None:
break
else:
result.append(location)
return result
return lst_fn
# direction functions (one step in the named direction)
left = make_dir_fn( 0, -1)
right = make_dir_fn( 0, 1)
up = make_dir_fn(-1, 0)
down = make_dir_fn( 1, 0)
# relationships between direction functions
dir_fns = [left, right, up, down]
lst_fn = {dir_fn: make_lst_fn(dir_fn) for dir_fn in dir_fns}
opposite_dir_fn = {left: right, right: left, up: down, down: up}
def attack_toward(location, dir_fn, whites, blacks):
"""
Return a list of pieces captured by attacking toward given direction
"""
# make sure attacker is white (swap if needed)
if location in blacks:
whites, blacks = blacks, whites
# make sure we have a valid attacker
if location not in whites:
return []
# make sure we have a space to move to
next_location = dir_fn(location)
if (next_location is None) or (next_location in whites) or (next_location in blacks):
return []
# get list of attacked locations
attacked = lst_fn[dir_fn](next_location)
captured = []
for location in attacked:
if location in blacks:
captured.append(location)
else:
break
return captured
def attack_away(location, dir_fn, whites, blacks):
"""
Return a list of pieces captured by attacking away from given direction
"""
# make sure attacker is white (swap if needed)
if location in blacks:
whites, blacks = blacks, whites
# make sure we have a valid attacker
if location not in whites:
return []
# make sure we have a space to move to
next_location = opposite_dir_fn[dir_fn](location)
if (next_location is None) or (next_location in whites) or (next_location in blacks):
return []
# get list of attacked locations
attacked = lst_fn[dir_fn](location)
captured = []
for location in attacked:
if location in blacks:
captured.append(location)
else:
break
return captured
attack_fns = [attack_toward, attack_away]
def main():
for prob in range(NUM_PROBS):
# get problem
whites, blacks = parse(input())
# pick an attacker, a direction, and an attack method
for location, dir_fn, attack_fn in product(whites, dir_fns, attack_fns):
captured = attack_fn(location, dir_fn, whites, blacks)
# stop when a successful attack is found!
if captured: break
# display results
if captured:
print(", ".join(str(i) for i in sorted(captured)))
else:
print("NONE")
if __name__ == "__main__":
main()