How do I make a dot disappear after being eaten? - python

I am attempting to program a python game using turtle-graphics, and I've run into some obstacles. When I run my code it allows me to direct the turtle around, then a whole bunch of dots start appearing, and then it has recursion depth error.
The section of code that I am having issues with is this:
def move():
colormode(255)
global turtle
global moving
x = randomColor()
if moving:
for i in range(1):
turtle.penup()
turtle.shape('turtle')
turtle.shapesize(.5, .5, .5)
turtle.color(x)
turtle.forward(5)
ontimer(move, 10 // FRAMES_PER_SECOND)
x = randrange(-250, 250)
y = randrange(-250, 250)
pen1 = Pen()
pen1.hideturtle()
pen1.penup()
pen1.goto(x, y)
pen1.dot(10, "red")
if turtle.pos() == pen1.pos():
pen1.clear()
pen1.goto(x, y)
How can I fix this? I want the dot to disappear when the turtle goes over it, and then a new random dot to generate, only one dot at a time.

you should:
Draw red point once on start and save the coordination.
After each move check the turtle position with your last_point (x,y).
If same, draw a dot in the same position with color of background(white I think).
3.1. Then create new random x,y and redraw the red dot.

The way I'd go about this is to define a second turtle with the shape and color of the food. Then stamp that turtle to generate food, keeping the result of the stamp() call so you can call clearstamp(stamp) on it later. I've set such up below with lots of food which the turtle chases down until they're all gone:
from turtle import Turtle, Screen
from random import randrange
WIDTH, HEIGHT = 500, 500
FRAMES_PER_SECOND = 24
TARGET_SIZE = 10
POSITION, STAMP = 0, 1
def move():
global meal
x, y = meal[POSITION]
tx, ty = turtle.position()
if x - TARGET_SIZE // 2 < tx < x + TARGET_SIZE // 2 and y - TARGET_SIZE // 2 < ty < y + TARGET_SIZE // 2:
food.clearstamp(meal[STAMP])
if meals:
meal = meals.pop()
else:
meal = None
if meal:
turtle.setheading(turtle.towards(meal[POSITION]))
turtle.forward(turtle.speed())
screen.ontimer(move, 1000 // FRAMES_PER_SECOND)
screen = Screen()
screen.setup(int(WIDTH * 1.1), int(HEIGHT * 1.1)) # size window but leave a border
turtle = Turtle(shape='turtle')
turtle.speed("fast")
turtle.penup()
food = Turtle(shape="circle", visible=False)
food.shapesize(0.5, 0.5)
food.color("red")
food.penup()
meals = []
for _ in range(10):
x = randrange(-WIDTH // 2, WIDTH // 2)
y = randrange(-HEIGHT // 2, HEIGHT // 2)
food.goto(x, y)
meals.append(((x, y), food.stamp()))
meal = meals.pop()
screen.ontimer(move, 1000 // FRAMES_PER_SECOND)
screen.exitonclick()
This turtle just chase a random bit of food, you can modify the code to make him go after the nearest food (as you have the list of meals with their positions) or take control of the turtle yourself.

Do:
(name).up()
(name).forward(10000)

Related

Trying to make two turtles move randomly in a square and saying when they're close to each other

So my assignement is to:
make a blue rectangle
write a function that makes the turle move in a random direction within an interval of 90 degrees and move forward in a random interval of 0-25
create a blue square
Move the turle to a random point in the square
Code so the turtle moves back inside the square if it leaves it
Create an additonal turle (both should have different colors)
Use the same statement to move both turtles (with the move_random function) 500 times
if the turtles are closer than 50 units - print a string that counts the number of times they are 50 units close.
This is what it should look like:
enter image description here
I've added some comments to explain my thought process
Any and all help is appreciated
The code:
EDIT: fixed the indentations, now i get the error message on the last line that the name "meet" is not defined. Also if i run the code without the last line which is supposed to print the amount of close encounters, nothing happens, no errors, but no turtles either.
import turtle
import random
#makes the jump function
def jump(t, x, y):
t.penup()
t.goto(x, y)
t.pendown()
#creares a turtle at a defined place
def make_turtle(x, y):
t = turtle.Turtle()
jump(t, x, y) # Use of the function defined above
return t
#function to create a rectangle and fill it with a color
def rectangle(x, y, width, height, color):
t = make_turtle(x, y)
t.speed(0)
t.hideturtle()
t.fillcolor(color)
t.begin_fill()
for dist in [width, height, width, height]:
t.forward(dist)
t.left(90)
t.end_fill()
#function to move turtle in a random heading (90 degree interval) between 0--25 units forward
#While also making it turn around if it is outside of the square
def move_random(t):
if abs(t.pos()[0]) >= 250 or abs(t.pos()[1]) >= 250:
target = (0, 0)
d = (0,0)
t.setheading(d)
else:
ini = t.heading()
new = rd.randint(ini - 45, ini + 45)
t.setheading(new)
t.forward(rd.randint(0, 25))
#creates the square and both turtles
t = make_turtle(0 , 0)
t.color("green")
t2 = make_turtle(0 , 0)
t2.color("black")
rectangle(-250, -250, 500, 500, "lightblue")
jump(t, rd.randint(-250, 250), rd.randint(-250, 250))
jump(t2, rd.randint(-250, 250), rd.randint(-250, 250)) #jumps the turles randomly in the square
meet = 0
for i in range(1, 501): #makes the turtles move randomly as specified above
move_random(t)
move_random(t2)
if t.distance(t2) < 50:
t.write("close")
meet += 1
print(str(meet), "close encounter") #prints the amount of times they are close to each other
if abs(t.pos()[0]) >= 250 or abs(t.pos()[1]) >= 250:
target = (0, 0)
d = (0,0)
t.setheading(d)
else:
See that function before the "else:"? You missed a tab there.

Turning simple polygons about a point in Python Turtle

I need help turning polygon shapes (triangle and square) in Python turtle to match a picture.
Below I am trying to copy the image.
I specifically need help on what to add to my code given the triangle and square to have them repeat outwards like the picture. Because as of now the triangles and squares look like this (pentagon code is correct and works) All help is appreciated. Thank you.
import turtle
def polygon(turtle, side, length):
turtle.color("Blue")
for i in range(4):
turtle.backward(length)
turtle.left(side)
def polygon1(turtle, side1, length):
turtle.color("Green")
for i in range(3):
turtle.left(side1)
turtle.forward(length)
def polygon2(turtle, side2, length):
turtle.color("Red")
for i in range(5):
turtle.forward(length)
turtle.left(side2)
def main():
my_turtle = turtle.Turtle()
wn = turtle.Screen()
Bill = turtle.Turtle()
length = 100
side = 90
side1 = 120
side2 = 72
Bill.pensize(5)
Bill.speed(0)
#Pentagons
Bill.pu()
Bill.right(180)
y = -45
for i in range(5):
Bill.pu()
Bill.goto(60, y)
Bill.pd()
polygon2(Bill, side2, length)
y -= 20
#Triangle
Bill.pu()
Bill.left(240)
x = 45
for j in range(5):
Bill.pu()
Bill.goto(10, x)
Bill.pd()
polygon1(Bill, side1, length)
x += 20
#Square
Bill.pu()
Bill.left(240)
b = 6
for b in range(5):
Bill.pu()
Bill.goto(148, b)
Bill.pd()
polygon(Bill, side, length)
b -= 20
wn.exitonclick()
if __name__ == '__main__':
main()
pentagon code is correct and works
I don't believe the pentagon code is correct nor that you're approaching this in the correct way. The inner three shapes should form an equilateral triangle -- yours don't as you're eyeballing instead of calculating. Instead of trying to get the turtle to be in the right spot, why not have the turtle move forward in the direction of the sides of this central triangle, drawing polygons as it goes.
That is, embrace the drawing as a whole rather than trying to divide and conquer.
We'd need to make sure the polygon drawing code restores the turtle's state when it's done, so it can simply move forward to the next polygon. We'll need to make explicit which numbers are arbitrary, and which are calculable. Although the original diagram appears to use at least three turtles to achieve it's result, we'll do it with one as you attempted:
from turtle import Turtle, Screen
SHAPES = [(5, "Red"), (3, "Green"), (4, "Blue")]
LENGTH = 100
DELTA = 20
REPLICATIONS = 5
THICKNESS = 5
HEIGHT = (3 ** 0.5 / 2) * LENGTH # assumes 3 shapes, should fix!
DIVISIONS = 360 / len(SHAPES)
def polygon(turtle, sides, color):
turtle.color(color)
turtle.left(90)
turtle.forward(LENGTH / 2)
for _ in range(sides):
turtle.right(360 / sides)
turtle.forward(LENGTH)
turtle.backward(LENGTH / 2) # restore turtle to original state
turtle.right(90)
wn = Screen()
bill = Turtle()
bill.speed('fastest')
bill.pensize(THICKNESS)
bill.penup()
for offset, (sides, color) in enumerate(SHAPES):
bill.setheading(-DIVISIONS * offset - 90)
bill.forward(HEIGHT / 3) # assumes 3 shapes, should fix!
for _ in range(REPLICATIONS):
bill.pendown()
polygon(bill, sides, color)
bill.penup()
bill.forward(DELTA)
bill.home()
wn.exitonclick()

Having trouble with turtles

I am having an issue with turtles.
This is the code so far:
'''
Levi Davis
This program demonstrates my knowledge on turtles based on problem one in the
third set of homework questions
'''
import turtle
import math
def draw_arc(t, angle, num_segments, length):
'''
draws an arc with turtle 't' that has a number of segments equal to 'num_segments'
and a length equal to 'length' with a turn angle of 'angle' divided by 'num_segments'
'''
#this is my calculations on the actual turning of the turtle
turn_angle = angle // num_segments
init_turn = ((num_segments - 1) * turn_angle) // 2
#the initial turn of the turtle and the loop to make the arc
t.right(init_turn)
for count in range(num_segments):
t.forward(length/num_segments)
t.left(turn_angle)
#undoing the final turn and the initial turn
t.right(turn_angle + init_turn)
def draw_squiggle(t, angle, num_segments, length, num_squiggles):
'''
This function utilizes draw_arc() to create a squiggly line
'''
for x in range(num_squiggles):
draw_arc(t, angle, num_segments, length)
draw_arc(t, -(angle), num_segments, length)
def draw_petal(t, angle, num_segments, length):
'''
draws a filled in petal shape using 2 arcs and a 180 degree turn
'''
t.begin_fill()
draw_arc(t, angle, num_segments, length)
t.left(180)
draw_arc(t, angle, num_segments, length)
t.left(180)
t.end_fill()
def draw_leaf(t, angle, num_segments, length):
draw_petal(t, angle, num_segments, length)
t.fillcolor(t.pencolor())
draw_petal(t, angle, num_segments, (length / 2))
wn = turtle.Screen()
bob = turtle.Turtle()
bob.pencolor("tomato2")
bob.pensize(5)
bob.fillcolor("black")
#Because clare told me to I made her into a turtle
clare = turtle.Turtle()
clarepen = "green"
clarefill = "purple"
clare.pencolor(clarepen)
clare.pensize(3)
clare.fillcolor(clarefill)
#testing of functions
#draw_arc(bob, 100, 10, 10)
#draw_arc(bob, -100, 10, 10)
#draw_squiggle(bob, -100, 10, 10, 2)
#draw_petal(clare, 100, 10, 40)
#draw_leaf(clare, 100, 10, 40)
#that one shape that is kind of trippy to look at... I think?...
size = 80
def draw_weird_shape(t1, t2):
startx = -size / 2
starty = -size / 2 * math.tan(math.radians(144 /2))
t1.up()
t1.goto(startx, starty)
t1.down()
t2.up()
t2.goto(startx, starty)
t2.down()
t1_fill = "purple"
t1_pen = "green"
for count in range(10):
t1.forward(size/2)
t1.right(90)
draw_squiggle(t1, 50, 10, 20, 2)
draw_leaf(t1, 50, 10, 50)
t1.pencolor(t1_pen)
t1.fillcolor(t1_fill)
t1.right(180)
draw_squiggle(t1, 50, 10, 20, 2)
t1.right(90)
t1.forward(size/2)
t1.left(36)
t2.up()
t2.forward(size)
t2.left(18)
t2.right(90)
t2.down()
draw_petal(t2, 50, 5, 25)
t2.up()
t2.left(108)
draw_weird_shape(clare, bob)
'''
clare.forward(20)
clare.left(18)
clare.right(90)
clare.forward(20)
clare.left(180)
clare.forward(20)
clare.right(90)
clare.forward(20)
'''
wn.exitonclick()
The problem appears to be around line 100.
When the squiggle starts to go back it does not go back in the 180 degree turn like it should.
When the squiggle starts to go back it does not go back in the 180
degree turn like it should.
Your problem is this code:
#this is my calculations on the actual turning of the turtle
turn_angle = angle // num_segments
init_turn = ((num_segments - 1) * turn_angle) // 2
By using integer division, //, you introduce just enough error that the arc code underlying the squiggle doesn't retrace the same path. Instead use floating point division, /, to keep it slightly more accurate:
# this is my calculations on the actual turning of the turtle
turn_angle = angle / num_segments
init_turn = ((num_segments - 1) * turn_angle) / 2

How to initialize multiple turtles in Python with classes

I am a beginner at Python and I'm new to Stack Exchange. I'm trying to write a program that has 5 turtles moving within a square. I've got code that does what I want, but it's tedious and I'd like to initialize all my turtles using classes instead of doing it one by one. I just want them to start out at random coordinates and with a random heading.
The problems with my code:
Only one turtle is shown on screen. Two are defined in the code below.
The turtle's heading and coordinates aren't being initialized.
Here's the code that I've tried:
import numpy as np
from turtle import *
# setting up screen
reset()
screensize(550)
Screen().bgcolor('black')
tracer(0)
# drawing box
t0 = Turtle()
t0.penup()
t0.goto(-256,-256)
t0.color('cyan')
t0.pendown()
for i in range(4):
t0.forward(512)
t0.left(90)
t0.ht()
# parameters
velocity = 5
iterations = 200
boxsize = 512
ranheader = np.random.random()*360
ranx = np.random.random()*boxsize
rany = np.random.random()*boxsize
class turtle_agents(Turtle):
def _init_(self):
self.up()
self.seth(ranheader)
self.setpos(ranx,rany)
self.velocity = velocity
self.down()
# turtle
t1 = turtle_agents()
t1.color('green')
t2 = turtle_agents()
t2.color('blue')
# turtle movement
for turtle in turtles():
for i in range(iterations):
turtle.forward(velocity)
if turtle.xcor() >= 256:
turtle.goto(-256,t0.ycor())
elif turtle.xcor() <= -256:
turtle.goto(256,t0.ycor())
elif turtle.ycor() >= 256:
turtle.goto(t0.xcor(),-256)
elif turtle.ycor() <= -256:
turtle.goto(t0.xcor(),256)
update()
exitonclick()
only one turtle shown on screen. Two are defined in the code below.
the turtle's heading and coordinates aren't being initialized.
I believe the problem is that you defined the random position and heading once, outside the turtle creation loop so they all start in the same place, move in the same direction at the same speed. I.e. they're right on top of each other.
We don't need #BlivetWidget's explicit List to fix the problem since, as you discovered, turtles are already maintained in a list which we can get via the screen's turtles() method. Below is my rework of your code to fix various issues:
from turtle import Screen, Turtle
from random import randrange, randint
# parameters
COLORS = ['green', 'blue', 'red', 'orange', 'white']
ITERATIONS = 500
VELOCITY = 5
BOX_SIZE = 512
# setting up screen
screen = Screen()
screen.setup(BOX_SIZE + 50, BOX_SIZE + 50)
screen.bgcolor('black')
screen.tracer(False)
# drawing box
turtle = Turtle()
turtle.hideturtle()
turtle.color('cyan')
turtle.penup()
turtle.goto(-BOX_SIZE/2, -BOX_SIZE/2)
turtle.pendown()
for _ in range(4):
turtle.forward(BOX_SIZE)
turtle.left(90)
# turtle
for color in COLORS:
angle = randrange(360)
x = randint(-BOX_SIZE/2, BOX_SIZE/2)
y = randint(-BOX_SIZE/2, BOX_SIZE/2)
turtle = Turtle()
turtle.color(color)
turtle.setheading(angle)
turtle.penup()
turtle.setposition(x, y)
turtle.pendown()
# turtle movement
for _ in range(ITERATIONS):
for turtle in screen.turtles():
turtle.forward(VELOCITY)
x, y = turtle.position()
if x >= BOX_SIZE/2:
turtle.penup()
turtle.setx(-BOX_SIZE/2)
turtle.pendown()
elif x <= -BOX_SIZE/2:
turtle.penup()
turtle.setx(BOX_SIZE/2)
turtle.pendown()
elif y >= BOX_SIZE/2:
turtle.penup()
turtle.sety(-BOX_SIZE/2)
turtle.pendown()
elif y <= -BOX_SIZE/2:
turtle.penup()
turtle.sety(BOX_SIZE/2)
turtle.pendown()
screen.update()
screen.exitonclick()
I agree with #BlivetWidget that "you don't need to create a class just to move them to your starting positions". I use a simple loop above.
You should consider storing your turtles in a list, as the turtles are already objects and you don't need to create a class just to move them to your starting positions. Lists in Python are incredibly powerful because they can store arbitrary data types. Here, I will create 5 turtles and move them so you can tell them apart:
import turtle
num_turtles = 5
my_turtles = [turtle.Turtle() for i in range(num_turtles)]
for i, turt in enumerate(my_turtles):
turt.forward(50 * i)
You want to do the same thing, just replace my turt.forward() line with whatever you want the turtles to do. In your case, go to a random position within your square.

Spirograph Turtle Python

How can I play with a turtle and how can I use a turtle?
I have trouble getting the thing to work as in the picture shown below (ignore the colors).
from turtle import *
from math import *
def formulaX(R, r, p, t):
x = (R-r)*cos(t) - (r + p)*cos((R-r)/r*t)
def formulaY(R, r, p, t):
y = (R-r)*sin(t) - (r + p)*sin((R-r)/r*t)
def t_iterating(R, r, p):
t = 2*pi
up()
goto(formulaX, formulaY)
down()
while (True):
t = t + 0.01
formulaX(R, r, p, t)
formulaY(R, r, p, t)
def main():
R = int(input("The radius of the fixed circle: "))
r = int(input("The radius of the moving circle: "))
p = int(input("The offset of the pen point, between <10 - 100>: "))
if p < 10 or p > 100:
input("Incorrect value for p!")
t_iterating(R, r, p)
input("Hit enter to close...")
main()'
I am trying to make that kind of shape. Here is the coding I have done so far.
Try changing your t_iterating function to this:
def t_iterating(R, r, p):
t = 2*pi # It seems odd to me to start from 2*pi rather than 0.
down()
while t < 20*pi: # This loops while t goes from 2*pi to 20*pi.
t = t+0.01
goto(formulaX(R, r, p, t), formulaY(R, r, p, t))
up()
No! You're missing the point of the turtle! You should try to do it all with relative movements of the turtle. Think about how you would draw the shape if you were the turtle, crawling on a large floor, dragging a paintbrush from your butt.
At each small fragment of time, the turtle will perform one small iteration of a differential equation which governs the whole behavior. It is not generally wise to precompute the x y coordinates and use the turtle's GOTO function.
The turtle itself should have only relative knowledge of its surroundings. It has a direction, and a position. And these two pieces of state are modified by turning and moving.
So, think about how you would draw the spiral. Particularly, think about drawing the very first circle. As the circle appears to close, something interesting happens: it misses. It misses by a tiny little amount, which turns out to be a fraction of a circle. It is this missing curvature that closes the large pattern of circles in a circle, as they add up to one complete turn.
When the whole figure is drawn, the turtle is back to its original position and orientation.
This is my code. The color may not be exact, but here it is:
from turtle import *
from random import randint
speed(10000)
for i in range(20):
col = randint(1, 5)
if col == 1:
pencolor("orange")
elif col == 2:
pencolor("blue")
elif col == 3:
pencolor("green")
elif col == 4:
pencolor("purple")
elif col == 5:
pencolor("dark blue")
circle(50)
left(20)
This is the output:
My code is here and the function was built for automatically choosing the random colour.
from turtle import Turtle, Screen
import random
timmy = Turtle()
screen = Screen()
screen.colormode(255)
timmy.shape("turtle")
timmy.speed("fastest")
angle = [0, 90, 180, 270]
def random_color():
red = random.randint(0, 255)
green = random.randint(0, 255)
blue = random.randint(0, 255)
colour = (red, green, blue)
return colour
def draw_circles(num_of_gap):
for _ in range(int(360 / num_of_gap)):
timmy.color(random_color())
timmy.circle(100)
timmy.right(num_of_gap)
draw_circles(20)
screen.exitonclick()
Spirograph using Python Turtle with random colours
Code:
import random
from turtle import Turtle, Screen
tim = Turtle()
tim.shape("classic")
def turtle_color():
R = random.random()
G = random.random()
B = random.random()
return tim.pencolor(R, G, B)
tim.speed("fastest")
for _ in range(72):
turtle_color()
tim.circle(100)
tim.left(5)
screen = Screen()
screen.exitonclick()
Output:
You basically get the turtle to loop through the 360 degrees and you can choose two pen colours.
from turtle import Turtle, Screen
tim = Turtle()
tim.shape("turtle")
tim.color("green")
### total degrees in circle = 360
### turn left must be a divisor of 360 (1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 18, 20, 24, 30, 36, 40, 45, 60, 72, 90) NOTE: some divisors do not work as well
degrees = 360
turn_left = 12
total_circles = int(degrees / turn_left)
tim.pensize(3)
tim.speed(0)
def circle_colour1():
### choose your colour here:
tim.pencolor("pink")
tim.circle(-100)
tim.left(turn_left)
def circle_colour2():
### choose your colour here:
tim.pencolor("grey")
tim.circle(-100)
tim.left(turn_left)
for _ in range(0, int(total_circles / 2)):
circle_colour1()
circle_colour2()
screen = Screen()
screen.exitonclick()
Real basic (360°/10) is:
from turtle import Turtle as d
draw = d()
draw.speed(0)
draw.pensize(3)
for _ in range(0, 36):
draw.circle(-100)
draw.left(10)

Categories

Resources