Advertisement
Guest User

Untitled

a guest
Jan 19th, 2020
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.49 KB | None | 0 0
  1. from turtle import Turtle, Screen
  2. from collections import deque
  3. import numpy as np
  4. import math
  5. import copy
  6.  
  7. def rotate(point, angle):
  8. px, py = point
  9. angle = angle * math.pi/180.0
  10. qx = math.cos(angle) * px - math.sin(angle) * py
  11. qy = math.sin(angle) * px + math.cos(angle) * py
  12. return qx, qy
  13.  
  14. def dist(p1, p2):
  15. return math.sqrt((p2[0]-p1[0])**2+(p2[1]-p1[1])**2)
  16.  
  17. def recompute_sectors(turtle):
  18. cur_position = turtle.position()
  19. current_sectors = copy.deepcopy(turtle.current_sectors)
  20. min_sector_distance = 1000
  21. for sector in current_sectors:
  22. if dist(cur_position, sector) > 150:
  23. turtle.current_sectors.remove(sector)
  24. if dist(cur_position, sector) < min_sector_distance:
  25. min_sector_distance = dist(cur_position, sector)
  26.  
  27. if min_sector_distance > 10:
  28. new_sector = cur_position
  29. turtle.current_sectors.add(new_sector)
  30. turtle.visited_sectors[new_sector] = 1
  31.  
  32. for sector in turtle.visited_sectors:
  33. if sector not in turtle.current_sectors and dist(cur_position, sector) < 10:
  34. turtle.visited_sectors[sector] += 1
  35. turtle.current_sectors.add(sector)
  36.  
  37. near_pt = int(cur_position[0]), int(cur_position[1])
  38. if near_pt in turtle.point_visits:
  39. turtle.point_visits[near_pt] += 1
  40. else:
  41. turtle.point_visits[near_pt] = 1
  42.  
  43. cur_color = turtle.color()
  44. if near_pt in turtle.point_colors:
  45. turtle.point_colors[near_pt].add(cur_color)
  46. else:
  47. turtle.point_colors[near_pt] = set(cur_color)
  48.  
  49. def validate_sectors(turtle):
  50. result = True
  51. for sector in turtle.visited_sectors:
  52. if turtle.visited_sectors[sector] > 6:
  53. result = False
  54.  
  55. for near_pt in turtle.point_visits:
  56. if turtle.point_visits[near_pt] > 6:
  57. result = False
  58.  
  59. for near_pt in turtle.point_colors:
  60. if len(turtle.point_colors[near_pt]) > 4:
  61. result = False
  62.  
  63. #print turtle.position(), turtle.visited_sectors, turtle.point_visits, turtle.point_colors, result
  64. return result
  65.  
  66. def validate_position(turtle):
  67. p = turtle.position()
  68. new_allowed_rotations = []
  69. for r in turtle.allowed_rotations:
  70. _, y = rotate(p, r)
  71. if y < 10.1 and y > -10.1:
  72. new_allowed_rotations.append(r)
  73. if not new_allowed_rotations:
  74. return False
  75. turtle.allowed_rotations = new_allowed_rotations
  76.  
  77. return True
  78.  
  79. def process_line(l, turtle):
  80. items = deque(l.split(" "))
  81. num_actions = 0
  82. travel_distance = 0
  83. success = True
  84. while items:
  85. if items[0] == "pd":
  86. if turtle.isdown():
  87. num_actions -= 1
  88. #success = False
  89. turtle.pendown()
  90. turtle.moves.append(items[0])
  91. elif items[0] == "pu":
  92. if not turtle.isdown():
  93. num_actions -= 1
  94. #success = False
  95. turtle.penup()
  96. turtle.moves.append(items[0])
  97. elif items[0] == "co":
  98. turtle.pencolor(items[1])
  99. turtle.moves.append((items[0], items[1]))
  100. items.popleft()
  101. elif items[0] == "fd":
  102. turtle.forward(int(items[1]))
  103. turtle.moves.append((items[0], items[1]))
  104. turtle.travel_distance += int(items[1])
  105. travel_distance += int(items[1])
  106. recompute_sectors(turtle)
  107. success = success and validate_position(turtle) and validate_sectors(turtle)
  108. items.popleft()
  109. elif items[0] == "bk":
  110. turtle.backward(int(items[1]))
  111. turtle.moves.append((items[0], items[1]))
  112. turtle.travel_distance += int(items[1])
  113. travel_distance += int(items[1])
  114. success = success and validate_position(turtle) and validate_sectors(turtle)
  115. items.popleft()
  116. elif items[0] == "lt":
  117. turtle.left(int(items[1]))
  118. turtle.moves.append((items[0], items[1]))
  119. items.popleft()
  120. elif items[0] == "rt":
  121. turtle.right(int(items[1]))
  122. turtle.moves.append((items[0], items[1]))
  123. items.popleft()
  124. else:
  125. assert False, items[0]
  126. items.popleft()
  127. num_actions += 1
  128. if not success:
  129. break
  130. return success, num_actions, travel_distance
  131.  
  132.  
  133. def try_to_finish(turtle, sofar):
  134. endline = "lt 120 pu fd 10 pd fd 10 rt 60 pu fd 30 pd rt 120 fd 20 pu lt 120 fd 40"
  135. finish_success, finish_numactions, travel_distance = process_line(endline, turtle) # TODO travel distance
  136. if finish_success:
  137. print("Solution: ", sofar)
  138. else:
  139. print("Finish failed")
  140. for i in range(finish_numactions):
  141. turtle.undo()
  142.  
  143. def backtrack(turtle, num_actions, allowed_rotations, travel_distance, visited_sectors, current_sectors, point_visits, moves, point_colors):
  144. for i in range(num_actions):
  145. turtle.undo()
  146. turtle.allowed_rotations = allowed_rotations
  147. turtle.travel_distance -= travel_distance
  148. turtle.visited_sectors = visited_sectors
  149. turtle.current_sectors = current_sectors
  150. turtle.point_visits = point_visits
  151. turtle.moves = moves
  152. turtle.point_colors = point_colors
  153.  
  154. def iterate(turtle, lines, sofar, depth=0):
  155.  
  156. allowed_rotations = copy.deepcopy(turtle.allowed_rotations)
  157. visited_sectors = copy.deepcopy(turtle.visited_sectors)
  158. current_sectors = copy.deepcopy(turtle.current_sectors)
  159. point_visits = copy.deepcopy(turtle.point_visits)
  160. point_colors = copy.deepcopy(turtle.point_colors)
  161. moves = copy.deepcopy(turtle.moves)
  162. yertle.sofar = sofar
  163. for l in lines:
  164. success, num_actions, travel_distance = process_line(l, turtle)
  165. if success:
  166. remaining = [ol for ol in lines if l != ol]
  167. if len(remaining) < 4:
  168. print len(remaining), turtle.travel_distance
  169. if len(remaining) == 0:
  170. print turtle.moves
  171. print sofar
  172. clickHandler(0, 0)
  173. sofar.append((l, num_actions, allowed_rotations))
  174. iterate(turtle, remaining, sofar, depth+1)
  175. backtrack(turtle, num_actions, allowed_rotations, travel_distance, visited_sectors, current_sectors, point_visits, moves, point_colors)
  176.  
  177.  
  178. startlines = [
  179. "co blue pd rt 30 fd 10 bk 10 lt 120 fd 10 lt 60 pu fd 10",
  180. # "pd fd 10 pu fd 10 pd fd 10 bk 10 lt 60 fd 10 lt 120 pu fd 20 pd fd 10 pu bk 50", # 6
  181. # "bk 10 rt 60 fd 10 lt 120 fd 20 rt 120 pu fd 10 pd lt 120 fd 10 rt 60", # 1
  182. # "fd 10 pu fd 10 pd fd 10 rt 60 fd 10 rt 120 fd 10 rt 60 fd 10 rt 120 pu fd 20", # 3
  183. # "fd 10 pd rt 60 fd 20 co cyan lt 120 fd 20 rt 60 pu fd 20 pd rt 120 fd 10 bk 10", # 2
  184. ]
  185.  
  186. midlines = [
  187. "bk 10 rt 60 fd 10 lt 120 fd 20 rt 120 pu fd 10 pd lt 120 fd 10 rt 60", # 1
  188. "fd 10 pd rt 60 fd 20 co cyan lt 120 fd 20 rt 60 pu fd 20 pd rt 120 fd 10 bk 10", # 2
  189. "fd 10 pu fd 10 pd fd 10 rt 60 fd 10 rt 120 fd 10 rt 60 fd 10 rt 120 pu fd 20", # 3
  190. "lt 60 fd 10 pu bk 20 co magenta pd fd 10 rt 60 pu fd 20 pd lt 60 fd 10 rt 60 pu", # 4
  191. "pd bk 10 lt 60 pu fd 20 pd rt 60 fd 10 lt 60 pu bk 10 pd rt 60 bk 10 fd 10 co white", # 5
  192. "pd fd 10 pu fd 10 pd fd 10 bk 10 lt 60 fd 10 lt 120 pu fd 20 pd fd 10 pu bk 50", # 6
  193. "pd fd 10 rt 60 pu fd 10 pd rt 60 fd 20 bk 10 lt 60 bk 10 pu fd 20 pd fd 10", # 7
  194. "pd lt 120 fd 10 pu fd 40 pd lt 120 fd 20 rt 120 pu fd 40 pd rt 60 fd 20", # 8
  195. "pu fd 10 rt 60 fd 60 pd fd 10 pu fd 40 pd rt 180 co green fd 20 lt 60 pu fd 10", # 9
  196. "pu fd 20 pd rt 60 fd 10 co red fd 10 lt 120 fd 10 lt 60 fd 10 bk 10 lt 60", # 10
  197. "rt 120 pu fd 30 pd rt 120 fd 10 bk 10 lt 120 pu fd 70 pd rt 120 co yellow fd 10", # 11
  198. "rt 60 pu fd 10 pd lt 60 fd 10 rt 60 pu fd 10 pd fd 10 pu fd 20 pd rt 60 fd 10" #12
  199. ]
  200.  
  201.  
  202. yertle = Turtle(visible=False)
  203. def clickHandler(a, b):
  204. print(yertle.sofar)
  205. print(yertle.moves)
  206. input('Press a key')
  207.  
  208. if __name__ == "__main__":
  209. screen = Screen()
  210. screen.bgcolor("black")
  211. screen.onclick(clickHandler)
  212. yertle.speed('fastest')
  213. yertle.penup()
  214. yertle.allowed_rotations = np.arange(30, 31, 1)
  215. yertle.travel_distance = 0
  216. yertle.moves = []
  217. yertle.current_sectors = set()
  218. yertle.visited_sectors = dict()
  219. yertle.point_visits = dict()
  220. yertle.point_colors = dict()
  221. yertle.sofar = None
  222. for l in startlines:
  223. process_line(l, yertle)
  224. iterate(yertle, midlines, [])
  225. screen.exitonclick()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement