Random Turtle movement, bound in window - python

Created the program to randomize the movement of the turtle but cannot get it to break the loop once it touches a boundary (window). Tried a few solutions posted with similar questions but still no luck.
from turtle import Turtle, Screen
import random
def createTurtle(color, width):
tempName = Turtle("turtle")
tempName.speed("fastest")
tempName.color(color)
tempName.width(width)
return tempName
def inScreen(screen, turt):
min_x, max_x = -wn.window_width() / 2 , wn.window_width() / 2
min_y, max_y = -wn.window_height() / 2 , wn.window_height() / 2
turtleX, turtleY = turt.pos()
while (min_x < turtleX < max_x) and (min_y < turtleY < max_y):
turt.left(random.randrange(360))
turt.fd(random.randrange(100))
turtleX, turtleY = turt.pos()
print(turtleX, ",", turtleY)
wn = Screen()
alpha = createTurtle("red", 3)
inScreen(wn, alpha)
wn.exitonclick()

The variables turtleX and turtleY are being used in your while condition, but you never reevaluate them within the loop.
This is why your print function only ever outputs 0.0 , 0.0

Related

How to keep random walk scenario from going outside graphics window

I have created a random walk scenario where it takes one step in a random direction for a specific number of times. The one thing that I have run in to is that sometimes it will go off of the graphics window that I have set up and I can no longer see where it is at.
Here is the code:
from random import *
from graphics import *
from math import *
def walker():
win = GraphWin('Random Walk', 800, 800)
win.setCoords(-50, -50, 50, 50)
center = Point(0, 0)
x = center.getX()
y = center.getY()
while True:
try:
steps = int(input('How many steps do you want to take? (Positive integer only) '))
if steps > 0:
break
else:
print('Please enter a positive number')
except ValueError:
print('ERROR... Try again')
for i in range(steps):
angle = random() * 2 * pi
newX = x + cos(angle)
newY = y + sin(angle)
newpoint = Point(newX, newY).draw(win)
Line(Point(x, y), newpoint).draw(win)
x = newX
y = newY
walker()
My question is, Is there a way that I can set parameters on the graphics window so that the walker can not go outside the window? And if it tries to, it would just turn around and try another direction?
Try defining upper and lower bounds for x and y. Then use a while loop that keeps trying random points until the next one is in bounds.
from random import *
from graphics import *
from math import *
def walker():
win = GraphWin('Random Walk', 800, 800)
win.setCoords(-50, -50, 50, 50)
center = Point(0, 0)
x = center.getX()
y = center.getY()
while True:
try:
steps = int(input('How many steps do you want to take? (Positive integer only) '))
if steps > 0:
break
else:
print('Please enter a positive number')
except ValueError:
print('ERROR... Try again')
# set upper and lower bounds for next point
upper_X_bound = 50.0
lower_X_bound = -50.0
upper_Y_bound = 50.0
lower_Y_bound = -50.0
for i in range(steps):
point_drawn = 0 # initialize point not drawn yet
while point_drawn == 0: # do until point is drawn
drawpoint = 1 # assume in bounds
angle = random() * 2 * pi
newX = x + cos(angle)
newY = y + sin(angle)
if newX > upper_X_bound or newX < lower_X_bound:
drawpoint = 0 # do not draw, x out of bounds
if newY > upper_Y_bound or newY < lower_Y_bound:
drawpoint = 0 # do not draw, y out of bounds
if drawpoint == 1: # only draw points that are in bounds
newpoint = Point(newX, newY).draw(win)
Line(Point(x, y), newpoint).draw(win)
x = newX
y = newY
point_drawn = 1 # set this to exit while loop
walker()

Turtle Gradient Color (review code)

I am trying to use Turtle to print 30 hexagons that are spiralling and have a gradient color change from red to black.
I am multiplying my for loop i in order to change the set values in (r, b, g) so, at some point, it will exceed r=255. I include an if statement to have it not exceed this, but it's giving me the error:
File "<ipython-input-4-35d45ac44fdd>", line 20
if r > '255'
^
SyntaxError: invalid syntax
What is causing this error?
FYI I am using Anaconda and a Jupyter notebook.
Here is my code:
import turtle
def draw_hexagon (t, size):
n=6
angle= 360/n
for i in range(n):
t.forward(size)
t.left(angle)
turtle.colormode(255)
mega=turtle.Turtle()
mega.speed(1000)
leng = 100
for i in range(30):
r = 5+(i*10)
g = 0
b = 0
color = (r, b, g)
if r > 255
print color(r,b,g)
mega.fillcolor(color)
mega.begin_fill()
draw_hexagon(mega, leng)
mega.end_fill()
leng = leng + 5
mega.left(5)
turtle.exitonclick()
My advice is to not use the if statement to get around the error but rather fix your math to avoid it in the first place. Plus some code cleanup:
from turtle import Turtle, Screen
MIN_COLOR = 5
MAX_COLOR = 255
COUNT = 30
ANGLE = 5
STARTING_LENGTH = 100
LENGTH_INCREMENT = 5
N = 6
def draw_polygon(turtle, size):
angle = 360 / N
for _ in range(N):
turtle.forward(size)
turtle.left(angle)
screen = Screen()
screen.colormode(255)
mega = Turtle()
mega.speed('fastest')
length = STARTING_LENGTH
for r in range(COUNT):
red = round(r * ((MAX_COLOR - MIN_COLOR) / (COUNT - 1))) + MIN_COLOR
color = (red, 0, 0)
mega.fillcolor(color)
mega.begin_fill()
draw_polygon(mega, length)
mega.end_fill()
length += LENGTH_INCREMENT
mega.left(ANGLE)
mega.hideturtle()
screen.exitonclick()

