I have been trying to figure out a way to check each adjacent cell for my minesweeper game and am coming up short. I am a beginner in python and would also like to start using OOP. however before I can even get there, I need to rectify this. all the tutorials I have seen don't use basic python, but different versions to the IDLE i use, so I am struggling. can anyone help me? I need to be able to go around each adjacent cell and check if there is a bomb there. The value to check if there is a bomb there is 1 and will also turn red. Thank you all so much! also if you could dumb it down a little for me, that would be lovely.
import random
import pygame
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
WIDTH = 20
HEIGHT = 20
MARGIN = 5
bombnum = 10
grid = []
for row in range(10):
grid.append([])
for column in range(10):
grid[row].append(0)
print(grid)
pygame.init()
WINDOW_SIZE = [255, 315]
screen = pygame.display.set_mode(WINDOW_SIZE)
pygame.display.set_caption("Array Backed Grid")
done = False
clock = pygame.time.Clock()
#class bomb:
#def revealed(self,pick):#this is the grid thats been picked
# self.shown = shown
def placebomb():
for i in range(bombnum):
while True:
row = random.randint(0,8)
column = random.randint(0,8)
if grid[row][column] == 0:
grid[row][column] = 1
break
placebomb()
# -------- Main Program Loop -----------
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
column = pos[0] // (WIDTH + MARGIN)
row = (pos[1]-50) // (HEIGHT + MARGIN)
grid[row][column] = 1
print("Click ", pos, "Grid coordinates: ", row, column)
screen.fill(BLACK)
for row in range(10):
for column in range(10):
color = WHITE
if grid[row][column] == 1:
color = RED
pygame.draw.rect(screen,
color,
[(MARGIN + WIDTH) * (column) + MARGIN,
50+(MARGIN + HEIGHT) * row + MARGIN,
WIDTH,
HEIGHT])
clock.tick(60)
pygame.display.flip()
pygame.quit()
First up, you definitely want to make an OOP project out of this. Minesweeper's probably near the complexity limit of what you can reasonably do without object-oriented programming, but if you want to take the basic Minesweeper concept and make it more interesting / complex, you're going to need better structure.
And even if you're not considering making it more complex, thinking about what sorts of complexities you could add in is helpful in planning your classes. (Perhaps you didn't realize there's a "planning your classes" step? I'll get to that.) My steps here should work for pretty much any beginning OOP project, since it seems Minesweeper's just a convenient example.
I realize this answer will be a giant diversion from OP's how-do-I-check-the-nearest-neighbors question, but OP was also asking about OOP and answering their question in an OOP context means getting a class model in place. Trying to retrofit OOP onto non-OOP code is possible, but is usually harder than doing OOP from scratch.
import
statements connecting them. By "blocking out classes," I mean "writing the simplest classes which will compile, but don't try to make them run." At this stage, you can / should have classes that look like this:class Grid:
"""A Game has one and only one Grid, a Grid is a collection of Cells arranged in a fixed pattern"""
def __init__(self, game, **setup_params):
"""Initialize the grid given a game and possibly other parameters for shape and size"""
raise NotImplementedError('This code has not yet been written.')
def resize_grid(self, new_size):
raise NotImplementedError('This code has not yet been written.')
def check_cell_at(self, position):
raise NotImplementedError('This code has not yet been written.')
Things to check: This is completely legal Python and compiles fine. All of your notes from steps 2-4 should end up in docstrings. All of the target functionality you described in your notes corresponds to particular methods on classes that have something to do with those functions. Every class you've described is present, and has a docstring describing its purpose & structure. Every class's __init__()
method takes the arguments that are necessary to instantiate the class. Every method takes some parameters that will likely be helpful. You can always edit the parameter lists later, but again, the point is to organize your code before you get too far into writing it, so that relationships and functionality are easy to track. If you're using Git or another version-tracking tool, make your first commit as soon as you're done with this step.
__init__()
methods are complete, and those are generally straightforward.Now, how do you check the neighbors of a cell?
def check(self):
"""Returns "BOMB" if this cell has a Bomb. Otherwise, returns the number of neighbors with bombs as an integer."""
if self.has_bomb:
return "BOMB"
neighboring_mines = 0
for cell in self.grid.get_neighbors_of(self.position):
if cell.has_bomb:
neighboring_mines += 1
return neighboring_mines