Python3でRPGを作る時に使えそうな技術の断片 -辞書で村を作ろう-

f:id:sakage24:20170712005838j:plain

今からお教えするやり方は別に村の作成に限りません。アイテムとか、装備とかの管理にも応用が効く方法です。一般的にクラスよりもリスト、リストよりも辞書タプルの方が速いし、管理しやすいし、メモリの節約にも繋がります。

※今までのように、最初から順番ソースコードを貼り付けて行く方式は辞めることにしました。今後は概念というか、コツを教える感じで行こうと思います。あの方式は手直しが多発してやる気が無くなるのです。

ソースコード

githubで管理しています。

github.com

前提知識

Pythonには関連する要素を一塊にする為の便利な機能が4つあります。

  1. リスト
  2. タプル
  3. 辞書
  4. 集合

それぞれメリットやデメリットを考察していきましょう。

リストの特徴

  • ミュータブル(後から変更可能)
  • 要素内の順序は保証されている
  • 同じ値を保存出来る

Pythonには、ミュータブル(後から変更可能)とイミュータブル(後から変更不可能)という概念があります。

  • リスト、辞書、集合 = ミュータブル
  • タプル = イミュータブル

実際、プログラミングをしているとタプルよりもリストや辞書を使うことの方が多いかと思います。タプルは作成以後も変更される余地の無い、定数を保存するような時に利用します。

>>> x = [1, 2, 3, 4, 5]
>>> x.append(1) # 後から追加可能(ミュータブル)
>>> x
[1, 2, 3, 4, 5, 1] # 同じ値を保存できる、順序が保証されている。

メリット

  • ミュータブルなので修正が簡単
  • 順番が保証されている
  • 内包表記が使える
  • メソッドが豊富

デメリット

  • メモリ消費量が多い
  • 複雑なデータ構造を保存するのは大変
  • 柔軟性が高い分、処理速度は低速
  • リスト内の検索は線形探索のため、最大でリスト要素分の時間が掛かる

タプルの特徴

  • イミュータブル
  • 順番が保証されている
  • 同じ値を保存できる

前述の通り、タプルは変更不可能のため主に定数リストとして使います。内包表記はありません。

>>> (x for x in range(10))
<generator object <genexpr> at 0x000001F60D2B6990>
>>>

()で内包表記にしてみてもエラーが出ないので勘違いしやすいですが、出力されるのはジェネレータです。


>>> gen = (x for x in range(10))
>>> for i in gen:
...     if i == 5:
i
...             break
...     i
...
0
1
2
3
4
>>> for i in gen:
...     i
...
6
7
8
9

メリット

  • メモリ消費量が少ない
  • 高速である

デメリット

  • 途中で変更が出来ない

辞書の特徴

辞書はキー(key)とバリュー(value)によって構成されています。他の言語だと連想配列とか、ハッシュって呼ばれています。


villages = {
"ほげ村": {
"座標": (8, 8),
"画像": 'img/hoge.jpg',
"村人": "やあ!!",
},
"モゲ村":{
"座標": (1, 1),
"画像": 'img/moge.jpg',
"村人": "もげ~!!",
},
"ぷよ村": {
"座標": (3, 4),
"画像": 'img/puyo.jpg',
"村人": "puyo!!",
}
}
print(dic["ぷよ村"]["座標"])
#####実行結果#####
(3, 4)

メリット

  • キーとバリューによって、一意のデータ集合を簡単に作成、取得出来る。
  • 検索は一発なので、高速。
  • 内包表記が出来る

デメリット

  • 順番は保証されない

集合の特徴

集合は、辞書の値を捨ててキーだけになった存在です。キーは一意でなければなりません。さらに集合に格納するためには、ハッシュ化が可能でなければなりません。

>>> lists = [1, 2, 3, 4, 4, 4, 5]
>>> set(lists)
{1, 2, 3, 4, 5}

メリット

  • 検索が高速
  • 重複を排除出来る
  • 内包表記が可能

デメリット

  • 順番は保証されない
  • 重複を保持出来ない

何故辞書なのか?

村には色々な情報が必要です。例えばワールドマップ上での位置(座標)、村の画像、村人のセリフなどなどです。ほげ村というキー(key)に対応する様々な値(value)を自在に検索、取得出来る必要があるのです。

辞書なら、for文で回すのも簡単です。


villages = {
"ほげ村": {
"座標": (8, 8),
"画像": 'img/hoge.jpg',
"村人": "やあ!!",
},
"モゲ村":{
"座標": (1, 1),
"画像": 'img/moge.jpg',
"村人": "もげ~!!",
},
"ぷよ村": {
"座標": (3, 4),
"画像": 'img/puyo.jpg',
"村人": "puyo!!",
}
}
for key, value in village.items():
print(f"{key}:{value}")
ほげ村:{'座標': (8, 8), '画像': 'img/hoge.jpg', '村人': 'やあ!!'}
モゲ村:{'座標': (1, 1), '画像': 'img/moge.jpg', '村人': 'もげ~!!'}
ぷよ村:{'座標': (3, 4), '画像': 'img/puyo.jpg', '村人': 'puyo!!'}

終わり

というわけで、村の作成には辞書を使いましょう!!前置き長い割に説明一瞬で終わっちゃってワロタww

オススメの教科書類

指定教科書
入門 Python 3

入門 Python 3

これ無しでPython開発は無理です。私的にはあまり演習問題の類は説かずに知りたいことがあったら読む、辞書的な感じで使っています。

  • スライスって何?
  • リスト内包表記って何なんだよあれ?
  • リストとタプルはどう違うの?
  • そもそも集合って何に使うの?

少しでも上記に当てはまるなら購入しましょう。せっかくPythonを使っているんですから、有効に使えるようにしてみませんか?

副読本
Effective Python ―Pythonプログラムを改良する59項目

Effective Python ―Pythonプログラムを改良する59項目

  • 他言語を得意としているプログラマがPythonを書いた時にやりがちなこと…
  • ゲームの保存に使えるpickle
  • この機能はこう使うべきである
  • while, for文のelseを使うべきではない理由
  • Pythonでセッター, ゲッターを使うべきではない理由

みたいに、様々な事例とともにPythonのベストノウハウ、やってはいけないアンチパターンが紹介されています。pycon2016でも確か推されてましたw

初心者から上級者まで、手元に置いておくべき本です。

副読本2
退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング

退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング

ノンプログラマー向けとありますが、経験者の方も結構アイディアを貰える本でした。
序盤は文法の解説ですので、読み飛ばせます。後半は様々な局面で使えそうな自動化処理の書き方が載っていました。

ゲームの所持アイテムを辞書で表現しよう…みたいにゲームプログラマーに役立つ演習もありましたw

副読本3
ゲーム開発者のためのAI入門

ゲーム開発者のためのAI入門

  • 作者: David M. Bourg,Glenn Seemann,株式会社クイープ
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2005/01/12
  • メディア: 大型本
  • 購入: 24人 クリック: 395回
  • この商品を含むブログ (77件) を見る

C言語での解説が主ですが、しっかりとした説明があるので、だいたい分かりました。Pythonでも使える知識がほとんどです。ただ、ファジー理論など、数学的な要素は私にはどうともしがたい躓きポイントでしたw

ローグライクゲームに使える最短経路探索法やAIの作成法、確率の基本まで教えてもらえる良本でした!!

コメントを残す

メールアドレスが公開されることはありません。