1+ # SPDX-FileCopyrightText: 2024 Tim Cocks for Adafruit Industries
2+ #
3+ # SPDX-License-Identifier: MIT
4+ """
5+ Karel the Robot helper class
6+ """
7+
18import json
29import time
310
3441 "dark_green" ,
3542 "turquoise" ,
3643 "dark_blue" ,
37- "dark_red"
44+ "dark_red" ,
3845]
3946COLOR_VALUES = [
4047 0xFFFFFF ,
5259 0x008700 ,
5360 0x00C0C0 ,
5461 0x0000AA ,
55- 0x800000
62+ 0x800000 ,
5663]
5764
5865
@@ -69,10 +76,15 @@ class NoBeepersInBag(Exception):
6976
7077
7178class Karel :
72- def __init__ (self , spritesheet_bmp , spritesheet_palette , world_width = 20 , world_height = 15 ):
73-
74- self .tilegrid = TileGrid (spritesheet_bmp , pixel_shader = spritesheet_palette ,
75- default_tile = 0 , tile_width = TILE_SIZE , tile_height = TILE_SIZE )
79+ def __init__ (self , spritesheet_bmp , spritesheet_palette ):
80+
81+ self .tilegrid = TileGrid (
82+ spritesheet_bmp ,
83+ pixel_shader = spritesheet_palette ,
84+ default_tile = 0 ,
85+ tile_width = TILE_SIZE ,
86+ tile_height = TILE_SIZE ,
87+ )
7688 self ._direction = EAST
7789 self .beeper_count = 0
7890
@@ -111,15 +123,16 @@ def y(self, new_value):
111123
112124class World :
113125 def __init__ (self , display , world_width = 10 , world_height = 10 , beeper_limit = False ):
114- print ("world init()" )
115126 self .world_width = world_width
116127 self .world_height = world_height
117128 color_count = len (COLOR_NAMES )
118129 self .background_bmp = Bitmap (world_width , world_height , color_count )
119130 self .background_palette = Palette (color_count )
120131 for i , color_val in enumerate (COLOR_VALUES ):
121132 self .background_palette [i ] = color_val
122- self .background_tilegrid = TileGrid (bitmap = self .background_bmp , pixel_shader = self .background_palette )
133+ self .background_tilegrid = TileGrid (
134+ bitmap = self .background_bmp , pixel_shader = self .background_palette
135+ )
123136 self .background_group = Group (scale = TILE_SIZE )
124137 self .background_group .append (self .background_tilegrid )
125138 self .display = display
@@ -128,12 +141,20 @@ def __init__(self, display, world_width=10, world_height=10, beeper_limit=False)
128141 self .world_group .append (self .background_group )
129142
130143 lib_dir = "/" .join (__file__ .split ("/" )[0 :3 ])
131- # print(lib_dir)
132- self .spritesheet_bmp , self .spritesheet_palette = adafruit_imageload .load (f"{ lib_dir } /spritesheet_24px.png" )
144+ self .spritesheet_bmp , self .spritesheet_palette = adafruit_imageload .load (
145+ f"{ lib_dir } /spritesheet.png"
146+ )
133147 self .spritesheet_palette .make_transparent (0 )
134148
135- self .world_tilegrid = TileGrid (self .spritesheet_bmp , pixel_shader = self .spritesheet_palette ,
136- tile_width = TILE_SIZE , tile_height = TILE_SIZE , width = 20 , height = 15 , default_tile = 7 )
149+ self .world_tilegrid = TileGrid (
150+ self .spritesheet_bmp ,
151+ pixel_shader = self .spritesheet_palette ,
152+ tile_width = TILE_SIZE ,
153+ tile_height = TILE_SIZE ,
154+ width = 20 ,
155+ height = 15 ,
156+ default_tile = 7 ,
157+ )
137158
138159 self .beeper_limit = beeper_limit
139160
@@ -154,24 +175,24 @@ def _init_beeper_counts(self):
154175
155176 self .beeper_count_labels = {}
156177 self .beeper_counts = []
157- for y in range (self .background_bmp . width ):
158- self .beeper_counts .append ([0 for x in range (self .background_bmp . width )])
178+ for _ in range (self .world_height ):
179+ self .beeper_counts .append ([0 for x in range (self .world_width )])
159180
160181 def load_state (self , state_obj ):
161182 self ._init_beeper_counts ()
162183 if "beeper_counts" in state_obj ["input" ]:
163184 for beeper_count_loc_str in state_obj ["input" ]["beeper_counts" ].keys ():
164185 beeper_count_loc = [int (_ ) for _ in beeper_count_loc_str .split ("," )]
165- print (beeper_count_loc )
166- self .beeper_counts [world .world_height - 1 - beeper_count_loc [1 ]][beeper_count_loc [0 ]] \
167- = state_obj ["input" ]["beeper_counts" ][beeper_count_loc_str ]
168- for row in self .beeper_counts :
169- print (row )
186+ self .beeper_counts [world .world_height - 1 - beeper_count_loc [1 ]][
187+ beeper_count_loc [0 ]
188+ ] = state_obj ["input" ]["beeper_counts" ][beeper_count_loc_str ]
170189 update_beeper_count_labels ()
171190
172191 self .karel .x = state_obj ["input" ]["karel" ]["x" ]
173192 self .karel .y = self .world_height - 1 - state_obj ["input" ]["karel" ]["y" ]
174- self .karel .direction = DIRECTION_WORDS .index (state_obj ["input" ]["karel" ]["direction" ])
193+ self .karel .direction = DIRECTION_WORDS .index (
194+ state_obj ["input" ]["karel" ]["direction" ]
195+ )
175196
176197 for y , row in enumerate (state_obj ["input" ]["world" ]):
177198 for x , cell in enumerate (row ):
@@ -185,15 +206,21 @@ def check_goal_state(self, state_obj):
185206 if self .karel .x != state_obj ["goal" ]["karel" ]["x" ]:
186207 print ("karel x incorrect" )
187208 return False
188- if self .karel .direction != DIRECTION_WORDS .index (state_obj ["goal" ]["karel" ]["direction" ]):
209+ if self .karel .direction != DIRECTION_WORDS .index (
210+ state_obj ["goal" ]["karel" ]["direction" ]
211+ ):
189212 print ("karel dir incorrect" )
190213 return False
191214
192215 if "beeper_counts" in state_obj ["goal" ]:
193216 for beeper_count_loc_str in state_obj ["goal" ]["beeper_counts" ].keys ():
194217 beeper_count_loc = [int (_ ) for _ in beeper_count_loc_str .split ("," )]
195- if self .beeper_counts [world .world_height - 1 - beeper_count_loc [1 ]][beeper_count_loc [0 ]] != \
196- state_obj ["goal" ]["beeper_counts" ][beeper_count_loc_str ]:
218+ if (
219+ self .beeper_counts [world .world_height - 1 - beeper_count_loc [1 ]][
220+ beeper_count_loc [0 ]
221+ ]
222+ != state_obj ["goal" ]["beeper_counts" ][beeper_count_loc_str ]
223+ ):
197224 print (f"beeper count incorrect { beeper_count_loc } " )
198225 return False
199226
@@ -202,34 +229,18 @@ def check_goal_state(self, state_obj):
202229
203230 goal_cell_index = state_obj ["goal" ]["world" ][y ][x ]
204231 if self .world_tilegrid [x , y ] != goal_cell_index :
205- print (f"world mismatch: { (x , y )} : { self .world_tilegrid [x , y ]} != { goal_cell_index } " )
232+ print (
233+ f"world mismatch: { (x , world .world_height - 1 - y )} : "
234+ + f"{ self .world_tilegrid [x , y ]} != { goal_cell_index } "
235+ )
206236 return False
207-
208- # print(f"({x}, {y}) goal: {goal_cell_index} actual: {self.world_tilegrid[x, y]}")
209- # if goal_cell_index == 0:
210- # if self.karel.x != x or self.karel.y != y or self.karel.direction != EAST:
211- # return False
212- # elif goal_cell_index == 1:
213- # if self.karel.x != x or self.karel.y != y or self.karel.direction != NORTH:
214- # return False
215- # elif goal_cell_index == 2:
216- # if self.karel.x != x or self.karel.y != y or self.karel.direction != WEST:
217- # return False
218- # elif goal_cell_index == 3:
219- # if self.karel.x != x or self.karel.y != y or self.karel.direction != SOUTH:
220- # return False
221- # else:
222- # if self.world_tilegrid[x, y] != goal_cell_index:
223- # return False
224237 return True
225238
226239
227240world = World (board .DISPLAY )
228241
229242
230243def move ():
231- print (f"Moving: { world .karel .direction } " )
232-
233244 if front_is_blocked ():
234245 raise FrontIsBlocked ("Karel can't move there" )
235246
@@ -313,8 +324,9 @@ def left_is_blocked():
313324
314325def paint_corner (color ):
315326 if color not in COLOR_NAMES :
316- raise ValueError (f"Color { color } is not valid. Supported colors are { COLOR_NAMES } " )
317- print (f"name: { color } index: { COLOR_NAMES .index (color )} " )
327+ raise ValueError (
328+ f"Color { color } is not valid. Supported colors are { COLOR_NAMES } "
329+ )
318330 world .background_bmp [world .karel .x , world .karel .y ] = COLOR_NAMES .index (color )
319331
320332
@@ -330,12 +342,16 @@ def update_beeper_count_labels():
330342 if (x , y ) in world .beeper_count_labels :
331343 world .beeper_count_labels [(x , y )].text = str (count )
332344 else :
333- world .beeper_count_labels [(x , y )] = Label (terminalio .FONT ,
334- text = str (count ),
335- color = 0x000000 ,
336- anchor_point = (0.5 , 0.5 ),
337- anchored_position = (x * TILE_SIZE + TILE_SIZE // 2 ,
338- y * TILE_SIZE + TILE_SIZE // 2 ))
345+ world .beeper_count_labels [(x , y )] = Label (
346+ terminalio .FONT ,
347+ text = str (count ),
348+ color = 0x000000 ,
349+ anchor_point = (0.5 , 0.5 ),
350+ anchored_position = (
351+ x * TILE_SIZE + TILE_SIZE // 2 ,
352+ y * TILE_SIZE + TILE_SIZE // 2 ,
353+ ),
354+ )
339355 world .world_group .append (world .beeper_count_labels [(x , y )])
340356
341357
@@ -345,8 +361,9 @@ def pick_beeper():
345361
346362 world .karel .beeper_count += 1
347363
348- world .beeper_counts [world .karel .y ][world .karel .x ] = max (0 ,
349- world .beeper_counts [world .karel .y ][world .karel .x ] - 1 )
364+ world .beeper_counts [world .karel .y ][world .karel .x ] = max (
365+ 0 , world .beeper_counts [world .karel .y ][world .karel .x ] - 1
366+ )
350367 update_beeper_count_labels ()
351368 if world .beeper_counts [world .karel .y ][world .karel .x ] == 0 :
352369 world .world_tilegrid [world .karel .x , world .karel .y ] = 5
@@ -426,10 +443,11 @@ def right_is_clear():
426443def front_is_clear ():
427444 return not front_is_blocked ()
428445
446+
429447def load_state_file (state_filepath ):
430448 with open (state_filepath , "r" ) as f :
431449 ch_obj = json .load (f )
432450 world .load_state (ch_obj )
433451
434452 time .sleep (DELAY )
435- return ch_obj
453+ return ch_obj
0 commit comments