PYXEL GUIDE / PUZZLE
Pythonでパズルゲームを作る
パズルゲームは、Pythonでゲーム作りを学ぶのにぴったりのジャンルです。このページでは、パズルの基本の形を小さなサンプルで確かめてから、このサイトのパズル講座32本を難易度別に紹介します。
- 講座の数
- パズルジャンル 32講座(各5ステップ・遊べる完成版つき)
- この記事のサンプル
- マス目の反転パズル(約70行・追加ファイルなし)
- 確認したバージョン
- Pyxel 2.9.9

パズルゲームの基本の形
アクションゲームは、キャラクターが毎フレーム少しずつ動きます。パズルゲームは、キーを押したときだけ状態が1段階進むのが特長です。速さやタイミングより「ルール」が中心なので、1手ずつ結果を確かめながら作れます。Pythonでゲーム作りを学ぶのに、ぴったりのジャンルです。
多くのパズルゲームは、次の5つの部品でできています。
盤面(状態)を持つ
どのマスに何があるかを、リストや辞書で覚えます。
入力を「1手」に変える
キーを押した瞬間(
pyxel.btnp)だけを、1手として受け付けます。その手が打てるかを調べる
壁や盤の外なら、何も変えません。
盤面を変えて、クリアを調べる
変えたあとで、クリアの条件を満たしているかを確かめます。
1手前に戻せるようにする(Undo)
盤面を変える前に、今の盤面を保存しておきます。
小さな反転パズルを作る
5×5のマスのうち、明るいマスをすべて消せばクリアのパズルです。カーソルのあるマスで Space キーを押すと、そのマスと上下左右のマスが反転(明るい ⇔ 暗い)します。矢印キーでカーソルを動かし、Z キーで1手戻し、R キーで最初からやり直せます。
import pyxel
SIZE = 5
CELL = 16
LEFT = 40
TOP = 20
START_MOVES = [(1, 1), (3, 1), (2, 2), (1, 3), (3, 3)]
class App:
def __init__(self):
pyxel.init(160, 120, title="Flip Puzzle")
self.reset()
pyxel.run(self.update, self.draw)
def reset(self):
self.board = [[False] * SIZE for _ in range(SIZE)]
for x, y in START_MOVES:
self.flip(x, y)
self.cx = 2
self.cy = 2
self.moves = 0
self.history = []
def flip(self, x, y):
for dx, dy in [(0, 0), (1, 0), (-1, 0), (0, 1), (0, -1)]:
nx = x + dx
ny = y + dy
if 0 <= nx < SIZE and 0 <= ny < SIZE:
self.board[ny][nx] = not self.board[ny][nx]
def is_clear(self):
return not any(any(row) for row in self.board)
def update(self):
if pyxel.btnp(pyxel.KEY_R):
self.reset()
return
if self.is_clear():
return
if pyxel.btnp(pyxel.KEY_LEFT):
self.cx = max(0, self.cx - 1)
if pyxel.btnp(pyxel.KEY_RIGHT):
self.cx = min(SIZE - 1, self.cx + 1)
if pyxel.btnp(pyxel.KEY_UP):
self.cy = max(0, self.cy - 1)
if pyxel.btnp(pyxel.KEY_DOWN):
self.cy = min(SIZE - 1, self.cy + 1)
if pyxel.btnp(pyxel.KEY_SPACE):
self.history.append([row[:] for row in self.board])
self.flip(self.cx, self.cy)
self.moves += 1
if pyxel.btnp(pyxel.KEY_Z) and self.history:
self.board = self.history.pop()
self.moves -= 1
def draw(self):
pyxel.cls(1)
for y in range(SIZE):
for x in range(SIZE):
color = 10 if self.board[y][x] else 5
pyxel.rect(LEFT + x * CELL + 1, TOP + y * CELL + 1, CELL - 2, CELL - 2, color)
pyxel.rectb(LEFT + self.cx * CELL, TOP + self.cy * CELL, CELL, CELL, 8)
pyxel.text(4, 6, f"MOVES:{self.moves}", 7)
pyxel.text(4, 108, "ARROWS+SPACE Z:UNDO R:RESET", 6)
if self.is_clear():
pyxel.text(64, 6, "CLEAR!", 10)
App().venv\Scripts\python.exe flip_puzzle.py.venv/bin/python flip_puzzle.py| コードの部分 | 役割 |
|---|---|
self.board | 盤面です。True が明るいマスで、self.board[y][x] のように「行・列」の順で読みます。 |
flip() | 1手の中身です。盤の外(0〜4の範囲の外)になるマスは、調べてとばします。 |
is_clear() | すべてのマスが False なら、クリアです。 |
self.history | Undo のための、過去の盤面です。Space を押す前の盤面をコピーして積み、Z で取り出します。 |
reset() | すべて消えた盤面から、START_MOVES の5か所を反転して問題を作ります。 |
# 5×5の盤面を作る(最初はすべて False = 消えた状態)
self.board = [[False] * SIZE for _ in range(SIZE)]
# y行目・x列目のマスを読む
self.board[y][x]最初の盤面を「すべて消えた状態から、何手か反転して作る」のがポイントです。同じマスを2回押すと元に戻るので、同じ5か所を押せば、必ずクリアできます。ランダムに明るいマスを置くと、解けない問題ができてしまうことがあります。
self.history.append(self.board) と書くと、今の盤面と同じリストを保存するだけです。あとで盤面を変えると、保存したはずの過去まで変わってしまいます。行ごとにコピーしてから保存しましょう。
# × 今の盤面と同じリストを指すだけ
self.history.append(self.board)
# ○ 行ごとにコピーしてから保存する
self.history.append([row[:] for row in self.board])リストのコピーについては、共通入門のPythonの状態を読むで、短い例を動かして確かめられます。
START_MOVES に (0, 0) を1つ足すと、問題が変わります。どこを押せば解けるか、予想してから遊んでみましょう。ヒント:同じマスを2回押すと、元に戻ります。
パズルを作るときの5つのコツ
このサイトのパズル講座で、くり返し出てくる考え方です。自分のパズルを作るときにも、そのまま使えます。
マス目の位置とピクセルを分ける
盤面はマスの番号(何列目・何行目)で持ち、描くときだけピクセルに変えます。マスの大きさを変えても、ルールは変わりません。(→ 画面とマップの座標、逆向き倉庫)
動けた1手だけを数える
壁に当たって動けなかった手は、手数も時間も進めません。プレイヤーが「1手むだにした」と感じずにすみます。(→ 後から来る壁)
まとめて動かすときは、先に全部調べる
2つ以上の物が同時に動くときは、全部が動けるかを確かめてから、一度に動かします。1つずつ動かすと、順番で結果が変わってしまいます。(→ 逆向き倉庫)
Undo は「戻したい値」をまとめて保存する
位置だけでなく、手数や持ち物など、戻したい値をひとまとめにして保存します。(→ 一歩貸してください、Pythonの状態を読む)
次に起きることを見せる
「次はこうなる」という予告を表示すると、プレイヤーが考えやすくなります。予告と実際の処理に同じ関数を使うと、2つがずれません。(→ まばたき劇場)
パズル講座32本(難易度別)
このサイトには、パズルジャンルの講座が32本あります。どの講座にも、ブラウザーで遊べる完成版、それだけで動く5段階のPythonファイル、元の完成版のソースが付いています。難易度は、コードの量や考え方の難しさから決めた目安です。
入門(2本)
コードの量が少なく、最初の1本に選びやすい講座です。
初級(15本)
マス目の移動・1手の確定・Undo など、パズルの基本がそろっています。
中級(15本)
同時に変化する仕組みや、推理・最適化の考え方まで広がります。
どれから始める?
迷ったら、作りたいパズルに近いものから選びましょう。
| 作りたいもの | おすすめの講座 |
|---|---|
| はじめてのマス目パズル | 一歩貸してください(1手前の命令を覚えて、Undo まで作る) |
| 箱を押して動かすパズル | 逆向き倉庫(2つの箱がどちらも動けるときだけ動かす) |
| 手がかりから答えを絞りこむパズル | 音のないピアノ、伝言は三文字 |
| たくさんのマスが同時に変わるパズル | ひと箱の天気、消防水路 |
| 配置や組み合わせを考えるパズル | ちいさな錬金冷蔵庫(入門の目安) |
Pyxelで作るのがはじめての方は、先にはじめる準備で最初の画面を出しておきましょう。講座の流れは学習順と教材の選び方にまとめています。
この記事で確認したこと
講座の一覧(タイトル・遊び方・難易度・学ぶこと)は、このサイトのトップページの講座データから、ジャンルが「パズル」の32講座を取り出して作っています。
flip_puzzle.py は、Pyxelの代わりに入力と描画命令を記録する模擬モジュールで動かし、最初の盤面がクリア状態でないこと、START_MOVES と同じ5か所を押すとクリアになること、Z で1手前の盤面に戻ること、クリア後は手が増えないこと、R で最初の盤面に戻ること、描く四角と文字が画面に収まることを確かめています。実際のPyxelのウィンドウでの表示確認は、この記事の作成時には行っていません。
Pyxelの使い方ガイド
ほかのガイドも、講座の前後にあわせて読めます。