Draw Checkerboard on Python - python

I want to draw a checkerboard on Python, but I only get one black square.
Can you help me fix this program?
import turtle
def filled_square(size, color, x, y):
turtle.setpos(x, y)
turtle.color(color)
turtle.begin_fill()
for i in range(4):
angle = 90
turtle.fd(size)
turtle.lt(angle)
turtle.end_fill()
turtle.up()
import sys
n = int(sys.argv[1])
s = int(sys.argv[2])
square_size = s//n
y=0
for i in range(n):
x = 0
for j in range(n):
if (i+j)%2==0:
filled_square(square_size, "red", x, y)
else:
filled_square(square_size, "black", x, y)
x+=square_size
turtle.down()
turtle.done()

y=0
for i in range(n):
x = 0
for j in range(n):
if (i+j)%2==0:
filled_square(square_size, "red", x, y)
else:
filled_square(square_size, "black", x, y)
x+=square_size
Couple problems here.
There's not much point in increasing the value of x when you reset it right back to zero in the next iteration, so the initial assignment should be above the for loop.
you never update the value of y.
x = 0
for i in range(n):
y=0
for j in range(n):
if (i+j)%2==0:
filled_square(square_size, "red", x, y)
else:
filled_square(square_size, "black", x, y)
y+=square_size
x+=square_size
Now you should get the checkerboard shape you want.
Alternate solution: you can avoid the problem of bookkeeping the values of x and y by not having those values at all. You can derive the coordinates of the squares straight from i and j.
for i in range(n):
for j in range(n):
if (i+j)%2==0:
filled_square(square_size, "red", i*square_size, j*square_size)
else:
filled_square(square_size, "black", i*square_size, j*square_size)
It might also be nice to consolidate the common logic in your if and else blocks, and only differentiate the values that actually change (namely, the color)
for i in range(n):
for j in range(n):
if (i+j)%2==0:
color = "red"
else:
color = "black"
filled_square(square_size, color, i*square_size, j*square_size)

You need to increment both x and y. Also note that x should be incremented in the inner loop. Here is the working code,
import turtle
def filled_square(size, color, x, y):
turtle.setpos(x, y)
turtle.color(color)
turtle.begin_fill()
for i in range(4):
angle = 90
turtle.fd(size)
turtle.lt(angle)
turtle.end_fill()
turtle.up()
import sys
n = int(sys.argv[1])
s = int(sys.argv[2])
square_size = s//n
y=0
for i in range(n):
x = 0
for j in range(n):
if (i+j)%2==0:
filled_square(square_size, "red", x, y)
else:
filled_square(square_size, "black", x, y)
x+=square_size
y+=square_size
turtle.down()
turtle.done()

I recommend using functional programming like this for board/game work. It'll make everything easier to maintain and make implementing new features easier.
import turtle
def filled_square(size, color, x, y):
turtle.up()
turtle.setpos(x, y)
turtle.color(color)
turtle.begin_fill()
for i in range(4):
angle = 90
turtle.fd(size)
turtle.lt(angle)
turtle.end_fill()
def board(length, size, x_pos=0, y_pos=0):
for y in range(length):
for x in range(length):
if (x+y)%2==0:
filled_square(
size, "red", (x * square_size) - x_pos, (y * square_size) - y_pos)
else:
filled_square(
size, "black", (x * square_size) - x_pos, (y * square_size) - y_pos)
turtle.done()
Keyword arguments are great too. If you decided you wanted to add more colors, it is as easy as adding an two parameters,
def board(length, size, x_pos=0, y_pos=0, color1="red", color2="black"):
for y in range(length):
for x in range(length):
if (x+y)%2==0:
filled_square(
size, color1, (x * square_size) - x_pos, (y * square_size) - y_pos)
else:
filled_square(
size, color2, (x * square_size) - x_pos, (y * square_size) - y_pos)

Related

Having trouble making the Sierpinski Carpet using recursion only and python turtle

