三目並べ(Tick Tack Toe)の勝敗を出力

問題

Tick-Tack-Toe 〜 横へな 2012.7.6

文字列形式で入力された先攻後攻の手から勝敗(引き分け)を判断する。
不正な入力は考慮しないが、不正な手(すでに置かれている場所に置こうとする)は考慮する。

解答

def tick_tack_toe(record):
    record = map(lambda x: int(x)-1, record)
    board = [-1 for x in range(9)]
    seq = ["o", "x"]
    x = 0  #先攻後攻
    for index, t in enumerate(record):
        if 9 <= index:
            return "Draw game."
        if not board[t] == -1:
            x = 1 - x
            return "Foul : %s won." % seq[x] # 今の手順の反対の相手が勝った
        else:
            board[t] = x
        for i in range(3):
            horize = [x == s for s in board[i*3:(i*3)+3]]
            vertic = [x == s for s in [board[i], board[i+3], board[i+6]]]
            skew_l = [x == s for s in [board[0], board[4], board[8]]]
            skew_r = [x == s for s in [board[2], board[4], board[6]]]
            if all(horize) or all(vertic) or all(skew_l) or all(skew_r):
                return "%s won." % seq[x]
        x = 1 - x # 手順反転
    return "Draw game."

1時間強かかった。きつい。

テスト

import nose
from nose.tools import eq_
from tick_tack_toe import tick_tack_toe

def test_x_won():
    eq_(tick_tack_toe('79538246'), 'x won.')
    eq_(tick_tack_toe('35497162193'), 'x won.')
    eq_(tick_tack_toe('61978543'), 'x won.')
    eq_(tick_tack_toe('254961323121'), 'x won.')
    eq_(tick_tack_toe('6134278187'), 'x won.')

def test_foul_x_won():
    eq_(tick_tack_toe('4319581'), 'Foul : x won.')
    eq_(tick_tack_toe('9625663381'), 'Foul : x won.')
    eq_(tick_tack_toe('7975662'), 'Foul : x won.')
    eq_(tick_tack_toe('2368799597'), 'Foul : x won.')
    eq_(tick_tack_toe('18652368566'), 'Foul : x won.')

def test_o_won():
    eq_(tick_tack_toe('965715'), 'o won.')
    eq_(tick_tack_toe('38745796'), 'o won.')
    eq_(tick_tack_toe('371929'), 'o won.')
    eq_(tick_tack_toe('758698769'), 'o won.')
    eq_(tick_tack_toe('42683953'), 'o won.')

def test_foul_o_won():
    eq_(tick_tack_toe('618843927'), 'Foul : o won.')
    eq_(tick_tack_toe('36535224'), 'Foul : o won.')
    eq_(tick_tack_toe('882973'), 'Foul : o won.')
    eq_(tick_tack_toe('653675681'), 'Foul : o won.')
    eq_(tick_tack_toe('9729934662'), 'Foul : o won.')

def test_draw():
    eq_(tick_tack_toe('972651483927'), 'Draw game.')
    eq_(tick_tack_toe('5439126787'), 'Draw game.')
    eq_(tick_tack_toe('142583697'), 'Draw game.')
    eq_(tick_tack_toe('42198637563'), 'Draw game.')
    eq_(tick_tack_toe('657391482'), 'Draw game.')

if __name__ == "__main__":
    nose.main()