Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import pygame
- import random
- import sys
- class Cell(object):
- def __init__(self, is_mine, is_visible=False, is_flagged=False):
- self.is_mine = is_mine
- self.is_visible = is_visible
- self.is_flagged = is_flagged
- def show(self):
- self.is_visible = True
- def flag(self):
- self.is_flagged = not self.is_flagged
- def place_mine(self):
- self.is_mine = True
- def draw(self, screen, x, y, size, text_repr):
- (width, height) = size
- cell_img = pygame.image.load(text_repr + ".png").convert_alpha()
- cell_img = pygame.transform.scale(cell_img, size)
- screen.blit(cell_img, (x, y))
- class Board(tuple):
- def __init__(self, tup):
- super().__init__()
- self.height = len(self)
- self.width = len(self[0])
- self.is_playing = True
- def show(self, row_id, col_id):
- cell = self[row_id][col_id]
- if not cell.is_visible and not cell.is_flagged:
- cell.show()
- if (cell.is_mine and not cell.is_flagged):
- self.is_playing = False
- elif self.count_surrounding(row_id, col_id) == 0:
- [self.show(surr_row, surr_col) for (surr_row, surr_col) in
- self.get_neighbours(row_id, col_id) if
- self.is_in_range(surr_row, surr_col)]
- def flag(self, row_id, col_id):
- cell = self[row_id][col_id]
- if not cell.is_visible:
- cell.flag()
- def show_mines(self):
- [cell.show() for row in self for cell in row if cell.is_mine]
- def place_mine(self, row_id, col_id):
- self[row_id][col_id].place_mine()
- def get_repr(self, row_id, col_id):
- cell = self[row_id][col_id]
- if cell.is_visible:
- if cell.is_mine:
- return "m"
- else:
- return str(self.count_surrounding(row_id, col_id))
- elif cell.is_flagged:
- return "f"
- else:
- return "x"
- def count_surrounding(self, row_id, col_id):
- count = 0
- for (surr_row, surr_col) in self.get_neighbours(row_id, col_id):
- if (self.is_in_range(surr_row, surr_col) and
- self[surr_row][surr_col].is_mine):
- count += 1
- return count
- def get_neighbours(self, row_id, col_id):
- SURROUNDING = ((-1, -1), (-1, 0), (-1, 1),
- (0 , -1), (0 , 1),
- (1 , -1), (1 , 0), (1 , 1))
- return ((row_id + surr_row, col_id + surr_col) for (surr_row, surr_col)
- in SURROUNDING)
- def is_in_range(self, row_id, col_id):
- return 0 <= row_id < self.height and 0 <= col_id < self.width
- @property
- def remaining_mines(self):
- remaining = 0
- for row in self:
- for cell in row:
- if cell.is_mine:
- remaining += 1
- if cell.is_flagged:
- remaining -= 1
- return remaining
- @property
- def is_solved(self):
- if self.remaining_mines != 0:
- return False
- for row in self:
- for cell in row:
- if cell.is_mine and not cell.is_flagged:
- return False
- return True
- class GUIBoard(Board):
- def draw(self, screen):
- cell_width = screen.get_width() // self.width
- cell_height = screen.get_height() // self.height
- for (row_id, row) in enumerate(self):
- for (col_id, cell) in enumerate(row):
- cell.draw(screen, col_id * cell_width, row_id * cell_height,
- (cell_width, cell_height),
- self.get_repr(row_id, col_id))
- def mouse_handler(self, event, screen):
- LEFT = 1
- RIGHT = 3
- cell_width = screen.get_width() // self.width
- cell_height = screen.get_height() // self.height
- (x, y) = event.pos
- row_id = y // cell_height
- col_id = x // cell_width
- if event.button == LEFT:
- self.show(row_id, col_id)
- elif event.button == RIGHT:
- self.flag(row_id, col_id)
- def create_board(size, mines):
- (width, height) = size
- board = GUIBoard(tuple([tuple([Cell(False) for i in range(width)])
- for j in range(height)]))
- available_pos = list(range(width * height))
- for i in range(mines):
- new_pos = random.choice(available_pos)
- available_pos.remove(new_pos)
- (row_id, col_id) = (new_pos % height, new_pos // height)
- board.place_mine(row_id, col_id)
- return board
- def play():
- SIZE = (WIDTH, HEIGHT) = (9, 9)
- MINES = 10
- PIXELS_PER_CELL = 30
- pygame.init()
- screen = pygame.display.set_mode((WIDTH * PIXELS_PER_CELL,
- HEIGHT * PIXELS_PER_CELL))
- pygame.display.set_caption("PyMines")
- board = create_board(SIZE, MINES)
- while True:
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- pygame.quit()
- sys.exit()
- elif (event.type == pygame.MOUSEBUTTONDOWN and board.is_playing and
- not board.is_solved):
- board.mouse_handler(event, screen)
- message = None
- if not board.is_playing:
- board.show_mines()
- message = pygame.image.load("lose.png").convert_alpha()
- elif board.is_solved:
- message = pygame.image.load("win.png").convert_alpha()
- board.draw(screen)
- if message:
- message = pygame.transform.scale(message, (screen.get_width(),
- screen.get_height() //
- 5))
- screen.blit(message, (0, 0))
- pygame.display.update()
- def main():
- play()
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement