If constructing an object is entagled with different cases and conditions it's better to use factory. That's not the case here. Instead of this. ```python def make_board(mines, size): '''function that uses my created Board methods to create the playing board''' board = Board(tuple([tuple([Cell(True,True,True) for i in range(size+1)]) for j in range(size+1)])) open_pos = list(range(size-1)*(size-1)) for i in range(mines): new_pos = random.choice(open_pos) #randomly select from open positions open_pos.remove(new_pos) # take that new position out of the open one (row_coord,col_coord) = (new_pos % 9, new_pos // 9) # mod and floor div board.put_mine(row_coord,col_coord) #put the mine in the new random location return board ``` You can do this. Notice also how I've transformed your code from imperative into declarative and used `prefer composition over inheritance` by creating `self.cells`. ```python def chunks(sequence, n): iters = (iter(iterable),) * n return zip(*iters) class Board: '''class that creates the playing board''' def __init__(self, mines_count, height, width): #initializing size = height * width mines = chain(repeat(True, mines_count), repeat(False, size - mines_count)) mines = rnd.shuffle(mines) cells = (Cell(is_mine) for is_mine in mines) self.cells = chunks(cells, width) self.playing = True ``` Use default values in initializer of Cell ```python class Cell(object): """a class to deal with individual cells""" def __init__(self, can_see, flagged, is_mine): #initializing Cell class self.can_see = not can_see self.flagged = not flagged self.is_mine = is_mine class Cell(object): '''a class to deal with individual cells''' def __init__(self, is_mine, visible=False, flagged=False): #initializing Cell class self.visible = visible self.flagged = flagged self.is_mine = is_mine ``` And `is_solved` can be expressed much shortly and more readable ```python def is_solved(self): for row in self: for cell in row: if not(cell.can_see or cell.flagged): return False return True ``` ```python def is_solved(self): return all(c.visible and c.flagged for c in chain.from_iterable(self.cells)) ``` No need for parenthesis in sequence unpacking and in conditionals too. ```python for col_coord, cell in enumerate(row): ... if cell.is_mine and not cell.flagged: ``` You're not finding neighbours they just are. Using `iterools` ```python def find_neighbors(self, row_coord,col_coord): surr = ((-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)) y = ((row_coord + surr_row, col_coord + surr_col) for (surr_row,surr_col) in surr) return y def neighbors(self, row, col): return ( self.cells[row + x][col + y] for x, y in product((-1, 0, 1), repeat=2) if (x, y) != (0, 0) and 0 <= row + x <= self.width and 0 <= col + y <= self.height ) ``` And now this ```python def count_surroundings(self,row_coord,col_coord): count = 0 for (surr_row,surr_col) in self.find_neighbors(row_coord,col_coord): if (self.is_in_range(surr_row,surr_col) and self[surr_row][surr_col].is_mine): count += 1 return count ``` Becomes oneliners ```python def surrounding_mines_count(self,row_coord,col_coord): return sum(cell.is_mine for cell in self.neighbors(row, col)) def mines_left(self): return sum(c.is_mine and not c.flagged for c in chain.from_iterable(self.cells)) ```