karel_asset.py 24 KB

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