import turtle
window = turtle.Screen()
window.screensize(1920,1080)
window.setup(width=1.0, height=1.0, startx=None, starty=None)
# T is a global variable
T = turtle.Turtle()
T.shape('turtle')
T.speed(2)
def forward_and_rotate(distance, degree, t):
t.forward(distance)
t.left(degree)
def draw_square_recursion(distance, t, sides_left=4):
t.pendown()
if sides_left == 0:
return
else:
forward_and_rotate(distance, 90, t)
draw_square_recursion(distance, t, sides_left-1)
t.penup()
def draw_filled_square(t, side_len, color='black'):
current_color = T.pencolor()
t.pendown()
t.color(color)
t.begin_fill()
draw_square_recursion(side_len, t, 4)
t.end_fill()
t.penup()
T.color(current_color)
# Starter code
def sier_carp(t, l, n):
if n == 0:
home = t.pos()
t.goto(home + (l/3, l/3))
draw_filled_square(t, l/3)
t.goto(home)
else:
sier_carp(t, l/3, n - 1)
t.fd(l/3)
sier_carp(t, l/3, n -1)
t.fd(l/3)
sier_carp(t, l/3, n -1)
t.fd(l/3)
t.left(90)
t.fd(l/3)
sier_carp(t, l/3, n - 1)
t.fd(l/3)
sier_carp(t, l/3, n -1)
t.fd(l/3)
t.left(90)
t.fd(l/3)
sier_carp(t, l/3, n - 1)
t.fd(l/3)
sier_carp(t, l/3, n -1)
t.fd(l/3)
t.left(90)
t.fd(l/3)
sier_carp(t, l/3, n - 1)
t.fd(l/3)
sier_carp(t, l/3, n -1)
t.fd(l/3)
t.left(90)
t.fd(l/3)
# add more cases!
T.penup()
sl = 200
draw_square_recursion(sl, T, 4)
sier_carp(T, sl, 1)
I'm having a hard time drawing the Sierpinski carpet using recursion only and no loops. However after the first three squares are drawn and I try to rotate to the left and do the next 2 squares on the nest site, the squares go out of line. If you want you can try out this code and see how it looks like. Btw the color are inversed to white around and black inside and not the usual carpet version of black around and white square.
I'm going to do a simplied version of your code -- although repetitive, your starter code does achieve your goal of recursion only. However, I'm going to use stamping instead of drawing so we can focus on the recursive image and not the mechanics of drawing squares with turtles:
from turtle import Screen, Turtle
SIDE_LENGTH = 200
CURSOR_SIZE = 20
def draw_filled_square(t, side_len):
t.shapesize(side_len / CURSOR_SIZE)
t.stamp()
def sier_carp(t, l, n):
draw_filled_square(t, l)
if n < 1:
return
x, y = t.position()
t.setx(x + l)
sier_carp(t, l/3, n - 1)
t.sety(y + l)
sier_carp(t, l/3, n - 1)
t.setx(x)
sier_carp(t, l/3, n - 1)
t.setx(x - l)
sier_carp(t, l/3, n - 1)
t.sety(y)
sier_carp(t, l/3, n - 1)
t.sety(y - l)
sier_carp(t, l/3, n - 1)
t.setx(x)
sier_carp(t, l/3, n - 1)
t.setx(x + l)
sier_carp(t, l/3, n - 1)
t.goto(x, y)
screen = Screen()
screen.setup(width=1.0, height=1.0)
turtle = Turtle()
turtle.hideturtle()
turtle.shape('square')
turtle.penup()
sier_carp(turtle, SIDE_LENGTH, 4)
screen.exitonclick()
I intentionally avoided speeding things up with screen.tracer(False) as you should see how it's drawn in a counterclockwise pattern.
I believe the problem is simpler than you're making it. It's important in this sort of drawing that your recursive function return the turtle to where it was when the function started. This allows the caller to make valid assumptions about its position.
Here are the concepts I've noted before starting:
Define a function that takes in a coordinate and a square size, and return the 8 surrounding coordinates.
Define a function that takes in a coordinate and a square size, and draw a square with the given size as its length, and the given coordinate as its center point.
Define the main function that will take in a coordinate, a size and the number of recursions. The coordinate will be the center of the Sierpinski Carpet and the size will be the size of the finished Sierpinski Carpet.
With the above notes in mind, let's begin to construct our program:
Import the turtle module, turn off tracer (optional) for efficiency and hide the turtle cursor:
import turtle
turtle.tracer(0)
turtle.hideturtle()
Define the function that takes in coordinate and a unit, and return a list of all 8 coordinates surrounding the given coordinate:
def surrounding(cor, size):
x, y = cor
return [(x - size, y + size),
(x + size, y + size),
(x - size, y - size),
(x + size, y - size),
(x - size, y),
(x + size, y),
(x, y + size),
(x, y - size)]
Define a recursive function that will take in a coordinate, size and a count. It will draw a square with its center at the given coordinate and its size one third of the given size, so that the sides of the finished carpet will end up the given size. The count is there to tell the function when to stop recursing; when the count reaches 0:
def draw_square(cor, size, count):
size /= 3
count -= 1
turtle.penup()
turtle.goto(cor[0] - size / 2, cor[1] + size / 2)
turtle.pendown()
turtle.begin_fill()
turtle.forward(size)
turtle.right(90)
turtle.forward(size)
turtle.right(90)
turtle.forward(size)
turtle.right(90)
turtle.forward(size)
turtle.right(90)
turtle.end_fill()
if count:
func(surrounding(cor, size), size, count)
Define a recursive function that takes in a coordinate and a size. It will use the surroundings function defined earlier to convert that coordinate into a list of surround coordinates. Then, it will use the draw_square function defined earlier to draw a square at each of the surrounding coordinates:
def func(cors, size, count):
if len(cors) == 2:
draw_square(cors, size, count)
else:
draw_square(cors[0], size, count)
draw_square(cors[1], size, count)
draw_square(cors[2], size, count)
draw_square(cors[3], size, count)
draw_square(cors[4], size, count)
draw_square(cors[5], size, count)
draw_square(cors[6], size, count)
draw_square(cors[7], size, count)
Finally, call the main function, func, and update the turtle screen (if tracer was set to 0).
func((0, 0), 600, 5)
turtle.update()
Altogether:
import turtle
turtle.tracer(0)
turtle.hideturtle()
def surrounding(cor, size):
x, y = cor
return [(x - size, y + size),
(x + size, y + size),
(x - size, y - size),
(x + size, y - size),
(x - size, y),
(x + size, y),
(x, y + size),
(x, y - size)]
def draw_square(cor, size, count):
size /= 3
count -= 1
turtle.penup()
turtle.goto(cor[0] - size / 2, cor[1] + size / 2)
turtle.pendown()
turtle.begin_fill()
turtle.forward(size)
turtle.right(90)
turtle.forward(size)
turtle.right(90)
turtle.forward(size)
turtle.right(90)
turtle.forward(size)
turtle.right(90)
turtle.end_fill()
if count:
func(surrounding(cor, size), size, count)
def func(cors, size, count):
if len(cors) == 2:
draw_square(cors, size, count)
else:
draw_square(cors[0], size, count)
draw_square(cors[1], size, count)
draw_square(cors[2], size, count)
draw_square(cors[3], size, count)
draw_square(cors[4], size, count)
draw_square(cors[5], size, count)
draw_square(cors[6], size, count)
draw_square(cors[7], size, count)
func((0, 0), 600, 5)
turtle.update()
Output:

