Skip to content

Commit

Permalink
Merge pull request #10 from yourdanov/win_history-v1.03
Browse files Browse the repository at this point in the history
Win history v1.03
  • Loading branch information
yourdanov authored Oct 18, 2024
2 parents 3ee8dde + f2c8165 commit 4fc6854
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 74 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Slots Machine Game v1.02
# Slots Machine Game v1.03

v1.01

Expand Down Expand Up @@ -28,6 +28,16 @@ v1.02
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/yourdanov/Slots/blob/main/slots_v102_3.png">
</picture>

v1.03

<div>
<img src="https://github.com/yourdanov/Slots/blob/main/slots_v103.png" width="500px"</img>
</div>

<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/yourdanov/Slots/blob/main/slots_v103.png">
</picture>

This Python program implements a slot machine game using tkinter GUI library.

## Table of Contents
Expand All @@ -49,6 +59,7 @@ This Python program implements a slot machine game using tkinter GUI library.
- Change bet amount.
- Change symbols and background color.
- Auto Spin
- Win History

## Usage

Expand All @@ -68,4 +79,8 @@ Added to version v1.01
Added to version v1.02

- Auto Spin functionality
- On Display Spins remaining text while the Auto Spin is enabled
- On Display Spins remaining text while the Auto Spin is enabled

Added to version v1.03

- Win history table
174 changes: 102 additions & 72 deletions slots.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import tkinter as tk
from tkinter import messagebox, Menu, colorchooser, simpledialog
from tkinter import messagebox, Menu, simpledialog, colorchooser
import random


def show_about():
messagebox.showinfo("About", "Slots Machine Game\nCreated by Atanas Yourdanov")


class SlotMachine:
def __init__(self, root):
self.spin_button = None
self.slot_labels = None
self.message_label = None
self.history_data = []
self.history_table = None
self.frame = None
self.root = root
self.root.title("Slots Machine")
self.root.geometry("1200x800")
self.root.resizable(True, True) # Allow window resizing
self.root.geometry("1635x1111") # Increased window size to fit history table
self.root.resizable(False, False) # Not allowing window resizing

self.symbol_sets = {
'Default': ['🍒', '🍋', '🍀', '♠', '7'],
Expand All @@ -29,7 +27,7 @@ def __init__(self, root):
self.bet = 0.0
self.initial_budget = 0.0
self.spin_counter = 0
self.auto_spin_count = 0 # Initialize auto_spin_count here
self.auto_spin_count = 0
self.auto_spin_active = False
self.create_menu()
self.create_widgets()
Expand All @@ -55,7 +53,7 @@ def create_menu(self):

help_menu = Menu(menu, tearoff=0)
menu.add_cascade(label="Help", menu=help_menu)
help_menu.add_command(label="About", command=show_about)
help_menu.add_command(label="About", command=lambda: messagebox.showinfo("About", "Slots Machine Game\nCreated by Atanas Yourdanov"))

def create_widgets(self):
self.frame = tk.Frame(self.root, bg='darkgreen')
Expand All @@ -74,12 +72,12 @@ def create_widgets(self):
self.slot_labels.append(col)

self.spin_button = tk.Button(self.frame, text="Spin! (Space)", command=self.spin, bg='red', fg='white',
font=("Helvetica", 14, 'bold'))
self.spin_button.grid(row=6, column=1, columnspan=1, pady=20)
font=("Helvetica", 16, 'bold'))
self.spin_button.grid(row=6, column=1, columnspan=1, pady=10)

self.change_bet_button = tk.Button(self.frame, text="Change Bet!", command=self.ask_for_bet, bg='blue',
fg='white', font=("Helvetica", 14, 'bold'))
self.change_bet_button.grid(row=7, column=1, columnspan=1, pady=10)
self.change_bet_button.grid(row=7, column=2, columnspan=1, pady=10)

self.auto_spin_button = tk.Button(self.frame, text="Auto Spin!", command=self.auto_spin_setup, bg='purple',
fg='white', font=("Helvetica", 14, 'bold'))
Expand Down Expand Up @@ -121,6 +119,25 @@ def create_widgets(self):
bg='green', fg='white', font=("Helvetica", 14, 'bold'))
self.set_budget_bet_button.grid(row=0, column=5, pady=10)

