2017-05-19

tobijibu

おばけキャッチ2を買った

週末から旅行に行くのですが、旅行といえばアナログゲームです。 簡単なルールでとても盛り上がる「おばけキャッチ」を持っていこうと思ったのですが、 先日実家に行った際に置いてきてしまったので、急遽「おばけキャッチ2」を買いました。

おばけが女の子でかわいいです。

どんなゲームかざっくり説明すると、白いおばけ、赤いタオル、青いブラシ、緑のカエル、グレーのお風呂という5種類のコマがあります。 お題のカードに描かれた絵から、後述するルールに則って対象のコマを早く手にした人がカードを獲得できます。 お手つきや、間違えた物を取った場合はお手つきで手持ちのカードを正解したプレイヤーに渡します。 沢山カードを獲得したプレイヤーが勝ち。

イメージできたでしょうか。カードではなくコマを取るカルタのようなゲームです。

ルールの詳細が分からなければ面白さがイメージ出来ませんね。ここから詳細を書いていきます。

基本ルール

お題カードには2つのコマの絵が描かれています。 しかし、中にはカードに書かれたコマの色が、実際のコマの色と違うものもあります。 答えとなるコマを判断するには、以下のルールを適用します。どんなカードであっても必ず1つのコマが決まるような組み合わせで描かれています。

  • 描かれているモノの形と色が同じものがあれば、それを取ります。
  • 描かれているモノの形と色が同じものが無い場合、描かれているモノの形も色も違うものを取ります。
例えば...

- 白いおばけと、グレーのブラシが描かれている場合、「おばけ」を取ります。

- グレーのお風呂と、青いおばけが描かれている場合、「お風呂」を取ります。

- 赤いブラシと、緑のおばけが描かれている場合、「お風呂」を取ります。
赤(タオル)でもなく、緑(カエル)でもなく、ブラシ(青)でもなく、おばけ(白)でもないのは「お風呂」のみです。

- 緑のお風呂と、赤いおばけが描かれている場合 「ブラシ」を取ります。
緑(カエル)でもなく、赤(タオル)でもなく、お風呂(グレー)でもなく、おばけ(白)でもないのは「ブラシ」のみです。

と、ここまでが基本ルールです。


追加ルール

続いて無印にもある追加ルールです。

  • 「カエル」が描かれている場合は、答えのコマを取らずにコマの名前を言います。
例えば...

- 白いおばけと、グレーのカエルが描かれている場合、おばけと「言います」。

- 緑のカエルと、青いお風呂が描かれている場合、カエルと「言います」。

- 赤いお風呂と、青いのカエルが描かれている場合、おばけと「言います」。
赤(タオル)でもなく、青(ブラシ)でもなく、お風呂(グレー)でもなく、カエル(緑)でもないのは「おばけ」です。 そして、カエルが描かれているので、取らずに言います。

結構混乱してきますね。


もっと追加ルール

おばけキャッチ2の場合はさらに追加ルールがあります。

なんと、カエルは2カ国語を話します。カエルが描かれている場合のアクションが2つに分岐します。

  • 描かれているモノの形と色が同じものがあれば、答えを外国語で言います。
  • モノの形と色が同じものが無い場合、描かれているモノの形も色も違うものを母国語で言います。

※説明書には英語とドイツ語で記載されていますが、日本語と英語で良いと思います。

例えば...

- 白いおばけと、グレーのカエルが描かれている場合、「ゴースト」と言います。

- 緑のカエルと、青いお風呂が描かれている場合、「フロッグ」と言います。

- 赤いお風呂と、青いのカエルが描かれている場合、「おばけ」と言います。


もっともっと追加ルール

さらにさらにルールの追加です。

タオルを使ったのは誰? タオルが描かれている場合のアクションがあります。

  • 「タオル」が描かれている場合は「常に」タオルの色のコマが答えになります。
例えば...

- 白いおばけと、グレーのタオルが描かれている場合、「お風呂」を取ります。
白いおばけがありますが、グレーのタオルがあるので、おばけではなく、タオルと同じ色の「お風呂」が答えになります。

- 赤いカエルと、青いのタオルが描かれている場合、「くし」と「言います」。
青いのタオルがあるので、お風呂ではなく、タオルと同じ色の「ブラシ」が答えになり、カエルが居るので、コマを取らずに答えを言います。

- 青いカエルと、赤いタオルが描かれている場合、「フロッグ」と「言います」。
赤いタオルがあるので、「タオル」が答えになり、カエルが居ますので、答えを言うのですが、「赤いタオル」は外国語でいうので「フロッグ」になります。


