├── requirements.txt
├── audio
└── track.mp3
├── graphics
├── 0
│ ├── bg.png
│ ├── gridline.png
│ ├── gridline2.png
│ ├── gridline3.png
│ ├── gridline4.png
│ └── symbols
│ │ ├── 0_floppy.png
│ │ ├── 0_seven.png
│ │ ├── 0_diamond.png
│ │ ├── 0_hourglass.png
│ │ └── 0_telephone.png
└── font
│ └── PLACE_FONT_HERE
├── player.py
├── wins.py
├── settings.py
├── main.py
├── ui.py
├── README.md
├── .gitignore
├── reel.py
└── machine.py
/requirements.txt:
--------------------------------------------------------------------------------
1 | pygame>=2.1.2
--------------------------------------------------------------------------------
/audio/track.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notaSWE/pygameslots/HEAD/audio/track.mp3
--------------------------------------------------------------------------------
/graphics/0/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notaSWE/pygameslots/HEAD/graphics/0/bg.png
--------------------------------------------------------------------------------
/graphics/0/gridline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notaSWE/pygameslots/HEAD/graphics/0/gridline.png
--------------------------------------------------------------------------------
/graphics/0/gridline2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notaSWE/pygameslots/HEAD/graphics/0/gridline2.png
--------------------------------------------------------------------------------
/graphics/0/gridline3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notaSWE/pygameslots/HEAD/graphics/0/gridline3.png
--------------------------------------------------------------------------------
/graphics/0/gridline4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notaSWE/pygameslots/HEAD/graphics/0/gridline4.png
--------------------------------------------------------------------------------
/graphics/font/PLACE_FONT_HERE:
--------------------------------------------------------------------------------
1 | # I downloaded the kidspace.ttf font from https://dl.dafont.com/dl/?f=kidspace
--------------------------------------------------------------------------------
/graphics/0/symbols/0_floppy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notaSWE/pygameslots/HEAD/graphics/0/symbols/0_floppy.png
--------------------------------------------------------------------------------
/graphics/0/symbols/0_seven.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notaSWE/pygameslots/HEAD/graphics/0/symbols/0_seven.png
--------------------------------------------------------------------------------
/graphics/0/symbols/0_diamond.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notaSWE/pygameslots/HEAD/graphics/0/symbols/0_diamond.png
--------------------------------------------------------------------------------
/graphics/0/symbols/0_hourglass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notaSWE/pygameslots/HEAD/graphics/0/symbols/0_hourglass.png
--------------------------------------------------------------------------------
/graphics/0/symbols/0_telephone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notaSWE/pygameslots/HEAD/graphics/0/symbols/0_telephone.png
--------------------------------------------------------------------------------
/player.py:
--------------------------------------------------------------------------------
1 | from settings import *
2 |
3 | class Player():
4 | def __init__(self):
5 | self.balance = 1000.00
6 | self.bet_size = 10.00
7 | self.last_payout = 0.00
8 | self.total_won = 0.00
9 | self.total_wager = 0.00
10 |
11 | def get_data(self):
12 | player_data = {}
13 | player_data['balance'] = "{:.2f}".format(self.balance)
14 | player_data['bet_size'] = "{:.2f}".format(self.bet_size)
15 | player_data['last_payout'] = "{:.2f}".format(self.last_payout) if self.last_payout else "N/A"
16 | player_data['total_won'] = "{:.2f}".format(self.total_won)
17 | player_data['total_wager'] = "{:.2f}".format(self.total_wager)
18 | return player_data
19 |
20 | def place_bet(self):
21 | bet = self.bet_size
22 | self.balance -= bet
23 | self.total_wager += bet
--------------------------------------------------------------------------------
/wins.py:
--------------------------------------------------------------------------------
1 | # Helper functions to detect wins
2 |
3 | def flip_horizontal(result):
4 | # Flip results horizontally to keep them in a more readable list
5 | horizontal_values = []
6 | for value in result.values():
7 | horizontal_values.append(value)
8 | # 'Rotate' 90 degrees to get text representation of spin in order
9 | rows, cols = len(horizontal_values), len(horizontal_values[0])
10 | hvals2 = [[""] * rows for _ in range(cols)]
11 | for x in range(rows):
12 | for y in range(cols):
13 | hvals2[y][rows - x - 1] = horizontal_values[x][y]
14 | hvals3 = [item[::-1] for item in hvals2]
15 | return hvals3
16 |
17 | def longest_seq(hit):
18 | subSeqLength, longest = 1, 1
19 | start, end = 0, 0
20 | for i in range(len(hit) - 1):
21 | # Check to see if indices in hit parameter are sequential
22 | if hit[i] == hit[i + 1] - 1:
23 | subSeqLength += 1
24 | if subSeqLength > longest:
25 | longest = subSeqLength
26 | start = i + 2 - subSeqLength
27 | end = i + 2
28 | else:
29 | subSeqLength = 1
30 | return hit[start:end]
--------------------------------------------------------------------------------
/settings.py:
--------------------------------------------------------------------------------
1 | # Display settings
2 | DEFAULT_IMAGE_SIZE = (300, 300)
3 | FPS = 120
4 | HEIGHT = 1000
5 | WIDTH = 1600
6 | START_X, START_Y = 0, -300
7 | X_OFFSET, Y_OFFSET = 20, 0
8 |
9 | # Images
10 | BG_IMAGE_PATH = 'graphics/0/bg.png'
11 | GRID_IMAGE_PATH = 'graphics/0/gridline.png'
12 | GAME_INDICES = [1, 2, 3] # 0 and 4 are outside of play area
13 | SYM_PATH = 'graphics/0/symbols'
14 |
15 | # Text
16 | TEXT_COLOR = 'White'
17 | # You need to provide your own font in the below directory
18 | # I downloaded Kidspace font from https://www.dafont.com/kidspace.font
19 | UI_FONT = 'graphics/font/kidspace.ttf'
20 | UI_FONT_SIZE = 30
21 | WIN_FONT_SIZE = 110
22 |
23 | # 5 Symbols for demo
24 | # symbols = {
25 | # 'diamond': f"{SYM_PATH}/0_diamond.png",
26 | # 'floppy': f"{SYM_PATH}/0_floppy.png",
27 | # 'hourglass': f"{SYM_PATH}/0_hourglass.png",
28 | # 'seven': f"{SYM_PATH}/0_seven.png",
29 | # 'telephone': f"{SYM_PATH}/0_telephone.png"
30 | # }
31 |
32 | # 4 Symbols for more wins
33 | symbols = {
34 | 'diamond': f"{SYM_PATH}/0_diamond.png",
35 | 'floppy': f"{SYM_PATH}/0_floppy.png",
36 | 'hourglass': f"{SYM_PATH}/0_hourglass.png",
37 | 'hourglass2': f"{SYM_PATH}/0_hourglass.png",
38 | 'telephone': f"{SYM_PATH}/0_telephone.png"
39 | }
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | from machine import Machine
2 | from settings import *
3 | import ctypes, pygame, sys
4 |
5 | # Maintain resolution regardless of Windows scaling settings
6 | ctypes.windll.user32.SetProcessDPIAware()
7 |
8 | class Game:
9 | def __init__(self):
10 |
11 | # General setup
12 | pygame.init()
13 | self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
14 | pygame.display.set_caption('Slot Machine Demo')
15 | self.clock = pygame.time.Clock()
16 | self.bg_image = pygame.image.load(BG_IMAGE_PATH).convert_alpha()
17 | self.grid_image = pygame.image.load(GRID_IMAGE_PATH).convert_alpha()
18 | self.machine = Machine()
19 | self.delta_time = 0
20 |
21 | # Sound
22 | main_sound = pygame.mixer.Sound('audio/track.mp3')
23 | main_sound.play(loops = -1)
24 |
25 | def run(self):
26 |
27 | self.start_time = pygame.time.get_ticks()
28 |
29 | while True:
30 | # Handle quit operation
31 | for event in pygame.event.get():
32 | if event.type == pygame.QUIT:
33 | pygame.quit()
34 | sys.exit()
35 |
36 | # Time variables
37 | self.delta_time = (pygame.time.get_ticks() - self.start_time) / 1000
38 | self.start_time = pygame.time.get_ticks()
39 |
40 | pygame.display.update()
41 | self.screen.blit(self.bg_image, (0, 0))
42 | self.machine.update(self.delta_time)
43 | self.screen.blit(self.grid_image, (0, 0))
44 | self.clock.tick(FPS)
45 |
46 | if __name__ == '__main__':
47 | game = Game()
48 | game.run()
--------------------------------------------------------------------------------
/ui.py:
--------------------------------------------------------------------------------
1 | from player import Player
2 | from settings import *
3 | import pygame, random
4 |
5 | class UI:
6 | def __init__(self, player):
7 | self.player = player
8 | self.display_surface = pygame.display.get_surface()
9 | try:
10 | self.font, self.bet_font = pygame.font.Font(UI_FONT, UI_FONT_SIZE), pygame.font.Font(UI_FONT, UI_FONT_SIZE)
11 | self.win_font = pygame.font.Font(UI_FONT, WIN_FONT_SIZE)
12 | except:
13 | print("Error loading font!")
14 | print(f"Currently, the UI_FONT variable is set to {UI_FONT}")
15 | print("Does the file exist?")
16 | quit()
17 | self.win_text_angle = random.randint(-4, 4)
18 |
19 | def display_info(self):
20 | player_data = self.player.get_data()
21 |
22 | # Balance and bet size
23 | balance_surf = self.font.render("Balance: $" + player_data['balance'], True, TEXT_COLOR, None)
24 | x, y = 20, self.display_surface.get_size()[1] - 30
25 | balance_rect = balance_surf.get_rect(bottomleft = (x, y))
26 |
27 | bet_surf = self.bet_font.render("Wager: $" + player_data['bet_size'], True, TEXT_COLOR, None)
28 | x = self.display_surface.get_size()[0] - 20
29 | bet_rect = bet_surf.get_rect(bottomright = (x, y))
30 |
31 | # Draw player data
32 | pygame.draw.rect(self.display_surface, False, balance_rect)
33 | pygame.draw.rect(self.display_surface, False, bet_rect)
34 | self.display_surface.blit(balance_surf, balance_rect)
35 | self.display_surface.blit(bet_surf, bet_rect)
36 |
37 | # Print last win if applicable
38 | if self.player.last_payout:
39 | last_payout = player_data['last_payout']
40 | win_surf = self.win_font.render("WIN! $" + last_payout, True, TEXT_COLOR, None)
41 | x1 = 800
42 | y1 = self.display_surface.get_size()[1] - 60
43 | win_surf = pygame.transform.rotate(win_surf, self.win_text_angle)
44 | win_rect = win_surf.get_rect(center = (x1, y1))
45 | self.display_surface.blit(win_surf, win_rect)
46 |
47 | def update(self):
48 | pygame.draw.rect(self.display_surface, 'Black', pygame.Rect(0, 900, 1600, 100))
49 | self.display_info()
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Pygame Slots
2 | #### Pygame-based slot machine with easily changeable symbols, sound effects, and music.
3 |
4 | ## Demos
5 | #### Graphics/music included in this Github repo:
6 |
7 | https://user-images.githubusercontent.com/98667270/189539691-6cc22c1d-d719-4339-9889-77163738a07d.mp4
8 |
9 | #### Licensed symbols via Adobe Stock and additional sound effects via Google search:
10 |
11 | https://user-images.githubusercontent.com/98667270/189508033-ac361229-e493-44d3-a441-e075d22c3ddb.mp4
12 |
13 | ## Features
14 |
15 | - Five reels, each with three symbols in play at any given time
16 | - 300x300 png image symbols that are easy to change via Python dictionary
17 | - Easy-to-import audio (commented out by default)
18 | - Basic win animation
19 | - Basic UI
20 |
21 | ## Tech
22 |
23 | Basically just Pygame:
24 |
25 | - [Pygame] - Python game library
26 | - Images/Music/Sound effects
27 |
28 | ## Installation
29 |
30 | Pygame and Python3 are required, as well as the [kidspace.ttf] font in graphics/font/
31 |
32 | ```sh
33 | pip install -r requirements.txt
34 | ```
35 |
36 | From cmd/PowerShell:
37 |
38 | ```sh
39 | python main.py
40 | ```
41 |
42 | ## Media
43 |
44 | I have provided some basic symbols that don't look great but they work well enough. You can simply add a new directory and create a new symbol dictionary in settings.py to replace them. Same with audio files! See comments throughout for more info.
45 |
46 | ## Win Data
47 | win_data is formatted as such:
48 | `{1: ['symbol_1', [1, 2, 3]], 3: ['symbol_2', [0, 1, 2]]}`
49 |
50 | ## Future Development
51 | I will probably try to recreate this in an actual game engine at some point. Potential future work includes:
52 | - Better animations
53 | - More win scenarios
54 | - Simulations
55 | - Web version
56 |
57 | ## Thanks
58 | [Clear Code]: If you are new to Pygame, you need to watch Clear Code's videos. They are incredible!
59 | Additionally, I had some help on delta_time/animation staggering as well as the music from two of my friends - thank you!
60 | ## License
61 |
62 | [Creative Commons 0 License]
63 |
64 | [//]: # (These are reference links used in the body of this note and get stripped out when the markdown processor does its job. There is no need to format nicely because it shouldn't be seen. Thanks SO - http://stackoverflow.com/questions/4823468/store-comments-in-markdown-syntax)
65 | [Pygame]:
66 | [Creative Commons 0 License]:
67 | [Clear Code]:
68 | [kidspace.ttf]:
69 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 | *.pyc
6 |
7 | # C extensions
8 | *.so
9 |
10 | # Distribution / packaging
11 | .Python
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | pip-wheel-metadata/
25 | share/python-wheels/
26 | *.egg-info/
27 | .installed.cfg
28 | *.egg
29 | MANIFEST
30 |
31 | # PyInstaller
32 | # Usually these files are written by a python script from a template
33 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
34 | *.manifest
35 | *.spec
36 |
37 | # Installer logs
38 | pip-log.txt
39 | pip-delete-this-directory.txt
40 |
41 | # Unit test / coverage reports
42 | htmlcov/
43 | .tox/
44 | .nox/
45 | .coverage
46 | .coverage.*
47 | .cache
48 | nosetests.xml
49 | coverage.xml
50 | *.cover
51 | *.py,cover
52 | .hypothesis/
53 | .pytest_cache/
54 |
55 | # Translations
56 | *.mo
57 | *.pot
58 |
59 | # Django stuff:
60 | *.log
61 | local_settings.py
62 | db.sqlite3
63 | db.sqlite3-journal
64 |
65 | # Flask stuff:
66 | instance/
67 | .webassets-cache
68 |
69 | # Scrapy stuff:
70 | .scrapy
71 |
72 | # Sphinx documentation
73 | docs/_build/
74 |
75 | # PyBuilder
76 | target/
77 |
78 | # Jupyter Notebook
79 | .ipynb_checkpoints
80 |
81 | # IPython
82 | profile_default/
83 | ipython_config.py
84 |
85 | # pyenv
86 | .python-version
87 |
88 | # pipenv
89 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
90 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
91 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
92 | # install all needed dependencies.
93 | #Pipfile.lock
94 |
95 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
96 | __pypackages__/
97 |
98 | # Celery stuff
99 | celerybeat-schedule
100 | celerybeat.pid
101 |
102 | # SageMath parsed files
103 | *.sage.py
104 |
105 | # Environments
106 | .env
107 | .venv
108 | env/
109 | venv/
110 | ENV/
111 | env.bak/
112 | venv.bak/
113 |
114 | # Spyder project settings
115 | .spyderproject
116 | .spyproject
117 |
118 | # Rope project settings
119 | .ropeproject
120 |
121 | # mkdocs documentation
122 | /site
123 |
124 | # mypy
125 | .mypy_cache/
126 | .dmypy.json
127 | dmypy.json
128 |
129 | # Pyre type checker
130 | .pyre/
131 |
132 | # Licensed media
133 | audio/win*.wav
134 | audio/stop.mp3
135 | audio/spin.mp3
136 | audio/spinclip.mp3
137 | graphics/font/kidspace.ttf
138 | graphics/neon/*
139 | graphics/neon
140 | graphics/test/*
141 | graphics/test
142 |
143 | # Clear Code debug file
144 | debug.py
--------------------------------------------------------------------------------
/reel.py:
--------------------------------------------------------------------------------
1 | from settings import *
2 | import pygame, random
3 |
4 | class Reel:
5 | def __init__(self, pos):
6 | self.symbol_list = pygame.sprite.Group()
7 | self.shuffled_keys = list(symbols.keys())
8 | random.shuffle(self.shuffled_keys)
9 | self.shuffled_keys = self.shuffled_keys[:5] # Only matters when there are more than 5 symbols
10 |
11 | self.reel_is_spinning = False
12 |
13 | # Sounds
14 | # self.stop_sound = pygame.mixer.Sound('audio/stop.mp3')
15 | # self.stop_sound.set_volume(0.5)
16 |
17 | for idx, item in enumerate(self.shuffled_keys):
18 | self.symbol_list.add(Symbol(symbols[item], pos, idx))
19 | pos = list(pos)
20 | pos[1] += 300
21 | pos = tuple(pos)
22 |
23 | def animate(self, delta_time):
24 | if self.reel_is_spinning:
25 | self.delay_time -= (delta_time * 1000)
26 | self.spin_time -= (delta_time * 1000)
27 | reel_is_stopping = False
28 |
29 | if self.spin_time < 0:
30 | reel_is_stopping = True
31 |
32 | # Stagger reel spin start animation
33 | if self.delay_time <= 0:
34 |
35 | # Iterate through all 5 symbols in reel; truncate; add new random symbol on top of stack
36 | for symbol in self.symbol_list:
37 | symbol.rect.bottom += 100
38 |
39 | # Correct spacing is dependent on the above addition eventually hitting 1200
40 | if symbol.rect.top == 1200:
41 | if reel_is_stopping:
42 | self.reel_is_spinning = False
43 | # self.stop_sound.play()
44 |
45 | symbol_idx = symbol.idx
46 | symbol.kill()
47 | # Spawn random symbol in place of the above
48 | self.symbol_list.add(Symbol(symbols[random.choice(self.shuffled_keys)], ((symbol.x_val), -300), symbol_idx))
49 |
50 | def start_spin(self, delay_time):
51 | self.delay_time = delay_time
52 | self.spin_time = 1000 + delay_time
53 | self.reel_is_spinning = True
54 |
55 | def reel_spin_result(self):
56 | # Get and return text representation of symbols in a given reel
57 | spin_symbols = []
58 | for i in GAME_INDICES:
59 | spin_symbols.append(self.symbol_list.sprites()[i].sym_type)
60 | return spin_symbols[::-1]
61 |
62 | class Symbol(pygame.sprite.Sprite):
63 | def __init__(self, pathToFile, pos, idx):
64 | super().__init__()
65 |
66 | # Friendly name
67 | self.sym_type = pathToFile.split('/')[3].split('.')[0]
68 |
69 | self.pos = pos
70 | self.idx = idx
71 | self.image = pygame.image.load(pathToFile).convert_alpha()
72 | self.rect = self.image.get_rect(topleft = pos)
73 | self.x_val = self.rect.left
74 |
75 | # Used for win animations
76 | self.size_x = 300
77 | self.size_y = 300
78 | self.alpha = 255
79 | self.fade_out = False
80 | self.fade_in = False
81 |
82 | def update(self):
83 | # Slightly increases size of winning symbols
84 | if self.fade_in:
85 | if self.size_x < 320:
86 | self.size_x += 1
87 | self.size_y += 1
88 | self.image = pygame.transform.scale(self.image, (self.size_x, self.size_y))
89 |
90 | # Fades out non-winning symbols
91 | elif not self.fade_in and self.fade_out:
92 | if self.alpha > 115:
93 | self.alpha -= 7
94 | self.image.set_alpha(self.alpha)
--------------------------------------------------------------------------------
/machine.py:
--------------------------------------------------------------------------------
1 | from player import Player
2 | from reel import *
3 | from settings import *
4 | from ui import UI
5 | from wins import *
6 | import pygame
7 |
8 | class Machine:
9 | def __init__(self):
10 | self.display_surface = pygame.display.get_surface()
11 | self.machine_balance = 10000.00
12 | self.reel_index = 0
13 | self.reel_list = {}
14 | self.can_toggle = True
15 | self.spinning = False
16 | self.can_animate = False
17 | self.win_animation_ongoing = False
18 |
19 | # Results
20 | self.prev_result = {0: None, 1: None, 2: None, 3: None, 4: None}
21 | self.spin_result = {0: None, 1: None, 2: None, 3: None, 4: None}
22 |
23 | self.spawn_reels()
24 | self.currPlayer = Player()
25 | self.ui = UI(self.currPlayer)
26 |
27 | # Import sounds
28 | # self.spin_sound = pygame.mixer.Sound('audio/spinclip.mp3')
29 | # self.spin_sound.set_volume(0.15)
30 | # self.win_three = pygame.mixer.Sound('audio/winthree.wav')
31 | # self.win_three.set_volume(0.6)
32 | # self.win_four = pygame.mixer.Sound('audio/winfour.wav')
33 | # self.win_four.set_volume(0.7)
34 | # self.win_five = pygame.mixer.Sound('audio/winfive.wav')
35 | # self.win_five.set_volume(0.8)
36 |
37 | def cooldowns(self):
38 | # Only lets player spin if all reels are NOT spinning
39 | for reel in self.reel_list:
40 | if self.reel_list[reel].reel_is_spinning:
41 | self.can_toggle = False
42 | self.spinning = True
43 |
44 | if not self.can_toggle and [self.reel_list[reel].reel_is_spinning for reel in self.reel_list].count(False) == 5:
45 | self.can_toggle = True
46 | self.spin_result = self.get_result()
47 |
48 | if self.check_wins(self.spin_result):
49 | self.win_data = self.check_wins(self.spin_result)
50 | # Play the win sound
51 | # self.play_win_sound(self.win_data)
52 | self.pay_player(self.win_data, self.currPlayer)
53 | self.win_animation_ongoing = True
54 | self.ui.win_text_angle = random.randint(-4, 4)
55 |
56 | def input(self):
57 | keys = pygame.key.get_pressed()
58 |
59 | # Checks for space key, ability to toggle spin, and balance to cover bet size
60 | if keys[pygame.K_SPACE] and self.can_toggle and self.currPlayer.balance >= self.currPlayer.bet_size:
61 | self.toggle_spinning()
62 | self.spin_time = pygame.time.get_ticks()
63 | self.currPlayer.place_bet()
64 | self.machine_balance += self.currPlayer.bet_size
65 | self.currPlayer.last_payout = None
66 |
67 | def draw_reels(self, delta_time):
68 | for reel in self.reel_list:
69 | self.reel_list[reel].animate(delta_time)
70 |
71 | def spawn_reels(self):
72 | if not self.reel_list:
73 | x_topleft, y_topleft = 10, -300
74 | while self.reel_index < 5:
75 | if self.reel_index > 0:
76 | x_topleft, y_topleft = x_topleft + (300 + X_OFFSET), y_topleft
77 |
78 | self.reel_list[self.reel_index] = Reel((x_topleft, y_topleft)) # Need to create reel class
79 | self.reel_index += 1
80 |
81 | def toggle_spinning(self):
82 | if self.can_toggle:
83 | self.spin_time = pygame.time.get_ticks()
84 | self.spinning = not self.spinning
85 | self.can_toggle = False
86 |
87 | for reel in self.reel_list:
88 | self.reel_list[reel].start_spin(int(reel) * 200)
89 | # self.spin_sound.play()
90 | self.win_animation_ongoing = False
91 |
92 | def get_result(self):
93 | for reel in self.reel_list:
94 | self.spin_result[reel] = self.reel_list[reel].reel_spin_result()
95 | return self.spin_result
96 |
97 | def check_wins(self, result):
98 | hits = {}
99 | horizontal = flip_horizontal(result)
100 | for row in horizontal:
101 | for sym in row:
102 | if row.count(sym) > 2: # Potential win
103 | possible_win = [idx for idx, val in enumerate(row) if sym == val]
104 |
105 | # Check possible_win for a subsequence longer than 2 and add to hits
106 | if len(longest_seq(possible_win)) > 2:
107 | hits[horizontal.index(row) + 1] = [sym, longest_seq(possible_win)]
108 | if hits:
109 | self.can_animate = True
110 | return hits
111 |
112 | def pay_player(self, win_data, curr_player):
113 | multiplier = 0
114 | spin_payout = 0
115 | for v in win_data.values():
116 | multiplier += len(v[1])
117 | spin_payout = (multiplier * curr_player.bet_size)
118 | curr_player.balance += spin_payout
119 | self.machine_balance -= spin_payout
120 | curr_player.last_payout = spin_payout
121 | curr_player.total_won += spin_payout
122 |
123 | # You need to provide sounds and load them in the Machine init function for this to work!
124 | def play_win_sound(self, win_data):
125 | sum = 0
126 | for item in win_data.values():
127 | sum += len(item[1])
128 | if sum == 3: self.win_three.play()
129 | elif sum == 4: self.win_four.play()
130 | elif sum > 4: self.win_five.play()
131 |
132 | def win_animation(self):
133 | if self.win_animation_ongoing and self.win_data:
134 | for k, v in list(self.win_data.items()):
135 | if k == 1:
136 | animationRow = 3
137 | elif k == 3:
138 | animationRow = 1
139 | else:
140 | animationRow = 2
141 | animationCols = v[1]
142 | for reel in self.reel_list:
143 | if reel in animationCols and self.can_animate:
144 | self.reel_list[reel].symbol_list.sprites()[animationRow].fade_in = True
145 | for symbol in self.reel_list[reel].symbol_list:
146 | if not symbol.fade_in:
147 | symbol.fade_out = True
148 |
149 | def update(self, delta_time):
150 | self.cooldowns()
151 | self.input()
152 | self.draw_reels(delta_time)
153 | for reel in self.reel_list:
154 | self.reel_list[reel].symbol_list.draw(self.display_surface)
155 | self.reel_list[reel].symbol_list.update()
156 | self.ui.update()
157 | self.win_animation()
158 |
159 | # Balance/payout debugger
160 | # debug_player_data = self.currPlayer.get_data()
161 | # machine_balance = "{:.2f}".format(self.machine_balance)
162 | # if self.currPlayer.last_payout:
163 | # last_payout = "{:.2f}".format(self.currPlayer.last_payout)
164 | # else:
165 | # last_payout = "N/A"
166 | # debug(f"Player balance: {debug_player_data['balance']} | Machine balance: {machine_balance} | Last payout: {last_payout}")
--------------------------------------------------------------------------------