0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【python】pygameでマインスイーパ風のゲームを作ってみた

Last updated at Posted at 2024-07-19

背景

pygameでスペースインベーダー作りたい。

PCスペック

項目 情報
OS macOS Sonoma 14.4.1
ハードウェア MacBook Pro 16inc 2023
プロセッサ Apple M2 pro
メモリ 32GB

ソースコード

py main.py
import pygame
import random
import sys

# Pygameの初期化
pygame.init()

# 定数の設定
WIDTH = 800
HEIGHT = 600
GRID_SIZE = 20
TILE_SIZE = 30
MINE_COUNT = 50

# 色の定義
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREY = (192, 192, 192)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

# フォントの設定
FONT = pygame.font.SysFont('comicsans', 20)

# スクリーンの設定
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Minesweeper')

# タイルクラスの定義
class Tile:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.is_mine = False
        self.is_revealed = False
        self.is_flagged = False
        self.adjacent_mines = 0

    def draw(self):
        if self.is_revealed:
            pygame.draw.rect(screen, GREY, (self.x * TILE_SIZE, self.y * TILE_SIZE, TILE_SIZE, TILE_SIZE))
            if self.is_mine:
                pygame.draw.circle(screen, BLACK, (self.x * TILE_SIZE + TILE_SIZE // 2, self.y * TILE_SIZE + TILE_SIZE // 2), TILE_SIZE // 4)
            elif self.adjacent_mines > 0:
                text = FONT.render(str(self.adjacent_mines), True, BLACK)
                screen.blit(text, (self.x * TILE_SIZE + TILE_SIZE // 2 - text.get_width() // 2, self.y * TILE_SIZE + TILE_SIZE // 2 - text.get_height() // 2))
        else:
            pygame.draw.rect(screen, WHITE, (self.x * TILE_SIZE, self.y * TILE_SIZE, TILE_SIZE, TILE_SIZE))
            if self.is_flagged:
                pygame.draw.circle(screen, RED, (self.x * TILE_SIZE + TILE_SIZE // 2, self.y * TILE_SIZE + TILE_SIZE // 2), TILE_SIZE // 4)
        pygame.draw.rect(screen, BLACK, (self.x * TILE_SIZE, self.y * TILE_SIZE, TILE_SIZE, TILE_SIZE), 1)

# ゲームボードの初期化
def init_board():
    board = [[Tile(x, y) for y in range(HEIGHT // TILE_SIZE)] for x in range(WIDTH // TILE_SIZE)]
    mines = random.sample([tile for row in board for tile in row], MINE_COUNT)
    for mine in mines:
        mine.is_mine = True
    for row in board:
        for tile in row:
            if not tile.is_mine:
                tile.adjacent_mines = sum(1 for nx in range(tile.x - 1, tile.x + 2) for ny in range(tile.y - 1, tile.y + 2) if 0 <= nx < WIDTH // TILE_SIZE and 0 <= ny < HEIGHT // TILE_SIZE and board[nx][ny].is_mine)
    return board

# ゲームオーバーの処理
def game_over(board):
    for row in board:
        for tile in row:
            tile.is_revealed = True
    draw_board(board)
    pygame.display.update()
    pygame.time.wait(2000)
    pygame.quit()
    sys.exit()

# ゲームクリアの確認
def check_win(board):
    for row in board:
        for tile in row:
            if not tile.is_mine and not tile.is_revealed:
                return False
    return True

# タイルを開く処理
def reveal_tile(board, x, y):
    tile = board[x][y]
    if tile.is_revealed or tile.is_flagged:
        return
    tile.is_revealed = True
    if tile.is_mine:
        game_over(board)
    elif tile.adjacent_mines == 0:
        for nx in range(x - 1, x + 2):
            for ny in range(y - 1, y + 2):
                if 0 <= nx < WIDTH // TILE_SIZE and 0 <= ny < HEIGHT // TILE_SIZE:
                    reveal_tile(board, nx, ny)

# ゲームボードの描画
def draw_board(board):
    for row in board:
        for tile in row:
            tile.draw()

# メイン関数
def main():
    board = init_board()
    run = True

    while run:
        screen.fill(GREEN)
        draw_board(board)
        pygame.display.flip()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            elif event.type == pygame.MOUSEBUTTONDOWN:
                x, y = pygame.mouse.get_pos()
                x //= TILE_SIZE
                y //= TILE_SIZE
                if event.button == 1:
                    reveal_tile(board, x, y)
                    if check_win(board):
                        print("You win!")
                        run = False
                elif event.button == 3:
                    tile = board[x][y]
                    tile.is_flagged = not tile.is_flagged

    pygame.quit()

if __name__ == "__main__":
    main()

画面

スクリーンショット 2024-07-19 12.00.54.png

まとめ

できた。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?