見出し画像

【スキルテスト】tic-tac-toe (○✖️ゲーム)をPythonで書いてみた

こんにちは。アメリカ・シリコンバレー在住のSeikaです。

アメリカでエンジニアとして働いている友人から、
tic-tac-toe(ティック・タック・トゥー)が就職のスキルテストとして出たと聞きました。
そこで、今回はtic-tac-toeをPythonで書いていきたいと思います。

(2024年5月7日公開)



1. tic-tac-toeとは?

Tic-Tac-Toeは、古くから親しまれている二人用のシンプルなボードゲームです。日本では「三目並べ」や「○✖️ゲーム」として知られています。

一人は「○」、もう一人は「✖️」を使用し、
3×3の9マスのボードに自分のマークを交互に配置。
3つ連続したら勝ち、というゲームです。

tic-tac-toeという名前の由来は諸説あるそうですが、
「Tic」, 「Tac」, 「Toe」 という音が、
それぞれ「カチカチ」、「トコトコ」、「ポン」といった擬音語(オノマトペ)であり、
ゲームのプレイ中にマス目に駒を置くリズミカルな音を表現からきていると言われています。

2. コード全体

こちらが今回Pythonで書いたコードです。

class Tictactoe:
    def __init__(self, user):
        self.user = user
        self.board = []

    def initialize_board(self):
        """3x3の空のボードを初期化します。"""
        self.board = [["-", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]]

    def show_board(self):
        """現在のボードの状態を表示します。"""
        for row in self.board:
            print(" ".join(row))

    def is_board_filled(self):
        """ボードが全て埋まっているかをチェックします。"""
        for row in self.board:
            if "-" in row:
                return False
        return True

    def check_winner(self):
        """3つが揃ったかをチェックし、勝者がいる場合はTrueを返します。"""
        # 行でチェック
        for row in self.board:
            if all(element == self.user for element in row):
                return True

        # 列でチェック
        for column_index in range(len(self.board)):
            if all(row[column_index] == self.user for row in self.board):
                return True

        # 対角線でチェック (左上から右下)
        if all(self.board[i][i] == self.user for i in range(len(self.board))):
            return True

        # 対角線でチェック (右上から左下)
        if all(self.board[i][len(self.board) - 1 - i] == self.user for i in range(len(self.board))):
            return True

        return False

    def place_piece(self, row, column):
        """指定した行と列に現在のプレイヤーの駒を配置します。"""
        if self.board[row][column] == "-":
            self.board[row][column] = self.user
        else:
            print("そのマスはすでに埋まっています。")

    def switch_players(self):
        """現在のプレイヤーを切り替えます。"""
        self.user = "o" if self.user == "x" else "x"

    def start_game(self):
        """ゲームを開始し、プレイを進行します。"""
        self.initialize_board()
        while not self.is_board_filled():
            print(f"It's {self.user}'s turn now.")
            self.show_board()

            try:
                row = int(input("Please type in the index of the row (0, 1, or 2): "))
                column = int(input("Please type in the index of the column (0, 1, or 2): "))
            except ValueError:
                print("無効な入力です。整数値を入力してください。")
                continue

            if 0 <= row <= 2 and 0 <= column <= 2:
                self.place_piece(row, column)
                if self.check_winner():
                    print(f"{self.user} won!")
                    break
                self.switch_players()
            else:
                print("無効なインデックスです。0から2の間で入力してください。")

            if self.is_board_filled():
                print("It's a tie!")
                break

        self.show_board()


if __name__ == '__main__':
    game = Tictactoe("x")
    game.start_game()

3. コードの説明

ここからは各メソッド(関数)を見ていきます。

3-1. class Tictactoe

class Tictactoe:
def init(self, user):
self.user = user
self.board = []
  • class Tictactoe: ○✖️ゲームの全体を制御するクラス。

  • __init__(self, user): クラスが作られたときに呼ばれる初期化メソッド。

    • self.user: 最初にプレイするプレイヤー("x" または "o")。

    • self.board: 3x3のゲームボードを保持するリスト。


3-2. cinitialize_board(self)

def initialize_board(self):
     """3x3の空のボードを初期化します。"""
     self.board = [["-", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]]
  • initialize_board(self): 3x3の空のボードを作成します。

  • self.board: 各マスが "-" で初期化された2次元リスト。


3-3. show_board(self)

    def show_board(self):
        """現在のボードの状態を表示します。"""
        for row in self.board:
            print(" ".join(row))
  • show_board(self): 現在のボードの状態を表示。

  • 各行をスペースで区切って1行ずつ表示。


3-4. is_board_filled(self)

    def is_board_filled(self):
        """ボードが全て埋まっているかをチェックします。"""
        for row in self.board:
            if "-" in row:
                return False
        return True
  • is_board_filled(self): ボードがすべて埋まっているかどうかを確認。

  • もし "-"(空のマス)があれば、False を返す。

  • すべて埋まっていれば True を返す。