Drawing radiating circular trapezoid pattern with Turtle

I was just wondering how to draw some trapezoids in my turtle code.
I want my output to be like this:
What my output is right now:
Here's the code I've written so far:
import turtle as trtl
num_sides = 6
side_length = 15
circumradius = side_length
trtl.pencolor((245, 176, 66))
trtl.pensize(8)
for move_turtle in range(1):
trtl.penup()
trtl.sety(-circumradius)
trtl.pendown()
trtl.circle(circumradius, steps = num_sides)
circumradius *= 2
side_length = side_length + 8
trtl.pensize(12)
for move_turtle in range(1):
trtl.pencolor((255, 83, 71))
trtl.penup()
trtl.sety(-circumradius)
trtl.pendown()
trtl.circle(circumradius, steps = num_sides)
circumradius *= 2
for move_turtle in range(1):
trtl.pencolor((247, 220, 67))
trtl.penup()
trtl.sety(-circumradius)
trtl.pendown()
trtl.circle(circumradius, steps = num_sides)
circumradius *= 2
trtl.hideturtle()
What techniques can I use to get the desired output?
The approach I often take when given patterns like this is to think about a slight-of-hand trick that can produce the result with less trouble than figuring out how to draw something potentially fussy like a trapezoid.
In this case, if you remove the white spaces, we have a "pie"-shaped circle of different solid colors radiating from the middle. If we can manage to solve that simpler problem, then we can draw white lines on top and wind up with the desired result.
The only trig we need is the angle-to-coordinates formula:
x = cos(radians(angle)) * radius
y = sin(radians(angle)) * radius
Using this, we can iterate over n points (with some rotational offset) along the circumference of a circle with a loop and fill in the colors to make a pie:
import math
import turtle
def draw_pie(t, r, n, colors, rot_offset=0.5):
for i in range(n + 1):
a = 360 / n * (i + rot_offset)
t.color(colors[i%len(colors)])
t.begin_fill()
t.goto(0, 0)
x = math.cos(math.radians(a)) * r
y = math.sin(math.radians(a)) * r
t.goto(x, y)
t.end_fill()
if __name__ == "__main__":
t = turtle.Turtle()
t.screen.setup(540, 540)
t.penup()
t.speed("fastest")
sides = 6
draw_pie(t, 450, sides, ["#dd2", "orange", "#d02"])
t.ht()
turtle.exitonclick()
Next, we need to draw a bunch of thick white lines with square corners. Unfortunately, turtle draws rounded edges by default which aren't suitable for our needs. There are many tricks for making square edges (stamping is a reasonable method). The approach I used here was writing a custom rectangle drawing function that takes advantage of turtle.distance and turtle.setheading(turtle.towards(x, y)) which lets me point to the next point along the circumference of the circle. The rest is just loops to compute angles and picking the right values.
Here's the code:
import math
import turtle
def draw_rect(t, x, y, xx, yy, width):
t.goto(x, y)
t.setheading(t.towards(xx, yy))
t.begin_fill()
for d in [t.distance(xx, yy), width] * 2:
t.forward(d)
t.left(90)
t.end_fill()
def draw_pie(t, r, n, colors, rot_offset=0.5):
for i in range(n + 1):
a = 360 / n * (i + rot_offset)
t.color(colors[i%len(colors)])
t.begin_fill()
t.goto(0, 0)
x = math.cos(math.radians(a)) * r
y = math.sin(math.radians(a)) * r
t.goto(x, y)
t.end_fill()
def draw_reg_polygon(t, r, n, thickness, rot_offset=0.5):
for i in range(n):
a = 360 / n * (i + rot_offset)
x = math.cos(math.radians(a)) * r
y = math.sin(math.radians(a)) * r
a = 360 / n * (1 + i + rot_offset)
xx = math.cos(math.radians(a)) * r
yy = math.sin(math.radians(a)) * r
draw_rect(t, x, y, xx, yy, thickness)
if __name__ == "__main__":
t = turtle.Turtle()
t.screen.setup(540, 540)
t.penup()
t.speed("fastest")
sides = 6
draw_pie(t, 450, sides, ["#dd2", "orange", "#d02"])
t.color("white")
for r in range(50, 500, 100):
draw_reg_polygon(t, r, sides, 45)
t.ht()
turtle.exitonclick()