# Create history table
self.history_table = []
history_frame = tk.Frame(self.frame, bg='darkgreen')
history_frame.grid(row=0, column=6, rowspan=10, padx=10)

headers = ["Spin#", "Symbols", "Win Amount", "Win Type"]
for col, header in enumerate(headers):
header_label = tk.Label(history_frame, text=header, font=("Helvetica", 12, 'bold'),
bg='darkgreen', fg='white', relief='raised', width=15)
header_label.grid(row=0, column=col, padx=5, pady=5)

for row in range(1, 31): # Create 30 rows for history
row_labels = []
for col in range(4):
label = tk.Label(history_frame, text="", font=("Helvetica", 12), bg='darkgreen', fg='white', width=15, relief='sunken')
label.grid(row=row, column=col, padx=5, pady=5)
row_labels.append(label)
self.history_table.append(row_labels)

def setup_bindings(self):
self.root.bind('<Return>',
lambda e: self.set_budget_bet() if self.budget_entry.get().isdigit() else self.ask_for_bet())
Expand Down Expand Up @@ -222,7 +239,7 @@ def update_column(self, col_idx, symbols):
self.root.update()

def finish_spin(self, columns):
self.check_win(columns)
win = self.check_win(columns)
self.update_budget_label()
self.spinning = False

Expand All @@ -237,6 +254,9 @@ def finish_spin(self, columns):
self.enable_all_buttons()
self.auto_spin_active = False

if win > 0:
self.update_history(self.spin_counter, columns, win)

def check_win(self, columns):
win = 0
middle_row = [columns[i][2] for i in range(5)] # Middle row is the 3rd row (index 2)
Expand Down Expand Up @@ -304,15 +324,15 @@ def check_win(self, columns):
if len(pairs_adjacent) == 2:
win += self.bet * 1.6
self.budget += win
self.display_win(win, "Two Pairs (adjacent)")
self.display_win(win, "Adjacent Two Pairs")
return win

# Two pairs of same symbols not next to each other
pairs_non_adjacent = [symbol for symbol, count in symbol_counts.items() if count == 2]
if len(pairs_non_adjacent) == 2 and len(pairs_adjacent) != 2:
win += self.bet * 1.3
self.budget += win
self.display_win(win, "Two Pairs (non-adjacent)")
self.display_win(win, "Non-adjacent Two Pairs")
return win

# One pair
Expand All @@ -325,40 +345,28 @@ def check_win(self, columns):
return win

def display_win(self, win, condition):
self.message_label.config(text=f"You won: {win} ({condition})")
self.message_label.config(text=f"You won: {win:.2f} ({condition})")

def update_budget_label(self):
self.budget_label.config(text=f"Budget: {self.budget:.2f}")
def update_history(self, spin_number, columns, win):
middle_row = [columns[i][2] for i in range(5)] # Extract the middle row symbols

def update_bet_label(self):
self.bet_label.config(text=f"Current Bet: {self.bet:.2f}")
# Prepare data for history
symbols = " ".join(middle_row)
win_type = self.message_label.cget("text").split("(")[-1][:-1] # Extract the win type from message label
win_amount = f"{win:.2f}"

def new_game(self):
self.budget = 0.0
self.bet = 0.0
self.spin_counter = 0
self.spin_counter_label.config(text=f"Spin Count: {self.spin_counter}")
self.update_budget_label()
self.update_bet_label()
self.budget_entry.grid()
self.bet_entry.grid()
self.set_budget_bet_button.grid()
self.change_bet_button.config(state='normal')
self.spin_button.config(state='normal')
self.message_label.config(text="")
self.budget_entry.focus_set()
# Insert into history and handle rolling logic
if len(self.history_data) >= 30: # Remove the oldest entry if we exceed 30
self.history_data.pop(0)

def change_symbols(self, name):
self.symbols = self.symbol_sets[name]
self.new_game()
self.history_data.append([spin_number, symbols, win_amount, win_type])

