Reversi Game - Python Code
This is the Python code for a Reversi game.
import tkinter as tk
from tkinter import messagebox
class ReversiGame:
def __init__(self, master):
self.master = master
self.master.title("Reversi Game")
# Board setup (8x8 grid)
self.board = [] # List to hold button objects (buttons represent the board squares)
self.current_player = 'red' # red starts the game
self.game_over = False # Flag to check if the game is over
# Create and place labels for displaying the red and blue piece counts
self.red_count_label = tk.Label(self.master, text="Red: 2")
self.red_count_label.grid(row=0, column=0)
self.blue_count_label = tk.Label(self.master, text="Blue: 2")
self.blue_count_label.grid(row=0, column=1)
# Create the game board (8x8)
self.create_board()
# Setup initial pieces in the center of the board
self.setup_initial_pieces()
def create_board(self):
"""
You need to:
- Create a 8x8 grid of buttons for the board.
- Use loops to create buttons and store them in `self.board` (a 2D list).
- Bind the `on_click` function for each button to handle piece placement.
Variables to use:
- `row` and `col` to track positions in the board.
- `button` to represent each individual square.
- `self.board` stores buttons and pieces in a 2D list.
"""
for row in range(8):
row_buttons = []
for col in range(8):
button = tk.Button(self.master, width=6, height=3, command=lambda r=row, c=col: self.on_click(r, c))
button.grid(row=row+1, column=col)
button.piece = None # Initially, no piece on the square
row_buttons.append(button)
self.board.append(row_buttons)
def setup_initial_pieces(self):
"""
You need to:
- Set up the initial pieces in the center of the board.
- Place two red and two blue pieces in the middle (row 3, col 3, 4, 3, etc.).
Variables to use:
- `self.board[row][col].piece` to set the initial pieces.
"""
self.board[3][3].piece = 'red'
self.board[3][4].piece = 'blue'
self.board[4][3].piece = 'blue'
self.board[4][4].piece = 'red'
def on_click(self, row, col):
"""
You need to:
- Check if the game is over or if the square is already occupied.
- Verify if the move is valid, place the current player's piece, and flip the opponent's pieces.
- Update the counts and check if the game is over.
- Switch to the next player.
Variables to use:
- `row`, `col` are the clicked square's coordinates.
- `self.board[row][col]` is the button for that square.
- `self.current_player` stores the current player ('red' or 'blue').
- `self.game_over` is a flag that tracks if the game is over.
"""
if self.game_over:
return
if self.board[row][col].piece is not None:
return
if not self.is_valid_move(row, col, self.current_player):
return
# Place the piece for the current player
self.board[row][col].piece = self.current_player
self.flip_pieces(row, col, self.current_player)
# Update the piece counts
self.update_counts()
# Check if the game is over
self.check_game_over()
# Switch to the next player
self.switch_player()
def is_valid_move(self, row, col, player):
"""
You need to:
- Check if the clicked square is empty.
- Check all 8 directions from the clicked square for valid flips.
- A valid move should sandwich opponent's pieces between the player's piece.
Variables to use:
- `row`, `col` are the coordinates of the square the player clicked.
- `player` is the current player's color ('red' or 'blue').
Logic:
- If a piece can be flipped, it's a valid move.
- Return `True` if valid, otherwise `False`.
"""
pass # Implement the move validation logic here
def flip_pieces(self, row, col, player):
"""
You need to:
- Flip the opponent's pieces after a valid move.
- For each direction, check if there are opponent's pieces to flip.
Variables to use:
- `row`, `col` are the coordinates of the clicked square.
- `player` is the current player's color.
Logic:
- If opponent's pieces are sandwiched, flip them to the current player's color.
"""
pass # Implement the flipping of pieces logic here
def switch_player(self):
"""
You need to:
- Switch the turn to the other player.
Variables to use:
- `self.current_player` stores the current player's turn.
Logic:
- If it's 'red's turn, switch to 'blue'.
- If it's 'blue's turn, switch to 'red'.
"""
pass # Implement the logic to switch the player here
def update_counts(self):
"""
You need to:
- Count the number of red and blue pieces on the board.
- Update the labels for displaying the counts.
Variables to use:
- `self.red_count_label` and `self.blue_count_label` to display counts.
Logic:
- Count the number of 'red' and 'blue' pieces and update the labels.
"""
pass # Implement the logic to update the piece counts here
def check_game_over(self):
"""
You need to:
- Check if the game is over and announce the result.
Variables to use:
- `self.game_over` to track if the game is over.
Logic:
- If no more valid moves for either player, end the game.
- Declare the winner based on the count of pieces.
- If there is a tie, announce a draw.
"""
pass # Implement the logic to check if the game is over here
# Main loop to run the game
if __name__ == "__main__":
root = tk.Tk()
game = ReversiGame(root)
root.mainloop()
Solution
import tkinter as tk
from tkinter import messagebox
class ReversiGame:
def __init__(self, master):
self.master = master
self.master.title("Reversi Game")
self.board = []
self.current_player = 'red' # red starts the game
self.game_over = False
# Create the labels for displaying the piece counts
self.red_count_label = tk.Label(self.master, text="Red: 2")
self.red_count_label.grid(row=0, column=0)
self.blue_count_label = tk.Label(self.master, text="Blue: 2")
self.blue_count_label.grid(row=0, column=1)
self.create_board()
self.setup_initial_pieces()
def create_board(self):
"""Creates the game board GUI."""
for row in range(8):
row_list = []
for col in range(8):
button = tk.Button(self.master, width=6, height=3, command=lambda r=row, c=col: self.on_click(r, c))
button.grid(row=row+1, column=col)
button.piece = None # Set the initial piece to None
row_list.append(button)
self.board.append(row_list)
def setup_initial_pieces(self):
"""Sets up the initial pieces in the center."""
self.board[3][3].config(bg='blue')
self.board[3][3].piece = 'blue'
self.board[3][4].config(bg='red')
self.board[3][4].piece = 'red'
self.board[4][3].config(bg='red')
self.board[4][3].piece = 'red'
self.board[4][4].config(bg='blue')
self.board[4][4].piece = 'blue'
self.update_counts()
def on_click(self, row, col):
"""Handles the logic when a button (board square) is clicked."""
if self.game_over:
return # If the game is over, do nothing
button = self.board[row][col]
if button.piece is not None: # If the square is already occupied
return
if not self.is_valid_move(row, col, self.current_player): # If the move is not valid
return
# Place the piece
button.piece = self.current_player
button.config(bg=self.current_player)
# Flip the opponent's pieces
self.flip_pieces(row, col, self.current_player)
# Update the counts
self.update_counts()
# Switch players
self.switch_player()
# Check if the game is over
self.check_game_over()
def is_valid_move(self, row, col, player):
"""Checks if the move made by the player is valid."""
if self.board[row][col].piece is not None:
return False
opponent = 'blue' if player == 'red' else 'red'
directions = [(-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (1, 1), (-1, 1), (1, -1)]
for dr, dc in directions:
r, c = row + dr, col + dc
flip_found = False
while 0 <= r < 8 and 0 <= c < 8:
if self.board[r][c].piece == opponent:
flip_found = True
elif self.board[r][c].piece == player:
if flip_found:
return True
else:
break
else:
break
r += dr
c += dc
return False
def flip_pieces(self, row, col, player):
"""Flips the opponent's pieces after a valid move."""
opponent = 'blue' if player == 'red' else 'red'
directions = [(-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (1, 1), (-1, 1), (1, -1)]
for dr, dc in directions:
r, c = row + dr, col + dc
flip_pieces = []
while 0 <= r < 8 and 0 <= c < 8:
if self.board[r][c].piece == opponent:
flip_pieces.append((r, c))
elif self.board[r][c].piece == player:
for fr, fc in flip_pieces:
self.board[fr][fc].piece = player
self.board[fr][fc].config(bg=player)
break
else:
break
r += dr
c += dc
def switch_player(self):
"""Switches the turn to the other player."""
self.current_player = 'blue' if self.current_player == 'red' else 'red'
def update_counts(self):
"""Updates the count of red and blue pieces on the board."""
red_count = 0
blue_count = 0
for row in self.board:
for button in row:
if button.piece == 'red':
red_count += 1
elif button.piece == 'blue':
blue_count += 1
self.red_count_label.config(text=f"Red: {red_count}")
self.blue_count_label.config(text=f"Blue: {blue_count}")
def check_game_over(self):
"""Checks if the game is over and announces the winner."""
red_count = 0
blue_count = 0
for row in self.board:
for button in row:
if button.piece == 'red':
red_count += 1
elif button.piece == 'blue':
blue_count += 1
# Check if any player has no valid moves
if red_count + blue_count == 64 or red_count == 0 or blue_count == 0:
self.game_over = True
if red_count > blue_count:
winner = "Red wins!"
elif blue_count > red_count:
winner = "Blue wins!"
else:
winner = "It's a draw!"
messagebox.showinfo("Game Over", winner)
# Main loop to run the game
if __name__ == "__main__":
root = tk.Tk()
game = ReversiGame(root)
root.mainloop()