So for the last collision of my tron program, I want to record every movement each of my turtles makes into a set. Then I want to compare the set to the current position of the other turtle. How do I make that set?
Something like this:
positions_travelled_red = {(red.xcor(), red.ycor()), etc...)}
positions_travelled_blue = {(blue.xcor(), blue.ycor()), etc...)}
if positions_blue in positions_traveled_red:
print("Red wins")
How do I get all the positions into "positions_travelled_red"?
This is what I tried (and failed):
red_direction = none
blue_direction = none
positions_traveled_r = {(red_player.xcor(), red_player.ycor())}
while move_player(red_player, red_direction):
positions_traveled_r.add((red_player.xcor(), red_player.ycor()))
Here is the move players function
def move_player(player, direction):
if direction == 'up':
player.setheading(90)
player.forward(5)
elif direction == 'down':
player.setheading(270)
player.forward(5)
elif direction == 'left':
player.setheading(180)
player.forward(5)
elif direction == 'right':
player.setheading(0)
player.forward(5)
In that code above, when I tried printing one of the sets it just gave me the starting position of the turtle and didn't add anything.
Here is my full code if you want to look at it:
def TronGame():
#Border
#box = Turtle()
#box.ht()
#box.color('purple')
#box.speed('fastest')
#box.pensize(10)
# box.pu()
# box.goto(-1*height, -1*width)
# box.pd()
# for i in range(4):
# box.forward(height)
# box.left(90)
# box.forward(width)
# box.left(90)
#Blue Player movements
def blue_up():
global blue_direction
blue_direction = 'up'
def blue_down():
global blue_direction
blue_direction = 'down'
def blue_left():
global blue_direction
blue_direction = 'left'
def blue_right():
global blue_direction
blue_direction = 'right'
#Red player Movemnts
def red_up():
global red_direction
red_direction = 'up'
def red_down():
global red_direction
red_direction = 'down'
def red_left():
global red_direction
red_direction = 'left'
def red_right():
global red_direction
red_direction = 'right'
#Player movements
def move_player(player, direction):
if direction == 'up':
player.setheading(90)
player.forward(5)
elif direction == 'down':
player.setheading(270)
player.forward(5)
elif direction == 'left':
player.setheading(180)
player.forward(5)
elif direction == 'right':
player.setheading(0)
player.forward(5)
# Helper function to print end of game message
def game_over(message):
TurtleCrash = turtle.Turtle(visible=False)
TurtleCrash.color("white")
style = ('Arial', 25, 'italic')
TurtleCrash.write(f"{message}\nGame over!", font=style, align='center')
def collisions():
global red_player
global blue_player
x_blue, y_blue = blue_player.xcor(), blue_player.ycor()
x_red, y_red = red_player.xcor(), red_player.ycor()
message_turtle = turtle.Turtle(visible=False)
message_turtle.color("white")
collision_text = ""
if(math.isclose(x_blue, x_red, abs_tol=10.0) and
math.isclose(y_blue, y_red, abs_tol=10.0)):
collision_text = "Red and Blue Crashed!\nGame over!"
if x_blue > width/2 or x_blue < -1*width/2:
collision_text = "Blue went out of bounds.\nRed wins!"
if y_blue > height/2 or y_blue < -1*height/2:
collision_text = "Blue went out of bounds.\nRed wins!"
if x_red > width/2 or x_red < -1*width/2:
collision_text = "Red went out of bounds.\nBlue wins!"
time.sleep(2)
if y_red > height/2 or y_red < -1*height/2:
collision_text = "Red went out of bounds.\nBlue wins!"
if collision_text:
message_turtle.write(collision_text,font=('Arial', 25, 'italic'), align='center')
if blue_player.pos in positions_traveled_r:
collision_text = "Red wins"
if red_player.pos in positions_traveled_b:
collision_text = "Blue wins"
return False
def MainTron():
global screen
global blue_player
global red_player
screen = turtle.Screen()
screen.setup(width, height)
screen.bgpic('TronBg.png')
screen.bgcolor('black')
screen.addshape('BlueBike.gif')
screen.addshape('RedBike.gif')
blue_player = turtle.Turtle()
blue_player.shape('BlueBike.gif')
blue_player.pencolor("blue")
blue_player.pensize(3)
blue_player.pu()
blue_player.goto(-1*(width)/3, height/8)
blue_player.pd()
red_player = turtle.Turtle()
red_player.shape('RedBike.gif')
red_player.pencolor("red")
red_player.pensize(3)
red_player.pu()
red_player.goto(width/3, height/8)
red_player.pd()
while True:
RInstruction = turtle.Turtle(visible=False)
RInstruction.color("red")
style = ('Arial', 12, 'bold')
RInstruction.write("↑↓→← to move", font=style, align='Left')
BInstruction = turtle.Turtle(visible=False)
BInstruction.color("blue")
style = ('Arial', 15, 'bold')
BInstruction.write("WASD to move", font=style, align='Right')
break
for x in range(5):
my_turtle = turtle.Turtle(visible=False)
my_turtle.color("white")
style = ('Arial', 25, 'italic')
my_turtle.write(5-x, font=style, align='center')
time.sleep(1)
my_turtle.undo()
screen.listen()
screen.onkey(red_up, "Up")
screen.onkey(red_down, "Down")
screen.onkey(red_left, "Left")
screen.onkey(red_right, "Right")
screen.onkey(blue_up, "w")
screen.onkey(blue_down, "s")
screen.onkey(blue_left, "a")
screen.onkey(blue_right, "d")
def gameloop():
move_player(red_player, red_direction)
move_player(blue_player, blue_direction)
# Check for a collision. End game if there is one
if collisions():
return
#Repeat after 16ms (0.016s) (1000ms/16ms = 62.5 FPS)
screen.ontimer(gameloop, 16)
screen.ontimer(gameloop, 250)
gameloop()
screen.mainloop()
MainTron()
TronGame()
CodePudding user response:
Your code around the set looks correct.
Your mistake lies in while move_player(red_player, red_direction):
, as this will only run as long as move_player
returns something truthy.
By default functions return None
, which is falsey, so your loop runs 0 times. (but move_player still gets executed once for the first boolean check)
CodePudding user response:
If you want to experience collision detection you intend to achieve in action add to your code following snippet:
red_clones = []
blue_clones = []
def check_collisions():
global red_clones, blue_clones
msg = "" # will be used as flag indicating collision
rpc = red_player.clone(); rpc.hideturtle()
bpc = blue_player.clone(); bpc.hideturtle()
red_clones.append( rpc ); blue_clones.append( bpc )
for red_clone in red_clones:
if blue_player.distance(red_clone) < PLAYER_MIN_DISTANCE:
msg = "Blue crashed in Red's path.\nRed wins!"
for blue_clone in blue_clones:
if red_player.distance(blue_clone) < PLAYER_MIN_DISTANCE:
msg = "Red crashed in Blue's path.\nBlue wins!"
if( blue_player.distance(red_player) < PLAYER_MIN_DISTANCE ):
msg = "Red and Blue Crashed!\nGame over!"
That's it.
Now that you can see how it works you can go over to the next step and modify the provided solution in a way that the code runs faster and needs less computing power.