def change_background_color(self):
color = colorchooser.askcolor()[1]
if color:
self.frame.config(bg=color)
for i in range(5):
for j in range(5):
self.slot_labels[i][j].config(bg=color if j != 2 else 'yellow')
# Update the table
for i, data in enumerate(self.history_data):
self.history_table[i][0].config(text=data[0])
self.history_table[i][1].config(text=data[1])
self.history_table[i][2].config(text=data[2])
self.history_table[i][3].config(text=data[3])

def auto_spin_setup(self):
try:
Expand All @@ -376,23 +384,9 @@ def auto_spin_setup(self):

def cancel_auto_spin(self):
self.auto_spin_active = False
if not self.spinning:
self.enable_all_buttons()
self.auto_spin_count = 0
self.cancel_auto_spin_button.config(state='disabled')

if self.budget <= 0:
self.message_label.config(text="You have run out of budget. Game over!")
self.spin_button.config(state='disabled')
self.change_bet_button.config(state='disabled')
self.auto_spin_button.config(state='disabled')
self.cancel_auto_spin_button.config(state='disabled')

if self.auto_spin_active and self.auto_spin_count > 0:
self.root.after(500, self.auto_spin) # 500 ms delay before the next auto spin
else:
self.enable_all_buttons()
self.auto_spin_active = False
self.cancel_auto_spin_button.grid_remove()
self.enable_all_buttons()

def ask_for_spin_count(self):
try:
Expand All @@ -404,6 +398,25 @@ def ask_for_spin_count(self):
self.message_label.config(text="Invalid input for spin count. Please enter a positive integer.")
return None

def change_background_color(self):
color = colorchooser.askcolor()[1]
if color:
self.frame.config(bg=color)
for i in range(5):
for j in range(5):
self.slot_labels[i][j].config(bg=color if j != 2 else 'yellow')

def auto_spin(self):
if self.auto_spin_active and self.auto_spin_count > 0 and self.budget >= self.bet:
self.budget -= self.bet
self.spin_counter += 1
self.spin_counter_label.config(text=f"Spin Count: {self.spin_counter}")
self.animate_spin()
self.auto_spin_count -= 1
self.auto_spin_counter_label.config(text=f"Auto Spin Count: {self.auto_spin_count}")
else:
self.cancel_auto_spin()

def disable_all_buttons(self):
self.spin_button.config(state='disabled')
self.change_bet_button.config(state='disabled')
Expand All @@ -417,18 +430,35 @@ def enable_all_buttons(self):
self.auto_spin_button.config(state='normal')
self.cancel_auto_spin_button.grid_remove()

def auto_spin(self):
if self.auto_spin_active and self.auto_spin_count > 0 and self.budget >= self.bet:
self.disable_all_buttons()
self.budget -= self.bet
self.message_label.config(text="")
self.spin_counter += 1
self.spin_counter_label.config(text=f"Spin Count: {self.spin_counter}")
self.animate_spin()
self.auto_spin_count -= 1
self.auto_spin_counter_label.config(text=f"Auto Spin Count: {self.auto_spin_count}")
else:
self.cancel_auto_spin()
def update_budget_label(self):
self.budget_label.config(text=f"Budget: {self.budget:.2f}")

def update_bet_label(self):
self.bet_label.config(text=f"Current Bet: {self.bet:.2f}")

def new_game(self):
self.budget = 0.0
self.bet = 0.0
self.spin_counter = 0
self.history_data = [] # Clear history
for row in self.history_table: # Clear table
for label in row:
label.config(text="")

self.spin_counter_label.config(text=f"Spin Count: {self.spin_counter}")
self.update_budget_label()
self.update_bet_label()
self.budget_entry.grid()
self.bet_entry.grid()
self.set_budget_bet_button.grid()
self.change_bet_button.config(state='normal')
self.spin_button.config(state='normal')
self.message_label.config(text="")
self.budget_entry.focus_set()

def change_symbols(self, name):
self.symbols = self.symbol_sets[name]
self.new_game()


if __name__ == "__main__":
Expand Down
Binary file added slots_v103.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 4fc6854

Please sign in to comment.