karel_asset.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. import operator
  2. import logging
  3. import random
  4. # Logging to console
  5. logger = logging.getLogger(__name__)
  6. logging.basicConfig(level=logging.INFO) # Set loglevel to INFO or higher to prevent console spam.
  7. """
  8. Helper functions
  9. """
  10. # Return some hex colour
  11. """
  12. Waiting for Stanford to fix a bug in the environment
  13. CIP bug: https://codeinplace.stanford.edu/cip6/report?post=ac7c4ffd-1f90-475a-b4ee-2e5b73c5348f
  14. from matplotlib import colors
  15. import decimal
  16. def get_random_colour():
  17. return decimal.Decimal(random.randrange(0,10)/10), decimal.Decimal(random.randrange(0,10)/10), decimal.Decimal(random.randrange(0,10)/10)
  18. colour = colors.rgb2hex((get_random_colour()))
  19. background = colors.rgb2hex((get_random_colour()))
  20. """
  21. def generate_random_colour():
  22. # Generate random RGB values
  23. rgb_values = [random.randrange(256), random.randrange(256), random.randrange(256)]
  24. # Convert to HEX values
  25. hex_colours = [hex(value)[2:] for value in rgb_values] # Strip the '0x' prefix
  26. # Add leading "0" for single digit values
  27. for i in range(len(hex_colours)):
  28. if len(str(hex_colours[i])) == 1:
  29. hex_colours[i] = f"0{hex_colours[i]}"
  30. # Add leading "#" to hex values
  31. colour = '#' + ''.join(hex_colours)
  32. logger.debug(f"Generated random colour: {colour}")
  33. return colour
  34. """
  35. Asset functions
  36. """
  37. # Draw a background with random colour on the canvas
  38. def generate_random_background(canvas):
  39. background = canvas.create_rectangle(
  40. 1,
  41. 1,
  42. canvas.width,
  43. canvas.height,
  44. generate_random_colour(),
  45. generate_random_colour()
  46. )
  47. return background
  48. # Erase a passed Karel from the canvas
  49. def erase_asset(asset):
  50. canvas = asset[1][0]
  51. # Erase each shape of the asset
  52. for shape in asset[0].values():
  53. canvas.delete(shape)
  54. logger.debug(f"Erased asset: {asset}")
  55. # Move a passed Karel on the canvas
  56. """
  57. Waiting for Stanford to fix a bug in the environment
  58. CIP bug: https://codeinplace.stanford.edu/cip6/report?post=7043ece9-7653-4e39-8a63-5f4544b1d74b
  59. def move_karel(canvas, karel, x, y):
  60. for shape in karel[0].values():
  61. canvas.move(shape, x, y)
  62. logger.debug(f"Moved: {karel} by {x} horizontally, {y} vertically")
  63. """
  64. # Move a passed asset relative to previous position
  65. def relative_move_asset(asset, x:int=0, y:int=0):
  66. # Update coordinates in list
  67. asset[1][1] += x
  68. asset[1][2] += y
  69. # Replace asset
  70. erase_asset(asset)
  71. new_asset = draw_karel(asset[1][0], asset[1][1], asset[1][2], asset[1][3], asset[1][4], asset[1][5], asset[1][6], asset[1][7])
  72. logger.debug(f"Moved {asset} by {x} horizontally, {y} vertically, to {new_asset}")
  73. return new_asset
  74. # Move a passed asset in relation to her orientation
  75. def orientation_move_asset(asset, direction, amount):
  76. # Direction translation
  77. # East
  78. if asset[1][4].startswith("east"):
  79. if direction.lower() == "forward" or direction.lower() == "front":
  80. asset[1][1] += amount
  81. if direction.lower() == "left":
  82. asset[1][2] -= amount
  83. if direction.lower() == "right":
  84. asset[1][2] += amount
  85. if direction.lower() == "backward" or direction.lower() == "back":
  86. asset[1][1] -= amount
  87. # North
  88. if asset[1][4].startswith("north"):
  89. if direction.lower() == "forward" or direction.lower() == "front":
  90. asset[1][2] -= amount
  91. if direction.lower() == "left":
  92. asset[1][1] -= amount
  93. if direction.lower() == "right":
  94. asset[1][1] += amount
  95. if direction.lower() == "backward" or direction.lower() == "back":
  96. asset[1][2] += amount
  97. # West
  98. if asset[1][4].startswith("west"):
  99. if direction.lower() == "forward" or direction.lower() == "front":
  100. asset[1][1] -= amount
  101. if direction.lower() == "left":
  102. asset[1][2] += amount
  103. if direction.lower() == "right":
  104. asset[1][2] -= amount
  105. if direction.lower() == "backward" or direction.lower() == "back":
  106. asset[1][1] += amount
  107. # South
  108. if asset[1][4].startswith("south"):
  109. if direction.lower() == "forward" or direction.lower() == "front":
  110. asset[1][2] += amount
  111. if direction.lower() == "left":
  112. asset[1][1] += amount
  113. if direction.lower() == "right":
  114. asset[1][1] -= amount
  115. if direction.lower() == "backward" or direction.lower() == "back":
  116. asset[1][2] -= amount
  117. # Replace asset
  118. erase_asset(asset)
  119. new_karel = draw_karel(asset[1][0], asset[1][1], asset[1][2], asset[1][3], asset[1][4], asset[1][5], asset[1][6], asset[1][7])
  120. logger.debug(f"Moved: {asset} {direction} by {amount} as {new_karel}")
  121. return new_karel
  122. # Move a passed asset to new coordinates
  123. def absolute_move_asset(asset, x, y):
  124. # Update coordinates in list
  125. asset[1][1] = x
  126. asset[1][2] = y
  127. # Replace asset
  128. erase_asset(asset)
  129. new_karel = draw_karel(asset[1][0], asset[1][1], asset[1][2], asset[1][3], asset[1][4], asset[1][5], asset[1][6], asset[1][7])
  130. logger.debug(f"Moved: {asset} by {x} horizontally, {y} vertically, to {new_karel}")
  131. return new_karel
  132. # Change the orientation of a passed asset
  133. def rotate_asset(asset, direction):
  134. # Relative turn
  135. if direction == "right" or direction == "left":
  136. # East
  137. if asset[1][4] == "east":
  138. if direction == "right":
  139. asset[1][4] = "south"
  140. if direction == "left":
  141. asset[1][4] = "north"
  142. elif asset[1][4] == "east-flipped":
  143. if direction == "right":
  144. asset[1][4] = "south-flipped"
  145. if direction == "left":
  146. asset[1][4] = "north-flipped"
  147. # North
  148. elif asset[1][4] == "north":
  149. if direction == "right":
  150. asset[1][4] = "east"
  151. if direction == "left":
  152. asset[1][4] = "west"
  153. elif asset[1][4] == "north-flipped":
  154. if direction == "right":
  155. asset[1][4] = "east-flipped"
  156. if direction == "left":
  157. asset[1][4] = "west-flipped"
  158. # West
  159. elif asset[1][4] == "west":
  160. if direction == "right":
  161. asset[1][4] = "north"
  162. if direction == "left":
  163. asset[1][4] = "south"
  164. elif asset[1][4] == "west-flipped":
  165. if direction == "right":
  166. asset[1][4] = "north-flipped"
  167. if direction == "left":
  168. asset[1][4] = "south-flipped"
  169. # South
  170. elif asset[1][4] == "south":
  171. if direction == "right":
  172. asset[1][4] = "west"
  173. if direction == "left":
  174. asset[1][4] = "east"
  175. elif asset[1][4] == "south-flipped":
  176. if direction == "right":
  177. asset[1][4] = "west-flipped"
  178. if direction == "left":
  179. asset[1][4] = "east-flipped"
  180. # Absolute rotation
  181. elif direction == "east" or direction == "east-flipped" or direction == "north" or direction == "north-flipped" or direction == "west" or direction == "west-flipped" or direction == "south" or direction == "south-flipped":
  182. asset[1][4] = direction
  183. # Syntax error
  184. else:
  185. logger.error(f"Invalid rotation direction: {direction}")
  186. # Repalce asset
  187. erase_asset(asset)
  188. new_karel = draw_karel(asset[1][0], asset[1][1], asset[1][2], asset[1][3], asset[1][4], asset[1][5], asset[1][6], asset[1][7])
  189. logger.debug(f"Rotated Karel: {asset} by {direction} as {asset[1][4]} to {new_karel}")
  190. return new_karel
  191. # Recolour a passed asset on the canvas
  192. """
  193. Waiting for Stanford to fix a bug in the environment
  194. CIP bug: https://codeinplace.stanford.edu/cip6/report?post=c36ed931-3019-4830-8ba6-655c1a513471
  195. def recolour_karel(canvas, karel, colour:str="black", background:str="white"):
  196. for name, shape in karel[0].items(): # Loop over Karel dict
  197. if name.endswith("_fill"): # Background shape
  198. canvas.set_color(shape, background)
  199. canvas.set_outline_color(shape, background)
  200. else: # Foreground shape
  201. if name.endswith("_line") or name.endswith("_corner") or name == "mouth":
  202. canvas.set_color(shape, colour)
  203. elif name == "eye":
  204. #canvas.set_color(shape, "transparent")
  205. canvas.set_outline_color(shape, colour)
  206. else: # Legs and feet
  207. canvas.set_color(shape, colour)
  208. canvas.set_outline_color(shape, colour)
  209. """
  210. def recolour_asset(asset, colour:str="black", background:str="white"):
  211. # Random colours
  212. if colour == "random":
  213. colour = generate_random_colour()
  214. if background == "random":
  215. background = generate_random_colour()
  216. # Update colours in list
  217. asset[1][5] = colour
  218. asset[1][6] = background
  219. # Replace asset
  220. erase_asset(asset)
  221. new_karel = draw_karel(asset[1][0], asset[1][1], asset[1][2], asset[1][3], asset[1][4], asset[1][5], asset[1][6], asset[1][7])
  222. logger.debug(f"Re-coloured Karel: {asset} with {colour} and {background} to {new_karel}")
  223. return new_karel
  224. # Draw a random asset on the canvas
  225. def generate_random_asset(canvas):
  226. pass
  227. """
  228. Karel functions
  229. """
  230. # Draw a random Karel on the canvas
  231. def generate_random_karel(canvas):
  232. # Base the size on the shortest pane
  233. if canvas.width < canvas.height:
  234. size = random.randint(1, canvas.width)
  235. else:
  236. size = random.randint(1, canvas.height)
  237. # Generate random values (Inside the canvas geometry)
  238. centre_x = random.randint(int(size / 2), int(canvas.width - size / 2))
  239. centre_y = random.randint(int(size / 2), int(canvas.height - size / 2))
  240. orientation = random.choice(["east", "east-flipped", "north", "north-flipped", "west", "west-flipped", "south", "south-flipped"])
  241. transparent = random.choice((True, False))
  242. return draw_karel(canvas, centre_x, centre_y, size, orientation, "random", "random", transparent)
  243. # Draw a Karel
  244. def draw_karel(
  245. canvas,
  246. centre_x:int=25,
  247. centre_y:int=25,
  248. size:int=50,
  249. orientation:str="east",
  250. colour:str="black",
  251. background:str="white",
  252. transparent:bool=False
  253. ):
  254. # Body constants
  255. MARGIN = size / 8
  256. APPENDAGE_MULTIPLIER = MARGIN * 0.6
  257. # Random colours
  258. if colour == "random":
  259. colour = generate_random_colour()
  260. if background == "random":
  261. background = generate_random_colour()
  262. ''' Flipper case
  263. In order to be able to flip Karel, the operands in the forumlas must be able to switch around.
  264. Orientations are in relation to the centre of Karel.
  265. '''
  266. match orientation.lower():
  267. case "east" | "south-flipped":
  268. left_operand = operator.sub # Left / Top
  269. top_operand = operator.sub # Top / Left
  270. right_operand = operator.add # Right / Bottom
  271. bottom_operand = operator.add # Bottom / Right
  272. case "east-flipped" | "south":
  273. left_operand = operator.sub # Left / Top
  274. top_operand = operator.add # Bottom / Right
  275. right_operand = operator.add # Right / Bottom
  276. bottom_operand = operator.sub # Top / Left
  277. case "west" | "north-flipped":
  278. left_operand = operator.add # Right
  279. top_operand = operator.add # Bottom
  280. right_operand = operator.sub # Left
  281. bottom_operand = operator.sub # Top
  282. case "west-flipped" | "north":
  283. left_operand = operator.add # Right / Bottom
  284. top_operand = operator.sub # Top / Left
  285. right_operand = operator.sub # Left / Top
  286. bottom_operand = operator.add # Bottom / Right
  287. """ Coords case
  288. X and Y need to be swapped in case of a North or South facing Karel, yet the original vlaues have to be returned. (To prevent diagonal relative translation)
  289. """
  290. if orientation.lower() == "north" or orientation.lower() == "north-flipped" or orientation.lower() == "south" or orientation.lower() == "south-flipped":
  291. x = centre_y
  292. y = centre_x
  293. else:
  294. x = centre_x
  295. y = centre_y
  296. # Borders
  297. left = left_operand(x, size / 2)
  298. top = top_operand(y, size / 2)
  299. right = right_operand(x, size / 2)
  300. bottom = bottom_operand(y, size / 2)
  301. margin = size / 8
  302. appendage_multiplier = margin * 0.6
  303. # Body borders
  304. body_left = left_operand(x, size / 3)
  305. body_top = top
  306. body_right = right_operand(x, size / 3)
  307. body_bottom = bottom_operand(y, size / 2.6)
  308. eye_left = right_operand(body_left, margin)
  309. eye_top = bottom_operand(body_top, margin)
  310. eye_right = left_operand(body_right, margin)
  311. eye_bottom = top_operand(body_bottom, margin * 2)
  312. # Body coordinates
  313. top_left_corner = body_left, body_top
  314. left_diagonal_top = body_left, top_operand(body_bottom, margin)
  315. left_diagonal_bottom = eye_left, body_bottom
  316. right_diagonal_top = eye_right, body_top
  317. right_diagonal_bottom = body_right, bottom_operand(body_top, margin)
  318. bottom_right_corner = body_right, body_bottom
  319. mouth_left_corner = x, bottom_operand(eye_bottom, margin)
  320. mouth_right_corner = eye_right, mouth_left_corner[1]
  321. # Left appendage borders
  322. leftLeg_left = left_operand(body_left, margin)
  323. leftLeg_top = eye_bottom
  324. leftLeg_right = body_left
  325. leftLeg_bottom = bottom_operand(leftLeg_top, appendage_multiplier)
  326. leftFoot_left = leftLeg_left
  327. leftFoot_top = leftLeg_bottom
  328. leftFoot_right = right_operand(leftLeg_left, appendage_multiplier)
  329. leftFoot_bottom = bottom_operand(leftFoot_top, appendage_multiplier)
  330. # Right appendage borders
  331. rightLeg_left = x
  332. rightLeg_top = body_bottom
  333. rightLeg_right = right_operand(rightLeg_left, appendage_multiplier)
  334. rightLeg_bottom = bottom
  335. rightFoot_left = rightLeg_right
  336. rightFoot_top = top_operand(bottom, appendage_multiplier)
  337. rigthFoot_right = right_operand(rightLeg_right, appendage_multiplier)
  338. rightFoot_bottom = bottom
  339. # Draw Karel
  340. match orientation.lower():
  341. case "east" | "east-flipped" | "west" | "west-flipped":
  342. if not transparent:
  343. # Meat
  344. top_fill = canvas.create_rectangle(
  345. top_left_corner[0],
  346. top_left_corner[1],
  347. right_diagonal_top[0],
  348. eye_top,
  349. background,
  350. background
  351. )
  352. top_corner_fill = canvas.create_polygon(
  353. right_diagonal_top[0] , right_diagonal_top[1],
  354. right_diagonal_bottom[0], right_diagonal_bottom[1],
  355. eye_right, eye_top,
  356. color = background,
  357. outline = background
  358. )
  359. left_fill = canvas.create_rectangle(
  360. top_left_corner[0],
  361. eye_top,
  362. eye_left,
  363. left_diagonal_top[1],
  364. background,
  365. background
  366. )
  367. right_fill = canvas.create_rectangle(
  368. eye_right,
  369. eye_top,
  370. right_diagonal_bottom[0],
  371. eye_bottom,
  372. background,
  373. background
  374. )
  375. bottom_fill = canvas.create_rectangle(
  376. eye_left,
  377. eye_bottom,
  378. bottom_right_corner[0],
  379. bottom_right_corner[1],
  380. background,
  381. background
  382. )
  383. bottom_corner_fill = canvas.create_polygon(
  384. left_diagonal_top[0], left_diagonal_top[1],
  385. eye_left, left_diagonal_top[1],
  386. left_diagonal_bottom[0], left_diagonal_bottom[1],
  387. color = background,
  388. outline = background
  389. )
  390. # Outlines
  391. top_line = canvas.create_line(
  392. top_left_corner[0], top_left_corner[1],
  393. right_diagonal_top[0], right_diagonal_top[1],
  394. colour
  395. )
  396. top_corner = canvas.create_line(
  397. right_diagonal_top[0], right_diagonal_top[1],
  398. right_diagonal_bottom[0], right_diagonal_bottom[1],
  399. colour
  400. )
  401. left_line = canvas.create_line(
  402. top_left_corner[0], top_left_corner[1],
  403. left_diagonal_top[0], left_diagonal_top[1],
  404. colour
  405. )
  406. bottom_corner = canvas.create_line(
  407. left_diagonal_top[0], left_diagonal_top[1],
  408. left_diagonal_bottom[0], left_diagonal_bottom[1],
  409. colour
  410. )
  411. bottom_line = canvas.create_line(
  412. left_diagonal_bottom[0], left_diagonal_bottom[1],
  413. bottom_right_corner[0], bottom_right_corner[1],
  414. colour
  415. )
  416. right_line = canvas.create_line(
  417. right_diagonal_bottom[0], right_diagonal_bottom[1],
  418. bottom_right_corner[0], bottom_right_corner[1],
  419. colour
  420. )
  421. left_leg = canvas.create_rectangle(
  422. leftLeg_left,
  423. leftLeg_top,
  424. leftLeg_right,
  425. leftLeg_bottom,
  426. colour,
  427. colour
  428. )
  429. left_foot = canvas.create_rectangle(
  430. leftFoot_left,
  431. leftFoot_top,
  432. leftFoot_right,
  433. leftFoot_bottom,
  434. colour,
  435. colour
  436. )
  437. right_leg = canvas.create_rectangle(
  438. rightLeg_left,
  439. rightLeg_top,
  440. rightLeg_right,
  441. rightLeg_bottom,
  442. colour,
  443. colour
  444. )
  445. right_foot = canvas.create_rectangle(
  446. rightFoot_left,
  447. rightFoot_top,
  448. rigthFoot_right,
  449. rightFoot_bottom,
  450. colour,
  451. colour
  452. )
  453. eye = canvas.create_rectangle(
  454. eye_left,
  455. eye_top,
  456. eye_right,
  457. eye_bottom,
  458. "transparent",
  459. colour,
  460. )
  461. mouth = canvas.create_line(
  462. mouth_left_corner[0], mouth_left_corner[1],
  463. mouth_right_corner[0], mouth_right_corner[1],
  464. colour
  465. )
  466. case "north" | "north-flipped" | "south" | "south-flipped":
  467. if not transparent:
  468. # Meat
  469. top_fill = canvas.create_rectangle(
  470. top_left_corner[1], # Top Y
  471. right_diagonal_top[0], # Right X
  472. eye_top, # Bottom Y
  473. top_left_corner[0], # Left X
  474. background,
  475. background
  476. )
  477. top_corner_fill = canvas.create_polygon(
  478. right_diagonal_top[1] , right_diagonal_top[0],
  479. right_diagonal_bottom[1], right_diagonal_bottom[0],
  480. eye_top, eye_right,
  481. color = background,
  482. outline = background
  483. )
  484. left_fill = canvas.create_rectangle(
  485. eye_top,
  486. eye_left,
  487. left_diagonal_top[1],
  488. top_left_corner[0],
  489. background,
  490. background
  491. )
  492. right_fill = canvas.create_rectangle(
  493. eye_top,
  494. right_diagonal_bottom[0],
  495. eye_bottom,
  496. eye_right,
  497. background,
  498. background
  499. )
  500. bottom_fill = canvas.create_rectangle(
  501. eye_bottom,
  502. bottom_right_corner[0],
  503. bottom_right_corner[1],
  504. eye_left,
  505. background,
  506. background
  507. )
  508. bottom_corner_fill = canvas.create_polygon(
  509. left_diagonal_top[1], left_diagonal_top[0],
  510. left_diagonal_top[1], eye_left,
  511. left_diagonal_bottom[1], left_diagonal_bottom[0],
  512. color = background,
  513. outline = background
  514. )
  515. # Outlines
  516. top_line = canvas.create_line(
  517. top_left_corner[1], top_left_corner[0],
  518. right_diagonal_top[1], right_diagonal_top[0],
  519. colour
  520. )
  521. top_corner = canvas.create_line(
  522. right_diagonal_top[1], right_diagonal_top[0],
  523. right_diagonal_bottom[1], right_diagonal_bottom[0],
  524. colour
  525. )
  526. left_line = canvas.create_line(
  527. top_left_corner[1], top_left_corner[0],
  528. left_diagonal_top[1], left_diagonal_top[0],
  529. colour
  530. )
  531. bottom_corner = canvas.create_line(
  532. left_diagonal_top[1], left_diagonal_top[0],
  533. left_diagonal_bottom[1], left_diagonal_bottom[0],
  534. colour
  535. )
  536. bottom_line = canvas.create_line(
  537. left_diagonal_bottom[1], left_diagonal_bottom[0],
  538. bottom_right_corner[1], bottom_right_corner[0],
  539. colour
  540. )
  541. right_line = canvas.create_line(
  542. right_diagonal_bottom[1], right_diagonal_bottom[0],
  543. bottom_right_corner[1], bottom_right_corner[0],
  544. colour
  545. )
  546. left_leg = canvas.create_rectangle(
  547. leftLeg_top,
  548. leftLeg_right,
  549. leftLeg_bottom,
  550. leftLeg_left,
  551. colour,
  552. colour
  553. )
  554. left_foot = canvas.create_rectangle(
  555. leftFoot_top,
  556. leftFoot_right,
  557. leftFoot_bottom,
  558. leftFoot_left,
  559. colour,
  560. colour
  561. )
  562. right_leg = canvas.create_rectangle(
  563. rightLeg_top,
  564. rightLeg_right,
  565. rightLeg_bottom,
  566. rightLeg_left,
  567. colour,
  568. colour
  569. )
  570. right_foot = canvas.create_rectangle(
  571. rightFoot_top,
  572. rigthFoot_right,
  573. rightFoot_bottom,
  574. rightFoot_left,
  575. colour,
  576. colour
  577. )
  578. eye = canvas.create_rectangle(
  579. eye_top,
  580. eye_right,
  581. eye_bottom,
  582. eye_left,
  583. "transparent",
  584. colour,
  585. )
  586. mouth = canvas.create_line(
  587. mouth_left_corner[1], mouth_left_corner[0],
  588. mouth_right_corner[1], mouth_right_corner[0],
  589. colour
  590. )
  591. # Return each object so it can later be altered/destroyed
  592. if transparent:
  593. shapes = {
  594. "top_line": top_line,
  595. "top_corner": top_corner,
  596. "left_line": left_line,
  597. "bottom_corner": bottom_corner,
  598. "bottom_line": bottom_line,
  599. "right_line": right_line,
  600. "left_leg": left_leg,
  601. "left_foot": left_foot,
  602. "right_foot": right_foot,
  603. "right_leg": right_leg,
  604. "right_foot": right_foot,
  605. "eye": eye,
  606. "mouth": mouth
  607. }
  608. else: # Not transparent
  609. shapes = {
  610. "top_fill": top_fill,
  611. "top_corner_fill": top_corner_fill,
  612. "left_fill": left_fill,
  613. "right_fill": right_fill,
  614. "bottom_fill": bottom_fill,
  615. "bottom_corner_fill": bottom_corner_fill,
  616. "top_line": top_line,
  617. "top_corner": top_corner,
  618. "left_line": left_line,
  619. "bottom_corner": bottom_corner,
  620. "bottom_line": bottom_line,
  621. "right_line": right_line,
  622. "left_leg": left_leg,
  623. "left_foot": left_foot,
  624. "right_foot": right_foot,
  625. "right_leg": right_leg,
  626. "right_foot": right_foot,
  627. "eye": eye,
  628. "mouth": mouth
  629. }
  630. arguments = [canvas, centre_x, centre_y, size, orientation.lower(), colour, background, transparent]
  631. logger.debug(f"Created Karel: {shapes, arguments}")
  632. return [shapes, arguments]