Change my Python Turtle code for N columns and M rows

I have my code ready to show 3x3 equilateral triangles, but I don't know how to change it so N amount of equilateral triangles can be shown in a column (one triangle above another one) and M amount of equilateral triangles can be shown in a row (one triangle next to another one). Any help is much appreciated!
My code is:
import turtle
ara = turtle.Turtle() #name of the turtle
ara.speed(0)
ara.pensize(10)
def pile_left(t, l, n): #first column
t = l * 3 ** 0.5 / 2
for j in range(n):
if j == 0 : ara.fillcolor('red')
if j == 1 : ara.fillcolor('orange')
if j == 2 : ara.fillcolor('green')
ara.pu()
ara.shape('turtle')
ara.begin_fill()
for i in range(3):
ara.lt(120)
ara.fd(l)
ara.end_fill()
ara.sety(ara.ycor() + t)
pile_left(ara, 60, 3)
def pile_middle(t, l, n): #second column
t = l * 3 ** 0.5 / 2
ara.goto(60,0)
for j in range(n):
if j == 0 : ara.fillcolor('purple')
if j == 1 : ara.fillcolor('yellow')
if j == 2 : ara.fillcolor('peachpuff')
ara.pu()
ara.shape('turtle')
ara.begin_fill()
for i in range(3):
ara.lt(120)
ara.fd(l)
ara.end_fill()
ara.sety(ara.ycor() + t)
pile_middle(ara, 60, 3)
def pile_right(t, l, n): #third column
t = l * 3 ** 0.5 / 2
ara.goto(120,0)
for j in range(n):
if j == 0 : ara.fillcolor('grey')
if j == 1 : ara.fillcolor('brown')
if j == 2 : ara.fillcolor('blue')
ara.pu()
ara.shape('turtle')
ara.begin_fill()
for i in range(3):
ara.lt(120)
ara.fd(l)
ara.end_fill()
ara.sety(ara.ycor() + t)
pile_right(ara, 60, 3)
turtle.mainloop()
You can run it on trinket.io/python to see who it currently does.
I have my code ready to show 3x3 equilateral triangles
No, not really. You have your code ready to show 1x3 equilateral triangles, and you simply duplicated your code three times to emulate a second dimension. Your problem is that you can't duplicate your code M times to solve this problem.
The answer in this situation is less, but smarter, code. We're going to need nested loops for N and M, and the ability to move forward by length l for each M and vertically by height t for each N:
from turtle import Screen, Turtle
COLORS = ['red', 'orange', 'green', 'purple', 'yellow', 'pink', 'grey', 'brown', 'blue']
def pile(turtle, length, columns, rows):
height = length * 3 ** 0.5 / 2
x_origin = turtle.xcor()
color = 0
for _ in range(rows):
for _ in range(columns):
turtle.color(COLORS[color % len(COLORS)])
turtle.begin_fill()
for _ in range(3):
turtle.forward(length)
turtle.left(120)
turtle.end_fill()
turtle.forward(length)
color += 1
turtle.setposition(x_origin, turtle.ycor() + height)
screen = Screen()
yertle = Turtle('turtle')
yertle.speed('fastest')
yertle.penup()
pile(yertle, 60, 4, 5)
yertle.hideturtle()
screen.exitonclick()
However, this is a perfect example where stamping would be simpler than filling. We can make the turtle itself an equilateral triangle, then move it and stamp it:
from turtle import Screen, Turtle
COLORS = ['red', 'orange', 'green', 'purple', 'yellow', 'pink', 'grey', 'brown', 'blue']
CURSOR_SIZE = 20
def pile(turtle, length, columns, rows):
turtle.shapesize(length / CURSOR_SIZE)
height = length * 3 ** 0.5 / 2
y_origin = turtle.ycor()
color = 0
for _ in range(columns):
for _ in range(rows):
turtle.color(COLORS[color % len(COLORS)])
turtle.stamp()
turtle.forward(height)
color += 1
turtle.setposition(turtle.xcor() + length, y_origin)
screen = Screen()
yertle = Turtle('triangle')
yertle.speed('fastest')
yertle.setheading(90)
yertle.penup()
pile(yertle, 60, 4, 5)
yertle.hideturtle()
screen.exitonclick()
Not only simpler, but faster too!

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.

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