Skip to content

Instantly share code, notes, and snippets.

@horstjens
Created January 28, 2023 12:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save horstjens/5aceb761975d7e84891ddfaf3794ce50 to your computer and use it in GitHub Desktop.
Save horstjens/5aceb761975d7e84891ddfaf3794ce50 to your computer and use it in GitHub Desktop.
import turtle
"""
crocodile puzzle
move and rotate tiles
"""
import random
def paint_head(size=100, big=20, medium=15, small=7):
# save start position
x,y = turtle.pos()
# save start orientation
heading = turtle.heading()
turtle.pendown()
turtle.left(10)
# body
turtle.pensize(big)
turtle.forward(size)
# head
turtle.right(30)
turtle.pensize(medium)
turtle.forward(2*medium)
# eye
turtle.penup()
turtle.pensize(1)
turtle.backward(medium/2)
turtle.left(90)
turtle.forward(medium/2)
turtle.pensize(small)
turtle.pencolor("black")
turtle.fillcolor("pink")
turtle.pendown()
turtle.begin_fill()
turtle.circle(small)
turtle.end_fill()
turtle.penup()
turtle.backward(medium)
turtle.pensize(small)
turtle.pencolor("black")
turtle.fillcolor("pink")
turtle.pendown()
turtle.begin_fill()
turtle.circle(small)
turtle.end_fill()
turtle.penup()
turtle.goto(x,y)
turtle.setheading(heading)
turtle.pendown()
def paint_tail(size=100, big=15, medium=10, small=7):
# save start position
x,y = turtle.pos()
# save start orientation
heading = turtle.heading()
turtle.pendown()
turtle.pensize(big)
turtle.right(15)
turtle.forward(size/1.5)
turtle.left(35)
turtle.pensize(medium)
turtle.forward(size/2)
turtle.right(35)
turtle.pensize(small)
turtle.forward(size/3)
turtle.goto(x,y)
turtle.setheading(heading)
turtle.pendown()
def bye():
turtle.bye()
def randomize_tiles():
# make random tile rotations
for y, row in enumerate(Game.lines):
for x, col in enumerate(row):
tile = Game.lines[y][x]
for i in range(random.randint(0,4)):
tile.rotate_left()
# make random tile swaps
for _ in range(100):
c1 = random.randint(0,2)
r1 = random.randint(0,2)
c2 = random.randint(0,2)
r2 = random.randint(0,2)
# swap
Game.lines[r1][c1], Game.lines[r2][c2] = Game.lines[r2][c2], Game.lines[r1][c1]
draw_all()
def swap(x,y):
row, col = calculate_tile_number_from_mousclickposition(x,y)
if None in (row, col):
return
if not Game.a_square_is_selected:
# paint big pink selection sqare
turtle.penup()
turtle.goto(col*Tile.size + Game.offset_x, row*Tile.size + Game.offset_y)
turtle.setheading(0) # east
turtle.forward(Tile.size/2)
turtle.left(90)
turtle.pendown()
turtle.pensize(3)
turtle.pencolor("brown")
for _ in range(4):
turtle.forward(Tile.size/2)
turtle.left(90)
turtle.forward(Tile.size/2)
turtle.penup()
turtle.goto(1*Tile.size + Game.offset_x, 2.75 * Tile.size + Game.offset_y)
turtle.pendown()
turtle.pencolor("black")
turtle.write("Click on other tile to swap the tiles", align="center", font=("System", 20))
turtle.update()
Game.a_square_is_selected = True
Game.selected_row = row
Game.selected_col = col
else:
# make the swap
Game.lines[row][col], Game.lines[Game.selected_row][Game.selected_col] = Game.lines[Game.selected_row][Game.selected_col], Game.lines[row][col]
Game.a_square_is_selected = False
Game.selected_row = None
Game.selected_col = None
turtle.clear()
draw_all()
def rotate(x,y):
row, col = calculate_tile_number_from_mousclickposition(x,y)
if None in (row, col):
return
Game.lines[row][col].rotate_left()
turtle.clear()
draw_all()
def draw_all():
turtle.clear()
turtle.penup()
turtle.goto(0,0)
counter = 1
for y, line in enumerate(Game.lines):
for x, tile in enumerate(line):
turtle.penup()
turtle.goto(x*Tile.size + Game.offset_x, y*Tile.size + Game.offset_y)
#turtle.pendown()
#turtle.circle(5)
#turtle.pendown()
#turtle.setheading(tile.heading)
tile.draw(str(counter))
counter += 1
turtle.penup()
turtle.goto(1*Tile.size + Game.offset_x, -0.75*Tile.size + Game.offset_y)
turtle.pencolor("black")
turtle.pendown()
turtle.write("left-click on tiles to swap, right-click to rotate, press r to randomize tiles, q to quit",
align="center")
turtle.update() # force draw and display, removes missing artifacts from use of tracer
def calculate_tile_number_from_mousclickposition(x,y):
#print("i got arguments:",x,y)
col, row = None, None
if Tile.size * -1.5 < x < - Tile.size //2:
col = 0
elif -Tile.size/2 < x < Tile.size /2:
col = 1
elif Tile.size /2 < x < Tile.size * 1.5:
col = 2
if Tile.size * -1.5 < y < - Tile.size //2:
row = 0
elif -Tile.size/2 < y < Tile.size /2:
row = 1
elif Tile.size /2 < y < Tile.size * 1.5:
row = 2
#print("row:", row, "col:", col)
return(row, col)
class Tile:
size = 200
number = 0
colordict = {"y":"yellow",
"b":"blue",
"r":"red",
"g":"green",
}
functiondict = {"H":paint_head,
"T":paint_tail,
}
def __init__(self, code=None):
self.code = code
self.heading = 0 # east
#self.number = Tile.number
#Tile.number += 1
#Game.tiles[self.number] = self
def rotate_left(self):
self.heading += 90
if self.heading == 360:
self.heading = 0
#print("before:", self.code)
self.code = self.code[-2:]+self.code[:-2]
#print("after :", self.code)
def rotate_right(self):
self.heading -= 90
if self.heading == -90:
self.heading = 270
#print("before:", self.code)
self.code = self.code[2:]+self.code[:2]
#print("after :", self.code)
def draw(self, centerstring="1"):
slice_start = 0
slice_stop = 2
# assuming that the turtle is in the middle of a cell/card
startx, starty = turtle.pos()
heading = turtle.heading()
turtle.pendown()
#turtle.circle(5)
turtle.write(centerstring, align="center")
# draw outer border of cell
turtle.setheading(0) # east
turtle.penup()
turtle.forward(Tile.size//2) # E
turtle.left(90) # looking north
for _ in range(4):
my_slice = self.code[slice_start:slice_stop]
color = Tile.colordict[my_slice[0]]
figure = Tile.functiondict[my_slice[1]]
slice_start += 2
slice_stop += 2
# looking outside
turtle.left(90)
# looking now inside to center of cell
turtle.pendown()
turtle.pencolor(color)
figure(Tile.size//4)
turtle.pencolor("black")
turtle.pensize(1)
turtle.right(90)
turtle.forward(Tile.size//2) # corner
turtle.left(90)
turtle.forward(Tile.size//2) # middle
class Game:
#tiles = {}
lines = []
screen = None # turtle screen
offset_y = - Tile.size * 1.0
offset_x = - Tile.size * 1.0
a_square_is_selected = False
selected_row = None
selected_col = None
def __init__(self):
# start reading original matrix from left to right, , top down
line = []
line.append(Tile("yHbHrTgT"))
line.append(Tile("rHgHyTgT"))
line.append(Tile("yHbHrTbT"))
Game.lines.insert(0,line)
line=[]
line.append(Tile("yHgHrTbT"))
line.append(Tile("rHgHyTbT"))
line.append(Tile("yHbHrTgT"))
Game.lines.insert(0,line)
line=[]
line.append(Tile("gHbHyTrT"))
line.append(Tile("rHbHgTyT"))
line.append(Tile("bHgHrTyT"))
Game.lines.insert(0,line)
def setup(self):
turtle.speed(0)
turtle.setup(width=1024,height=800)
Game.screen = turtle.Screen()
Game.screen.bgcolor("pink")
Game.screen.tracer(150,0)
def run(self):
randomize_tiles()
draw_all()
Game.screen.onclick(swap,1)
Game.screen.onclick(rotate,3)
Game.screen.onkey(randomize_tiles,"r")
Game.screen.onkey(bye,"q")
Game.screen.listen()
turtle.mainloop()
#turtle.exitonclick()
if __name__ == "__main__":
g = Game()
g.setup()
g.run()
#x = Tile("yHbHrTgT")
#x.rotate_left()
#x.rotate_right()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment