Python - тральщик, использующий Numpy: как мне считать бомбы вокруг каждой плитки? - PullRequest
0 голосов
/ 10 июня 2018

Я пытался сделать простую минную доску, но когда я выполняю следующий код:

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.

Любая помощь будет высоко ценится:)

1 Ответ

0 голосов
/ 10 июня 2018

Я вижу несколько проблем с вашим кодом.

Во-первых, вы не обновляете self.board, вы обновляете board, то есть ваш окончательный результат не будет возвращать никаких цифр, кроме '0'и 'b'.

Вы также не обновляете числа в первой строке, я полагаю, чтобы предотвратить ошибку индексации?Я бы поменял ваши диапазоны от 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)
...