From: Skullheadx <94652084+Skullheadx@users.noreply.github.com> Date: Sat, 3 Jun 2023 02:26:30 +0000 (-0400) Subject: polish X-Git-Url: http://git.skullheadx.com/nixos/blog/static/gitweb.css?a=commitdiff_plain;h=29dc2a19ea0dc90485d048d4bc2356e15900d85a;p=Minesweeper.git polish --- diff --git a/README.md b/README.md index 46dc5b0..6e272d3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # Minesweeper - + +## CREDITS + +assets: https://kia.itch.io/16x16-tileset-for-minesweeper \ No newline at end of file diff --git a/assets/1.png b/assets/1.png new file mode 100644 index 0000000..868d97a Binary files /dev/null and b/assets/1.png differ diff --git a/assets/2.png b/assets/2.png new file mode 100644 index 0000000..e492676 Binary files /dev/null and b/assets/2.png differ diff --git a/assets/3.png b/assets/3.png new file mode 100644 index 0000000..cfccd11 Binary files /dev/null and b/assets/3.png differ diff --git a/assets/4.png b/assets/4.png new file mode 100644 index 0000000..57a52b3 Binary files /dev/null and b/assets/4.png differ diff --git a/assets/5.png b/assets/5.png new file mode 100644 index 0000000..531895d Binary files /dev/null and b/assets/5.png differ diff --git a/assets/6.png b/assets/6.png new file mode 100644 index 0000000..711d2e8 Binary files /dev/null and b/assets/6.png differ diff --git a/assets/7.png b/assets/7.png new file mode 100644 index 0000000..9db5003 Binary files /dev/null and b/assets/7.png differ diff --git a/assets/8.png b/assets/8.png new file mode 100644 index 0000000..a6132a8 Binary files /dev/null and b/assets/8.png differ diff --git a/assets/bomb.png b/assets/bomb.png new file mode 100644 index 0000000..4448787 Binary files /dev/null and b/assets/bomb.png differ diff --git a/assets/empty.png b/assets/empty.png new file mode 100644 index 0000000..ed005e1 Binary files /dev/null and b/assets/empty.png differ diff --git a/assets/explosion.png b/assets/explosion.png new file mode 100644 index 0000000..a326251 Binary files /dev/null and b/assets/explosion.png differ diff --git a/assets/flag.png b/assets/flag.png new file mode 100644 index 0000000..0757b98 Binary files /dev/null and b/assets/flag.png differ diff --git a/assets/minesweeper.png b/assets/minesweeper.png new file mode 100644 index 0000000..3c7f8e1 Binary files /dev/null and b/assets/minesweeper.png differ diff --git a/assets/outline.png b/assets/outline.png new file mode 100644 index 0000000..b81638e Binary files /dev/null and b/assets/outline.png differ diff --git a/assets/undiscovered.png b/assets/undiscovered.png new file mode 100644 index 0000000..039bfe1 Binary files /dev/null and b/assets/undiscovered.png differ diff --git a/assets/undiscovered_bomb.png b/assets/undiscovered_bomb.png new file mode 100644 index 0000000..1a5d8b4 Binary files /dev/null and b/assets/undiscovered_bomb.png differ diff --git a/game.py b/game.py index a01a8c2..715833c 100644 --- a/game.py +++ b/game.py @@ -4,27 +4,29 @@ from grid import Grid class Game: - def __init__(self): - self.grid = Grid(10, 10, 5) - self.game_over = False + def __init__(self): + self.grid = Grid(25, 25, 100) + self.game_over = False - def update(self, delta): - for event in pygame.event.get(): - if event.type == pygame.QUIT: - return COMMAND_EXIT - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_r: - return COMMAND_RESTART + def update(self, delta): + for event in pygame.event.get(): + if event.type == pygame.QUIT: + return COMMAND_EXIT + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_r: + return COMMAND_RESTART - mouse_pos = pygame.mouse.get_pos() - mouse_button = pygame.mouse.get_pressed() - if self.grid.update(delta, mouse_pos, mouse_button): - return COMMAND_LOSE - if self.grid.win(): - return COMMAND_WIN + mouse_pos = pygame.mouse.get_pos() + mouse_button = pygame.mouse.get_pressed() + if self.grid.update(delta, mouse_pos, mouse_button): + for bomb in self.grid.bombs: + bomb.reveal() + return COMMAND_LOSE + if self.grid.win(): + return COMMAND_WIN - return COMMAND_NONE + return COMMAND_NONE - def draw(self, screen): - screen.fill(BLACK) - self.grid.draw(screen) + def draw(self, screen): + screen.fill(BLACK) + self.grid.draw(screen) diff --git a/grid.py b/grid.py index 5a43186..c562536 100644 --- a/grid.py +++ b/grid.py @@ -4,114 +4,146 @@ from setup import * class Grid: - def __init__(self, length, height, bomb_count): - self.length, self.height = length, height - self.grid = [[Cell(j, i) for j in range(self.length)] for i in range(self.height)] - - self.bomb_count = bomb_count - self.place_bombs(self.bomb_count) - - self.mouse_cooldown = 0 - - for row in self.grid: - for cell in row: - neighbors = [] - for i in range(-1, 2): - for j in range(-1, 2): - x = int(cell.position.x // Cell.cell_size + i) - y = int(cell.position.y // Cell.cell_size + j) - if 0 <= y < self.height and 0 <= x < self.length and not (i == 0 and j == 0): - neighbors.append(self.grid[y][x]) - cell.give_number(neighbors) - - def update(self, delta, mouse_pos, mouse_button): - if self.mouse_cooldown > 0: - self.mouse_cooldown -= delta - return False - - for row in self.grid: - for cell in row: - if cell.position.x <= mouse_pos[0] <= cell.position.x + Cell.cell_size and cell.position.y <= mouse_pos[1] <= cell.position.y + Cell.cell_size: - if mouse_button[0] == 1: - self.mouse_cooldown = 0.2 - if cell.update(self.grid, self.height, self.length): - return True - elif mouse_button[2] == 1: - if not cell.discovered: - cell.flagged = not cell.flagged - self.mouse_cooldown = 0.2 - return False - - def win(self): - for row in self.grid: - for cell in row: - if not cell.is_bomb and not cell.discovered: - return False - return True - - def draw(self, screen): - for row in self.grid: - for cell in row: - cell.draw(screen) - - def place_bombs(self, bomb_count): - while bomb_count > 0: - x = random.randint(0, self.length - 1) - y = random.randint(0, self.height - 1) - if not self.grid[y][x].is_bomb: - self.grid[y][x].is_bomb = True - bomb_count -= 1 + def __init__(self, length, height, bomb_count): + self.length, self.height = length, height + self.position = pygame.Vector2(SCREEN_WIDTH / 2 - Cell.cell_size * self.length / 2, + SCREEN_HEIGHT / 2 - Cell.cell_size * self.height / 2) + self.grid = [[Cell(self.position.x, self.position.y, j, i) for j in range(self.length)] for i in + range(self.height)] + + self.bomb_count = bomb_count + self.place_bombs(self.bomb_count) + + self.mouse_cooldown = 0 + + self.bombs = [] + + for row in self.grid: + for cell in row: + neighbors = [] + for i in range(-1, 2): + for j in range(-1, 2): + x = int(cell.grid_position.x + j) + y = int(cell.grid_position.y + i) + if 0 <= y < self.height and 0 <= x < self.length and not (i == 0 and j == 0): + neighbors.append(self.grid[y][x]) + cell.give_number(neighbors) + if cell.is_bomb: + self.bombs.append(cell) + + def update(self, delta, mouse_pos, mouse_button): + if self.mouse_cooldown > 0: + self.mouse_cooldown -= delta + return False + + for row in self.grid: + for cell in row: + if cell.position.x <= mouse_pos[0] <= cell.position.x + Cell.cell_size and cell.position.y <= mouse_pos[ + 1] <= cell.position.y + Cell.cell_size: + if mouse_button[0] == 1: + self.mouse_cooldown = 0.2 + if cell.update(self.grid, self.height, self.length): + return True + elif mouse_button[2] == 1: + if not cell.discovered: + cell.flagged = not cell.flagged + self.mouse_cooldown = 0.2 + return False + + def win(self): + for row in self.grid: + for cell in row: + if not cell.is_bomb and not cell.discovered: + return False + return True + + def draw(self, screen): + pygame.draw.rect(screen, BACKGROUND, ( + self.position.x - 2, self.position.y - 2, self.length * Cell.cell_size + 4, + self.height * Cell.cell_size + 4)) + pygame.draw.rect(screen, BORDER, ( + self.position.x - 2, self.position.y - 2, self.length * Cell.cell_size + 4, + self.height * Cell.cell_size + 4), + 2) + for row in self.grid: + for cell in row: + cell.draw(screen) + + def place_bombs(self, bomb_count): + while bomb_count > 0: + x = random.randint(0, self.length - 1) + y = random.randint(0, self.height - 1) + if not self.grid[y][x].is_bomb: + self.grid[y][x].is_bomb = True + bomb_count -= 1 class Cell: - cell_size = 25 - font = pygame.font.SysFont("Arial", 20) - - def __init__(self, x, y): - self.position = pygame.Vector2(x * self.cell_size, y * self.cell_size) - self.is_bomb = False - self.flagged = False - self.number = 0 - self.discovered = False - self.color = GRAY - self.text = None - - def update(self, grid, height, length): - if self.discovered or self.flagged: - return False - self.discovered = True - self.color = GREEN - if self.is_bomb: - self.color = RED - return True - - if self.number == 0: - for i in range(-1, 2): - for j in range(-1, 2): - x = int(self.position.x // self.cell_size + i) - y = int(self.position.y // self.cell_size + j) - if 0 <= y < height and 0 <= x < length and not (i == 0 and j == 0): - if not grid[y][x].discovered and not grid[y][x].flagged: - grid[y][x].update(grid, height, length) - - return False - - def give_number(self, neighbors): - if self.is_bomb: - return - for neighbor in neighbors: - if neighbor.is_bomb: - self.number += 1 - - self.text = self.font.render(str(self.number), True, BLACK) - - def draw(self, screen): - display_color = self.color - if self.flagged: - display_color = BLUE - - pygame.draw.rect(screen, display_color, (self.position.x, self.position.y, self.cell_size, self.cell_size)) - pygame.draw.rect(screen, BLACK, (self.position.x, self.position.y, self.cell_size, self.cell_size), 1) - if self.discovered and self.number > 0: - screen.blit(self.text, self.text.get_rect( - center=(self.position.x + self.cell_size / 2, self.position.y + self.cell_size / 2))) + cell_size = 25 + numbers = { + 0: pygame.transform.scale(pygame.image.load("assets/empty.png"), (cell_size, cell_size)), + 1: pygame.transform.scale(pygame.image.load("assets/1.png"), (cell_size, cell_size)), + 2: pygame.transform.scale(pygame.image.load("assets/2.png"), (cell_size, cell_size)), + 3: pygame.transform.scale(pygame.image.load("assets/3.png"), (cell_size, cell_size)), + 4: pygame.transform.scale(pygame.image.load("assets/4.png"), (cell_size, cell_size)), + 5: pygame.transform.scale(pygame.image.load("assets/5.png"), (cell_size, cell_size)), + 6: pygame.transform.scale(pygame.image.load("assets/6.png"), (cell_size, cell_size)), + 7: pygame.transform.scale(pygame.image.load("assets/7.png"), (cell_size, cell_size)), + 8: pygame.transform.scale(pygame.image.load("assets/8.png"), (cell_size, cell_size)), + } + + flag = pygame.transform.scale(pygame.image.load("assets/flag.png"), (cell_size, cell_size)) + undiscovered = pygame.transform.scale(pygame.image.load("assets/undiscovered.png"), (cell_size, cell_size)) + explosion = pygame.transform.scale(pygame.image.load("assets/explosion.png"), (cell_size, cell_size)) + undiscovered_bomb = pygame.transform.scale(pygame.image.load("assets/undiscovered_bomb.png"), + (cell_size, cell_size)) + + def __init__(self, pos_x, pos_y, x, y): + self.position = pygame.Vector2(pos_x + x * self.cell_size, pos_y + y * self.cell_size) + self.grid_position = pygame.Vector2(x, y) + self.is_bomb = False + self.flagged = False + self.number = 0 + self.discovered = False + self.revealed = False + + def update(self, grid, height, length): + if self.discovered or self.flagged: + return False + self.discovered = True + if self.is_bomb: + return True + + if self.number == 0: + for i in range(-1, 2): + for j in range(-1, 2): + x = int(self.grid_position.x + i) + y = int(self.grid_position.y + j) + if 0 <= y < height and 0 <= x < length and not (i == 0 and j == 0): + if not grid[y][x].discovered and not grid[y][x].flagged: + grid[y][x].update(grid, height, length) + return False + + def give_number(self, neighbors): + if self.is_bomb: + return + for neighbor in neighbors: + if neighbor.is_bomb: + self.number += 1 + + def reveal(self): + if not self.discovered: + self.revealed = True + + def draw(self, screen): + if self.revealed: + screen.blit(self.undiscovered_bomb, self.position) + elif self.discovered: + if self.is_bomb: + screen.blit(self.explosion, self.position) + else: + screen.blit(self.numbers[self.number], self.position) + else: + screen.blit(self.undiscovered, self.position) + if self.flagged: + screen.blit(self.flag, self.position) diff --git a/main.py b/main.py index 530f487..f39ec1b 100644 --- a/main.py +++ b/main.py @@ -4,25 +4,24 @@ from menus import Lose, Win def main(): - scene = Game() - is_running = True - delta = 0 - while is_running: - status = scene.update(delta) - scene.draw(screen) + scene = Game() + is_running = True + while is_running: + delta = clock.tick(60) / 1000 - if status == COMMAND_EXIT: - is_running = False - elif status == COMMAND_RESTART: - scene = Game() - elif status == COMMAND_WIN: - scene = Win(screen) - elif status == COMMAND_LOSE: - scene = Lose(screen) + status = scene.update(delta) + scene.draw(screen) + pygame.display.update() - pygame.display.update() - delta = clock.tick(60) / 1000 + if status == COMMAND_EXIT: + is_running = False + elif status == COMMAND_RESTART: + scene = Game() + elif status == COMMAND_WIN: + scene = Win(screen) + elif status == COMMAND_LOSE: + scene = Lose(screen) if __name__ == "__main__": - main() + main() diff --git a/menus.py b/menus.py index 67a8aec..8aa28cf 100644 --- a/menus.py +++ b/menus.py @@ -2,45 +2,45 @@ from setup import * class Menu: - title = pygame.font.SysFont("Arial", 30) - subtitle = pygame.font.SysFont("Arial", 20) - padding = 10 - - def __init__(self, screen, title, subtitle, text_color=RED): - self.bg = screen.copy() - self.titleText = self.title.render(title, True, text_color) - self.subtitleText = self.subtitle.render(subtitle, True, text_color) - - def update(self, delta): - for event in pygame.event.get(): - if event.type == pygame.QUIT: - return COMMAND_EXIT - elif event.type == pygame.KEYDOWN: - if event.key == pygame.K_r: - return COMMAND_RESTART - return COMMAND_NONE - - def draw(self, screen): - screen.blit(self.bg, (0, 0)) - titleRect = self.titleText.get_rect(center=(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)) - subtitleRect = self.subtitleText.get_rect(center=(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 + 50)) - boxRect = pygame.Rect(min(titleRect.x, subtitleRect.x) - self.padding, - min(titleRect.y, subtitleRect.y) - self.padding, - max(titleRect.width, subtitleRect.width) + self.padding * 2, - titleRect.height / 2 + subtitleRect.height / 2 + abs( - titleRect.y - subtitleRect.y) + self.padding * 2) - pygame.draw.rect(screen, BLACK, boxRect) - pygame.draw.rect(screen, GRAY, boxRect, 4) - screen.blit(self.titleText, titleRect) - screen.blit(self.subtitleText, subtitleRect) + title = pygame.font.SysFont("Arial", 30) + subtitle = pygame.font.SysFont("Arial", 20) + padding = 10 + + def __init__(self, screen, title, subtitle, text_color=RED): + self.bg = screen.copy() + self.titleText = self.title.render(title, True, text_color) + self.subtitleText = self.subtitle.render(subtitle, True, text_color) + + def update(self, delta): + for event in pygame.event.get(): + if event.type == pygame.QUIT: + return COMMAND_EXIT + elif event.type == pygame.KEYDOWN: + if event.key == pygame.K_r: + return COMMAND_RESTART + return COMMAND_NONE + + def draw(self, screen): + screen.blit(self.bg, (0, 0)) + titleRect = self.titleText.get_rect(center=(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)) + subtitleRect = self.subtitleText.get_rect(center=(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 + 50)) + boxRect = pygame.Rect(min(titleRect.x, subtitleRect.x) - self.padding, + min(titleRect.y, subtitleRect.y) - self.padding, + max(titleRect.width, subtitleRect.width) + self.padding * 2, + titleRect.height / 2 + subtitleRect.height / 2 + abs( + titleRect.y - subtitleRect.y) + self.padding * 2) + pygame.draw.rect(screen, BLACK, boxRect) + pygame.draw.rect(screen, GRAY, boxRect, 4) + screen.blit(self.titleText, titleRect) + screen.blit(self.subtitleText, subtitleRect) class Lose(Menu): - def __init__(self, screen): - super().__init__(screen, "You Lose!", "Press R to restart") + def __init__(self, screen): + super().__init__(screen, "You Lose!", "Press R to restart") class Win(Menu): - def __init__(self, screen): - super().__init__(screen, "You Win!", "Press R to play again", GREEN) + def __init__(self, screen): + super().__init__(screen, "You Win!", "Press R to play again", GREEN) diff --git a/setup.py b/setup.py index 694ac4b..b3cfcce 100644 --- a/setup.py +++ b/setup.py @@ -1,10 +1,10 @@ import pygame pygame.init() -SCREEN_WIDTH = 800 -SCREEN_HEIGHT = 600 +SCREEN_WIDTH, SCREEN_HEIGHT = pygame.display.Info().current_h - 60, pygame.display.Info().current_h - 60 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("Minesweeper") +pygame.display.set_icon(pygame.image.load("assets/bomb.png")) clock = pygame.time.Clock() RED = (255, 0, 0) @@ -13,7 +13,8 @@ BLUE = (0, 0, 255) BLACK = (0, 0, 0) WHITE = (255, 255, 255) GRAY = (128, 128, 128) - +BACKGROUND = (51, 28, 23) +BORDER = (187, 127, 87) COMMAND_EXIT = 0 COMMAND_RESTART = 1