迷路ゲームを作ろう
今回は2次元リストを使った迷路ゲームを作ります。
迷路は8x8のマスを持ち、Sのマスからスタートして、Gのマスがゴールです。
白いマスが移動できるマスで、黒いマスが移動できないマスとなります。
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
0 | S | |||||||
1 | ||||||||
2 | ||||||||
3 | ||||||||
4 | ||||||||
5 | ||||||||
6 | ||||||||
7 | G |
ゲームの仕様は、以下のようになります。
仕様
- 2次元リストを使って迷路のイメージを定義する
- 配列の要素の種類は0、1、2として、0は通行不可、1は通行可能、2はゴールとする
- 移動キーは、wは上移動、sは下移動、aは左移動、dは右移動とする
- qキーでスクリプトを終了する
- ゴールに到達したらスクリプトを終了する
実行イメージ
実行イメージは、以下のようになります。
現在地は、2次元リストのインデックスで、[縦/横]という意味です。
qを入力するとゲームは終了します。
実行例
> python maze1.py
+++ 操作方法 [上:w][下:s][左:a][右:d][終了:q] +++
+++ 現在地 [0/0] +++
>>> s
+++ 現在地 [1/0] +++
>>> s
+++ 現在地 [2/0] +++
>>> d
:
:
+++ 現在地 [6/6] +++
>>> d
+++ 現在地 [6/7] +++
>>> s
+++ ゴール!! +++
Pythonスクリプト
ゲームのPythonスクリプトは、以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
### キー操作 UP, DOWN, LEFT, RIGHT = range(4) KEY_DIC = {"w":UP, "s":DOWN, "a":LEFT, "d":RIGHT} ### マップ ####### 0 1 2 3 4 5 6 7 ##### MAP = [[1,0,0,0,0,0,0,0], # 0 [1,0,0,1,1,1,1,0], # 1 [1,1,1,1,0,0,1,0], # 2 [0,0,0,0,1,1,1,0], # 3 [0,0,0,0,1,0,0,0], # 4 [0,0,0,0,1,1,1,0], # 5 [0,0,0,0,0,0,1,1], # 6 [0,0,0,0,0,0,0,2]] # 7 ### メッセージ MES_N_1 = "+++ 操作方法 [上:w][下:s][左:a][右:d][終了:q] +++" MES_N_2 = "+++ 現在地 [{:d}/{:d}] +++" MES_N_3 = "+++ ゴール!! +++" MES_E_1 = "+++ キーが違います +++" MES_E_2 = "+++ 移動できません +++" ### 迷路クラス class Maze: ### 初期化メソッド def __init__(self, now_h, now_w): ### 現在地 self.now_h = now_h self.now_w = now_w ### 現在地表示 def draw(self): print(MES_N_2.format(self.now_h, self.now_w)) ### 移動 def move(self, u_input): ### 次位置 next_h = self.now_h next_w = self.now_w ### 上移動 if u_input == UP: next_h -= 1 if (next_h < 0) or (MAP[next_h][next_w] == 0): print(MES_E_2) else: self.now_h -= 1 ### 下移動 elif u_input == DOWN: next_h += 1 if (next_h > len(MAP)-1) or (MAP[next_h][next_w] == 0): print(MES_E_2) else: self.now_h += 1 ### 左移動 elif u_input == LEFT: next_w -= 1 if (next_w < 0) or (MAP[next_h][next_w] == 0) : print(MES_E_2) else: self.now_w -= 1 ### 右移動 elif u_input == RIGHT: next_w += 1 if (next_w > len(MAP[next_h])-1) or (MAP[next_h][next_w] == 0): print(MES_E_2) else: self.now_w += 1 ### ゴール確認 if MAP[self.now_h][self.now_w] == 2: print(MES_N_3) return True ### ゴールするまでFalseを返す return False #################### ### メイン処理 #################### ### スタート地点 now_h = 0 now_w = 0 ### 迷路クラス生成 maze = Maze(now_h, now_w) ### 操作方法表示 print(MES_N_1) ### メインループ while True: ### 位置表示 maze.draw() ### 行動入力 input_key = input(">>> ") ### 終了 if input_key == "q": break ### 入力確認 for x in list(KEY_DIC.keys()): if input_key == x: break else: print(MES_E_1) continue ### 移動 rc = maze.move(KEY_DIC[input_key]) if rc == True: ### 終了 break |
スクリプト解説
2行目
UP、DOWN、LEFT、RIGHTに、それぞれ0、1、2、3の値を定義します。
3行目
キー辞書を定義します。
wがUP、sがDOWN、aがLEFT、dがRIGHTになります。
7~14行目
マップの2次元リストを定義します。
0が移動不可、1が移動可能、2がゴールとなります。
17~21行目
各種メッセージを定義します。
24~83行目
迷路クラスを定義します。
34、35行目
現在地表示メソッドを定義します。
[縦/横]でマップリストのインデックスを表しています。
38~83行目
移動メソッドを定義します。
w、s、a、dキーの操作でマスを移動します。
入力したキーに対応するマスに移動できるかどうか判断します。
リストのインデックスがマイナス、インデックスの最大値以上、マスの値が0だった場合は、移動ができない旨のメッセージを表示します。
移動したマスの値が2だった場合は、ゴールとなりゲームは終了します。
90、91行目
スタート地点を定義します。
ここでは、マップリストの[0][0]をスタート地点にしています。
94行目
迷路クラスを生成します。
100~125行目
while文を使ってループ処理に入ります。条件にTrueを使っているので、無限ループとなります。
ゴールに到達するか、qを入力するとループが終了します。
103行目
迷路の現在地(インデックス)を表示します。
106行目
input()関数を使って、迷路の中を移動します。
109、110行目
qが入力された場合は、break文によりループを抜けてスクリプトが終了します。
113~118行目
入力したキーの値がキー辞書にあるかどうかを判定します。
定義されていないキーが入力された場合は、ループの先頭に戻ります。
121~125行目
移動メソッドを呼び出します。
戻り値がTrueの場合は、break文によりwhileループを抜けて、スクリプトが終了します。