10000 Add files via upload · src255/rabbitmath@5bb54ad · GitHub
[go: up one dir, main page]

Skip to content

Commit 5bb54ad

Browse files
authored
Add files via upload
Game code for Rotating Table problem in RabbitMath's Grade 12 Curriculum
0 parents  commit 5bb54ad

File tree

1 file changed

+337
-0
lines changed

1 file changed

+337
-0
lines changed

play.py

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
import time
2+
import numpy as np
3+
import pygame as pg
4+
from collections import Counter
5+
6+
# COLOURS
7+
WHITE = (255, 255, 255)
8+
BLACK = (0, 0, 0)
9+
GREY = (175, 175, 175)
10+
GENTIAN = (100, 25, 255)
11+
BRIGHTER_GENTIAN = (150, 25, 255)
12+
BROWN1 = (170, 90, 5)
13+
BROWN2 = (150, 110, 10)
14+
DULL_RED = (200, 0, 0)
15+
RED = (255, 0, 0)
16+
BLUE = (70, 210, 255)
17+
BRIGHT_GREEN = (0, 255, 0)
18+
GREEN = (0, 200, 0)
19+
20+
21+
class Pad:
22+
def __init__(self, colour, radius, x, y, hide=True):
23+
self.colour = colour
24+
self.radius = int(round(radius))
25+
self.x = int(round(x))
26+
self.y = int(round(y))
27+
self.hide = hide
28+
29+
def mark(self):
30+
a = Pad(WHITE, self.radius, self.x, self.y, False)
31+
return a
32+
33+
34+
class Table:
35+
def __init__(self, s, colour, radius, x, y, pc):
36+
self.size = s
37+
self.colour = colour
38+
self.radius = int(round(radius))
39+
self.angle = 0
40+
self.x = int(round(x))
41+
self.y = int(round(y))
42+
self.pads = list(Pad(pc[j], self.radius*pow(4, 0.75)/(3 * pow(size, 0.75)), self.x + self.radius*2/3 *
43+
np.cos(self.angle + j * np.pi * 2 / size),
44+
self.y + self.radius*2/3 * np.sin(self.angle + j
45+
* np.pi * 2 / size)) for j in range(size))
46+
self.spin_count = 0
47+
self.choices = 0
48+
49+
def shift(self, n, m):
50+
colours = [pad.colour for pad in self.pads]
51+
for i in range(self.size):
52+
self.pads[(i + m) % self.size].colour = colours[(i + n) % self.size]
53+
54+
def spin(self):
55+
self.choices = 0
56+
self.angle = np.random.uniform(0, 2*np.pi)
57+
for j in range(self.size):
58+
self.pads[j].x = int(round(self.x + self.radius*2/3 * np.cos(self.angle + j * np.pi * 2 / self.size)))
59+
self.pads[j].y = int(round(self.y + self.radius*2/3 * np.sin(self.angle + j * np.pi * 2 / self.size)))
60+
self.spin_count += 1
61+
for pad in self.pads:
62+
pad.hide = True
63+
64+
def switch(self, pad):
65+
i = self.pads.index(pad)
66+
if self.pads[i].colour == RED:
67+
self.pads[i].colour = BLUE
68+
else:
69+
self.pads[i].colour = RED
70+
71+
72+
def random_colour():
73+
if np.random.randint(2) == 0:
74+
return RED
75+
else:
76+
return BLUE
77+
78+
79+
# game prep (must be done in terminal)
80+
size = int(input('Enter number of pads: '))
81+
hands = int(input('Enter number of hands: '))
82+
# SIZE AT LEAST 4 FOR GOOD SPACING
83+
# size = 4
84+
# hands = 2
85+
86+
# START PYGAME
87+
pg.init()
88+
89+
display_width = 1000
90+
display_height = 600
91+
92+
game_display = pg.display.set_mode((display_width, display_height))
93+
pg.display.set_caption("Table Spin")
94+
pg.display.update()
95+
clock = pg.time.Clock()
96+
97+
pad_colours = [0] * size
98+
table = Table(size, 0, 0, 0, 0, pad_colours)
99+
win = False
100+
click = False
101+
reveal = False
102+
adversary = False
103+
104+
105+
def see():
106+
global reveal
107+
reveal = True
108+
109+
110+
def set_up():
111+
# create random pad colours
112+
global pad_colours
113+
pad_colours = [random_colour() for j in range(size)]
114+
# initialize table
115+
global table
116+
table = Table(size, BROWN1, display_height * 3 / 8, display_width / 2, display_height * 4 / 9, pad_colours)
117+
118+
119+
def draw(obj, hidden=False, white=False):
120+
if white:
121+
pg.draw.circle(game_display, WHITE, (obj.x, obj.y), obj.radius)
122+
elif hidden:
123+
pg.draw.circle(game_display, GREY, (obj.x, obj.y), obj.radius)
124+
else:
125+
pg.draw.circle(game_display, obj.colour, (obj.x, obj.y), obj.radius)
126+
127+
128+
def show_button(pad, ic, ac):
129+
mouse = pg.mouse.get_pos()
130+
131+
if np.sqrt(np.square(pad.x - mouse[0]) + np.square(pad.y - mouse[1])) < pad.radius:
132+
pg.draw.circle(game_display, ac, (pad.x, pad.y), pad.radius)
133+
134+
if click and table.choices < hands:
135+
pad.hide = False
136+
draw(pad, white=True)
137+
table.choices += 1
138+
139+
else:
140+
pg.draw.circle(game_display, ic, (pad.x, pad.y), pad.radius)
141+
142+
143+
def switch_button(pad):
144+
mouse = pg.mouse.get_pos()
145+
# click = pg.mouse.get_pressed()
146+
147+
draw(pad, pad.hide)
148+
if np.sqrt(np.square(pad.x - mouse[0]) + np.square(pad.y - mouse[1])) < pad.radius and click:
149+
if not pad.hide:
150+
table.switch(pad)
151+
draw(pad, pad.hide)
152+
153+
154+
def game_spin():
155+
game_display.fill(BLACK)
156+
pg.display.update()
157+
time.sleep(0.5)
158+
global reveal, win, adversary
159+
adversary = False
160+
reveal = False
161+
table.spin()
162+
163+
164+
def spin_button():
165+
square_button("SPIN", display_width/2 - 112, 540, 100, 50, GENTIAN, BRIGHTER_GENTIAN, game_spin)
166+
167+
168+
def reveal_button():
169+
square_button("REVEAL", display_width/2 + 12, 540, 100, 50, GENTIAN, BRIGHTER_GENTIAN, see)
170+
171+
172+
def menu_button():
173+
square_button("MENU", 875, 540, 100, 50, DULL_RED, RED, game_intro)
174+
175+
176+
def buttons():
177+
spin_button()
178+
reveal_button()
179+
menu_button()
180+
181+
182+
def draw_pads1():
183+
for pad in table.pads:
184+
if pad.hide:
185+
show_button(pad, GREY, WHITE)
186+
else:
187+
draw(pad.mark())
188+
189+
190+
def draw_pads2():
191+
global adversary
192+
if not adversary:
193+
chosen = [not a.hide for a in table.pads]
194+
ids = [i for i, x in enumerate(chosen) if not x]
195+
n = len(ids)
196+
skips = []
197+
for i in range(n):
198+
if n == 1:
199+
break
200+
elif i == n - 1:
201+
skip = table.size % (ids[i] - ids[0])
202+
else:
203+
skip = ids[i+1] - ids[i]
204+
if Counter(a[0] for a in skips)[str(skip)] == 0:
205+
skips.append([skip, ids[i]])
206+
for skip in skips:
207+
for i in range(table.size):
208+
if table.pads[i].colour != table.pads[(i+skip[0]) % table.size].colour:
209+
# if (ids[0] + skip) % table.size == ids[1]:
210+
# n = ids[0]
211+
# else:
212+
# n = ids[1]
213+
table.shift(i, skip[1])
214+
adversary = True
215+
break
216+
for pad in table.pads:
217+
if pad.hide:
218+
draw(pad, hidden=True)
219+
else:
220+
draw(pad.mark())
221+
222+
223+
def draw_pads3():
224+
for pad in table.pads:
225+
if pad.hide:
226+
draw(pad, hidden=True)
227+
else:
228+
switch_button(pad)
229+
230+
231+
def text_object(text, font):
232+
text_surface = font.render(text, True, WHITE)
233+
return text_surface, text_surface.get_rect()
234+
235+
236+
def message_display(text, s, x, y):
237+
normal_text = pg.font.Font('freesansbold.ttf', s)
238+
text_surf, text_rect = text_object(text, normal_text)
239+
text_rect.center = (round(x), round(y))
240+
game_display.blit(text_surf, text_rect)
241+
242+
pg.display.update()
243+
244+
245+
def win_msg():
246+
for pad in table.pads:
247+
draw(pad)
248+
pg.display.update()
249+
time.sleep(1)
250+
game_display.fill(BLACK)
251+
message_display("Congratulations,", 80, display_width/2, display_height/3)
252+
if table.spin_count == 0:
253+
message_display("you won without spinning!", 65, display_width/2, display_height/2)
254+
elif table.spin_count == 1:
255+
message_display("you won after a single spin!", 65, display_width/2, display_height/2)
256+
else:
257+
message_display("you won after " + str(table.spin_count) + " spins!", 80, display_width/2, display_height/2)
258+
pg.display.update()
259+
time.sleep(3)
260+
game_intro()
261+
262+
263+
def square_button(msg, x, y, w, h, ic, ac, action=None):
264+
global click
265+
x = int(round(x))
266+
y = int(round(y))
267+
w = int(round(w))
268+
h = int(round(h))
269+
mouse = pg.mouse.get_pos()
270+
click = pg.mouse.get_pressed()
271+
272+
if x+w > mouse[0] > x and y+h > mouse[1] > y:
273+
pg.draw.rect(game_display, ac, (x, y, w, h))
274+
275+
if click[0] == 1 and action is not None:
276+
action()
277+
else:
278+
pg.draw.rect(game_display, ic, (x, y, w, h))
279+
280+
small_text = pg.font.Font("freesansbold.ttf", 20)
281+
text_surf, text_rect = text_object(msg, small_text)
282+
text_rect.center = (int(x+(w/2)), int(y+(h/2)))
283+
game_display.blit(text_surf, text_rect)
284+
285+
286+
def game_loop():
287+
global win, click, reveal
288+
win = False
289+
reveal = False
290+
game_display.fill(BLACK)
291+
while not win:
292+
click = False
293+
for event in pg.event.get():
294+
if event.type == pg.QUIT:
295+
pg.quit()
296+
quit()
297+
elif event.type == pg.MOUSEBUTTONDOWN:
298+
click = True
299+
draw(table)
300+
if reveal:
301+
draw_pads3()
302+
elif table.choices < hands:
303+
draw_pads1()
304+
elif table.choices == hands:
305+
draw_pads2()
306+
message_display("Spin Count: " + str(table.spin_count), 30, display_width / 2, 515)
307+
buttons()
308+
if all(table.pads[i].colour == table.pads[0].colour for i in range(1, size)):
309+
win = True
310+
pg.display.update()
311+
clock.tick(60)
312+
win_msg()
313+
time.sleep(2)
314+
game_intro()
315+
316+
317+
def game_intro():
318+
set_up()
319+
if all(pad_colours[0] == pad_colours[i] for i in range(1, size)):
320+
table.switch(table.pads[size - 1])
321+
game_display.fill(BLACK)
322+
while True:
323+
for event in pg.event.get():
324+
print(event)
325+
if event.type == pg.QUIT:
326+
pg.quit()
327+
quit()
328+
329+
message_display("Table Spin", 100, display_width/2, display_height/3)
330+
331+
square_button("Play", 250, 450, 100, 50, GREEN, BRIGHT_GREEN, game_loop)
332+
square_button("Quit", 650, 450, 100, 50, DULL_RED, RED, quit)
333+
pg.display.update()
334+
clock.tick(60)
335+
336+
337+
game_intro()

0 commit comments

Comments
 (0)
0