デカ文字Python

デカ文字&短文でPythonを簡潔にまとめたブログ

Python SoloLearn Object-Oriented Programming④

f:id:pokita:20180421094155p:plain 

 

オブジェクト指向の最終章!
オブジェクト指向のゲームを作ってみよう!
という内容なんだけど、ゲームの内容が各節にわかれてて全体像が見にくく、SoloLearn のアプリではinput関数をうまく使えないため(謎)
Try it yourselfができないようになってます。

 

クソ教材が代…

 

そのためここではゲームで使われている各コードの解説です。

 

A Simple Game

 全体像

#②GameObjectクラスについて
class
GameObject:
class_name = ""
desc = ""
objects = {}

def __init__(self, name):
self.name = name
GameObject.objects[self.class_name] = self

def get_desc(self):
return self.class_name + "\n" + self.desc


class Goblin(GameObject):
def __init__(self, name):
self.class_name = "goblin"
self.health = 3
self.desc = "A foul creature"
super().__init__(name)

@property
def desc(self):
if self.health >= 3:
return self.desc
elif self.health == 2:
health_line = "It has a wound on its knee."
elif self.health == 1:
health_line = "Its left arm has been cut off!"
elif self.health <= 0:
health_line = "It is dead."
return self._desc + "\n" + health_line

@desc.setter
def desc(self, value):
self._desc = value


def hit(noun):
if noun in GameObject.objects:
thing = GameObject.objects[noun]
if type(thing) == Goblin:
thing.health = thing.health - 1
if thing.health <= 0:
msg = "You killed the goblin"
else:
msg = "You hit the {0}".format(thing.class_name)
else:
msg = "There is no {0}".format(noun)
return msg


goblin = Goblin("Gobbly")


def examine(noun):
if noun in GameObject.objects:
return GameObject.objects[noun].get_desc()
else:
return "There is no {0} here".format(noun)

#①get_input関数について
def get_input():
command = input(":").split()
verb_word = command[0]
if verb_word in verb_dict:
verb = verb_dict[verb_word]
else:
print("Unknown verb you {0}".format(verb_word))
return False

if len(command) >= 2:
noun_word = command[1]
print(verb(noun_word))
else:
print(verb("nothing"))


def say(noun):
return "You said {0}".format(noun)


def do(noun):
return "You did {0}".format(noun)


verb_dict = {"say": say, "do": do, "examine": examine, "hit":hit}

while True:
get_input()

①get_input関数について

command = input(": ").split()
print(command)
>>>: say hi!
['say', 'hi!']

input関数で入力されたstringは.split()メソッドにより、空白ごと分割されリストとして変数commandに戻される。

変数verb_wordにはcommand[0]、変数noun_wordにはcommand[1]が代入される。これで変数commandの役目終わり。
(このコード内ではcommand[2>=]の記述がないため。)

if verb_word in verb_dict:
verb = verb_dict[verb_word]
else:
print("Unknown verb you {0}".format(verb_word))
return False

verb_wordに代入されたstringがdict型変数verb_dictのキーに存在していないか調べられる。もし存在していた場合は、変数verbにverb_wordに対応した変数(ここでは関数say)が代入される。

   if len(command) >= 2:
noun_word = command[1]
print(verb(noun_word))
else:
print(verb("nothing"))

もしcommandが2つ以上要素を持ったリストなら、その2つ目の要素はnoun_wordとして扱われる。

このnoun_wordは、上で値が代入されたverb関数に引数として渡される。

while True:
get_input()

でget_input関数がエラーを吐き出すまでget_input関数を実行する。

②GameObjectクラスについて

class GameObject:
class_name = ""
desc = ""
objects = {}

def __init__(self, name):
self.name = name
GameObject.objects[self.class_name] = self

def get_desc(self):
return self.class_name + "\n" + self.desc

GameObjectのインスタンスが作られると、__init__(self)(コンストラクタ)が呼ばれて、GameObjectクラスの属性であるdict型objectsにclass_nameにインスタンス名が値としてclass_nameキーとして渡される。

class Goblin(GameObject):
def __init__(self, name):
self.class_name = "goblin"
self.health = 3
self.desc = "A foul creature"
super().__init__(name)

Goblinのインスタントが作られると、コンストラクタが呼ばれ、属性class_name  に"goblin"が代入される。

また、super().__init__(name)により、GameObjectのコンストラクタが呼ばれる。super().__init__(name)により継承元のコンストラクタを呼ぶのは、継承先のGoblinのコンストラクタによって、継承元のコンストラクタが上書き(オーバーライド)されてしまうからである。

goblin = Goblin("Gobbly")

によってGoblinクラスのインスタンスgoblinが作成されると、

①goblinインスタンスの属性.class_nameに"goblin"が代入される。

②呼び出された継承元のGameObjectクラスのコンストラクタによりクラス属性のGameObject.objectsが更新される。

③goblinインスタンスのメソッドget_descがセットされる。

def examine(noun):
if noun in GameObject.objects:
return GameObject.objects[noun].get_desc()
else:
return "There is no {0} here".format(noun)

examine関数は①get_input関数についてにおけるverbである。
examine関数の引数nounがもしGameObject.objectsのキーに存在するなら、そのキーに対応した値(インスタンス)のget_descメソッドが実行される。

 

今回はここまで。