3-5. check_winner(self)

def check_winner(self):
    """3つが揃ったかをチェックし、勝者がいる場合はTrueを返します。"""
    # 行でチェック
    for row in self.board:
        if all(element == self.user for element in row):
            return True

    # 列でチェック
    for column_index in range(len(self.board)):
        if all(row[column_index] == self.user for row in self.board):
            return True

    # 対角線でチェック (左上から右下)
    if all(self.board[i][i] == self.user for i in range(len(self.board))):
        return True

    # 対角線でチェック (右上から左下)
    if all(self.board[i][len(self.board) - 1 - i] == self.user for i in range(len(self.board))):
        return True

    return False
  • check_winner(self): プレイヤーが3つ揃ったかどうかを確認。

    • 行でチェック:

      • 各行を見て、すべて同じマークで埋まっている場合は勝者とする。

    • 列でチェック:

      • 各列を見て、すべて同じマークで埋まっている場合は勝者とする。

    • 対角線でチェック:

      • 左上から右下、または右上から左下の対角線が同じマークで埋まっている場合は勝者とする。

    • どれも揃っていなければ False を返す。


3-6. place_piece(self, row, column)

def place_piece(self, row, column):
    """指定した行と列に現在のプレイヤーの駒を配置します。"""
    if self.board[row][column] == "-":
        self.board[row][column] = self.user
    else:
        print("そのマスはすでに埋まっています。")
  • place_piece(self, row, column): 指定した行と列に現在のプレイヤーの駒を配置。

    • row: 駒を置く行のインデックス(0から2まで)。

    • column: 駒を置く列のインデックス(0から2まで)。

    • すでに駒が置かれている場合は警告メッセージを表示。


3-7. switch_players(self)

    def switch_players(self):
        """現在のプレイヤーを切り替えます。"""
        self.user = "o" if self.user == "x" else "x"
  • switch_players(self): 現在のプレイヤーを交互に切り替える。

  • "x" なら "o" に、 "o" なら "x" に変更。


3-8. start_game(self)

def start_game(self):
    """ゲームを開始し、プレイを進行します。"""
    self.initialize_board()
    while not self.is_board_filled():
        print(f"It's {self.user}'s turn now.")
        self.show_board()

        try:
            row = int(input("Please type in the index of the row (0, 1, or 2): "))
            column = int(input("Please type in the index of the column (0, 1, or 2): "))
        except ValueError:
            print("無効な入力です。整数値を入力してください。")
            continue

        if 0 <= row <= 2 and 0 <= column <= 2:
            self.place_piece(row, column)
            if self.check_winner():
                print(f"{self.user} won!")
                break
            self.switch_players()
        else:
            print("無効なインデックスです。0から2の間で入力してください。")

        if self.is_board_filled():
            print("It's a tie!")
            break

    self.show_board()
  • start_game(self): ゲームを開始し、進行させるメソッド。

    • ゲームの流れ:

      1. ボードを初期化。

      2. ボードが埋まるまで、次の操作を繰り返す。

        • 現在のプレイヤーのターンとボードを表示する。

        • 行と列のインデックスをプレイヤーから入力する。

        • 無効な入力や範囲外のインデックスをチェックする。

        • プレイヤーの駒をボードに配置する。

        • 勝者がいれば表示して終了する。

        • プレイヤーを切り替える。

        • ボードがすべて埋まった場合は引き分けを表示する。


3-9. if __name__ == '__main__'

if name == 'main':
game = Tictactoe("x")
game.start_game()
  • if __name__ == '__main__':: プログラムが直接実行されたときだけ動作する部分。

  • Tictactoe クラスのインスタンスを作成し、最初のプレイヤーを "x" に設定。

  • start_game メソッドを呼び出してゲームを開始。


4. 実行手順

  1. Pythonファイルとして保存: コードを tic_tac_toe.py という名前で保存します。

  2. Pythonで実行: ターミナルやコマンドプロンプトで以下のコマンドを使って実行します。

python3 tic_tac_toe.py

これでtic-tac-toeが楽しめます⭐️


今回はPythonでtic-tac-toeを書いてみました。
私の知人はアメリカでバリバリ働いているエンジニアで、
一瞬でこのコード書いてしまうような人なのですが、
tic-tac-toeというゲームが何かが分からず、
スキルテストがうまくいかなかったそうです。

外国で生活するには、スキルはもちろんのこと、文化理解・言語力も身につけていかないといけませんね。
日々学んでいこうと思う次第です💪
もし記事が役に立ったと思ったら、ぜひスキボタンを押してくださいね😊
それでは、次回の記事でお会いしましょう!

Follow me here😊

Image by Nisha Gill from Pixabay

この記事が参加している募集

#週末プロジェクト

4,716件

よろしければサポートお願いいたします。いただいたサポートはクリエイターとしての活動費に使わせていただきます。