Mementoパターンで戦国シミュレーション

#Mementoパターンで戦国シミュレーション

某社内の勉強会で発表する資料づくりの一環でコードを書きました。
数学ガールの著者でもある結城浩さんの[増補改訂版 Java言語で学ぶデザインパターン入門](https://www.amazon.co.jp/gp/product/B00I8ATHGW/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i1)に基づき、
Pythonでプログラムを作成しました。


```python:nobunaga.py
import random
import time

class Nobunaga:
    Busho = ['みつひで', 'らんまる', 'ひでよし', 'かついえ']

    def __init__(self, strength, resource):
        self.strength = strength
        self.resource = resource
        self.busho = []    

    def get_strength(self):
        return self.strength
    
    def get_resource(self):
        return self.resource
    
    def get_busho(self):
        prefix = ''
        if bool(random.randint(0,1)):
            prefix = '強い'
        return prefix + random.choice(Nobunaga.Busho)

    def __str__(self):
        return '[兵力 = {}, 資源 = {}, 武将 = {}]'.format(self.strength, self.resource, self.busho)

    def battle(self):
        dice = random.randint(1, 6)
        if dice == 1:
            self.strength += 100
            print('兵士を鍛錬し兵力が100上がった！')
        elif dice == 2 and self.resource > 99:
            self.resource *= 1.5
            print('戦を行って勝ち、資源が1.5倍になった！')
        elif dice == 3 and self.resource > 99:
            self.strength -= 100
            self.resource //= 2
            print('戦を行って負け、資源が半分になった！')
            print('兵力が100下がった！')
        elif dice == 4:
            b = self.get_busho()
            print('武将の{}が仲間になった！'.format(b))
            self.busho.append(b)
        elif dice == 5:
            if len(self.busho) > 0:
                b = random.choice(self.busho)
                print('武将{}が裏切った！'.format(b))
                self.busho.remove(b)
            else:
                print('何も起こらなかった')
        elif dice == 6:
            self.resource += 100
            print('農地を手に入れ、資源を100手に入れた！')
        else:
            print('資源が不足して何もできなかった...')

    def create_memento(self):
        m = Memento(self.strength,self.resource)
        for b in self.busho:
            if b.startswith('強い'):
                m.add_busho(b)
        return m

    def restore_memento(self, memento):
        self.strength = memento.get_strength()
        self.busho = memento.get_busho()

class Memento:
    def __init__(self,strength,resource):
        self.strength = strength
        self.resource = 0
        self.busho = []

    def get_strength(self):
        return self.strength

    def add_busho(self, busho):
        self.busho.append(busho)

    def get_busho(self):
        return self.busho

def main():
#クラスNobunagaのインスタンスnobuを生成
    nobu = Nobunaga(100,100)
    memento = nobu.create_memento()
    for i in range(10):
        print(str(i+1)+'年目')
        print('ステータス:{}'.format(nobu))
#メソッド名はもう少し考えればよかった...。battle以外もするのになぁ。
        nobu.battle()
        print('兵力は{}に、資源は{}になった！'.format(nobu.get_strength(), nobu.get_resource()))

        if nobu.get_strength() > memento.get_strength():
            print('      (だいぶ強くなったから、現在の状態を巻物に記しておこう)')
            memento = nobu.create_memento()
        elif nobu.get_strength() < memento.get_strength() / 2:
            print('      (だいぶ弱くなったから、以前の状態まで時間を遡ろう)')
            nobu.restore_memento(memento)
        time.sleep(1)
        print()

if __name__ == '__main__':
    main()

```



```:実行結果
1年目
ステータス:[兵力 = 100, 資源 = 100, 武将 = []]
兵士を鍛錬し兵力が100上がった！
兵力は200に、資源は100になった！
      (だいぶ強くなったから、現在の状態を巻物に記しておこう)

2年目
ステータス:[兵力 = 200, 資源 = 100, 武将 = []]
何も起こらなかった
兵力は200に、資源は100になった！

3年目
ステータス:[兵力 = 200, 資源 = 100, 武将 = []]
何も起こらなかった
兵力は200に、資源は100になった！

4年目
ステータス:[兵力 = 200, 資源 = 100, 武将 = []]
戦を行って勝ち、資源が1.5倍になった！
兵力は200に、資源は150.0になった！

5年目
ステータス:[兵力 = 200, 資源 = 150.0, 武将 = []]
農地を手に入れ、資源を100手に入れた！
兵力は200に、資源は250.0になった！

6年目
ステータス:[兵力 = 200, 資源 = 250.0, 武将 = []]
武将の強いみつひでが仲間になった！
兵力は200に、資源は250.0になった！

7年目
ステータス:[兵力 = 200, 資源 = 250.0, 武将 = ['強いみつひで']]
戦を行って勝ち、資源が1.5倍になった！
兵力は200に、資源は375.0になった！

8年目
ステータス:[兵力 = 200, 資源 = 375.0, 武将 = ['強いみつひで']]
戦を行って勝ち、資源が1.5倍になった！
兵力は200に、資源は562.5になった！

9年目
ステータス:[兵力 = 200, 資源 = 562.5, 武将 = ['強いみつひで']]
戦を行って負け、資源が半分になった！
兵力が100下がった！
兵力は100に、資源は281.0になった！

10年目
ステータス:[兵力 = 100, 資源 = 281.0, 武将 = ['強いみつひで']]
戦を行って負け、資源が半分になった！
兵力が100下がった！
兵力は0に、資源は140.0になった！
      (だいぶ弱くなったから、以前の状態まで時間を遡ろう)
```

ところで、強いってどうやって決めるのでしょうか？資源が多くても強いですし、武将が多くいても強い気がします
Strategyパターンと組み合わせてnobuの戦略を考えるのも面白いかもしれません！

それではまた！