0
2

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でマインスイーパーを作ってみよう!

Posted at

はじめに

今回は、Pythonのゲームライブラリ「Pygame」を使って、マインスイーパーを作成する方法を紹介します。マインスイーパーはシンプルながらも頭を使うゲームで、プログラミング初心者でも楽しみながら学べる題材です。この記事では、ゲームの基本的な実装から、クリアやゲームオーバーの処理までを丁寧に解説します。

必要なライブラリのインストール

まずは、Pygameをインストールしましょう。以下のコマンドを実行してください。

pip install pygame

マインスイーパーの基本設計

マインスイーパーは、プレイヤーがセルをクリックしていき、地雷を避けながらすべての安全なセルを開けることを目指すゲームです。地雷の数やセルの配置はランダムに決定されます。

ゲームの構成要素

  1. グリッド: セルが並ぶ2D配列。
  2. 地雷: ランダムに配置された危険なセル。
  3. 数字: 周囲に存在する地雷の数を表示するセル。
  4. 勝敗判定: 地雷をすべて避けて安全なセルを開けたら勝利、地雷をクリックしたらゲームオーバー。

実装コード

以下は、Pygameを使ったマインスイーパーの実装例です。

import pygame
import random
import sys

# 定数の設定
WIDTH, HEIGHT = 400, 400
GRID_SIZE = 9
CELL_SIZE = WIDTH // GRID_SIZE
MINE_COUNT = 10

# 色の設定
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (192, 192, 192)
DARK_GRAY = (160, 160, 160)
RED = (255, 0, 0)
BLUE = (0, 0, 255)

# Pygameの初期化
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Minesweeper")
font = pygame.font.Font(None, 36)

# グリッドを初期化
grid = [[0 for _ in range(GRID_SIZE)] for _ in range(GRID_SIZE)]
revealed = [[False for _ in range(GRID_SIZE)] for _ in range(GRID_SIZE)]

# 地雷を配置
mines = set()
while len(mines) < MINE_COUNT:
    x = random.randint(0, GRID_SIZE - 1)
    y = random.randint(0, GRID_SIZE - 1)
    if (x, y) not in mines:
        mines.add((x, y))
        grid[x][y] = -1

# 数値を更新
for x in range(GRID_SIZE):
    for y in range(GRID_SIZE):
        if grid[x][y] == -1:
            continue
        count = 0
        for i in range(max(0, x - 1), min(GRID_SIZE, x + 2)):
            for j in range(max(0, y - 1), min(GRID_SIZE, y + 2)):
                if grid[i][j] == -1:
                    count += 1
        grid[x][y] = count

def draw_grid():
    for x in range(GRID_SIZE):
        for y in range(GRID_SIZE):
            rect = pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
            color = DARK_GRAY if revealed[x][y] else WHITE
            pygame.draw.rect(screen, color, rect)
            pygame.draw.rect(screen, BLACK, rect, 1)

            if revealed[x][y]:
                if grid[x][y] == -1:
                    pygame.draw.circle(screen, RED, rect.center, CELL_SIZE // 4)
                elif grid[x][y] > 0:
                    text = font.render(str(grid[x][y]), True, BLUE)
                    screen.blit(text, text.get_rect(center=rect.center))

def reveal_cell(x, y):
    if revealed[x][y]:
        return
    revealed[x][y] = True
    if grid[x][y] == 0:
        for i in range(max(0, x - 1), min(GRID_SIZE, x + 2)):
            for j in range(max(0, y - 1), min(GRID_SIZE, y + 2)):
                if not revealed[i][j]:
                    reveal_cell(i, j)

def check_win():
    for x in range(GRID_SIZE):
        for y in range(GRID_SIZE):
            if grid[x][y] != -1 and not revealed[x][y]:
                return False
    return True

def display_message(message):
    text = font.render(message, True, BLACK)
    screen.blit(text, text.get_rect(center=(WIDTH // 2, HEIGHT // 2)))
    pygame.display.flip()
    pygame.time.wait(2000)  # 2秒間メッセージを表示
    pygame.quit()
    sys.exit()

# メインループ
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:  # 左クリック
                mx, my = event.pos
                x, y = mx // CELL_SIZE, my // CELL_SIZE
                if grid[x][y] == -1:
                    draw_grid()
                    pygame.display.flip()
                    display_message("Game Over")  # ゲームオーバー
                else:
                    reveal_cell(x, y)
                    if check_win():
                        draw_grid()
                        pygame.display.flip()
                        display_message("You Win!")  # ゲームクリア

    screen.fill(GRAY)
    draw_grid()
    pygame.display.flip()

pygame.quit()
sys.exit()

追加機能の説明

  • 選択済みセルの視覚化: プレイヤーが選択したセルは灰色で表示され、地雷が配置されていない安全なセルが明示的に区別されます。
  • 勝敗判定とメッセージ表示: ゲームオーバー時には「Game Over」、すべての安全なセルを開けた場合は「You Win!」と画面中央に表示されます。

実行方法

コードを実行すると、マインスイーパーが起動します。セルをクリックして地雷を避けながらゲームを進めましょう。ゲームオーバーやゲームクリアが達成されると、それぞれの結果に応じたメッセージが表示されます。

実行結果

スクリーンショット 2024-08-21 17.43.46.png

まとめ

この記事では、Pygameを使ったマインスイーパーの作成方法を紹介しました。ゲームの基本機能から視覚的なフィードバック、勝敗の判定まで、実際の開発に役立つ技術を学べたかと思います。Pygameを使った他のゲーム開発にも挑戦してみてください!

0
2
0

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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?