Pythonの基礎を学んだら、その知識を組み合わせて実際に動くものを作ってみたくなりますよね。**三目並べ(Tic-Tac-Toe)**は、辞書、関数、ループといった基本的な要素をすべて活用するのに最適なプロジェクトです。
この記事では、シンプルな三目並べゲームを、勝利判定や入力チェックなどの機能もすべて含んだ完成版として、ステップバイステップで作成する方法を解説します。
1. 準備:ゲームボードと表示関数
まず、ゲームの土台となる部分を作成します。
## ゲームボードのデータ構造
三目並べの3×3の盤面をプログラムで表現するには、各マスに名前を付けて管理できる辞書が便利です。キーをマスの位置(例:「A1」)、値をそのマスの状態(「X」、「O」、または空の ' '
)とします。
# ゲームボードを表す辞書を初期化
game_board = {
'A1': ' ', 'A2': ' ', 'A3': ' ',
'B1': ' ', 'B2': ' ', 'B3': ' ',
'C1': ' ', 'C2': ' ', 'C3': ' '
}
## ボードを表示する関数
次に、現在のゲームボードの状態を、人間が見やすい形(格子状)で表示する関数を作成します。
def display_board(board):
print(f"\n {board['A1']} | {board['A2']} | {board['A3']} ")
print("---+---+---")
print(f" {board['B1']} | {board['B2']} | {board['B3']} ")
print("---+---+---")
print(f" {board['C1']} | {board['C2']} | {board['C3']} \n")
この関数を定義しておくことで、ゲームの進行中、好きなタイミングで盤面を綺麗に表示できます。
2. 中核機能:勝利を判定する関数
ゲームとして成立させるために最も重要なのが、どちらかのプレイヤーが勝利したかを判定する機能です。三目並べの勝利パターンは、縦・横・斜めのいずれかで同じマークが3つ揃う計8パターンです。
この判定を行うための関数 check_winner()
を作成します。
def check_winner(board, player):
# 横のラインをチェック
if board['A1'] == board['A2'] == board['A3'] == player or \
board['B1'] == board['B2'] == board['B3'] == player or \
board['C1'] == board['C2'] == board['C3'] == player:
return True
# 縦のラインをチェック
if board['A1'] == board['B1'] == board['C1'] == player or \
board['A2'] == board['B2'] == board['C2'] == player or \
board['A3'] == board['B3'] == board['C3'] == player:
return True
# 斜めのラインをチェック
if board['A1'] == board['B2'] == board['C3'] == player or \
board['A3'] == board['B2'] == board['C1'] == player:
return True
return False
この関数は、引数としてボードの状態(board
)とプレイヤーのマーク(player
)を受け取り、そのプレイヤーが勝利していればTrue
を返します。
3. ゲームの心臓部:メインループの実装
いよいよ、ゲームの本体となるメインループを作成します。ここでは、勝敗が決まるか、盤面が埋まるまでゲームが続くようにwhile
ループを使い、以下の処理を実装します。
- 入力チェック:プレイヤーが既に使用済みのマスや、存在しないマスを入力した場合にエラーメッセージを表示し、再度入力を促します。
- 勝利判定:毎ターン、現在のプレイヤーが勝利したかどうかを
check_winner()
関数で確認します。 - 引き分け判定:9手すべて打ち終わっても勝者がいない場合、引き分けとします。
4. 完成したコード全体
それでは、これまでに作成した部品をすべて組み合わせて、三目並べゲームを完成させましょう。以下のコードをコピーして実行すれば、すぐに遊ぶことができます。
# --- データと関数の定義 ---
# 1. ゲームボードのデータ構造
game_board = {
'A1': ' ', 'A2': ' ', 'A3': ' ',
'B1': ' ', 'B2': ' ', 'B3': ' ',
'C1': ' ', 'C2': ' ', 'C3': ' '
}
# 2. ボードを表示する関数
def display_board(board):
print(f"\n {board['A1']} | {board['A2']} | {board['A3']} ")
print("---+---+---")
print(f" {board['B1']} | {board['B2']} | {board['B3']} ")
print("---+---+---")
print(f" {board['C1']} | {board['C2']} | {board['C3']} \n")
# 3. 勝利を判定する関数
def check_winner(board, player):
# 横のライン
if board['A1'] == board['A2'] == board['A3'] == player or \
board['B1'] == board['B2'] == board['B3'] == player or \
board['C1'] == board['C2'] == board['C3'] == player:
return True
# 縦のライン
if board['A1'] == board['B1'] == board['C1'] == player or \
board['A2'] == board['B2'] == board['C2'] == player or \
board['A3'] == board['B3'] == board['C3'] == player:
return True
# 斜めのライン
if board['A1'] == board['B2'] == board['C3'] == player or \
board['A3'] == board['B2'] == board['C1'] == player:
return True
return False
# --- ゲームのメイン処理 ---
current_player = 'X'
turn_count = 0
print("三目並べゲームを開始します!")
while True:
display_board(game_board)
# プレイヤーに入力を促す
print(f"プレイヤー '{current_player}' の番です。どこに打ちますか? (例: A1, B2など)")
move = input()
# --- 入力チェック ---
if move in game_board and game_board[move] == ' ':
game_board[move] = current_player
turn_count += 1
else:
print("無効な手です。空いているマスを正しく入力してください。")
continue # ループの最初に戻って再入力させる
# --- 勝利判定 ---
if check_winner(game_board, current_player):
display_board(game_board)
print(f"おめでとうございます!プレイヤー '{current_player}' の勝利です!")
break # ゲーム終了
# --- 引き分け判定 ---
if turn_count == 9:
display_board(game_board)
print("引き分けです。")
break # ゲーム終了
# --- プレイヤーの交代 ---
if current_player == 'X':
current_player = 'O'
else:
current_player = 'X'
これで、勝利・敗北・引き分けが正しく判定され、不正な入力も弾かれる、完全な三目並べゲームが完成しました。