Python Two-Player Tic-Tac-Toe Project - Solutions and Explanations
Tic-Tac-Toe Game:
Implement a two-player tic-tac-toe game.
From Wikipedia - Tic-tac-toe (American English), noughts and crosses (Commonwealth English), or Xs and Os (Canadian or Irish English) is a paper-and-pencil game for two players who take turns marking the spaces in a three-by-three grid with X or O. The player who succeeds in placing three of their marks in a horizontal, vertical, or diagonal row is the winner. It is a solved game, with a forced draw assuming best play from both players
Input values:
Players input their moves by specifying the row and column for placing their 'X' or 'O'.
Output value:
Current state of the tic-tac-toe board and feedback on the game state (e.g., win, draw).
Example:
Input values: Player 1, enter your move (row and column): 1, 1 Output value: Current state: | X | | | ------------- | | | | ------------- | | | | Input values: Player 2, enter your move (row and column): 2, 2 Output value: Current state: | X | | | ------------- | | 0 | | ------------- | | | | Input values: Player 1, enter your move (row and column): 1, 2 Output value: Current state: | X | X | | ------------- | | 0 | | ------------- | | | | Input values: Player 2, enter your move (row and column): 2, 1 Output value: Current state: X | X | | ------------- O | O | | ------------- | | | | Input values: Player 1, enter your move (row and column): 1, 3 Output value: Current state: | X | X | X | --------------- | 0 | 0 | | --------------- | | | | Output value: Player 1 wins!
Here are two different solutions for a two-player Tic-Tac-Toe game in Python. The game will allow two players to input their moves by specifying the row and column, and it will provide feedback on the game's current state and the outcome (win, draw, or continue).
Solution 1: Basic Approach Using Functions and Lists
Code:
# Solution 1: Basic Approach Using Functions and Lists
# Initialize the Tic-Tac-Toe board as a 3x3 matrix with empty strings
board = [[' ' for _ in range(3)] for _ in range(3)]
def print_board():
"""Print the current state of the Tic-Tac-Toe board."""
print("\nCurrent state:")
for row in range(3):
print("|".join(board[row]))
if row < 2:
print("-----")
def check_winner(player):
"""Check if the given player has won the game."""
# Check rows and columns
for i in range(3):
if all(board[i][j] == player for j in range(3)) or all(board[j][i] == player for j in range(3)):
return True
# Check diagonals
if all(board[i][i] == player for i in range(3)) or all(board[i][2 - i] == player for i in range(3)):
return True
return False
def check_draw():
"""Check if the game is a draw (i.e., all cells are filled with no winner)."""
return all(board[row][col] != ' ' for row in range(3) for col in range(3))
def make_move(player):
"""Prompt the current player to make a move and update the board."""
while True:
try:
move = input(f"Player {player}, enter your move (row and column): ")
row, col = map(int, move.split(","))
if board[row - 1][col - 1] == ' ':
board[row - 1][col - 1] = player
break
else:
print("This cell is already occupied. Please try again.")
except (ValueError, IndexError):
print("Invalid input. Please enter row and column as two numbers separated by a comma (e.g., 1, 2).")
def play_game():
"""Main function to handle the flow of the Tic-Tac-Toe game."""
current_player = 'X'
print("Welcome to Tic-Tac-Toe!")
while True:
print_board()
make_move(current_player)
# Check if the current player has won
if check_winner(current_player):
print_board()
print(f"Player {current_player} wins!")
break
# Check if the game is a draw
if check_draw():
print_board()
print("It's a draw!")
break
# Switch players
current_player = 'O' if current_player == 'X' else 'X'
# Start the Tic-Tac-Toe game
play_game()
Output:
Welcome to Tic-Tac-Toe! Current state: | | ----- | | ----- | | Player X, enter your move (row and column): 1,1 Current state: X| | ----- | | ----- | | Player O, enter your move (row and column): 1,3 Current state: X| |O ----- | | ----- | | Player X, enter your move (row and column): 3,1 Current state: X| |O ----- | | ----- X| | Player O, enter your move (row and column): 2,3 Current state: X| |O ----- | |O ----- X| | Player X, enter your move (row and column): 3,3 Current state: X| |O ----- | |O ----- X| |X Player O, enter your move (row and column): 2,1 Current state: X| |O ----- O| |O ----- X| |X Player X, enter your move (row and column): 3,2 Current state: X| |O ----- O| |O ----- X|X|X Player X wins!
Explanation:
Uses a 2D list board to represent the Tic-Tac-Toe grid.
- print_board() function displays the current state of the game board.
- check_winner() function checks if the current player has won by checking all rows, columns, and diagonals.
- check_draw() function checks if the game is a draw (i.e., all cells are filled).
- make_move() function handles user input for placing 'X' or 'O' and validates the input.
- play_game() function orchestrates the game flow, switching players and checking for win/draw conditions.
Solution 2: Using a Class-Based approach for Better Organization
Code:
# Solution 2: Using a Class-Based Approach for Better Organization
class TicTacToe:
"""Class to handle the Tic-Tac-Toe game."""
def __init__(self):
"""Initialize the Tic-Tac-Toe board and current player."""
self.board = [[' ' for _ in range(3)] for _ in range(3)]
self.current_player = 'X'
def print_board(self):
"""Print the current state of the Tic-Tac-Toe board."""
print("\nCurrent state:")
for row in range(3):
print("|".join(self.board[row]))
if row < 2:
print("-----")
def check_winner(self):
"""Check if the current player has won the game."""
# Check rows and columns
for i in range(3):
if all(self.board[i][j] == self.current_player for j in range(3)) or \
all(self.board[j][i] == self.current_player for j in range(3)):
return True
# Check diagonals
if all(self.board[i][i] == self.current_player for i in range(3)) or \
all(self.board[i][2 - i] == self.current_player for i in range(3)):
return True
return False
def check_draw(self):
"""Check if the game is a draw (i.e., all cells are filled with no winner)."""
return all(self.board[row][col] != ' ' for row in range(3) for col in range(3))
def make_move(self):
"""Prompt the current player to make a move and update the board."""
while True:
try:
move = input(f"Player {self.current_player}, enter your move (row and column): ")
row, col = map(int, move.split(","))
if self.board[row - 1][col - 1] == ' ':
self.board[row - 1][col - 1] = self.current_player
break
else:
print("This cell is already occupied. Please try again.")
except (ValueError, IndexError):
print("Invalid input. Please enter row and column as two numbers separated by a comma (e.g., 1, 2).")
def play(self):
"""Main function to handle the flow of the Tic-Tac-Toe game."""
print("Welcome to Tic-Tac-Toe!")
while True:
self.print_board()
self.make_move()
# Check if the current player has won
if self.check_winner():
self.print_board()
print(f"Player {self.current_player} wins!")
break
# Check if the game is a draw
if self.check_draw():
self.print_board()
print("It's a draw!")
break
# Switch players
self.current_player = 'O' if self.current_player == 'X' else 'X'
# Create an instance of the TicTacToe class and start the game
game = TicTacToe()
game.play()
Welcome to Tic-Tac-Toe! Current state: | | ----- | | ----- | | Player X, enter your move (row and column): 1,1 Current state: X| | ----- | | ----- | | Player O, enter your move (row and column): 2,2 Current state: X| | ----- |O| ----- | | Player X, enter your move (row and column): 2,1 Current state: X| | ----- X|O| ----- | | Player O, enter your move (row and column): 3,1 Current state: X| | ----- X|O| ----- O| | Player X, enter your move (row and column): 1,3 Current state: X| |X ----- X|O| ----- O| | Player O, enter your move (row and column): 3,3 Current state: X| |X ----- X|O| ----- O| |O Player X, enter your move (row and column): 3,2 Current state: X| |X ----- X|O| ----- O|X|O Player O, enter your move (row and column): 2,3 Current state: X| |X ----- X|O|O ----- O|X|O Player X, enter your move (row and column): 1,2 Current state: X|X|X ----- X|O|O ----- O|X|O Player X wins!
Explanation:
- Encapsulates the game logic within a ‘TicTacToe’ class, making the code more modular and organized.
- The ' __init__' method initializes the game board and sets the current player.
- The 'print_board()', 'check_winner()', 'check_draw()', and 'make_move()' methods handle various game functionalities, such as printing the board, checking for a winner or draw, and making moves.
- The 'play()' method manages the game loop, switches players, and checks for win/draw conditions.
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics