Python - 使用 Numpy 的扫雷器:如何计算每个方块周围的炸弹数?
Python - Minesweeper using Numpy: How do I count bombs around each tile?
我试图制作一个简单的扫雷板,但是当我执行以下代码时:
import random
import tkinter as tk
import numpy as np
WIDTH = 4
HEIGHT = 4
class Board:
def __init__(self, width, height):
self.width = width
self.height = height
number_of_mines = (width-1)*(height-1)
self.number_of_mines = number_of_mines
"""# added 'padding' to avoid IndexOutOfRange errors, so iterate statring at index 1 and iterate to index whatever-1"""
board = np.array([[0 for i in range(width+2)] for j in range(height+2)], dtype = str)
self.board = board
for i in range(number_of_mines):
# generate random co-ords for bombs
while True:
x_pos, y_pos = random.randint(1, width), random.randint(1,height)
if board[y_pos, x_pos] != 'b':
board[y_pos, x_pos] = 'b'
break
# iterate over each square of the board
for y_pos in range(1, height):
for x_pos in range(1, width):
# if the square in question is a bomb then skip it
if board[y_pos, x_pos] == 'b':
continue
adj_squares = board[(y_pos-1):3, (x_pos-1):3]
count = 0
for square in np.nditer(adj_squares):
if square == 'b':
count+=1
board[y_pos, x_pos]=str(count)
test = Board(WIDTH, HEIGHT)
print(test.board)
我得到这样的输出:
[['0' '0' '0' '0' '0' '0']
['0' 'b' 'b' 'b' 'b' '0']
['0' '2' '2' 'b' '0' '0']
['0' 'b' '0' '0' '0' '0']
['0' '0' 'b' 'b' 'b' '0']
['0' '0' '0' '0' '0' '0']]
比 4x4 板更大会破坏我的代码并给我一个 ValueError。
任何帮助将不胜感激:)
我发现您的代码存在多个问题。
首先,您不更新 self.board
,而是更新 board
,这意味着您的最终结果不会 return 除了“0”和 [=29] 之外的任何数字=].
你也不更新第一行的数字,我想是为了防止索引错误?我会将您的范围从 1 开始更改为 0 开始。
我已将此行代码更改如下以处理错误的索引:
adj_squares = board[(y_pos-1):3, (x_pos-1):3]
到这一行:
adj_squares = self.board[max((y_pos-1),0):min(height, y_pos + 2), max((x_pos-1),0):min(width, x_pos + 2)]
这可以防止数组在不存在的坐标中建立索引(在您的代码中,当您检查最后一列时它会出错)。
这使得最终结果:
import random
import numpy as np
WIDTH = 5
HEIGHT = 5
class Board:
def __init__(self, width, height):
self.width = width
self.height = height
number_of_mines = (width-1)*(height-1)
self.number_of_mines = number_of_mines
"""# added 'padding' to avoid IndexOutOfRange errors, so iterate statring at index 1 and iterate to index whatever-1"""
board = np.array([[0 for i in range(width+2)] for j in range(height+2)], dtype = str)
self.board = board
for i in range(number_of_mines):
# generate random co-ords for bombs
while True:
x_pos, y_pos = random.randint(1, width), random.randint(1,height)
if self.board[y_pos, x_pos] != 'b':
self.board[y_pos, x_pos] = 'b'
break
# iterate over each square of the board
for y_pos in range(0, height + 2):
for x_pos in range(0, width + 2):
# if the square in question is a bomb then skip it
if self.board[y_pos, x_pos] == 'b':
continue
adj_squares = self.board[max((y_pos-1),0):min(height + 2, y_pos + 2), max((x_pos-1),0):min(width + 2, x_pos + 2)] print(adj_squares)
count = 0
for square in np.nditer(adj_squares):
if square == 'b':
count+=1
print(count)
self.board[y_pos, x_pos]=str(count)
test = Board(WIDTH, HEIGHT)
print(test.board)
我试图制作一个简单的扫雷板,但是当我执行以下代码时:
import random
import tkinter as tk
import numpy as np
WIDTH = 4
HEIGHT = 4
class Board:
def __init__(self, width, height):
self.width = width
self.height = height
number_of_mines = (width-1)*(height-1)
self.number_of_mines = number_of_mines
"""# added 'padding' to avoid IndexOutOfRange errors, so iterate statring at index 1 and iterate to index whatever-1"""
board = np.array([[0 for i in range(width+2)] for j in range(height+2)], dtype = str)
self.board = board
for i in range(number_of_mines):
# generate random co-ords for bombs
while True:
x_pos, y_pos = random.randint(1, width), random.randint(1,height)
if board[y_pos, x_pos] != 'b':
board[y_pos, x_pos] = 'b'
break
# iterate over each square of the board
for y_pos in range(1, height):
for x_pos in range(1, width):
# if the square in question is a bomb then skip it
if board[y_pos, x_pos] == 'b':
continue
adj_squares = board[(y_pos-1):3, (x_pos-1):3]
count = 0
for square in np.nditer(adj_squares):
if square == 'b':
count+=1
board[y_pos, x_pos]=str(count)
test = Board(WIDTH, HEIGHT)
print(test.board)
我得到这样的输出:
[['0' '0' '0' '0' '0' '0']
['0' 'b' 'b' 'b' 'b' '0']
['0' '2' '2' 'b' '0' '0']
['0' 'b' '0' '0' '0' '0']
['0' '0' 'b' 'b' 'b' '0']
['0' '0' '0' '0' '0' '0']]
比 4x4 板更大会破坏我的代码并给我一个 ValueError。
任何帮助将不胜感激:)
我发现您的代码存在多个问题。
首先,您不更新 self.board
,而是更新 board
,这意味着您的最终结果不会 return 除了“0”和 [=29] 之外的任何数字=].
你也不更新第一行的数字,我想是为了防止索引错误?我会将您的范围从 1 开始更改为 0 开始。
我已将此行代码更改如下以处理错误的索引:
adj_squares = board[(y_pos-1):3, (x_pos-1):3]
到这一行:
adj_squares = self.board[max((y_pos-1),0):min(height, y_pos + 2), max((x_pos-1),0):min(width, x_pos + 2)]
这可以防止数组在不存在的坐标中建立索引(在您的代码中,当您检查最后一列时它会出错)。
这使得最终结果:
import random
import numpy as np
WIDTH = 5
HEIGHT = 5
class Board:
def __init__(self, width, height):
self.width = width
self.height = height
number_of_mines = (width-1)*(height-1)
self.number_of_mines = number_of_mines
"""# added 'padding' to avoid IndexOutOfRange errors, so iterate statring at index 1 and iterate to index whatever-1"""
board = np.array([[0 for i in range(width+2)] for j in range(height+2)], dtype = str)
self.board = board
for i in range(number_of_mines):
# generate random co-ords for bombs
while True:
x_pos, y_pos = random.randint(1, width), random.randint(1,height)
if self.board[y_pos, x_pos] != 'b':
self.board[y_pos, x_pos] = 'b'
break
# iterate over each square of the board
for y_pos in range(0, height + 2):
for x_pos in range(0, width + 2):
# if the square in question is a bomb then skip it
if self.board[y_pos, x_pos] == 'b':
continue
adj_squares = self.board[max((y_pos-1),0):min(height + 2, y_pos + 2), max((x_pos-1),0):min(width + 2, x_pos + 2)] print(adj_squares)
count = 0
for square in np.nditer(adj_squares):
if square == 'b':
count+=1
print(count)
self.board[y_pos, x_pos]=str(count)
test = Board(WIDTH, HEIGHT)
print(test.board)