0

I am trying to make a game where you have to collect the turtle so when you click a turtle it moves into a box. The problem with this is that when you click one of the turtles a turtle moves that you didn't click. I think that it is because I created one variable to control multiple turtles, but I don't know how to fix this. Here is my code: (btw, I was having trouble adding in the code using the 'code' button on stack overflow)

import turtle

import random

s = turtle. Screen()

s.bgcolor("lightgreen")

print("Welcome! this pond is infested with turtles! Can you catch all the turtles?")

for x in range(0,5):

  t = turtle.Turtle()

  c = 'yellow', 'gold', 'orange', 'red', 'magenta', 'navy', 'blue', 'purple', 'cyan', 'brown', 'black', 'gray', 'white'

  t.color(random.choice(c))

  t.shape("turtle")

  t.penup()

  t.hideturtle()

  r = random.randint(-75,75)

  r2 = random.randint(-75,75)

  r3 = random.randint(1,10)

  t.goto(r,r2)

  t.showturtle()

  def fxn (x, y):

    t.goto(95,-122)

    print("yes")

  t.onclick(fxn)
Billy
  • 1,157
  • 1
  • 9
  • 18

2 Answers2

1

We can patch your code using partial from functools. This allows us to pass "which turtle" through to your onclick() function:

from random import choice, randint
from functools import partial
from turtle import Screen, Turtle

COLORS = ['yellow', 'gold', 'orange', 'red', 'magenta', 'navy', 'blue', 'purple', 'cyan', 'brown', 'black', 'gray', 'white']

def fxn(t, x, y):
    t.goto(95, -122)

    print("yes")

screen = Screen()
screen.bgcolor('lightgreen')

print("Welcome! This pond is infested with turtles! Can you catch all the turtles?")

for x in range(5):
    t = Turtle()
    t.hideturtle()
    t.shape('turtle')
    t.color(choice(COLORS))
    t.penup()

    x = randint(-75, 75)
    y = randint(-75, 75)

    t.goto(x, y)
    t.onclick(partial(fxn, t))
    t.showturtle()

screen.mainloop()

The changes to accommodate partial() are minimal, most of the changes above were for style. I do agree with @Nathcat that using an object oriented approach would be better. But, since it's turtles we're chasing, I'd make MyTurtle be a turtle instead of contain a turtle:

from random import choice, randint
from turtle import Screen, Turtle

COLORS = ['yellow', 'gold', 'orange', 'red', 'magenta', 'navy', 'blue', 'purple', 'cyan', 'brown', 'black', 'gray', 'white']

class MyTurtle(Turtle):
    def __init__(self, color):
        super().__init__()

        self.hideturtle()
        self.color(color)
        self.shape('turtle')
        self.penup()

        x = randint(-75, 75)
        y = randint(-75, 75)

        self.goto(x, y)
        self.onclick(self.on_turtle_clicked)
        self.showturtle()

    def on_turtle_clicked(self, x, y):
        self.goto(95, -122)
        print("yes")


screen = Screen()
screen.bgcolor('lightgreen')

print("Welcome! This pond is infested with turtles! Can you catch all the turtles?")

turtles = [MyTurtle(choice(COLORS)) for _ in range(5)]

screen.mainloop()
cdlane
  • 40,441
  • 5
  • 32
  • 81
0

I would suggest doing this using Object Oriented Programming, because it will probably be significantly easier than doing it procedurally. It should be possible to do it procedurally, but tedious.

An Object Oriented example:

import turtle
import random

# Create MyTurtle class
class MyTurtle:
    def __init__(self, colour):
        self.t = turtle.Turtle()
        self.t.color(colour)
        self.t.shape("turtle")
        self.t.penup()
        self.t.hideturtle()
        r = random.randint(-75,75)
        r2 = random.randint(-75,75)
        r3 = random.randint(1,10)
        self.t.goto(r,r2)
        self.t.onclick(self.on_turtle_clicked)
        self.t.showturtle()

    def on_turtle_clicked(self, x, y):
        self.t.goto(95, -122)
        print("yes")


s = turtle.Screen()
s.bgcolor("lightgreen")

colours = ['yellow', 'gold', 'orange', 'red', 'magenta', 'navy', 'blue', 'purple', 'cyan', 'brown', 'black', 'gray', 'white']

print("Welcome! this pond is infested with turtles! Can you catch all the turtles?")

turtles = []
for x in range(0, 5):
    turtles.append(MyTurtle(random.choice(colours)))

Here is a tutorial for Object Oriented Programming in Python if you need it. https://realpython.com/python3-object-oriented-programming/

Hope that helps!

Nathcat
  • 120
  • 6
  • The line `self.t.color(random.choice(c))` causes an `"NameError: name 'c' is not defined"` as `c` no longer exists in your updated code. Also the color was determined externally and passed into the `__init__` method. – cdlane Apr 05 '22 at 15:34
  • Sorry, my mistake, this should be okay now – Nathcat Apr 05 '22 at 16:18