1

I was trying to make a simple minesweeper board but when I execute the following code:

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)

I get an output like this:

[['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']]

Going bigger than a 4x4 board breaks my code entirely giving me a ValueError.

Any help would be much appreciated :)

HasanQ585
  • 9
  • 4

1 Answers1

0

I see multiple issues with your code.

First off, you don't update self.board, you update board, meaning your final result will not return any numbers other than the '0' and 'b'.

You also do not update the numbers in the first row, I presume to prevent an indexing error? I would change your ranges from starting with 1 to starting with 0.

I have changed this line code as following to take care of the wrong indexing:

adj_squares = board[(y_pos-1):3, (x_pos-1):3]

To this line:

adj_squares = self.board[max((y_pos-1),0):min(height, y_pos + 2), max((x_pos-1),0):min(width, x_pos + 2)]

This prevents the array being indexed in non existent coordinates (in your code it goes wrong when you check the last column).

This makes the final result:

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)
Nathan
  • 3,558
  • 1
  • 18
  • 38
  • This still produces an incorrect result. My console prints out a series of boards when I run your revised code which aren't right – HasanQ585 Jun 10 '18 at 21:05
  • Could you give me an example? For me it works just fine. – Nathan Jun 10 '18 at 21:05
  • @HasanQ585 the issue was that the width of the board is not the same as 'width' and the height doesn't equal 'height'. You may wanna look into how you define those. (width 5 gives a table of 7 columns) – Nathan Jun 10 '18 at 21:09
  • code works nicely now thanks, I defined width and height as I did so as to avoid the indexing errors – HasanQ585 Jun 10 '18 at 21:24
  • @HasanQ585 glad to help, if you're happy with the answer, could you accept it? – Nathan Jun 10 '18 at 21:45