1

I'm trying to make a minesweeper game using lists in python. I have have this code so far:

import random as r
import sys

#dimension of board and number of bombs
width = int(sys.argv[1])
height = int(sys.argv[2])
b = int(sys.argv[3])

#creates the board
board = [[0.0] * width] * height

#places bombs
for i in range(b):
    x = r.randint(0, width - 1)
    y = r.randint(0, height - 1)
    board.insert(x, y, 0.1)

#prints board
for i in range(len(board)):
    for j in range(len(board[i]))
        print(board[i][j], end=" ")

I'm trying to get the bombs to be placed at random places on the board, but insert() only accepts 2 args. Is there any other way in which I can do this?

I have an idea to place a random bomb in row 1, then a random bomb in row 2, and so on and once it hits row n it loops back to row 1 until enough bombs have been placed, but I'm not sure if it will work (and I have no way of testing it because I have do idea how to do that either). I feel like this solution is pretty inefficient, so I'm also wondering if there's a more efficient way to do it.

Alex Ruan
  • 13
  • 4

3 Answers3

1

Use assignment instead of insert: board[x][y] = 0.1.

Also, be careful initializing your 2D board. board = [[0.0] * width] * height will make one list of size width and then will copy pointers to that list for all of the height i.e. if you assign 0.1 to the first cell in the first row board[0][0] the first item in every row will be assigned since they are all the same list. you have to instead use

   board = [[0.0]*width for _ in range(height)]
0

You can just use board[x][y] = 0.1 to access index y in row x of your board. Also, you don't want to build a board like that. The way you're doing it will only actually create 1 array with numbers. Here's your code with some modifications.

import random as r

# dimension of board and number of bombs
# (I'm using hard coded values as an example)
width = 5
height = 7
b = 10

#creates the board
board = []
for i in range(height): # create a new array for every row
    board.append([0.0] * width)

#places bombs
for i in range(b):
    x = r.randint(0, height - 1)
    y = r.randint(0, width - 1)
    board[x][y] = 0.1 # this is how you place a bomb at a random coordinate

#prints board
for row in board:
    print(row)

The resulting board for me looks like:

[0.0, 0.0, 0.1, 0.0, 0.0]                                                                                                                        
[0.0, 0.0, 0.0, 0.0, 0.0]                                                                                                                        
[0.0, 0.0, 0.0, 0.0, 0.0]                                                                                                                        
[0.1, 0.0, 0.1, 0.0, 0.1]                                                                                                                        
[0.1, 0.0, 0.0, 0.0, 0.1]                                                                                                                        
[0.0, 0.1, 0.0, 0.0, 0.1]                                                                                                                        
[0.0, 0.1, 0.0, 0.0, 0.0]

Note that you can end up with less than b bombs in case the random x and y values repeat. That's a good problem to solve next.

slider
  • 12,810
  • 1
  • 26
  • 42
0

We are dealing list of list. If we run your board initialization code and modify board value as follows:

>>> width = 2; height = 3
>>> board = [[0.0] * width] * height
>>> print board
[[0.0, 0.0], [0.0, 0.0], [0.0, 0.0]]
>>> x = 0; y = 1; board[y][x] = 1.1
>>> print board
[[1.1, 0.0], [1.1, 0.0], [1.1, 0.0]]

We see our modification appears three places. This is because we have put the same list ([0.0] * width) height times. One way of doing it properly is board = [[0.0] * width for _ in range(3)]. Please refer to Two dimensional array in python .

Since we are using list of list, one way of inserting element 0.1 for x and y will be using insert will be board[y].insert(x, 0.1). But I feel like that what you wanted to do is board[y][x]=0.1.

For the placing bombs, what you have described can be implemented like:

n = <the number of bombs>
for i in xrange(n):
    x = i % width  # x will iterate over 0 to width
    y = r.randint(0, height - 1)
    # insert bomb

Cheers,

Jo Shinhaeng
  • 36
  • 1
  • 4