This time I wanted to make a board game that is very popular in Brazil, it's called 'resta um', it means 'there's only one left'. The idea of the game is that there are holes in which there are pieces inside, the player has to pick pieces and 'jump' one another until there is only one left on the board. For a move to be allowed, the selected piece must be one tile away from where it will 'jump' and the hole in which it will go has to be empty. It's kind of hard to explain it since I believe this game doesn't exist outside Brazil.
Download it here: https://github.com/Tlomoloko/Resta-Um/tree/master
This is the main code, I tried to separate the game-logic from the Tkinter representation of the board and stuff.
import tkinter as tk
import Resta_Um_Logic as game_logic
root = tk.Tk()
WIDTH = 600
HEIGHT = 600
BUTTON_WIDTH = 72
BUTTON_HEIGHT = 72
PIECE_IMAGE = tk.PhotoImage(file='restaumpiece.png')
HOLE_IMAGE = tk.PhotoImage(file='restaumhole.png')
canvas = tk.Canvas(root, width= WIDTH, height= HEIGHT, bg='#c5d1ed')
canvas.pack()
frame = tk.Frame(canvas, bg= '#e5e8ec')
frame.place(relx= 0.5, rely= 0.05, relwidth= 0.9, relheight= 0.9, anchor= 'n')
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
board_parts = [*game_logic.board]
game_buttons = []
for board_part in board_parts:
if board_part.is_button:
screen_button = tk.Button(frame, width=BUTTON_WIDTH, height=BUTTON_HEIGHT, bg='white', command=lambda x= board_part: click_button(x))
screen_button.grid(row=board_part.row, column=board_part.column)
board_part.button = screen_button
game_buttons.append(board_part)
else:
empty_part = tk.Frame(frame, width= BUTTON_WIDTH, height= BUTTON_HEIGHT, bg='#e5e8ec')
empty_part.grid(row=board_part.row, column=board_part.column)
selected_button = None
def click_button(clicked_button):
global selected_button
if not any(button.is_selected for button in game_buttons):
clicked_button.is_selected = True
selected_button = clicked_button
selected_button.button.configure(relief= 'sunken')
else:
game_logic.check_moves(selected_button, clicked_button)
selected_button.button.configure(relief= 'raised')
for button in game_buttons:
button.is_selected = False
update_board()
def update_board():
global game_buttons
for button in game_buttons:
if button.has_piece:
button.button.configure(image= PIECE_IMAGE)
else:
button.button.configure(image= HOLE_IMAGE)
update_board()
root.mainloop()
Here I check if the 'selected' and 'targeted' pieces are valid.
class BoardPart():
def __init__(self, row, column, button, has_piece, is_selected, is_button):
self.row = row
self.column = column
self.button = button
self.has_piece = has_piece
self.is_selected = is_selected
self.is_button = is_button
board = [BoardPart(0, 0, None, None, None, False), BoardPart(0, 1, None, None, None, False), BoardPart(0, 2, None, True, False, True), BoardPart(0, 3, None, True, False, True), BoardPart(0, 4, None, True, False, True), BoardPart(0, 5, None, None, None, False), BoardPart(0, 6, None, None, None, False),
BoardPart(1, 0, None, None, None, False), BoardPart(1, 1, None, None, None, False), BoardPart(1, 2, None, True, False, True), BoardPart(1, 3, None, True, False, True), BoardPart(1, 4, None, True, False, True), BoardPart(1, 5, None, None, None, False), BoardPart(1, 6, None, None, None, False),
BoardPart(2, 0, None, True, False, True), BoardPart(2, 1, None, True, False, True), BoardPart(2, 2, None, True, False, True), BoardPart(2, 3, None, True, False, True), BoardPart(2, 4, None, True, False, True), BoardPart(2, 5, None, True, False, True), BoardPart(2, 6, None, True, False, True),
BoardPart(3, 0, None, True, False, True), BoardPart(3, 1, None, True, False, True), BoardPart(3, 2, None, True, False, True), BoardPart(3, 3, None, False, False, True), BoardPart(3, 4, None, True, False, True), BoardPart(3, 5, None, True, False, True), BoardPart(3, 6, None, True, False, True),
BoardPart(4, 0, None, True, False, True), BoardPart(4, 1, None, True, False, True), BoardPart(4, 2, None, True, False, True), BoardPart(4, 3, None, True, False, True), BoardPart(4, 4, None, True, False, True), BoardPart(4, 5, None, True, False, True), BoardPart(4, 6, None, True, False, True),
BoardPart(5, 0, None, None, None, False), BoardPart(5, 1, None, None, None, False), BoardPart(5, 2, None, True, False, True), BoardPart(5, 3, None, True, False, True), BoardPart(5, 4, None, True, False, True), BoardPart(5, 5, None, None, None, False), BoardPart(5, 6, None, None, None, False),
BoardPart(6, 0, None, None, None, False), BoardPart(6, 1, None, None, None, False), BoardPart(6, 2, None, True, False, True), BoardPart(6, 3, None, True, False, True), BoardPart(6, 4, None, True, False, True), BoardPart(6, 5, None, None, None, False), BoardPart(6, 6, None, None, None, False)]
def check_moves(selected_hole, target_hole):
hole_in_between = None
if selected_hole.has_piece and not target_hole.has_piece and selected_hole.row == target_hole.row:
if selected_hole.column - target_hole.column == 2:
for hole in board:
if hole.column == selected_hole.column - 1 and hole.row == selected_hole.row:
hole_in_between = hole
if hole_in_between.has_piece:
move_piece(hole_in_between, selected_hole, target_hole)
break
elif selected_hole.column - target_hole.column == -2:
for hole in board:
if hole.column == selected_hole.column + 1 and hole.row == selected_hole.row:
hole_in_between = hole
if hole_in_between.has_piece:
move_piece(hole_in_between, selected_hole, target_hole)
break
elif selected_hole.has_piece and not target_hole.has_piece and selected_hole.column == target_hole.column:
if selected_hole.row - target_hole.row == 2:
for hole in board:
if hole.row == selected_hole.row - 1 and hole.column == selected_hole.column:
hole_in_between = hole
if hole_in_between.has_piece:
move_piece(hole_in_between, selected_hole, target_hole)
break
elif selected_hole.row - target_hole.row == -2:
for hole in board:
if hole.row == selected_hole.row + 1 and hole.column == selected_hole.column:
hole_in_between = hole
if hole_in_between.has_piece:
move_piece(hole_in_between, selected_hole= selected_hole, target_hole= target_hole)
break
def move_piece(hole_in_between, selected_hole, target_hole):
hole_in_between.has_piece = False
selected_hole.has_piece = False
target_hole.has_piece = True
I couldn't figure out a way to check if there were no more possible moves or if the player won the game(if there was only one piece left), so if the player loses or wins the program doesn't do anything. I still want to update the game graphics, because they're still rough sketches haha.
Hope you guys like the game!