Advertisement
Guest User

PyMines

a guest
Nov 2nd, 2013
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.42 KB | None | 0 0
  1. import pygame
  2. import random
  3. import sys
  4.  
  5. class Cell(object):
  6.     def __init__(self, is_mine, is_visible=False, is_flagged=False):
  7.         self.is_mine = is_mine
  8.         self.is_visible = is_visible
  9.         self.is_flagged = is_flagged
  10.  
  11.     def show(self):
  12.         self.is_visible = True
  13.  
  14.     def flag(self):
  15.         self.is_flagged = not self.is_flagged
  16.  
  17.     def place_mine(self):
  18.         self.is_mine = True
  19.  
  20.     def draw(self, screen, x, y, size, text_repr):
  21.         (width, height) = size
  22.         cell_img = (pygame.image.load("images/" + text_repr + ".png")
  23.                     .convert_alpha())
  24.         cell_img = pygame.transform.scale(cell_img, size)
  25.         screen.blit(cell_img, (x, y))
  26.  
  27.  
  28. class Board(tuple):
  29.     def __init__(self, tup):
  30.         super().__init__()
  31.         self.height = len(self)
  32.         self.width = len(self[0])
  33.         self.is_playing = True
  34.  
  35.     def show(self, screen, row_id, col_id):
  36.         cell = self[row_id][col_id]
  37.         if not cell.is_visible:
  38.             if not cell.is_flagged:
  39.                 cell.show()
  40.                 if (cell.is_mine and not cell.is_flagged):
  41.                     self.is_playing = False
  42.  
  43.                 elif self.count_surrounding(row_id, col_id) == 0:
  44.                     [self.show(screen, surr_row, surr_col)
  45.                      for (surr_row, surr_col)
  46.                      in self.get_neighbours(row_id, col_id)
  47.                      if self.is_in_range(surr_row, surr_col)]
  48.            
  49.             self.draw_cell(screen, row_id, col_id)
  50.  
  51.     def flag(self, screen, row_id, col_id):
  52.         cell = self[row_id][col_id]
  53.         if not cell.is_visible:
  54.             cell.flag()
  55.             self.draw_cell(screen, row_id, col_id)
  56.  
  57.     def show_mines(self, screen):
  58.         for (row_id, row) in enumerate(self):
  59.             for (col_id, cell) in enumerate(row):
  60.                 if cell.is_mine:
  61.                     self.show(screen, row_id, col_id)
  62.  
  63.     def place_mine(self, row_id, col_id):
  64.         self[row_id][col_id].place_mine()
  65.  
  66.     def get_repr(self, row_id, col_id):
  67.         cell = self[row_id][col_id]
  68.         if cell.is_visible:
  69.             if cell.is_mine:
  70.                 return "m"
  71.             else:
  72.                 return str(self.count_surrounding(row_id, col_id))
  73.  
  74.         elif cell.is_flagged:
  75.             return "f"
  76.         else:
  77.             return "x"
  78.  
  79.     def count_surrounding(self, row_id, col_id):
  80.         count = 0
  81.         for (surr_row, surr_col) in self.get_neighbours(row_id, col_id):
  82.             if (self.is_in_range(surr_row, surr_col) and
  83.                 self[surr_row][surr_col].is_mine):
  84.                 count += 1
  85.         return count
  86.  
  87.     def get_neighbours(self, row_id, col_id):
  88.         SURROUNDING = ((-1, -1), (-1,  0), (-1,  1),
  89.                        (0 , -1),           (0 ,  1),
  90.                        (1 , -1), (1 ,  0), (1 ,  1))
  91.         return ((row_id + surr_row, col_id + surr_col) for (surr_row, surr_col)
  92.                 in SURROUNDING)
  93.  
  94.     def is_in_range(self, row_id, col_id):
  95.         return 0 <= row_id < self.height and 0 <= col_id < self.width
  96.  
  97.     def draw(self, screen):
  98.         for (row_id, row) in enumerate(self):
  99.             for (col_id, cell) in enumerate(row):
  100.                 self.draw_cell(screen, row_id, col_id)
  101.  
  102.     def draw_cell(self, screen, row_id, col_id):
  103.         cell = self[row_id][col_id]
  104.         cell_width = screen.get_width() // self.width
  105.         cell_height = screen.get_height() // self.height
  106.  
  107.         cell.draw(screen, col_id * cell_width, row_id * cell_height,
  108.                   (cell_width, cell_height),
  109.                   self.get_repr(row_id, col_id))
  110.  
  111.     def mouse_handler(self, event, screen):
  112.         LEFT = 1
  113.         RIGHT = 3
  114.         cell_width = screen.get_width() // self.width
  115.         cell_height = screen.get_height() // self.height
  116.         (x, y) = event.pos
  117.         row_id = y // cell_height
  118.         col_id = x // cell_width
  119.         if event.button == LEFT:
  120.             self.show(screen, row_id, col_id)
  121.         elif event.button == RIGHT:
  122.             self.flag(screen, row_id, col_id)
  123.  
  124.     @property
  125.     def remaining_mines(self):
  126.         remaining = 0
  127.         for row in self:
  128.             for cell in row:
  129.                 if cell.is_mine:
  130.                     remaining += 1
  131.                 if cell.is_flagged:
  132.                     remaining -= 1
  133.         return remaining
  134.  
  135.     @property
  136.     def is_solved(self):
  137.         if self.remaining_mines != 0:
  138.             return False
  139.  
  140.         for row in self:
  141.             for cell in row:
  142.                 if cell.is_mine and not cell.is_flagged:
  143.                     return False
  144.  
  145.         return True
  146.  
  147.  
  148. def create_board(size, mines):
  149.     (width, height) = size
  150.     board = Board(tuple([tuple([Cell(False) for i in range(width)])
  151.                          for j in range(height)]))
  152.  
  153.     available_pos = list(range(width * height))
  154.     for i in range(mines):
  155.         new_pos = random.choice(available_pos)
  156.         available_pos.remove(new_pos)
  157.         (row_id, col_id) = (new_pos % height, new_pos // height)
  158.         board.place_mine(row_id, col_id)
  159.     return board
  160.  
  161. def play():
  162.     SIZE = (WIDTH, HEIGHT) = (16, 16)
  163.     MINES = 40
  164.     PIXELS_PER_CELL = 30
  165.     pygame.init()
  166.     screen = pygame.display.set_mode((WIDTH * PIXELS_PER_CELL,
  167.                                       HEIGHT * PIXELS_PER_CELL))
  168.     pygame.display.set_caption("PyMines")
  169.     board = create_board(SIZE, MINES)
  170.     board.draw(screen)
  171.     while True:
  172.         for event in pygame.event.get():
  173.             if event.type == pygame.QUIT:
  174.                 pygame.quit()
  175.                 sys.exit()
  176.             elif (event.type == pygame.MOUSEBUTTONDOWN and board.is_playing and
  177.                   not board.is_solved):
  178.                 board.mouse_handler(event, screen)
  179.  
  180.         message = None
  181.         if not board.is_playing:
  182.             board.show_mines(screen)
  183.             message = pygame.image.load("images/lose.png").convert_alpha()
  184.         elif board.is_solved:
  185.             message = pygame.image.load("images/win.png").convert_alpha()
  186.  
  187.         if message:
  188.             message = pygame.transform.scale(message, (screen.get_width(),
  189.                                                        screen.get_height() //
  190.                                                        5))
  191.             screen.blit(message, (0, 0))
  192.         pygame.display.update()
  193.  
  194. def main():
  195.     play()
  196.  
  197.  
  198. if __name__ == "__main__":
  199.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement