読者です 読者をやめる 読者になる 読者になる

人工知能に関する断創録

人工知能、認知科学、心理学、ロボティクス、生物学などに興味を持っています。このブログでは人工知能のさまざまな分野について調査したことをまとめています。最近は、機械学習・Deep Learningに関する記事が多いです。



マップのロード

Pygame

今までマップはスクリプト内に書いて固定されていましたが、ファイルからさまざまなマップを読み込めるように変更してみます。

スクリプトを全文掲載すると長くなるので、ここからは主要部分のみ掲載することにします。スクリプトファイルはダウンロードしてください。

pyrpg08.zip
f:id:aidiary:20100606110149p:plain

マップファイルの構造

15 20
11111111111111111111
10000000000000000001
10000000000000000001
10000000000000000001
10000000000000000001
10000000000000000001
10000000011000000001
10000000011000000001
10000000000000000001
10000000000000000001
10000000000000000001
10000000000000000001
10000000000000000001
10000000000000000001
11111111111111111111

上のようなマップファイル(test.map)を用意します。0は

f:id:aidiary:20100605233457p:plain

で1は

f:id:aidiary:20100605233458p:plain

です。今までのマップと違って真ん中に湖を作りました。今回からマップのサイズもいろいろ変えられるようにファイルで指定します。1行目がマップのサイズで行数と列数です。

マップファイルの読み込み

マップファイルを読み込んでいるのはMapクラスです。

class Map:
    images = [None] * 256  # マップチップ(番号->イメージ)
    def __init__(self, name):
        self.name = name
        self.row = -1  # 行数
        self.col = -1  # 列数
        self.map = []  # マップデータ(2次元リスト)
        self.load()
    def load(self):
        """ファイルからマップをロード"""
        file = os.path.join("data", self.name + ".map")
        # テキスト形式のマップを読み込む
        fp = open(file)
        lines = fp.readlines()  # ファイル全体を行単位で読み込む
        row_str, col_str = lines[0].split()  # 行数と列数
        self.row, self.col = int(row_str), int(col_str)  # int型に変換
        for line in lines[1:]:  # マップデータを読み込む
            line = line.rstrip()  # 改行除去
            self.map.append([int(x) for x in list(line)])
        fp.close()

前回までとは違って、rowとcolとmapがインスタンス変数になったことに注意してください。またマップのコンストラクタでマップ名nameを引数として渡しています。マップのロードはload()関数で行い、row、col、mapにマップファイルから読み込んだデータをセットしています。マップファイルの名前はコンストラクタで渡したマップ名に拡張子(.map)を加えた.map になります。

Pythonでファイルを読み込むのは非常に簡単です。open()でファイルを開いて、readlines()で行単位で読み込んでリスト linesに格納します。マップデータは1行ずつ読み込み、int型に変換したうえで、self.mapに追加しています。今までと同じように self.mapは二次元リストのマップデータが格納されます。Pythonでファイルを扱うのが初めての人は上のサンプルスクリプトの途中にprint 文を挿入して各変数に何が格納されるか調べてみると理解しやすいと思います。

マップを作るのはmain()関数です。

    # マップの作成
    map = Map("test")

上のように書くとtest.mapからデータを読み込んだMapオブジェクトが作られます。他のファイルから読み込みたければtestの部分を変えます。

これでファイルからマップを読み込めるようになりましたが、大きいマップになるとマップファイルを自分で書くのは非常に面倒です。あとでマップエディタを作ってマップファイルを簡単に作れるようにしてみます。