ひるあんどんブログ

色々なことに手を出してみるブログ

Xs and Os Referee

Xs and Osとしても知られているTic-Tac-Toe(訳注:三目並べ)は二人のプレイヤー(XとO)が3x3のマスの空きマスに交代で書き込むゲームです。 水平、垂直、対角線の列(NW-SEとNE-SW)に自分のマークを3つ並べるのに成功したプレイヤーがゲームに勝ちます。

しかし我々はこのゲームをプレイしません。 あなたはこのゲームの結果の審判になってください。 ゲームの結果を与えられて、ゲームが勝利または引き分けで終わったのかと同時に誰が勝利者だったかを判定しなければいけません。 Xのプレイヤーが勝ったときは"X"を返し、Oのプレイヤーが勝ったときは"O"を返し、ゲームが引き分けのときは"D"を返すことを確実にしてください。

x-o-referee

ゲームの結果は文字列のリストとして表現されます、ここで"X"と"O"はプレイヤーのマークで"."は空きのマスです。

入力: あるゲームの結果、文字列のリスト (unicode)

出力: "X", "O" または "D"、文字列

例:

checkio([

"X.O",

"XX.",

"XOO"]) == "X"

checkio([

"OO.",

"XOX",

"XOX"]) == "O"

checkio([

"OOX",

"XXO",

"OXX"]) == "D"

どのように使われるか: このタスクのコンセプトは、データ型を繰り返すときにあなたの役に立つでしょう。 結果をチェックする方法を知ることをあなたに可能にすることで、ゲームのアルゴリズムにも使うことができます。

def checkio(game_result):
    for row in game_result:
        if row[0] == row[1] == row[2] and row[0] != ".":
            return row[0]
        
    if game_result[0][0] == game_result[1][0] == game_result[2][0] and game_result[0][0] != ".":
        return game_result[0][0]
    
    if game_result[0][1] == game_result[1][1] == game_result[2][1] and game_result[0][1] != ".":
        return game_result[0][1]
    
    if game_result[0][2] == game_result[1][2] == game_result[2][2] and game_result[0][2] != ".":
        return game_result[0][2]
        
    if game_result[0][0] == game_result[1][1] == game_result[2][2] and game_result[0][0] != ".":
        return game_result[0][0]
    
    if game_result[0][2] == game_result[1][1] == game_result[2][0] and game_result[0][2] != ".":
        return game_result[0][2]
    
    return "D"

if __name__ == '__main__':
    #These "asserts" using only for self-checking and not necessary for auto-testing
    assert checkio([
        "X.O",
        "XX.",
        "XOO"]) == "X", "Xs wins"
    assert checkio([
        "OO.",
        "XOX",
        "XOX"]) == "O", "Os wins"
    assert checkio([
        "OOX",
        "XXO",
        "OXX"]) == "D", "Draw"
    assert checkio([
        "O.X",
        "XX.",
        "XOO"]) == "X", "Xs wins again"
||< 

動きます。動くけど、あまりにも無駄が多すぎる。読んだら何してるか一瞬でわかるという意味では良いコードなのかもしれないけどね…。

さて、一位のコード

>|python|


def checkio(result):

    rows = result

    cols = map(''.join, zip(*rows))

    diags = map(''.join, zip(*[(r[i], r[2 - i]) for i, r in enumerate(rows)]))

    lines = rows + list(cols) + list(diags)

<200b>

    return 'X' if ('XXX' in lines) else 'O' if ('OOO' in lines) else 'D'

mapはシーケンスのすべての要素を関数の引数として実行し、その実行結果から新しいlistを作成する。

zipとenumerateは
forループで便利な zip, enumerate関数 » Python Snippets
ということらしい。

二重になっているリストを扱うときに便利な関数らしい。