Is there a way I can fix the way ji get neighbors of a 2d coordinate?
"""6.009 Lab 5 -- Mines"""
def dump(game):
"""Print a human-readable representation of game.
Arguments:
game (dict): Game state
>>> dump({'dimensions': [1, 2], 'mask': [[False, False]], 'board': [['.', 1]]})
dimensions: [1, 2]
board: ['.', 1]
mask: [False, False]
"""
lines = ["dimensions: {}".format(game["dimensions"]),
"board: {}".format("\n ".join(map(str, game["board"]))),
"mask: {}".format("\n ".join(map(str, game["mask"])))]
print("\n".join(lines))
def get_2d_neighbors(coord):
'''Get neighbors of a 2D coordinate
Take a 2d coordinate and return a list of all 8 possible neighbors as if the coordinate
does not fall on any edges of the board
>>> get_2d_neighbors((2,2))
[(1,1), (1,2), (1,3), (2,1), (2,3), (3,1), (3,2), (3,3)]
'''
neighbors = []
x = coord[0]
y = coord[1]
neighbor_list = [(x-1,y-1) , (x-1,y) , (x-1,y+1),
(x,y-1), (x, y+1),
(x+1,y-1) , (x+1,y) , (x+1,y+1)]
for neighbor in neighbor_list:
neighbors.append(neighbor)
return neighbors
def new_game(num_rows, num_cols, bombs):
"""Start a new game.
Return a game state dictionary, with the "board" and "mask" fields
adequately initialized.
Args:
num_rows (int): Number of rows
num_cols (int): Number of columns
bombs (list): List of bombs, given in (row, column) pairs
Returns:
A game state dictionary
>>> dump(new_game(2, 4, [(0, 0), (1, 0), (1, 1)]))
dimensions: [2, 4]
board: ['.', 3, 1, 0]
['.', '.', 1, 0]
mask: [False, False, False, False]
[False, False, False, False]
"""
game = {}
game['dimensions'] = [num_rows, num_cols]
game['mask'] = [[False]*num_cols]*num_rows
#game['board'] = [[0]*num_cols]*num_rows ||||| board_dict[i,j] = game['board'][i][j]
bomb_num = len(bombs)
if bomb_num == 0:
return game
r = range(bomb_num)
board_dict = {}
for i in range(num_rows):
for j in range(num_cols):
board_dict[i,j] = 0
for (x,y) in bombs:
board_dict[x,y] = '.'
possible_neighbors = get_2d_neighbors((x,y))
for neighbor in possible_neighbors:
try:
board_dict[neighbor] += 1
except TypeError:
continue
except KeyError:
continue
sorted_1d_board = [value for (key,value) in sorted(board_dict.items())]
board_2d_list = []
while len(sorted_1d_board)>0:
board_2d_list.append(sorted_1d_board[:num_cols])
del sorted_1d_board[:num_cols]
game['board'] = board_2d_list
return game
def dig(game, row, col):
"""Recursively dig up (row, col) and neighboring squares.
Update game["mask"] to reveal (row, col); then recursively reveal (dig up)
its neighbors, as long as (row, col) does not contain and is not adjacent to
a bomb. Return a pair: the first element indicates whether the game is over
using a string equal to "victory", "defeat", or "ongoing", and the second
one is a number indicates how many squares were revealed.
The first element is "defeat" when at least one bomb is visible on the board
after digging (i.e. game["mask"][bomb_location] == True), "victory" when all
safe squares (squares that do not contain a bomb) and no bombs are visible,
and "ongoing" otherwise.
Args:
game (dict): Game state
row (int): Where to start digging (row)
col (int): Where to start digging (col)
Returns:
Tuple[str,int]: A pair of game status and number of squares revealed
>>> game = {"dimensions": [2, 4],
... "board": [[".", 3, 1, 0],
... [".", ".", 1, 0]],
... "mask": [[False, True, False, False],
... [False, False, False, False]]}
>>> dig(game, 0, 3)
('victory', 4)
>>> dump(game)
dimensions: [2, 4]
board: ['.', 3, 1, 0]
['.', '.', 1, 0]
mask: [False, True, True, True]
[False, False, True, True]
>>> game = {"dimensions": [2, 4],
... "board": [[".", 3, 1, 0],
... [".", ".", 1, 0]],
... "mask": [[False, True, False, False],
... [False, False, False, False]]}
>>> dig(game, 0, 0)
('defeat', 1)
>>> dump(game)
dimensions: [2, 4]
board: ['.', 3, 1, 0]
['.', '.', 1, 0]
mask: [True, True, False, False]
[False, False, False, False]
"""
game['mask'][row][col] = True
square = game['board'][row][col]
if square == '.' :
return ('defeat', 1)
possible_neighbors = get_2d_neighbors((row,col))
row_range = range(game['dimensions'][0])
col_range = range(game['dimensions'][1])
actual_neighbors = []
for (r,c) in possible_neighbors:
if r in row_range and c in col_range:
actual_neighbors.append((r,c))
count = 1
if square == 0:
for (r,c) in actual_neighbors:
game['mask'][r][c] = True
count += 1
return (status, count)
def render(game, xray=False):
"""Prepare a game for display.
Returns a two-dimensional array (list of lists) of "_" (hidden squares), "."
(bombs), " " (empty squares), or "1", "2", etc. (squares neighboring bombs).
game["mask"] indicates which squares should be visible. If xray is True (the
default is False), game["mask"] is ignored and all cells are shown.
Args:
game (dict): Game state
xray (bool): Whether to reveal all tiles or just the ones allowed by
game["mask"]
Returns:
A 2D array (list of lists)
>>> render({"dimensions": [2, 4],
... "board": [[".", 3, 1, 0],
... [".", ".", 1, 0]],
... "mask": [[False, True, True, False],
... [False, False, True, False]]}, False)
[['_', '3', '1', '_'],
['_', '_', '1', '_']]
>>> render({"dimensions": [2, 4],
... "board": [[".", 3, 1, 0],
... [".", ".", 1, 0]],
... "mask": [[False, True, False, True],
... [False, False, False, True]]}, True)
[['.', '3', '1', ' '],
['.', '.', '1', ' ']]
"""
raise NotImplementedError
def render_ascii(game, xray=False):
"""Render a game as ASCII art.
Returns a string-based representation of argument "game". Each tile of the
game board should be rendered as in the function "render(game)".
Args:
game (dict): Game state
xray (bool): Whether to reveal all tiles or just the ones allowed by
game["mask"]
Returns:
A string-based representation of game
>>> print(render_ascii({"dimensions": [2, 4],
... "board": [[".", 3, 1, 0],
... [".", ".", 1, 0]],
... "mask": [[True, True, True, False],
... [False, False, True, False]]}))
.31_
__1_
"""
raise NotImplementedError
def nd_new_game(dims, bombs):
"""Start a new game.
Return a game state dictionary, with the "board" and "mask" fields
adequately initialized. This is an N-dimensional version of new_game().
Args:
dims (list): Dimensions of the board
bombs (list): bomb locations as a list of tuples, each an N-dimensional coordinate
Returns:
A game state dictionary
>>> dump(nd_new_game([2, 4, 2], [(0, 0, 1), (1, 0, 0), (1, 1, 1)]))
dimensions: [2, 4, 2]
board: [[3, '.'], [3, 3], [1, 1], [0, 0]]
[['.', 3], [3, '.'], [1, 1], [0, 0]]
mask: [[False, False], [False, False], [False, False], [False, False]]
[[False, False], [False, False], [False, False], [False, False]]
"""
raise NotImplementedError
def nd_dig(game, coords):
"""Recursively dig up square at coords and neighboring squares.
Update game["mask"] to reveal square at coords; then recursively reveal its
neighbors, as long as coords does not contain and is not adjacent to a
bomb. Return a pair: the first element indicates whether the game is over
using a string equal to "victory", "defeat", or "ongoing", and the second
one is a number indicates how many squares were revealed.
The first element is "defeat" when at least one bomb is visible on the board
after digging (i.e. game["mask"][bomb_location] == True), "victory" when all
safe squares (squares that do not contain a bomb) and no bombs are visible,
and "ongoing" otherwise.
This is an N-dimensional version of dig().
Args:
game (dict): Game state
coords (tuple): Where to start digging
Returns:
A pair of game status and number of squares revealed
>>> game = {"dimensions": [2, 4, 2],
... "board": [[[3, '.'], [3, 3], [1, 1], [0, 0]],
... [['.', 3], [3, '.'], [1, 1], [0, 0]]],
... "mask": [[[False, False], [False, True], [False, False], [False, False]],
... [[False, False], [False, False], [False, False], [False, False]]]}
>>> nd_dig(game, (0, 3, 0))
('ongoing', 8)
>>> dump(game)
dimensions: [2, 4, 2]
board: [[3, '.'], [3, 3], [1, 1], [0, 0]]
[['.', 3], [3, '.'], [1, 1], [0, 0]]
mask: [[False, False], [False, True], [True, True], [True, True]]
[[False, False], [False, False], [True, True], [True, True]]
>>> game = {"dimensions": [2, 4, 2],
... "board": [[[3, '.'], [3, 3], [1, 1], [0, 0]],
... [['.', 3], [3, '.'], [1, 1], [0, 0]]],
... "mask": [[[False, False], [False, True], [False, False], [False, False]],
... [[False, False], [False, False], [False, False], [False, False]]]}
>>> nd_dig(game, (0, 0, 1))
('defeat', 1)
>>> dump(game)
dimensions: [2, 4, 2]
board: [[3, '.'], [3, 3], [1, 1], [0, 0]]
[['.', 3], [3, '.'], [1, 1], [0, 0]]
mask: [[False, True], [False, True], [False, False], [False, False]]
[[False, False], [False, False], [False, False], [False, False]]
"""
raise NotImplementedError
def nd_render(game, xray=False):
"""Prepare a game for display.
Returns an N-dimensional array (nested lists) of "_" (hidden squares), "."
(bombs), " " (empty squares), or "1", "2", etc. (squares neighboring bombs).
game["mask"] indicates which squares should be visible. If xray is True (the
default is False), game["mask"] is ignored and all cells are shown.
This is an N-dimensional version of render().
Args:
game (dict): Game state
xray (bool): Whether to reveal all tiles or just the ones allowed by
game["mask"]
Returns:
An n-dimensional array (nested lists)
>>> nd_render({"dimensions": [2, 4, 2],
... "board": [[[3, '.'], [3, 3], [1, 1], [0, 0]],
... [['.', 3], [3, '.'], [1, 1], [0, 0]]],
... "mask": [[[False, False], [False, True], [True, True], [True, True]],
... [[False, False], [False, False], [True, True], [True, True]]]},
... False)
[[['_', '_'], ['_', '3'], ['1', '1'], [' ', ' ']],
[['_', '_'], ['_', '_'], ['1', '1'], [' ', ' ']]]
>>> nd_render({"dimensions": [2, 4, 2],
... "board": [[[3, '.'], [3, 3], [1, 1], [0, 0]],
... [['.', 3], [3, '.'], [1, 1], [0, 0]]],
... "mask": [[[False, False], [False, True], [False, False], [False, False]],
... [[False, False], [False, False], [False, False], [False, False]]]},
... True)
[[['3', '.'], ['3', '3'], ['1', '1'], [' ', ' ']],
[['.', '3'], ['3', '.'], ['1', '1'], [' ', ' ']]]
"""
raise NotImplementedError