make bouncing turtle with python

I am a beginner with python and I wrote this code to make bouncing ball with python turtle it works but have some errors like the ball disappearing
import turtle
turtle.shape("circle")
xdir = 1
x = 1
y = 1
ydir = 1
while True:
x = x + 3 * xdir
y = y + 3 * ydir
turtle.goto(x , y)
if x >= turtle.window_width():
xdir = -1
if x <= -turtle.window_width():
xdir = 1
if y >= turtle.window_height():
ydir = -1
if y <= -turtle.window_height():
ydir = 1
turtle.penup()
turtle.mainloop()
Although your approach to the problem works (my rework):
import turtle
turtle.shape("circle")
turtle.penup()
x, y = 0, 0
xdir, ydir = 3, 3
xlimit, ylimit = turtle.window_width() / 2, turtle.window_height() / 2
while True:
x = x + xdir
y = y + ydir
if not -xlimit < x < xlimit:
xdir = -xdir
if not -ylimit < y < ylimit:
ydir = -ydir
turtle.goto(x, y)
turtle.mainloop()
In the long run, it's the wrong approach to take. In this case, due to the infinite loop while True, the mainloop() method is never called so no other turtle event handlers are active. For example, if we wanted to use exitonclick() instead of mainloop(), it wouldn't work. Instead consider:
import turtle
turtle.shape("circle")
turtle.penup()
x, y = 0, 0
xdir, ydir = 3, 3
xlimit, ylimit = turtle.window_width() / 2, turtle.window_height() / 2
def move():
global x, y, xdir, ydir
x = x + xdir
y = y + ydir
if not -xlimit < x < xlimit:
xdir = -xdir
if not -ylimit < y < ylimit:
ydir = -ydir
turtle.goto(x, y)
turtle.ontimer(move, 5)
turtle.ontimer(move, 5)
turtle.exitonclick()
Here we've turned control back over to the mainloop and the motion is on an event timer. Other turtle events can execute so exitonclick() works. Just something to think about going forward before you program yourself, and your turtle, into a corner.
You need window_width()/2 and window_height()/2 to keep inside window.
ie.
if x >= turtle.window_width()/2:
xdir = -1
if x <= -turtle.window_width()/2:
xdir = 1
if y >= turtle.window_height()/2:
ydir = -1
if y <= -turtle.window_height()/2:
ydir = 1
You should put
turtle.penup()
Before the while loop to make your code better and a little bit faster. It is almost a bug!
You can bounce your wall, if you want to bounce it from upper wall, the screen width is 800 and length is 600
from turtle import turtle
turtle=Turtle()
def move(self)://This will move your ball in diagonal direction
x_dir=self.xcor()+self.x
y_dir=self.ycor()+self.y
self.goto(x_dir,y_dir)
def bounce(self)://This will bounce back
self.y *=-1
turtle.bounce()
This code is running because I did it with inheritance. You need to create a class then inherit all the properties and then create two methods there and then call those functions in the main class.

Python Turtle nested polygons/growing shapes

Basically we have to make this (20 units in between each polygon) using a function and a for loop:
But it has to work with any sided polygon with any side length. So far I have:
import turtle
tess = turtle.Turtle()
wn = turtle.Screen()
def draw_poly(t, n, sz):
"""
Makes Turtle t draw an n sided polygon of size sz
"""
for i in range(n):
t.forward(sz)
t.left(360/n)
sz = 20 #Length of sides
n = 4 #Number of sides
PosX = 0
PosY = 0
for i in range(5):
draw_poly(tess, n, sz)
tess.penup()
PosX = PosX - 20
PosY = PosY - 20
tess.goto(PosX,PosY)
sz = sz + 40
tess.pendown()
wn.mainloop()
My problem is that it only works with squares, and any other amount of sides/side length makes it off-center. How can I fix this?
You just need a bit of trigonometry. At the top of the script, add the line
from math import pi, tan
Then compute the new PosX, PosY as
PosX = PosX - 20
PosY = PosY - 20/tan(pi/n)

How can I fill each petal separately using begin_fill()?

I have the following code that generates a petal pattern for a flower I'm trying to build. However, the problem is the fill part.
What should happen is each petal to be filled individually:
Instead, what happens is this:
import turtle
import math
wn = turtle.Screen()
wn.bgcolor("white")
def draw_leaf(turtle, side, theta = 0):
angle = 2
turtle.color("#67bd3c")
for x in range(-180,180):
y = math.sin(math.radians(angle))
angle += 1
y = y * side
x_axis = (x % 180) * math.cos(math.radians(theta)) + y * math.sin(math.radians(theta))
y_axis = (x % 180) * (-1 * (math.sin(math.radians(theta)))) + y * math.cos(math.radians(theta))
turtle.goto(-1 * x_axis, -1 * y_axis)
return
def draw_flower(turtle, petals):
for x in range(petals):
theta = 180/(petals - 1)
turtle.pendown()
turtle.begin_fill()
draw_leaf(turtle, 35, theta * x)
turtle.end_fill()
turtle.penup()
turtle.left(theta)
return
draw_flower(turtle,4)
wn.exitonclick()
It looks like each draw_leaf call begins when the turtle is at the far end of the leaf that it just previously drew. So the polygon that is filled during the current draw_leaf includes that end point. This is more apparent if you draw each leaf with a different color.
One possible solution is to goto the center of the flower after your penup, before you draw the next leaf.
def draw_flower(turtle, petals):
start = turtle.pos()
for x in range(petals):
theta = 180/(petals - 1)
turtle.pendown()
turtle.begin_fill()
draw_leaf(turtle, 35, theta * x)
turtle.end_fill()
turtle.penup()
turtle.goto(*start)
turtle.left(theta)
return

Categories