簡易 Numer0n

何気なくテレビを見ていたら、 Numer0n というものをやっていました。

相手が任意に設定した3桁の数字を言い当てるゲームです。

ゲーム中、もし相手が言った数字の中に、自分が設定した数字と位置があっている数字が n 個あったら {n}eat 、位置は違うが設定した数字に含まれている数字が m 個あったら {m}bite と開示しなければなりません。

例:

正答: 123
回答: 321 ⇒ 1eat, 2bite
回答: 425 ⇒ 1eat, 0bite

といった感じです。 この開示された情報と勘を手がかりに正答を導いていきます。

結構面白いなー、と思ったので、手抜きではありますがそれっぽいの書いて見ました。

#-*- coding: utf-8 -*-

import random


class Numeron(object):
    length = 3
    answer = None

    def start(self):
        self.set_answer(self.gen_answer())

        while True:
            challenge = self.get_challenge()
            eat, bite = self.decision(challenge)
            print '%d eat, %d bite' % (eat, bite)
            if eat is self.length:
                break

    def end(self):
        pass

    def decision(self, challenge):
        eat = bite = 0
        for i in range(0, self.length):
            if challenge[i] is self.answer[i]:
                eat += 1
                continue

            if challenge[i] in self.answer:
                bite += 1

        return eat, bite

    def get_challenge(self):
        challenge = raw_input().strip()
        if not self.valid_challenge(challenge):
            print 'This challenge was invalid'
            challenge = self.get_challenge()

        return challenge

    def valid_challenge(self, challenge):
        if not (challenge.isdigit() and len(challenge) is self.length):
            return False

        for i in range(0, self.length):
            if challenge.count(challenge[i]) > 1:
                return False

        return True

    def set_length(self, length):
        assert isinstance(length, int)
        self.length = length

    def set_answer(self, answer):
        assert isinstance(answer, str)
        assert len(answer) is self.length
        assert answer.isdigit()

        self.answer = answer

    def gen_answer(self):
        answer = ''
        while len(answer) < self.length:
            candidate = str(random.randrange(0, 10))
            if not candidate in answer:
                answer += candidate

        return answer


if __name__ == '__main__':
    numeron = Numeron()
    numeron.start()
    numeron.end()