以上の6種類のルールを瞬時に判断して、的確な行動を取るわけです。

  • 描かれているモノの形と色が同じものがあれば、それを取ります。
  • 描かれているモノの形と色が同じものが無い場合、描かれているモノの形も色も違うものを取ります。
  • 「カエル」が描かれている場合は、コマを取らずにコマの名前を言います。
  • 「カエル」が描かれている場合に、描かれているモノの形と色が同じものがあれば、答えを外国語で言います。
  • 「カエル」が描かれている場合に、モノの形と色が同じものが無い場合、描かれているモノの形も色も違うものを母国語で言います。
  • 「タオル」が描かれている場合は「常に」タオルの色のコマが答えになります。

見えているはずのものが見えなかったり、言葉が口から出てこなかったり、その混乱具合を楽しむゲームです。


さて、ここまで長々とルールの詳細を説明してきましたが、何がやりたかったかというと、 「このゲームの選択ロジックを書いてみました」ということです。練習のつもりでPythonを使っています。


# -*- coding: utf-8 -*-
class ObakeCatch2():
    obj   = ['おばけ', 'てぬぐい', 'くし',  'かえる', 'ふろ']
    color = ['white',  'red',      'blue',  'green',  'gray']
    objEn = ['ghost',  'towel',    'brash', 'frog',   'bath']

    def doAction(self, depict1, depict2):
        self.depict1 = depict1
        self.depict2 = depict2
        self.setAct()
        self.setTowel()
        act = self.getActText()
        res = self.result()
        print(res + act)

    def setAct(self):
        self.isGet = (self.depict1['obj'] != 'かえる' and self.depict2['obj'] != 'かえる')

    def setTowel(self):
        self.hasTowel = (self.depict1['obj'] == 'てぬぐい' or self.depict2['obj'] == 'てぬぐい')

    def getActText(self):
        return 'を取る' if self.isGet else 'って言う'

    def result(self):
        # モノリストをコピー
        _obj = ObakeCatch2.obj[:]
        # カードに描かれているモノ・色の要素番号
        obj1Idx = ObakeCatch2.obj.index(self.depict1['obj'])
        col1Idx = ObakeCatch2.color.index(self.depict1['color'])
        obj2Idx = ObakeCatch2.obj.index(self.depict2['obj'])
        col2Idx = ObakeCatch2.color.index(self.depict2['color'])
        # 要素番号リストを生成して重複削除、降順ソート
        depictsIdx = sorted(set([obj1Idx, col1Idx, obj2Idx, col2Idx]), reverse=True)

        # ありえないパターン
        # 同じモノ・色が描かれている
        # (白いおばけと青いおばけ とか、赤いおばけと赤いくしとか)
        if (obj1Idx == obj2Idx or col1Idx == col2Idx):
            return 'どれでもないなにか'
        # モノ・色が揃っているのが2つ描かれている
        # (白いおばけと青いくし とか)
        if (obj1Idx == col1Idx and obj2Idx == col2Idx):
            return 'どれでもないなにか'

        # てぬぐいがある
        if (self.hasTowel):
            if (self.depict1['obj'] == 'てぬぐい'):
                return ObakeCatch2.obj[col1Idx] if self.isGet else ObakeCatch2.objEn[col1Idx]
            if (self.depict2['obj'] == 'てぬぐい'):
                return ObakeCatch2.obj[col2Idx] if self.isGet else ObakeCatch2.objEn[col2Idx]

        # 描かれているものが正しい
        if (obj1Idx == col1Idx):
            # 言う場合は英語
            return self.depict1['obj'] if self.isGet else ObakeCatch2.objEn[obj1Idx]
        if (obj2Idx == col2Idx):
            # 言う場合は英語
            return self.depict2['obj'] if self.isGet else ObakeCatch2.objEn[obj2Idx]

        # ありえないパターン
        # 答えが特定できない
        # (青いおばけと白いくし とか)
        if (len(depictsIdx) != 4):
            return 'どれでもないなにか'

        # 色も形も違うものが正しい
        for i in depictsIdx:
            del _obj[i]
        return _obj[0]

oc = ObakeCatch2()

depict1 = {'obj': 'おばけ', 'color': 'red'}
depict2 = {'obj': 'かえる', 'color': 'blue'}
oc.doAction(depict1, depict2)

depict1 = {'obj': 'おばけ', 'color': 'gray'}
depict2 = {'obj': 'くし',   'color': 'red'}
oc.doAction(depict1, depict2)

depict1 = {'obj': 'てぬぐい', 'color': 'green'}
depict2 = {'obj': 'かえる', 'color': 'blue'}
oc.doAction(depict1, depict2)

書いていて思ったのですが、ロジックの組み立て方は人それぞれでありつつも、 一瞬で組み立てて判断する人間の脳は凄いなと思いました。

ソースはこちらにあります。おばけキャッチ(無印)もあります。

おばけキャッチ名人技のパターンは、ちょっと考えるのがキツそうなのでやめました。