def test_get_next_lfb_on_grid_5(self): state = np.array([ [1, 1, 1, 1], [1, 1, 1, 1], [0, 0, 0, 1] ]) res = SolutionChecker.get_next_lfb_on_grid(state) self.assertEqual(res, (2, 0))
def get_next_turn(self, state, tile, val=1): new_board = np.copy(state.board) next_position = SolutionChecker.get_next_lfb_on_grid(new_board) # one without the other should not be possible if not next_position and len(state.tiles) == 0: print('solution found!') return ALL_TILES_USED, None elif not next_position: return NO_NEXT_POSITION_TILES_UNUSED, None success, new_board = SolutionChecker.place_element_on_grid_given_grid( tile, SolutionChecker.get_next_lfb_on_grid(new_board), val, new_board, get_cols(new_board), get_rows(new_board)) if not success: # cannot place the tile. this branch will not be considered return TILE_CANNOT_BE_PLACED, None return True, new_board
def get_best_tile_by_prediction(grid, tiles, prediction, dg, predict_move_index=True): ''' 1. mask invalid moves 2. renormalize the probability distribution 3. for each tile sum up which would be the probability of placing that tile in LFB 4. return the new grid Returns the tile which is the best in format [(rows, cols), position_to_place] ''' next_lfb = SolutionChecker.get_next_lfb_on_grid(grid) max_probability = -math.inf max_index = 0 best_tile = None rows, cols = grid.shape tile_probabilities = defaultdict(int) tile_counts = defaultdict(int) tiles_to_iterate_on = tiles SOFTMAX = False best_tile_individual = None best_prediction = 0 for i, tile in enumerate(tiles_to_iterate_on): tile = tuple(tile) success, _ = SolutionChecker.place_element_on_grid_given_grid( tile, next_lfb, val=1, grid=grid, cols=cols, rows=rows, get_only_success=True) if not success: continue if predict_move_index and SOFTMAX: ''' The best tile is predicted by taking the sum of the tiles with the same (width, height) ''' if tuple(tile) == (0, 0): continue tile_probabilities[tile] += prediction[i] tile_counts[tile] += 1 elif predict_move_index: if tuple(tile) == (0, 0): continue if prediction[i] > best_prediction: best_tile_individual = tile best_prediction = prediction[i] # if tile[0] * tile[1] > best_prediction: # best_tile_individual = tile # best_prediction = tile[0] * tile[1] else: probability = np.sum(prediction[next_lfb[0]:next_lfb[0] + tile[0], next_lfb[1]:next_lfb[1] + tile[1]]) # scale with area # probability = probability / (tile[0] * tile[1]) if probability > max_probability: max_index = i max_probability = probability best_tile = [tile, next_lfb] if predict_move_index and SOFTMAX: max_tile = None max_val = -math.inf for k in tile_probabilities.keys(): v = tile_probabilities[k] / tile_counts[k] if True: if v > max_val: max_tile = k max_val = v else: if k[0] * k[1] > max_val: max_tile = k max_val = k[0] * k[1] if max_tile: best_tile = [max_tile, next_lfb] elif predict_move_index: best_tile = [best_tile_individual, next_lfb] # print(tile_probabilities) # print(tile_counts) if not best_tile: print('No valid tile placement found') return best_tile
def test_get_next_lfb_on_grid_3(self): state = np.array([[1, 1, 1], [1, 1, 1]]) res = SolutionChecker.get_next_lfb_on_grid(state) self.assertIsNone(res)