forked from Annex5061/java-algorithms
-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathvariant 2.py
409 lines (335 loc) · 13 KB
/
variant 2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
import turtle
import random
# Setup the screen
screen = turtle.Screen()
screen.colormode(255)
screen.bgcolor("black")
# Ball variables
ball_size = 10.0
ball_speed = 5
# Boundary variables
box_size = 400.0
boundary = (box_size / 2.0) - ball_size
# Paddle variables
paddle_speed = 30
paddle_width = box_size / 6.0
paddle_thickness = paddle_width / 10.0
# For turtle mode
funny = False
#Drawing the box
box_drawer = turtle.Turtle()
box_drawer.penup()
box_drawer.speed(0)
box_drawer.goto(-box_size / 2.0, -box_size / 2.0)
box_drawer.pendown()
box_drawer.color("red")
for i in range(4):
box_drawer.forward(box_size)
box_drawer.left(90)
box_drawer.ht()
################################################################
############################ Paddle ############################
################################################################
#Making the paddle
paddle = turtle.Turtle()
paddle.color("aquamarine")
paddle.shape("square")
paddle.shapesize(paddle_thickness/20.0, paddle_width / 20.0)
'''
TODO: Paddle starting position
Move the paddle so that it starts at the coordinates (0, -boundary + 20)
'''
paddle.penup()
paddle.speed(0)
paddle.goto(0,-boundary + 20)
'''
TODO: Move paddle with arrow keys
1) If the user presses the right arrow key, the paddle moves to the right
by paddle_speed but only if the right edge of the paddle is less than boundary.
2) If the user presses the left arrow key, the paddle moves to the left
by paddle_speed but only if the left edge of the paddle is within the boundary.
Hint: paddle.xcor() will give you the x coordinate of the middle of the paddle.
How can you use this value and paddle_width to get the x coordinates of the
left and right edges of the paddle?
'''
#Paddle goes right when key pressed, only if within boundaries
def paddle_right():
if (paddle.xcor() + paddle_width / 2.0) < boundary:
paddle.forward(paddle_speed)
#Paddle goes left when key pressed, only if within boundaries
def paddle_left():
if (paddle.xcor() - paddle_width / 2.0) > -boundary:
paddle.backward(paddle_speed)
screen.onkey(paddle_right, "Right")
screen.onkey(paddle_left, "Left")
################################################################
############################ Bricks ############################
################################################################
# Brick variables
num_bricks = 10
gap_size = 10.0
brick_width = (box_size - (num_bricks + 1)*gap_size) / num_bricks
brick_thickness = brick_width / 2.0
'''
TODO: Write make_brick_row function
Write the function called make_brick_row that takes in a color and y coordinate.
This function will create one row of bricks, save each brick in a list and
return the list of bricks.
- Use num_bricks for the number of bricks per row.
- The color is a string that will tell you the color that you should make that
row of bricks.
- The y coordinate will be the y coordinate of all the bricks in this row.
- When you make your turtle bricks, you can change the speed of
the brick turtle to 0 so that the bricks are drawn more quickly.
- Use shape to make each brick a square and use shapesize to change
the size of each brick to (brick_thickness/20.0, brick_width/20.0)
Hint: The x coordinate of the first brick should be
-box_size/2.0 + gap_size + brick_width/2.0.
From there, the x coordinate of the second brick will be the
x coordinate of the previous brick plus brick_width plus gap_size
'''
def make_brick_row(color, y):
row = []
xBrick = (- box_size / 2.0) + gap_size + (brick_width / 2.0)
for i in range(num_bricks):
brick = turtle.Turtle()
brick.speed(0)
brick.shape("square")
brick.shapesize(brick_thickness / 20.0, brick_width/20.0)
brick.color(color)
brick.penup()
brick.goto(xBrick,y)
row.append(brick)
xBrick = xBrick + brick_width + gap_size
return row
'''
TODO: Create 4 rows of bricks
Call make_brick_row 4 times to create 4 rows and store the list of bricks
that is returned in the variables below (row1, row2, row3, row4).
You can make each brick row whatever color you want.
Hint 1: You'll need to calculate the y coordinate of each row of bricks.
Just like in the previous problem, use the variable box_size to
calculate the edge of the box.
Hint 2: The y coordinate of the top row of bricks should be the
y coordinate of the top of the box minus gap_size minus brick_thickness/2.0.
From there, the y coordinate of the next row down will be the y coordinate
of row above minus brick_thickness minus gap_size
'''
y_brick = (box_size / 2.0) - gap_size - (brick_thickness / 2.0)
row1 = make_brick_row("red", y_brick)
row2 = make_brick_row("green", y_brick - ((brick_thickness) + gap_size))
row3 = make_brick_row("blue", y_brick - 2*((brick_thickness) + gap_size))
row4 = make_brick_row("yellow", y_brick - 3*((brick_thickness) + gap_size))
################################################################
############################ Ball ##############################
################################################################
#Making the ball
ball = turtle.Turtle()
ball.speed(0)
ball.color("hot pink")
ball.shape("circle")
ball.penup()
ball.goto(0, paddle.ycor() + (paddle_thickness / 2.0) + ball_size)
# Set the angle of the ball
heading = random.randint(10,170)
print(heading)
ball.setheading(heading)
'''
TODO: Bounce wall
Create a function called bounce_wall that bounces the ball whenever it hits
the boundary.
- If the ball is at a corner (in other words, its x coordinate
and y coordinate are both past the boundaries) then the ball
should bounce back in exactly the opposite direction it came from.
One way to do this is to change the angle of the ball if it is past
the boundary. If you use this approach, use the function heading to get the
current angle of the ball and the function setheading to change
the angle of the ball.
- If the ball is past the left or right boundary, change the angle to be
180 minus the current angle
- If the ball is past the top of the boundary, change the angle to be
360 minus the current angle
Example use of heading and setheading:
turtle_angle = name_of_turtle.heading()
name_of_turtle.setheading(new_angle)
'''
#Checks for wall collision and changes direction
def bounce_wall():
if ball.xcor() > boundary or ball.xcor() < -boundary:
#For corners just turn around
if ball.ycor() > boundary:
ball.left(180)
#For side walls switch angle (always the same geometry)
else:
ball.setheading(180 - ball.heading())
#For top/bottom walls switch angle (always the same geometry)
elif ball.ycor() > boundary:
ball.setheading(360 - ball.heading())
'''
TODO: Bounce paddle
Create a function called bounce_paddle that bounces the ball off the paddle.
To check if the ball is touching the paddle,
you have to check that all the following are true:
1) the ball is heading downwards
2) the y coordinate of the ball minus the ball size is less
than the y coordinate of the top edge of the paddle
3) the x coordinate of the ball plus the ball size is greater
than the x coordinate of the left edge of the paddle
4) the x coordinate of the ball minus the ball size is less than the x coordinate of right edge of the paddle
If all the above conditions are True, then change the angle of the ball
to 360 minus the current angle.
Hint: Think about how to use paddle_width to calculate the edges of the paddle
'''
#Checks for paddle collision and changes direction
def bounce_paddle():
if ball.ycor() - ball_size < paddle.ycor() + (paddle_thickness / 2.0) and 180 < ball.heading():
if ball.xcor() + ball_size > paddle.xcor() - (paddle_width / 2.0):
if ball.xcor() - ball_size < paddle.xcor() + (paddle_width / 2.0):
ball.setheading(360 - ball.heading())
'''
TODO: Bounce brick row
Create a function called bounce_brick_row that accepts a
list of bricks as an argument.
This function should check whether the ball is touching each brick in the list.
If the ball is touching the brick and the brick is visible, then make sure
to hide the brick and bounce the ball (just like in bounce_paddle).
To check if a brick is visible, use the isvisible() function on each brick.
The isvisible function returns True if the brick is still visible.
To hide a turtle you can use the function ht.
Examples:
name_of_turtle.ht() #hide
name_of_turtle.isvisible()
Hint: To check if the ball is touching each brick, think about how you did
this for the paddle. Remember that in the case of bricks, you'll have to check
whether the ball is within all 4 edges of the brick and it doesn't matter
in what direction the ball is moving.
'''
def bounce_brick_row(row):
for brick in row:
if ball.ycor() + ball_size > brick.ycor() - (brick_thickness / 2.0): # ball up , brick down
if ball.ycor() - ball_size < brick.ycor() + (brick_thickness / 2.0): # ball down , brick up
if ball.xcor() + ball_size > brick.xcor() - (brick_width / 2.0): # ball right , brick left
if ball.xcor() - ball_size < brick.xcor() + (brick_width / 2.0): # ball left , brick right
if brick.isvisible():
brick.ht() # hide
ball.setheading(360 - ball.heading())
break
def bounce_bricks():
bounce_brick_row(row1)
bounce_brick_row(row2)
bounce_brick_row(row3)
bounce_brick_row(row4)
################################################################
####################### Turtle mode ############################
################################################################
def turtleMode():
for brick in row1:
brick.shape("square")
for brick in row2:
brick.shape("circle")
for brick in row3:
brick.shape("turtle")
for brick in row4:
brick.shape("turtle")
# paddle.shape("turtle")
# ball.shape("turtle")
global funny
funny = True
screen.onkey(turtleMode, "t")
#######################################################################
################ Gameplay ###############################
################################################################
'''
TODO: Write bricks_gone_row function
Create a function called bricks_gone_row that accepts a list of bricks
as an argument and returns True if all the bricks in that list are not visible.
The function returns False if there is still at least one brick that is visible.
To check if a brick is visible, use the isvisible() function on each brick.
The isvisible function returns True if the brick is still visible.
'''
def bricks_gone_row(row):
for brick in row:
if brick.isvisible():
return False
return True
'''
TODO: Write bricks_gone function
Create a function called bricks_gone that calls brick_gone_row 4 times:
once on each row (row1, row2, row3, row4).
If all 4 brick rows are gone, then return True. Otherwise return False.
'''
def bricks_gone():
if bricks_gone_row(row1) and bricks_gone_row(row2) and bricks_gone_row(row3) and bricks_gone_row(row4): # t and t and t and t
return True
return False
def startGame():
lose = False
# For turtle mode
counter = 0
#Make the ball move continuously
while True:
ball.forward(ball_speed)
'''
TODO: Player loses
If the ball is below the bottom boundary, then hide the ball turtle,
set the lose variable to True and break from this while loop.
'''
if ball.ycor() < -boundary:
ball.ht()
lose = True
break
bounce_wall()
bounce_paddle()
bounce_bricks()
'''
TODO: Call bricks_gone function
Call the bricks_gone function and if it returns True then break from
this while loop
'''
if bricks_gone():
break
##### For turtle mode #####
# Funny animation that runs when turtle mode is turned on
counter+=1
if funny and counter > 300:
paddle.shapesize(paddle_width/20.0,paddle_width/20.0)
for i in range(6):
for brick in row1:
brick.speed(0)
brick.left(30)
for i in range(6):
for brick in row2:
brick.speed(0)
brick.left(30)
for i in range(6):
for brick in row3:
brick.speed(0)
brick.left(30)
for i in range(6):
for brick in row4:
brick.speed(0)
brick.left(30)
counter = 0
##########################
'''
TODO: Create writer turtle for game over
Create a turtle that writes either "You lose!" or "You win!"
depending on the value of the variable lose.
You can use the function write for the turtle to write text.
Example:
name_of_turtle.write("Text to write on screen")
You'll want to change the color of the turtle to something other than black
so that you can see the text.
If you'd like, you can use the function ht to hide the turtle.
'''
writer_turtle = turtle.Turtle()
writer_turtle.color("white")
writer_turtle.ht()
if lose: # lose =true
writer_turtle.write("YOU LOSE!", font=("Arial", 16, "normal"))
else: # lose = false
writer_turtle.write("YOU WIN!", font=("Arial", 16, "normal"))
screen.onkey(startGame, "space")
screen.listen()
# Closes the game window when you click the screen
screen.exitonclick()