Advertisement
Guest User

Untitled

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