├── LICENSE.txt ├── README.md ├── algorithms ├── sierpinskis_game │ └── sierpinskis_game.py └── ulam_spiral │ ├── ulam_as_text_full.png │ ├── ulam_as_text_prime_only.png │ ├── ulam_spiral.png │ ├── ulam_spiral.py │ └── ulam_spiral.txt ├── artwork └── mona_lisa │ ├── mona_lisa.png │ └── mona_lisa.py ├── fractals ├── hilbert_curve │ ├── hilbert_curve.png │ └── hilbert_curve.py ├── koch_snowflake │ ├── koch_snowflake.png │ └── koch_snowflake.py ├── nondet_tree.png ├── nonuniformtree.py ├── sierpinski_square │ ├── sierpinski_square.png │ └── sierpinski_square.py ├── sierpinski_triangle │ ├── sierpinski_triangle.png │ └── sierpinski_triangle.py ├── tree.png ├── tree.py ├── tree_images │ ├── tree1.png │ ├── tree10.png │ ├── tree11.png │ ├── tree12.png │ ├── tree13.png │ ├── tree14.png │ ├── tree15.png │ ├── tree16.png │ ├── tree17.png │ ├── tree18.png │ ├── tree19.png │ ├── tree2.png │ ├── tree20.png │ ├── tree3.png │ ├── tree4.png │ ├── tree5.png │ ├── tree6.png │ ├── tree7.png │ ├── tree8.png │ └── tree9.png └── tree_multiple.png ├── interactive ├── draw_snowflakes.png ├── draw_snowflakes.py ├── sierpinski_game.png └── sierpinski_game.py └── simple ├── polygons.png ├── polygons.py ├── pythons.png └── pythons.py /LICENSE.txt: -------------------------------------------------------------------------------- 1 | All content in this repo is copyright Al Sweigart 2015. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # art-of-turtle-programming 2 | Various turtle drawing programs in Python 3 | 4 | Some examples from this repo: 5 | 6 | ![Sierpinski triangle](https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/master/fractals/sierpinski_triangle/sierpinski_triangle.png) 7 | 8 | ![Fractal tree](https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/master/fractals/tree.png) 9 | 10 | ![Mona Lisa](https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/master/artwork/mona_lisa/mona_lisa.png) 11 | 12 | -------------------------------------------------------------------------------- /algorithms/sierpinskis_game/sierpinskis_game.py: -------------------------------------------------------------------------------- 1 | # Sierpinkski's Game, by Al Sweigart al@inventwithpython.com 2 | # Sierpinkski's "game" is an algorithm that draws Sierpinski's Triangle 3 | # with turtle graphics. 4 | # More info at https://en.wikipedia.org/wiki/Chaos_game 5 | 6 | import turtle 7 | import random, time 8 | turtle.tracer(60, 0) # Make the turtle draw faster. 9 | turtle.setworldcoordinates(0, 0, 960, 810) 10 | turtle.bgcolor(0.1, 0.1, 0.1) 11 | turtle.penup() 12 | 13 | DOT_SIZE = 3 14 | NUMBER_OF_DOTS = 1500 15 | 16 | def halfway(x1, y1, x2, y2): 17 | # Find the distance halfway between x1, y1 and x2, y2: 18 | if x1 > x2: 19 | halfwayx = int(abs(x1 - x2) / 2.0) + x2 20 | else: 21 | halfwayx = int(abs(x2 - x1) / 2.0) + x1 22 | 23 | if y1 > y2: 24 | halfwayy = int(abs(y1 - y2) / 2.0) + y2 25 | else: 26 | halfwayy = int(abs(y2 - y1) / 2.0) + y1 27 | 28 | return (halfwayx, halfwayy) 29 | 30 | 31 | def playSierpinskisGame(ax, ay, bx, by, cx, cy): 32 | # Start the point at ax, ay: 33 | px = ax 34 | py = ay 35 | 36 | # Draw dots: 37 | for i in range(NUMBER_OF_DOTS): 38 | # Pick a random triangle point to move towards: 39 | random_point = random.randint(1, 3) 40 | 41 | # Move halfway to that point: 42 | if random_point == 1: 43 | # Move halfway to point A: 44 | px, py = halfway(px, py, ax, ay) 45 | turtle.goto(px, py) 46 | turtle.dot(DOT_SIZE) # Mark the dot. 47 | elif random_point == 2: 48 | # Move halfway to point B: 49 | px, py = halfway(px, py, bx, by) 50 | turtle.goto(px, py) 51 | turtle.dot(DOT_SIZE) # Mark the dot. 52 | elif random_point == 3: 53 | # Move halfway to point C: 54 | px, py = halfway(px, py, cx, cy) 55 | turtle.goto(px, py) 56 | turtle.dot(DOT_SIZE) # Mark the dot. 57 | turtle.update() # Finish drawing the screen. 58 | 59 | 60 | while True: 61 | # Pick a random color to draw with: 62 | redAmount = random.randint(50, 100) / 100.0 63 | greenAmount = random.randint(50, 100) / 100.0 64 | blueAmount = random.randint(50, 100) / 100.0 65 | turtle.pencolor(redAmount, greenAmount, blueAmount) 66 | 67 | # Pick three random points for the triangle: 68 | ax = random.randint(0, 960) 69 | ay = random.randint(0, 810) 70 | bx = random.randint(0, 960) 71 | by = random.randint(0, 810) 72 | cx = random.randint(0, 960) 73 | cy = random.randint(0, 810) 74 | 75 | # Play Sierpinski's Game to draw Sierpinski's Triangle: 76 | playSierpinskisGame(ax, ay, bx, by, cx, cy) 77 | 78 | time.sleep(2) # Pause for two seconds before clearing the screen. 79 | turtle.clear() 80 | -------------------------------------------------------------------------------- /algorithms/ulam_spiral/ulam_as_text_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/algorithms/ulam_spiral/ulam_as_text_full.png -------------------------------------------------------------------------------- /algorithms/ulam_spiral/ulam_as_text_prime_only.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/algorithms/ulam_spiral/ulam_as_text_prime_only.png -------------------------------------------------------------------------------- /algorithms/ulam_spiral/ulam_spiral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/algorithms/ulam_spiral/ulam_spiral.png -------------------------------------------------------------------------------- /algorithms/ulam_spiral/ulam_spiral.py: -------------------------------------------------------------------------------- 1 | # Ulam Spiral, by Al Sweigart al@inventwithpython.com 2 | # The Ulam spiral is a mysterious mathematics pattern for prime numbers 3 | # with turtle graphics. 4 | # More info at https://en.wikipedia.org/wiki/Ulam_spiral 5 | 6 | import turtle 7 | import math 8 | 9 | turtle.tracer(1000, 0) # Make the turtle draw faster. 10 | 11 | SPACING = 3 12 | DOT_SIZE = 4 13 | 14 | turtle.bgcolor('#353337') # Use a dark background color. 15 | turtle.pencolor('#CCCCCC') # The spiral is a light gray color. 16 | 17 | def amountOfDivisors(number): 18 | # Return the number of divisors for `number`. 19 | total = 0 20 | for i in range(2, int(math.sqrt(number)) + 1): 21 | # If i evenly divides number with no remainder, increase total. 22 | if number % i == 0: 23 | total += 1 24 | return total 25 | 26 | # (!) Comment this next line to draw the spiral. 27 | turtle.penup() 28 | turtle.forward(SPACING) # 1 is not prime, so skip 29 | turtle.left(90) 30 | turtle.dot(DOT_SIZE) # 2 is prime, so make a dot 31 | turtle.forward(SPACING) 32 | turtle.left(90) 33 | 34 | currentNumber = 3 # This is the number we test for primality. 35 | spiralSideLength = 3 36 | while currentNumber < 40000: 37 | # We draw two sides before increasing the spiral side length: 38 | for i in range(2): 39 | for j in range(spiralSideLength): 40 | divs = amountOfDivisors(currentNumber) 41 | currentNumber += 1 42 | 43 | if divs == 0: 44 | # Mark the prime number 45 | turtle.dot(DOT_SIZE, '#76b7eb') 46 | turtle.forward(SPACING) 47 | turtle.left(90) 48 | spiralSideLength += 1 49 | 50 | turtle.update() # Finish drawing the screen. 51 | turtle.exitonclick() # When user clicks on the window, close it. 52 | -------------------------------------------------------------------------------- /algorithms/ulam_spiral/ulam_spiral.txt: -------------------------------------------------------------------------------- 1 | In 1963, during the presentation of, as he put it, a “long and very boring paper” at a scientific meeting, mathematician Stanislaw Ulam began doodling. He wrote out numbers in a square spiral pattern, and then highlighted the prime numbers. 2 | Prime numbers are the whole numbers that are only evenly divisible by 1 and themselves. 17 is a prime, because it can only be evenly divided by 1 or 17. 8 is not prime, since in addition to 1 and 8 it can also be evenly divided by 2 and 4. The Greek mathematician Euclid proved that there are an infinite number of primes in 300 BCE. But across thousands of years, mathematicians have been unable to come up with a formula for predicting which numbers will be prime or composite (that is, not prime). Many questions about prime numbers remain to this day. 3 | But there have been several tantalizing clues. Ulam noticed that his spiral marked primes as often fell along diagonal, vertical, and horizontal lines. But it is still impossible to precisely predict where a prime will appear. 4 | This program recreates a verison visualization of the Ulam Spiral that Ulam created on the MANIAC II computer at Los Alamos Scientific Laboratory with Myron Stein and Mark Wells. The blue dots mark composite (that is, not prime) numbers, with the size of the dot related to how many divisors the composite number has. 5 | -------------------------------------------------------------------------------- /artwork/mona_lisa/mona_lisa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/artwork/mona_lisa/mona_lisa.png -------------------------------------------------------------------------------- /artwork/mona_lisa/mona_lisa.py: -------------------------------------------------------------------------------- 1 | # Mona Lisa, by Al Sweigart al@inventwithpython.com 2 | # Draws an Andy Warhol-like drawing of the Mona Lisa with turtle 3 | # graphics. 4 | 5 | import turtle 6 | turtle.tracer(400, 0) # Make the turtle draw faster. 7 | 8 | """The image data for the Mona Lisa. I created this through a complicated 9 | process: I found a picture of the Mona Lisa online, converted it to 10 | grayscale in Photoshop, then greatly increased the contrast, then shrunk 11 | it down, and converted that image into a pure black/white image. I wrote 12 | a script using the Pillow module to turn the black/white pixel 13 | information in to a stream of 1s and 0s, and then turned that binary 14 | number into this hexadecimal number.""" 15 | monaLisaData = '0x54a9554ebaaab5555b776eeb56addebdb5db5b33fd9b6d5d6db55affcaeed576d559dd71576ab7a9a76ee32ceb59b556edd591df6b5aead5b265add256954aa52ad5aa55aa96ab55fd576d569d2b556affea992a955b4aa94effd4dd555496aa57f7feb45554a51534b9dfecb2aa36caa4a627ff14a49c254922d12ffd69345b54552c037f88a951423249a89ffe6905494892bc44bfda6689e74925a22bfd7125432a927800bff9d24bdeac83b5edfef6935fb7757fbbfff6d10adddd4ba9b5ffff4d5eeef37a913ff55255fabaff86aaffff92aafffd59103feafaadfb6fffc99fffe8ab5bff5ffc947ffffbdffd6f7f571ffffeeb6f7bfefe3d57eeffffffff77d9afbf7f5b7bbd7ffe5b7fff7efbff7fbff29fffafbffeffdebf97ffffdfedff6ffffdffffded7feffdd6fffffff7fd5fdb76ffedefffffffffffb7ff77fbb7dbbfef5b7feb57fdd6ddbf5efbdeb5bfffd6feeffdffe9afffdedefbb7fff8227fefafbfdfbefe5116bfcbbb7eeffde048fffe4dddfbbffca027ffbb6ff75f7fa090bf7fdd7bbabdfc0096fbee33ffdf7e2484ffbfbd1ddebff000170dffbef7fcfca910affffe9fb5ffe00897bffffdbdc7ff90017fffffefabffee805ffffeafefefefb757beefffb76ebf7fbfffffbffbf76ffbeedbfffffdffdbdffff7ffffffffffffffbbeff6bfefb76ffffdffffff7fbffb3fbfffffffbbfefd59efffdbefeffffbeafffffffffffffff7f7fefffffffffeedfbeffedfbffffffffeffffffbffeffffff7efdf7ffffffffff7fffefffffffffdfffeffffffbefffffbfbffdffffffff7bffff7ffffffffbfffffffbdfffbbdfffffffbdffebbffffffffffffff7efffffffffffff7feff5ffffff7f7ffbf76f05ffdffdfffff7bf892bffffffdfffffbe4a5fffffffefffffd50affffffffffffdf6a43fffffffffffffbb51f7fdfbfffffffd4baad57ffdfbfffd6b4f7ffffffffffff3ae7affffffffbff5be73f77effffeff7e8bbdffffffddffff5bfcefbf7ffffff7fd8def7fffefffffffeffffbfffffffffffb7fffffffffffffffefb77fffffffffffffffffffffffbffffffbfffffffffffffffffffffffffffffff7fffffffffffffffffffffff7ffffffffffffffffffffffff7ff7ffdfffffffeffffffffffffffffffffffff7fffffffffffffffffffffffffff' 16 | 17 | def drawFromData(image_data, image_width, image_height, left, top, pixel_size): 18 | turtle.penup() 19 | 20 | inBinary = bin(int(image_data, 16)) 21 | 22 | # Remove '0b' from the start of the hex number: 23 | inBinary = inBinary[2:] 24 | 25 | # Add leading zeros to the binary number, if needed: 26 | inBinary = inBinary.rjust(image_width * image_height, '0') 27 | 28 | for y in range(image_height): 29 | for x in range(image_width): 30 | turtle.goto(left + (x * pixel_size), top - (y * pixel_size)) 31 | 32 | if inBinary[y * image_width + x] == '1': # (!) Try switching this to '0'. 33 | turtle.begin_fill() 34 | turtle.setheading(0) 35 | turtle.forward(pixel_size) # draw top of the box 36 | turtle.right(90) 37 | turtle.forward(pixel_size) # draw right edge of the box 38 | turtle.right(90) 39 | turtle.forward(pixel_size) # draw bottom of the box 40 | turtle.right(90) 41 | turtle.forward(pixel_size) # draw left edge of the box 42 | turtle.end_fill() # fill in the box 43 | 44 | turtle.bgcolor('#FFF7D0') 45 | turtle.fillcolor('#FF0C6B') 46 | drawFromData(monaLisaData, 68, 100, -272, 400, 4) 47 | turtle.fillcolor('#CE18FF') 48 | drawFromData(monaLisaData, 68, 100, 0, 400, 4) 49 | turtle.fillcolor('#7C0BE8') 50 | drawFromData(monaLisaData, 68, 100, -272, 0, 4) 51 | turtle.fillcolor('#460CFF') 52 | drawFromData(monaLisaData, 68, 100, 0, 0, 4) 53 | 54 | turtle.update() # Finish drawing the screen. 55 | turtle.exitonclick() # When user clicks on the window, close it. 56 | -------------------------------------------------------------------------------- /fractals/hilbert_curve/hilbert_curve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/hilbert_curve/hilbert_curve.png -------------------------------------------------------------------------------- /fractals/hilbert_curve/hilbert_curve.py: -------------------------------------------------------------------------------- 1 | # Hilbert Curve, by Al Sweigart al@inventwithpython.com 2 | # Draws the Hilbert Curve fractal with turtle graphics. 3 | # More info at: https://en.wikipedia.org/wiki/hilbertCurve 4 | # Good videos on space-filling curves: https://youtu.be/RU0wScIj36o 5 | # and https://youtu.be/3s7h2MHQtxc 6 | 7 | import turtle 8 | 9 | SIZE = 10 # (!) Try changing the line length by a litte. 10 | ANGLE = 90 # (!) Try changing the turning angle by a litte. 11 | LEVEL = 5 # (!) Try changing the recursive level by a litte. 12 | 13 | MAGENTA = '#B20059' 14 | PINK = '#FFE6F2' 15 | turtle.bgcolor(MAGENTA) 16 | turtle.pencolor(PINK) 17 | turtle.fillcolor(PINK) 18 | 19 | turtle.tracer(1, 0) # Make the turtle draw faster. 20 | 21 | turtle.penup() 22 | turtle.goto(-320, 0) 23 | turtle.pendown() 24 | 25 | #turtle.setheading(20) # (!) Try uncommenting this line. 26 | 27 | def hilbertCurve(level, angle): 28 | if level == 0: 29 | return 30 | 31 | turtle.right(angle) 32 | hilbertCurve(level - 1, -angle) 33 | turtle.forward(SIZE) 34 | turtle.left(angle) 35 | hilbertCurve(level - 1, angle) 36 | turtle.forward(SIZE) 37 | hilbertCurve(level - 1, angle) 38 | turtle.left(angle) 39 | turtle.forward(SIZE) 40 | hilbertCurve(level - 1, -angle) 41 | turtle.right(angle) 42 | 43 | def filledInHilbert(): 44 | turtle.begin_fill() 45 | hilbertCurve(LEVEL, ANGLE) # draw first quadrant 46 | turtle.forward(SIZE) 47 | 48 | hilbertCurve(LEVEL, ANGLE) # draw second quadrant 49 | turtle.left(ANGLE) 50 | turtle.forward(SIZE) 51 | turtle.left(ANGLE) 52 | 53 | hilbertCurve(LEVEL, ANGLE) # draw third quadrant 54 | turtle.forward(SIZE) 55 | 56 | hilbertCurve(LEVEL, ANGLE) # draw fourth quadrant 57 | turtle.left(ANGLE) 58 | turtle.forward(SIZE) 59 | turtle.left(ANGLE) 60 | turtle.end_fill() 61 | 62 | filledInHilbert() 63 | turtle.update() # Finish drawing the screen. 64 | turtle.exitonclick() # When user clicks on the window, close it. 65 | -------------------------------------------------------------------------------- /fractals/koch_snowflake/koch_snowflake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/koch_snowflake/koch_snowflake.png -------------------------------------------------------------------------------- /fractals/koch_snowflake/koch_snowflake.py: -------------------------------------------------------------------------------- 1 | # Koch Snowflake, by Al Sweigart al@inventwithpython.com 2 | # Draws a Koch snowflake fractal with turtle graphics. 3 | 4 | import turtle 5 | turtle.tracer(1, 0) # Make the turtle draw faster. 6 | 7 | LEVELS = 5 # More than 5 levels becomes too small to see. 8 | 9 | def snowflakeSide(sideLength, levels): 10 | # Draw a single side of the snowflake (this is called a Koch curve): 11 | turtle.pencolor('black') 12 | if levels == 0: 13 | turtle.forward(sideLength) 14 | return 15 | sideLength = sideLength / 3.0 16 | snowflakeSide(sideLength, levels-1) 17 | 18 | # "Erase" the middle segment by drawing a white line over it. 19 | turtle.pencolor('white') 20 | turtle.pensize(2) 21 | turtle.forward(sideLength) 22 | turtle.forward(-sideLength) 23 | turtle.pencolor('black') 24 | turtle.pensize(1) 25 | 26 | turtle.left(60) 27 | snowflakeSide(sideLength, levels-1) 28 | turtle.right(120) 29 | snowflakeSide(sideLength, levels-1) 30 | turtle.left(60) 31 | snowflakeSide(sideLength, levels-1) 32 | 33 | def drawSnowflake(sideLength, levels): 34 | # Draw 6 Koch curves to draw a Koch snowflake. 35 | for i in range(6): 36 | snowflakeSide(sideLength, levels) 37 | turtle.right(60) 38 | 39 | # Move into the starting position: 40 | LENGTH = 300.0 41 | turtle.penup() 42 | turtle.backward(LENGTH / 2.0) 43 | turtle.right(90) 44 | turtle.backward(1.75 * LENGTH / 2.0) 45 | turtle.left(90) 46 | turtle.pendown() 47 | 48 | # Draw the snowflake: 49 | for lev in range(LEVELS): 50 | drawSnowflake(LENGTH, lev) 51 | 52 | turtle.update() # Finish drawing the screen. 53 | turtle.exitonclick() # When user clicks on the window, close it. 54 | -------------------------------------------------------------------------------- /fractals/nondet_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/nondet_tree.png -------------------------------------------------------------------------------- /fractals/nonuniformtree.py: -------------------------------------------------------------------------------- 1 | # Nonuniform Fractal Tree Drawer, by Al Sweigart al@inventwithpython.com 2 | # Draws nonuniform fractal trees with turtle graphics. 3 | 4 | import turtle 5 | import random 6 | import time 7 | 8 | PALE_TAN = '#FEF9EE' 9 | DARK_BROWN = '#130d0f' 10 | turtle.bgcolor(PALE_TAN) 11 | turtle.pencolor(DARK_BROWN) 12 | 13 | turtle.tracer(10000, 0) # Make the turtle draw faster. 14 | 15 | def drawBranch(x, y, direction, branchLength): 16 | # if the branch is too small, just quit 17 | if branchLength < 5: 18 | return 19 | 20 | # Draw the branch: 21 | branchThickness = max(branchLength / 7.0, 1) + random.randint(-1, 1) 22 | turtle.pensize(branchThickness) 23 | for i in range(4): 24 | turtle.forward(branchLength / 4.0 + random.randint(-10, 10)) 25 | turtle.left(random.randint(-8, 8)) 26 | 27 | if random.randint(0, 5) == 0: 28 | tinyBranchAngle = random.randint(-LEFT_ANGLE, RIGHT_ANGLE) 29 | turtle.right(tinyBranchAngle) 30 | drawBranch(turtle.xcor(), turtle.ycor(), turtle.heading(), branchLength / 2) 31 | turtle.left(tinyBranchAngle) 32 | turtle.pensize(branchThickness) 33 | 34 | if random.randint(0, 5) == 0: 35 | branchLength = branchLength * 0.9 36 | 37 | # Draw the two recursive branches: 38 | if random.randint(0, 9) != 0: 39 | turtle.left(LEFT_ANGLE) 40 | drawBranch(turtle.xcor(), turtle.ycor(), turtle.heading(), branchLength - LEFT_DECREASE) 41 | turtle.right(LEFT_ANGLE) 42 | 43 | if random.randint(0, 9) != 0: 44 | turtle.right(RIGHT_ANGLE) 45 | drawBranch(turtle.xcor(), turtle.ycor(), turtle.heading(), branchLength - RIGHT_DECREASE) 46 | turtle.left(RIGHT_ANGLE) 47 | 48 | # Return back to the starting point: 49 | turtle.penup() 50 | turtle.goto(x, y) 51 | turtle.setheading(direction) 52 | turtle.pendown() 53 | 54 | def drawTree(x, y, direction, seed): 55 | global LEFT_ANGLE, RIGHT_ANGLE, LEFT_DECREASE, RIGHT_DECREASE 56 | 57 | # Go to the starting point: 58 | turtle.penup() 59 | turtle.goto(x, y) 60 | turtle.setheading(direction) 61 | turtle.pendown() 62 | 63 | # Try changing these values and looking at the results: 64 | random.seed(seed) 65 | LEFT_ANGLE = random.randint(10, 30) 66 | RIGHT_ANGLE = random.randint(10, 30) 67 | LEFT_DECREASE = random.randint( 6, 15) 68 | RIGHT_DECREASE = random.randint( 6, 15) 69 | START_SIZE = random.randint(80, 120) 70 | 71 | # Draw the tree: 72 | drawBranch(x, y, direction, START_SIZE) 73 | turtle.update() # Finish drawing the screen. 74 | 75 | seed = 0 76 | while True: 77 | # Get psuedorandom numbers for the branch properties: 78 | random.seed(seed) 79 | drawTree(0, -310, 90, seed) 80 | time.sleep(2) 81 | turtle.clear() 82 | seed += 1 83 | 84 | turtle.update() # Finish drawing the screen. 85 | turtle.exitonclick() # When user clicks on the window, close it. 86 | -------------------------------------------------------------------------------- /fractals/sierpinski_square/sierpinski_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/sierpinski_square/sierpinski_square.png -------------------------------------------------------------------------------- /fractals/sierpinski_square/sierpinski_square.py: -------------------------------------------------------------------------------- 1 | # Sierpinski Square, by Al Sweigart al@inventwithpython.com 2 | # Draws the Sierpinski Square (also called Carpet) with turtle graphics. 3 | # More info at: https://en.wikipedia.org/wiki/Sierpinski_carpet 4 | 5 | import turtle 6 | turtle.tracer(100, 0) # Make the turtle draw faster. 7 | 8 | # Setup the colors: 9 | LIGHT_ORANGE = '#FFD78E' 10 | BLUE = '#517DB2' 11 | FG_COLOR = LIGHT_ORANGE 12 | BG_COLOR = BLUE 13 | turtle.bgcolor(BG_COLOR) 14 | turtle.pencolor(FG_COLOR) 15 | 16 | def drawCarpet(left, top, width, height): 17 | if width < 5 or height < 5: 18 | return 19 | 20 | # Draw the outer rectangle: 21 | turtle.penup() 22 | turtle.goto(left, top) 23 | turtle.pendown() 24 | turtle.fillcolor(FG_COLOR) 25 | 26 | turtle.begin_fill() 27 | turtle.setheading(0) 28 | turtle.forward(width) 29 | turtle.right(90) 30 | turtle.forward(height) 31 | turtle.right(90) 32 | turtle.forward(width) 33 | turtle.right(90) 34 | turtle.forward(height) 35 | turtle.end_fill() 36 | 37 | www = width / 3.0 38 | hhh = height / 3.0 39 | 40 | # Draw the inner rectangle: 41 | turtle.penup() 42 | turtle.goto(left + www, top - hhh) 43 | turtle.pendown() 44 | turtle.fillcolor(BG_COLOR) 45 | 46 | turtle.begin_fill() 47 | turtle.setheading(0) 48 | turtle.forward(www) 49 | turtle.right(90) 50 | turtle.forward(hhh) 51 | turtle.right(90) 52 | turtle.forward(www) 53 | turtle.right(90) 54 | turtle.forward(hhh) 55 | turtle.end_fill() 56 | 57 | # Recursive calls for the eight surrounding sections: 58 | 59 | # Draw in the top-left section: 60 | drawCarpet(left, top, www, hhh) 61 | # Draw in the top section: 62 | drawCarpet(left + www, top, www, hhh) 63 | # Draw in the top-right section: 64 | drawCarpet(left + (www * 2), top, www, hhh) 65 | # Draw in the left section: 66 | drawCarpet(left, top - hhh, www, hhh) 67 | # Draw in the right section: 68 | drawCarpet(left + (www * 2), top - hhh, www, hhh) 69 | # Draw in the bottom-left section: 70 | drawCarpet(left, top - (hhh * 2), www, hhh) 71 | # Draw in the bottom: 72 | drawCarpet(left + www, top - (hhh * 2), www, hhh) 73 | # Draw bottom-right: 74 | drawCarpet(left + (www * 2), top - (hhh * 2), www, hhh) 75 | 76 | # Start the recursive drawing: 77 | drawCarpet(-350, 350, 700, 700) 78 | 79 | turtle.update() # Finish drawing the screen. 80 | turtle.exitonclick() # When user clicks on the window, close it. -------------------------------------------------------------------------------- /fractals/sierpinski_triangle/sierpinski_triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/sierpinski_triangle/sierpinski_triangle.png -------------------------------------------------------------------------------- /fractals/sierpinski_triangle/sierpinski_triangle.py: -------------------------------------------------------------------------------- 1 | # Sierpinski Triangle, by Al Sweigart al@inventwithpython.com 2 | # Draws the Sierpinski Triangle fractal with turtle graphics. 3 | 4 | import turtle 5 | import math 6 | 7 | turtle.tracer(1000, 0) # Make the turtle draw faster. 8 | turtle.setworldcoordinates(0, 0, 960, 810) 9 | turtle.bgcolor(0.9, 0.9, 0.9) 10 | 11 | BASE_SIZE = 13 12 | BASE_HEIGHT = BASE_SIZE * math.sin(60 * (math.pi / 180)) 13 | START_X = 50 14 | START_Y = 20 15 | 16 | def drawTriangle(x, y, color): 17 | turtle.penup() 18 | turtle.pencolor(color) 19 | turtle.goto(x, y) # Go to bottom-left corner of the triangle. 20 | turtle.pendown() 21 | turtle.setheading(60) 22 | turtle.forward(BASE_SIZE) # Draw first side. 23 | turtle.right(120) 24 | turtle.forward(BASE_SIZE) # Draw second side. 25 | turtle.right(120) 26 | turtle.forward(BASE_SIZE) # Draw third side. 27 | 28 | def drawSierpinski(x, y, level, color): 29 | if level == 0: 30 | # The base case, where triangles are too small to draw more. 31 | drawTriangle(x, y, color) 32 | drawTriangle(x + (BASE_SIZE * 0.5), y + BASE_HEIGHT, color) 33 | drawTriangle(x + BASE_SIZE, y, color) 34 | else: 35 | # The recursive case, where three more triangles are drawn. 36 | drawSierpinski(x, y, level - 1, color) 37 | drawSierpinski(x + (BASE_SIZE * 0.5 * (2 ** level)), y + (BASE_HEIGHT * (2 ** level)), level - 1, color) 38 | drawSierpinski(x + (BASE_SIZE * (2 ** level)), y, level - 1, color) 39 | 40 | # Loop from 5 to 0, drawing 5 levels of triangles with different colors: 41 | for i in range(5, -1, -1): 42 | red = 1 - (0.2 * i) 43 | green = 0.1 * i 44 | blue = 0.1 * i 45 | drawSierpinski(START_X, START_Y, i, (red, green, blue)) 46 | 47 | turtle.hideturtle() 48 | turtle.update() # Finish drawing the screen. 49 | turtle.exitonclick() # When user clicks on the window, close it. 50 | -------------------------------------------------------------------------------- /fractals/tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree.png -------------------------------------------------------------------------------- /fractals/tree.py: -------------------------------------------------------------------------------- 1 | # Fractal Tree Drawer, by Al Sweigart al@inventwithpython.com 2 | # Draws fractal trees with turtle graphics. 3 | 4 | import random 5 | import time 6 | import turtle 7 | 8 | turtle.tracer(1000, 0) # Make the turtle draw faster. 9 | turtle.setworldcoordinates(0, 0, 700, 700) 10 | turtle.hideturtle() 11 | 12 | def drawBranch(startPosition, direction, branchLength): 13 | if branchLength < 5: 14 | # Base case; the branches are two small to keep drawing more: 15 | return 16 | 17 | # Go to the starting point & direction: 18 | turtle.penup() 19 | turtle.goto(startPosition) 20 | turtle.setheading(direction) 21 | 22 | # Draw the branch (thickness is 1/7 the length): 23 | turtle.pendown() 24 | turtle.pensize(max(branchLength / 7.0, 1)) 25 | turtle.forward(branchLength) 26 | 27 | # Record the position of the branch's end: 28 | endPosition = turtle.position() 29 | leftDirection = direction + LEFT_ANGLE 30 | leftBranchLength = branchLength - LEFT_DECREASE 31 | rightDirection = direction - RIGHT_ANGLE 32 | rightBranchLength = branchLength - RIGHT_DECREASE 33 | 34 | # Recursive case; draw two more branches: 35 | drawBranch(endPosition, leftDirection, leftBranchLength) 36 | drawBranch(endPosition, rightDirection, rightBranchLength) 37 | 38 | seed = 0 39 | while True: 40 | # Get psuedorandom numbers for the branch properties: 41 | random.seed(seed) 42 | LEFT_ANGLE = random.randint(10, 30) 43 | LEFT_DECREASE = random.randint( 6, 15) 44 | RIGHT_ANGLE = random.randint(10, 30) 45 | RIGHT_DECREASE = random.randint( 6, 15) 46 | START_LENGTH = random.randint(80, 120) 47 | 48 | # Write out the seed number: 49 | turtle.clear() 50 | turtle.penup() 51 | turtle.goto(10, 10) 52 | turtle.write('Seed: %s' % (seed)) 53 | 54 | # Draw the tree: 55 | drawBranch((350, 10), 90, START_LENGTH) 56 | turtle.update() # Finish drawing the screen. 57 | time.sleep(2) 58 | 59 | seed = seed + 1 # Use the next number for the next seed. 60 | -------------------------------------------------------------------------------- /fractals/tree_images/tree1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree1.png -------------------------------------------------------------------------------- /fractals/tree_images/tree10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree10.png -------------------------------------------------------------------------------- /fractals/tree_images/tree11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree11.png -------------------------------------------------------------------------------- /fractals/tree_images/tree12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree12.png -------------------------------------------------------------------------------- /fractals/tree_images/tree13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree13.png -------------------------------------------------------------------------------- /fractals/tree_images/tree14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree14.png -------------------------------------------------------------------------------- /fractals/tree_images/tree15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree15.png -------------------------------------------------------------------------------- /fractals/tree_images/tree16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree16.png -------------------------------------------------------------------------------- /fractals/tree_images/tree17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree17.png -------------------------------------------------------------------------------- /fractals/tree_images/tree18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree18.png -------------------------------------------------------------------------------- /fractals/tree_images/tree19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree19.png -------------------------------------------------------------------------------- /fractals/tree_images/tree2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree2.png -------------------------------------------------------------------------------- /fractals/tree_images/tree20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree20.png -------------------------------------------------------------------------------- /fractals/tree_images/tree3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree3.png -------------------------------------------------------------------------------- /fractals/tree_images/tree4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree4.png -------------------------------------------------------------------------------- /fractals/tree_images/tree5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree5.png -------------------------------------------------------------------------------- /fractals/tree_images/tree6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree6.png -------------------------------------------------------------------------------- /fractals/tree_images/tree7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree7.png -------------------------------------------------------------------------------- /fractals/tree_images/tree8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree8.png -------------------------------------------------------------------------------- /fractals/tree_images/tree9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_images/tree9.png -------------------------------------------------------------------------------- /fractals/tree_multiple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/fractals/tree_multiple.png -------------------------------------------------------------------------------- /interactive/draw_snowflakes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/interactive/draw_snowflakes.png -------------------------------------------------------------------------------- /interactive/draw_snowflakes.py: -------------------------------------------------------------------------------- 1 | # Koch Snowflake Drawer, by Al Sweigart al@inventwithpython.com 2 | # Click in the window to draw koch snowflakes with turtle graphics. 3 | 4 | import turtle 5 | import random 6 | import math 7 | 8 | PURPLISH_BLUE = '#1C2340' 9 | turtle.bgcolor(PURPLISH_BLUE) 10 | turtle.pencolor('white') 11 | turtle.tracer(10, 0) # Make the turtle draw faster. 12 | 13 | def snowflakeSide(length_side, levels): 14 | # Draw a "koch curve" for one of the six sides of the snowflake. 15 | if levels == 0: 16 | turtle.forward(length_side) 17 | return 18 | length_side = length_side / 3.0 19 | snowflakeSide(length_side, levels-1) 20 | turtle.left(60) 21 | snowflakeSide(length_side, levels-1) 22 | turtle.right(120) 23 | snowflakeSide(length_side, levels-1) 24 | turtle.left(60) 25 | snowflakeSide(length_side, levels-1) 26 | 27 | def drawSnowflake(length_side, levels): 28 | # Draw a snowflake by drawing six "koch curves". 29 | for i in range(6): 30 | snowflakeSide(length_side, levels) 31 | turtle.right(60) 32 | 33 | def drawMultiSnowflake(x, y): 34 | # The turtle module passes the XY coordinates of where the mouse 35 | # clicked in the window when it calls this function. 36 | 37 | # The snowflakes are drawn at a random angle. 38 | turtle.setheading(random.randint(0, 360)) 39 | for length in range(1, 5): # Draw snowflakes of varying lengths. 40 | if random.randint(0, 2) == 0: 41 | # In 1 in 3 times, we skip the snowflake of this length. 42 | continue 43 | 44 | # Set a random line thickness (pensize) and length of each 45 | # side of the snowflake: 46 | turtle.pensize(random.randint(1, 4)) 47 | length = length * random.randint(20, 40) 48 | 49 | # Move the turtle to the starting position: 50 | turtle.penup() 51 | turtle.goto(x, y) 52 | turtle.backward(length / 2.0) 53 | turtle.right(90) 54 | turtle.backward(length * math.sqrt(3) / 2.0) 55 | turtle.left(90) 56 | turtle.pendown() 57 | 58 | # Draw a snowflake. 59 | drawSnowflake(length, random.randint(2, 4)) 60 | turtle.update() # Finish drawing the screen. 61 | 62 | # Call drawMultiSnowflake() when screen is clicked: 63 | turtle.onscreenclick(drawMultiSnowflake) 64 | turtle.mainloop() # Start the program, and run until the window is closed. 65 | -------------------------------------------------------------------------------- /interactive/sierpinski_game.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/interactive/sierpinski_game.png -------------------------------------------------------------------------------- /interactive/sierpinski_game.py: -------------------------------------------------------------------------------- 1 | # To play Sierpinski's Game, click three times in the window to select the three 2 | # points of the triangle. Then click somewhere inside the triangle to begin. 3 | # The animation speeds up over time. 4 | 5 | from turtle import * 6 | import random 7 | 8 | setworldcoordinates(0, 0, 960, 810) 9 | bgcolor('#4b4b6e') 10 | pencolor('white') 11 | pensize(2) 12 | penup() 13 | 14 | click_num = 1 15 | 16 | def setup_clicks(x, y): 17 | global click_num, point_A, point_B, point_C 18 | 19 | if click_num == 1: 20 | point_A = (x, y) 21 | goto(point_A) 22 | #dot(12, 'red') # (!) Try commenting this out to hide the red dot 23 | elif click_num == 2: 24 | point_B = (x, y) 25 | goto(point_B) 26 | #dot(12, 'green') # (!) Try commenting this out to hide the green dot 27 | elif click_num == 3: 28 | point_C = (x, y) 29 | goto(point_C) 30 | #dot(12, 'blue') # (!) Try commenting this out to hide the blue dot 31 | elif click_num == 4: 32 | goto(x, y) 33 | start_the_game() 34 | click_num += 1 35 | 36 | def start_the_game(): 37 | global point_A, point_B, point_C 38 | 39 | # start in the middle of the triangle 40 | left = min(point_A[0], point_B[0], point_C[0]) 41 | right = max(point_A[0], point_B[0], point_C[0]) 42 | bottom = min(point_A[1], point_B[1], point_C[1]) 43 | top = max(point_A[1], point_B[1], point_C[1]) 44 | goto(left + int((right - left) / 2), bottom + int((top - bottom) / 2)) 45 | 46 | for i in range(25000): 47 | roll = random.randint(1, 3) 48 | if roll == 1: 49 | dest = point_A 50 | elif roll == 2: 51 | dest = point_B 52 | elif roll == 3: 53 | dest = point_C 54 | 55 | midx = int(abs(dest[0] - xcor()) / 2) + min(dest[0], xcor()) 56 | midy = int(abs(dest[1] - ycor()) / 2) + min(dest[1], ycor()) 57 | goto(midx, midy) 58 | dot(2) 59 | 60 | if i == 20: 61 | tracer(4, 0) # Make the turtle draw fast. 62 | elif i == 2000: 63 | tracer(10000, 0) # Make the turtle draw faster. 64 | 65 | 66 | onscreenclick(setup_clicks) 67 | mainloop() # Start the program, and run until the window is closed. 68 | -------------------------------------------------------------------------------- /simple/polygons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/simple/polygons.png -------------------------------------------------------------------------------- /simple/polygons.py: -------------------------------------------------------------------------------- 1 | # Polygons, by Al Sweigart al@inventwithpython.com 2 | # A turtle program to draw polygons. Every line is the same length. 3 | 4 | import turtle 5 | 6 | turtle.tracer(1, 0) # Make the turtle draw faster. 7 | 8 | # Move the turtle to the starting position: 9 | turtle.penup() 10 | turtle.goto(-100, -300) # The starting position is x -100, y -300. 11 | turtle.pendown() 12 | 13 | # (!) Uncomment the following line, and changing 30 to another number: 14 | #turtle.setheading(30) 15 | 16 | # (!) Try changing this pensize to other sizes: 17 | turtle.pensize(3) 18 | # (!) Try changing this line to other colors: 19 | turtle.pencolor('green') 20 | 21 | for sides in range(3, 21): # Draw polygons with 3 to 21 sides. 22 | for i in range(sides): # Draw each of the sides for this polygon. 23 | turtle.forward(100) 24 | turtle.left(360 / sides) 25 | 26 | # Write out the number of sides for the shape: 27 | if i == int(sides / 2.0): 28 | turtle.write(str(sides)) 29 | -------------------------------------------------------------------------------- /simple/pythons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asweigart/art-of-turtle-programming/f1f77c52732e98128ef72828aa1e4a6d32cf1306/simple/pythons.png -------------------------------------------------------------------------------- /simple/pythons.py: -------------------------------------------------------------------------------- 1 | # Pythons, by Al Sweigart al@inventwithpython.com 2 | # Drawing pythons with turtle graphics. 3 | 4 | import turtle 5 | import random 6 | 7 | turtle.tracer(100, 0) # Make the turtle draw faster. 8 | 9 | NUMBER_OF_SNAKES = 1 10 | GAP = 10 11 | THICKNESS = 20 12 | SNAKE_COLORS = ['#71BF2E', '#4C7F1E', '#97FF3D', '#26400F', '#88E537'] 13 | 14 | def drawSnakeHead(length): 15 | turtle.begin_fill() 16 | final_position = turtle.position() 17 | turtle.left(90) 18 | turtle.forward(length - THICKNESS) 19 | turtle.left(90) 20 | turtle.forward(THICKNESS * 3) 21 | turtle.left(90) 22 | turtle.forward(THICKNESS / 2.0) 23 | turtle.right(90) # draw tongue 24 | turtle.forward(THICKNESS) 25 | turtle.right(45) 26 | turtle.forward(THICKNESS / 3.0) 27 | turtle.backward(THICKNESS / 3.0) 28 | turtle.left(90) 29 | turtle.forward(THICKNESS / 3.0) 30 | turtle.backward(THICKNESS / 3.0) 31 | turtle.right(45) 32 | turtle.backward(THICKNESS) 33 | turtle.left(90) # end tongue 34 | turtle.forward(THICKNESS / 2.0) 35 | turtle.left(90) 36 | turtle.forward(THICKNESS * 2) 37 | turtle.right(90) 38 | turtle.forward(length - THICKNESS) 39 | turtle.left(90) 40 | turtle.forward(THICKNESS) 41 | turtle.penup() 42 | turtle.goto(final_position) 43 | turtle.left(90) 44 | turtle.forward(length - THICKNESS * 1.3) 45 | turtle.left(90) 46 | turtle.forward(THICKNESS * 1.5) 47 | turtle.dot(8, 'black') # The snake's eye is black. 48 | turtle.backward(THICKNESS * 1.5) 49 | turtle.right(90) 50 | turtle.backward(length - THICKNESS * 1.3) 51 | turtle.right(90) 52 | turtle.pendown() 53 | turtle.end_fill() 54 | 55 | def drawTwistUpSegment(length): 56 | turtle.begin_fill() 57 | turtle.forward(GAP) 58 | turtle.left(90) 59 | turtle.forward(length - THICKNESS) 60 | turtle.right(90) 61 | turtle.forward(THICKNESS) 62 | final_position = turtle.position() 63 | turtle.right(90) 64 | turtle.penup() 65 | turtle.forward(THICKNESS) 66 | turtle.pendown() 67 | turtle.forward(length - THICKNESS) 68 | turtle.right(90) 69 | turtle.forward(THICKNESS + GAP) 70 | turtle.end_fill() 71 | turtle.penup() 72 | turtle.goto(final_position) 73 | turtle.pendown() 74 | turtle.right(180) 75 | 76 | 77 | def drawTwistDownSegment(length): 78 | turtle.begin_fill() 79 | turtle.forward(GAP + THICKNESS) 80 | turtle.right(90) 81 | turtle.forward(length - THICKNESS) 82 | final_position = turtle.position() 83 | turtle.penup() 84 | turtle.forward(THICKNESS) 85 | turtle.pendown() 86 | turtle.right(90) 87 | turtle.forward(THICKNESS) 88 | turtle.right(90) 89 | turtle.forward(length - THICKNESS) 90 | turtle.left(90) 91 | turtle.forward(GAP) 92 | turtle.end_fill() 93 | turtle.penup() 94 | turtle.goto(final_position) 95 | turtle.pendown() 96 | turtle.right(180) 97 | 98 | def drawSnake(lengths): 99 | drawSnakeHead(lengths[0]) 100 | for i in range(1, len(lengths) - 1, 2): 101 | drawTwistUpSegment(lengths[i]) 102 | drawTwistDownSegment(lengths[i + 1]) 103 | 104 | turtle.pensize(4) 105 | # Draw the snakes: 106 | for i in range(10): 107 | # Go to the starting position: 108 | turtle.penup() 109 | turtle.goto(random.randint(-400, 400), random.randint(-400, 400)) 110 | turtle.pendown() 111 | turtle.setheading(random.randint(0, 360)) 112 | 113 | # Set up the snake coloration: 114 | turtle.pencolor(random.choice(SNAKE_COLORS)) 115 | 116 | redAmount = random.randint(0, 100) / 100.0 117 | greenAmount = random.randint(0, 100) / 100.0 118 | blueAmount = random.randint(0, 100) / 100.0 119 | # (!) Uncomment the following line to use random colors. 120 | #turtle.pencolor(redAmount, greenAmount, blueAmount) 121 | 122 | turtle.fillcolor(turtle.pencolor()) 123 | 124 | # Draw the snake: 125 | lengths = [] 126 | # Each snake has a random amount of segments: 127 | for j in range(random.randint(6, 12)): 128 | # Each segment has random lengths: 129 | lengths.append(random.randint(40, 150)) 130 | # Draw the segments: 131 | drawSnake(lengths) 132 | 133 | turtle.update() # Finish drawing the screen. 134 | turtle.exitonclick() # When user clicks on the window, close it. --------------------------------------------------------------------------------