@@ -58,33 +58,78 @@ def __init__(self, x: int, y: int, block_grid: Grid, block_pen: LayerTurtle):
5858 _draw_grid (block_grid , block_pen )
5959
6060 def move_down (self , grid : Grid ) -> bool :
61- if _check_block_grid_placement (self .block_grid , self .x , self .y + 1 , grid = grid ):
61+ if _check_bad_block_grid_placement (self .block_grid , self .x , self .y + 1 , grid = grid ):
6262 return False
6363 self .y += 1
6464 self .sync_image ()
6565 return True
6666
6767 def move_right (self , grid : Grid ) -> bool :
68- if _check_block_grid_placement (self .block_grid , self .x + 1 , self .y , grid = grid ):
68+ if _check_bad_block_grid_placement (self .block_grid , self .x + 1 , self .y , grid = grid ):
6969 return False
7070 self .x += 1
7171 self .sync_image ()
7272 return True
7373
7474 def move_left (self , grid : Grid ) -> bool :
75- if _check_block_grid_placement (self .block_grid , self .x - 1 , self .y , grid = grid ):
75+ if _check_bad_block_grid_placement (self .block_grid , self .x - 1 , self .y , grid = grid ):
7676 return False
7777 self .x -= 1
7878 #print(f"* left ==> x={self.x}")
7979 self .sync_image ()
8080 return True
8181
82+ def rotate (self , grid : Grid ) -> bool :
83+ (rotated_block_grid , y_offset ) = _rotate_block_grid_if_possible (self .block_grid , self .x , self .y , grid = grid )
84+ if rotated_block_grid is None :
85+ return False
86+ self .block_grid = rotated_block_grid
87+ self .y += y_offset
88+ self .block_pen .clear ()
89+ _draw_grid (self .block_grid , self .block_pen )
90+ return True
91+
92+
8293 def sync_image (self ):
8394 anchor_x = self .x * _block_unit_width
8495 anchor_y = self .y * _block_unit_width
8596 self .block_pen .setLevelAnchor (anchor_x , anchor_y )
8697
8798
99+
100+ def _check_bad_block_grid_cells_placement (grid_cells : list [list [int ]], block_grid_x_off : int , block_grid_y_offset : int , grid : Grid , check_boundary : bool = True ) -> bool :
101+ n_rows = len (grid_cells )
102+ n_cols = len (grid_cells [0 ]) if n_rows > 0 else 0
103+ for y in range (n_rows ):
104+ for x in range (n_cols ):
105+ if grid_cells [y ][x ] != 0 :
106+ row_idx = y + block_grid_y_offset
107+ col_idx = x + block_grid_x_off
108+ if row_idx < 0 :
109+ continue # never mind above the grid
110+ if row_idx < 0 or row_idx >= grid .n_rows :
111+ if not check_boundary :
112+ continue
113+ return True
114+ if col_idx < 0 or col_idx >= grid .n_cols :
115+ if not check_boundary :
116+ continue
117+ return True
118+ if grid .get_value (row_idx , col_idx ) != 0 :
119+ return True
120+ return False
121+
122+
123+ def _rotate_block_grid_cells (grid_cells : list [list [int ]]) -> list [list [int ]]:
124+ rotated = []
125+ for x in range (len (grid_cells [0 ])):
126+ new_row = []
127+ for y in range (len (grid_cells ) - 1 , - 1 , - 1 ):
128+ new_row .append (grid_cells [y ][x ])
129+ rotated .append (new_row )
130+ return rotated
131+
132+
88133def _randomize_grid (randomize_row_count : int ) -> Grid :
89134 grid_cells = []
90135 for y in range (_grid_n_rows ):
@@ -120,25 +165,38 @@ def _draw_grid(grid: Grid, pen: LayerTurtle):
120165 color_number = grid .get_value (y , x )
121166 _draw (x , y , color_number , pen )
122167
123- def _check_block_grid_placement (block_grid : Grid , block_grid_x_off : int , block_grid_y_offset : int , grid : Grid , check_boundary : bool = True ) -> bool :
124- for y in range (block_grid .n_rows ):
125- for x in range (block_grid .n_cols ):
126- if block_grid .get_value (y , x ) != 0 :
127- row_idx = y + block_grid_y_offset
128- col_idx = x + block_grid_x_off
129- if row_idx < 0 :
130- continue # never mind above the grid
131- if row_idx < 0 or row_idx >= grid .n_rows :
132- if not check_boundary :
133- continue
134- return True
135- if col_idx < 0 or col_idx >= grid .n_cols :
136- if not check_boundary :
137- continue
138- return True
139- if grid .get_value (row_idx , col_idx ) != 0 :
140- return True
141- return False
168+ def _check_bad_block_grid_placement (block_grid : Grid , block_grid_x_off : int , block_grid_y_offset : int , grid : Grid , check_boundary : bool = True ) -> bool :
169+ if True :
170+ return _check_bad_block_grid_cells_placement (block_grid .grid_cells , block_grid_x_off , block_grid_y_offset , grid , check_boundary )
171+ else :
172+ for y in range (block_grid .n_rows ):
173+ for x in range (block_grid .n_cols ):
174+ if block_grid .get_value (y , x ) != 0 :
175+ row_idx = y + block_grid_y_offset
176+ col_idx = x + block_grid_x_off
177+ if row_idx < 0 :
178+ continue # never mind above the grid
179+ if row_idx < 0 or row_idx >= grid .n_rows :
180+ if not check_boundary :
181+ continue
182+ return True
183+ if col_idx < 0 or col_idx >= grid .n_cols :
184+ if not check_boundary :
185+ continue
186+ return True
187+ if grid .get_value (row_idx , col_idx ) != 0 :
188+ return True
189+ return False
190+
191+
192+ def _rotate_block_grid_if_possible (block_grid : Grid , block_grid_x_off : int , block_grid_y_offset : int , grid : Grid ) -> (Grid , int ):
193+ block_grid_cells = block_grid .grid_cells
194+ rotated_cells = _rotate_block_grid_cells (block_grid_cells )
195+ y_offset = len (rotated_cells ) - len (block_grid_cells )
196+ if _check_bad_block_grid_cells_placement (rotated_cells , block_grid_x_off , block_grid_y_offset + y_offset , grid , check_boundary = True ):
197+ return (None , None )
198+ rotated_block_grid = Grid (grid_cells = rotated_cells )
199+ return (rotated_block_grid , y_offset )
142200
143201
144202def _commit_block_grid (block_grid : Grid , block_grid_x_off : int , block_grid_y_offset : int , grid : Grid ):
0 commit comments