def generate_next_board_states(state): """ Generates a list of board states from all the possible next legal moves :param state: Current board state from which the next legal moves will be evaluated :return: list of board states from all the possible next legal moves """ # If the max number of turns has been reached, then the game is over if state.turn_number == GameConstants.MAX_TURN_NUMBER or state.game_over: state.game_over = True return [] state_list = list() # Generate a new state with updated meta data for the next turn new_state = copy.deepcopy(state) new_state.turn_number += 1 new_state.recycling_mode = new_state.turn_number >= GameConstants.MAX_CARDS_IN_GAME - 1 new_state.active_player = not state.active_player if not state.recycling_mode: state_list = generate_next_placed_board_states(new_state) else: # For each card you can remove, make a new state and call generate_next_placed_board_states on it # Append all the possible next states into a super list of board states and return states_with_removed_cards = generate_next_removed_board_states(new_state) for state, old_card in states_with_removed_cards: state_list.extend(generate_next_placed_board_states(state, old_card)) # For each state generated, check if it triggered a victory condition and set its game_over values appropriately for state in state_list: BoardHelper.victory_move(state.last_moved_card.coords1, state) BoardHelper.victory_move(state.last_moved_card.coords2, state) return state_list
def is_valid(self): for row in self.board: if BoardHelper.is_set_valid(row) is False: return False for column_index in range(0, 9): if BoardHelper.is_set_valid(self.get_column(column_index)) is False: return False for square_index in range(0, 9): if BoardHelper.is_set_valid(self.get_3_by_3_square(square_index)) is False: return False return True
def PlotSegmentedBoard(board_image, fen): grids = BoardHelper.ImageToGrids(board_image, g_grid_size, g_grid_size).reshape(g_grid_num, g_grid_size, g_grid_size, 3) labels = BoardHelper.FENtoL(fen) fig = plt.figure(figsize=(15, 15)) plt.suptitle(fen, size=16) for i in range(64): plt.subplot(8, 8, i+1) plt.imshow(grids[i,:]) plt.title(labels[i]) plt.xticks(()) plt.yticks(()) return fig
def PreprocessKernel(name): img = DataHelper.ReadImage(name, gray=True) grids = SVCClassifier.SVCPreprocess(img) labels = np.array( BoardHelper.FENtoOneHot( DataHelper.GetCleanNameByPath(name))).argmax(axis=1) return grids, labels
def setBoards(self): ret, self.__boardsinfodict = BoardHelper.getBoardsInfo() if not ret: self.__boardsinfodict = {} return for boardname in self.__boardsinfodict.keys(): self.ui.mcuCombox.addItem(boardname)
def func_generator(train_file_names): for image_file_name in train_file_names: img = DataHelper.ReadImage(image_file_name) x = CNNClassifier.PreprocessImage(img) y = np.array( BoardHelper.FENtoOneHot( DataHelper.GetCleanNameByPath(image_file_name))) yield x, y
def TestAccuracy(self, test_file_names): num_files = len(test_file_names) predict_result = self.__model__.predict( CNNClassifier.func_generator(test_file_names)).argmax(axis=1) predict_result = predict_result.reshape(num_files, -1) predicted_fen_arr = np.array([ BoardHelper.LtoFEN(BoardHelper.LabelArrayToL(labels)) for labels in predict_result ]) test_fens = np.array([ DataHelper.GetCleanNameByPath(file_name) for file_name in test_file_names ]) final_accuracy = (predicted_fen_arr == test_fens).astype( np.float).mean() return final_accuracy
def generate_board_states_placement(state, coord, id, old_card, orientations): # Possible states resulting in the placement of a card state_list = list() for orientation in orientations: new_state = copy.deepcopy(state) new_card = Card(id, orientation, coord) # Make sure the card is in a new position orientation if old_card and old_card.orientation == new_card.orientation and old_card.coords1 == new_card.coords1: continue # If there already exists a card in the cell then skip #if state.board[new_card.coords1].card or state.board[new_card.coords2].card: # print('This should never be reached {}'.format(state.top_empty_cell)) # break BoardHelper.fill_cells(new_card, new_state) new_state.last_moved_card = new_card state_list.append(new_state) return state_list
def test_is_set_valid(self): self.assertTrue(BoardHelper.is_set_valid([1, 2, 3, 4, 5, 6, 7, 8, 9], False)) self.assertFalse(BoardHelper.is_set_valid([2, 2, 3, 4, 5, 6, 7, 8, 9], False)) self.assertFalse(BoardHelper.is_set_valid([1, 2, 3, 4, 5, None, 7, 8, 9], False)) self.assertTrue(BoardHelper.is_set_valid([1, 2, 3, 4, 5, None, None, 8, 9], True)) self.assertTrue(BoardHelper.is_set_valid([2, 9, 3, 4, 5, 6, 7, 8, 1], False)) self.assertFalse(BoardHelper.is_set_valid([4, 2, 3, 4, 5, 6, 7, 8, 9], False))
def __deepcopy__(self, memodict={}): new_inst = BoardState() # Initialize the board with empty cells for row in range(GameConstants.NUM_ROWS): for col in range(GameConstants.NUM_COLS): new_inst.board[row, col] = Cell((row, col)) new_inst.turn_number = int(self.turn_number) new_inst.recycling_mode = bool(self.recycling_mode) new_inst.game_over = bool(self.game_over) new_inst.active_player = copy.copy(self.active_player) new_inst.heuristic_value = float( self.heuristic_value) if self.heuristic_value else None new_inst.winner = copy.copy(self.winner) for card in self.cards.values(): new_inst.cards[card.id] = Card(card.id, card.orientation, card.coords1) BoardHelper.fill_cells( card, new_inst) # This will also populate self.top_empty_cell if self.last_moved_card: new_inst.last_moved_card = new_inst.cards[self.last_moved_card.id] return new_inst
def PreprocessImage(image): image = transform.resize(image, (g_down_sampled_size, g_down_sampled_size), mode='constant') # 1st and 2nd dim is 8 grids = BoardHelper.ImageToGrids(image, g_down_sampled_grid_size, g_down_sampled_grid_size) # debug #plt.imshow(grids[0][3]) #plt.show() return grids.reshape(g_grid_row * g_grid_col, g_down_sampled_grid_size, g_down_sampled_grid_size, 3)
def generate_next_removed_board_states(state): state_list = list() last_horizontal = False # Pass through every empty cell at the top of a column and remove cards below rebuild_top_empty(state) for col, row in enumerate(state.top_empty_cell): # If the last card removed was a horizontal card, then this will be the second cell of the same card, ignore it if last_horizontal: last_horizontal = False continue if row > 0: card_below = state.board[row - 1, col].card # Don't move this card if it was the last card moved if card_below.id == state.last_moved_card.id: continue if card_below.horizontal: if col < GameConstants.NUM_COLS and row == state.top_empty_cell[col + 1] \ and card_below is state.board[row - 1, col + 1].card: # This is a legal horizontal card that can be removed last_horizontal = True else: # This is a horizontal card that cannot be removed continue # This is a legal vertical or Horizontal card that can be removed new_state = copy.deepcopy(state) BoardHelper.remove_cells(card_below.coords1, card_below.coords2, new_state) rebuild_top_empty(new_state) state_list.append((new_state, card_below)) return state_list
def solve(self): for (row_index, row) in enumerate(self.board.board): for (column_index, cell) in enumerate(row): if cell.value is None: square_index = BoardHelper.get_square_index(column_index, row_index) square = Square(self.board.get_3_by_3_square(square_index)) possible_values = cell.get_possible_values( row, self.board.get_column(column_index), square.get_as_list() ) if possible_values is not None: if len(possible_values) is 1: cell.set_value(possible_values[0]) self.squares_solved += 1 else: self.squares_unsolved += 1
def competition_heuristic(state): """ calculates a heuristic value given the board state :param state: BoardState object """ color_counter = [] fill_counter = [] # Check streaks, moving up along first column for row in range(0, GameConstants.NUM_ROWS): # Check Horizontally color_counter.extend( BoardHelper.count_streaks_along_line(Cell.get_color, row, 0, Dir.RIGHT, state.board)) fill_counter.extend( BoardHelper.count_streaks_along_line(Cell.get_fill, row, 0, Dir.RIGHT, state.board)) # Check Ascending Diagonals color_counter.extend( BoardHelper.count_streaks_along_line(Cell.get_color, row, 0, Dir.DIAG_UR, state.board)) fill_counter.extend( BoardHelper.count_streaks_along_line(Cell.get_fill, row, 0, Dir.DIAG_UR, state.board)) # Check Descending Diagonals color_counter.extend( BoardHelper.count_streaks_along_line(Cell.get_color, row, 0, Dir.DIAG_DR, state.board)) fill_counter.extend( BoardHelper.count_streaks_along_line(Cell.get_fill, row, 0, Dir.DIAG_DR, state.board)) # Check Streaks, moving right along first row for col in range(0, GameConstants.NUM_COLS): # Check vertical streaks color_counter.extend( BoardHelper.count_streaks_along_line(Cell.get_color, 0, col, Dir.UP, state.board)) fill_counter.extend( BoardHelper.count_streaks_along_line(Cell.get_fill, 0, col, Dir.UP, state.board)) if col != 0: # Check Ascending Diagonals color_counter.extend( BoardHelper.count_streaks_along_line(Cell.get_color, 0, col, Dir.DIAG_UR, state.board)) fill_counter.extend( BoardHelper.count_streaks_along_line(Cell.get_fill, 0, col, Dir.DIAG_UR, state.board)) # Check Descending Diagonals color_counter.extend( BoardHelper.count_streaks_along_line(Cell.get_color, 0, col, Dir.DIAG_DR, state.board)) fill_counter.extend( BoardHelper.count_streaks_along_line(Cell.get_fill, 0, col, Dir.DIAG_DR, state.board)) heuristic_val = 0 heuristic_val += color_counter.count(1) - fill_counter.count(1) heuristic_val += (color_counter.count(2) - fill_counter.count(2)) * 3 heuristic_val += (color_counter.count(3) - fill_counter.count(3)) * 20 heuristic_val += (color_counter.count(4) - fill_counter.count(4)) * 100000 return heuristic_val
def open_competition_heuristic(state): """ calculates a heuristic value given the board state :param state: BoardState object """ color_counter = [] fill_counter = [] # Check streaks, moving up along first column max_row = max(state.top_empty_cell) - 1 for row in range(0, GameConstants.NUM_ROWS): if row < max_row: # Check Horizontally color_counter.extend( BoardHelper.count_open_streaks_along_line( Cell.get_color, row, 0, Dir.RIGHT, state.board)) fill_counter.extend( BoardHelper.count_open_streaks_along_line( Cell.get_fill, row, 0, Dir.RIGHT, state.board)) # Check Ascending Diagonals color_counter.extend( BoardHelper.count_open_streaks_along_line(Cell.get_color, row, 0, Dir.DIAG_UR, state.board)) fill_counter.extend( BoardHelper.count_open_streaks_along_line(Cell.get_fill, row, 0, Dir.DIAG_UR, state.board)) # Check Descending Diagonals color_counter.extend( BoardHelper.count_open_streaks_along_line(Cell.get_color, row, 0, Dir.DIAG_DR, state.board)) fill_counter.extend( BoardHelper.count_open_streaks_along_line(Cell.get_fill, row, 0, Dir.DIAG_DR, state.board)) # Check Streaks, moving right along first row for col in range(0, GameConstants.NUM_COLS): # Check vertical streaks color_counter.extend( BoardHelper.count_open_streaks_along_line(Cell.get_color, 0, col, Dir.UP, state.board)) fill_counter.extend( BoardHelper.count_open_streaks_along_line(Cell.get_fill, 0, col, Dir.UP, state.board)) if col != 0: # Check Ascending Diagonals color_counter.extend( BoardHelper.count_open_streaks_along_line( Cell.get_color, 0, col, Dir.DIAG_UR, state.board)) fill_counter.extend( BoardHelper.count_open_streaks_along_line( Cell.get_fill, 0, col, Dir.DIAG_UR, state.board)) # Check Descending Diagonals color_counter.extend( BoardHelper.count_open_streaks_along_line( Cell.get_color, 0, col, Dir.DIAG_DR, state.board)) fill_counter.extend( BoardHelper.count_open_streaks_along_line( Cell.get_fill, 0, col, Dir.DIAG_DR, state.board)) heuristic_val = 0 heuristic_val += color_counter.count(1) - fill_counter.count(1) heuristic_val += (color_counter.count(2) - fill_counter.count(2)) * 30 heuristic_val += (color_counter.count(3) - fill_counter.count(3)) * 200000 heuristic_val += (color_counter.count(5) - fill_counter.count(5)) * 20000000 if not state.maximizing: sign = 1 else: sign = -1 # Play towards center initially if state.turn_number < 2: heuristic_val -= sign * abs((GameConstants.NUM_COLS - 1) / 2 - state.last_moved_card.coords1[1]) * 999999 # Check for a victory color_win = (4 in color_counter) fill_win = (4 in fill_counter) # If both get a 4-streak, the active player is the true winner if color_win and fill_win: heuristic_val = sign * 1000000000 elif color_win: heuristic_val = 1000000000 elif fill_win: heuristic_val = -1000000000 return heuristic_val
test_SVC = False SVC_load_model = True if test_ABC: abc = Classifiers.ABClassifier() train_names = DataHelper.GetFileNamesInDir(g_train_dir) if ABC_load_model: print("abc: loading model from " + abc_model_file) abc.LoadModel(abc_model_file) else: abc.Train(train_names) y_truth = BoardHelper.FENtoL(DataHelper.GetCleanNameByPath(a_random_file)) img = DataHelper.ReadImage(a_random_file, gray = True) pred = abc.Predict(img) print("truth: ", ''.join(y_truth)) print("pred : ", ''.join(pred)) # save model if not ABC_load_model: print("abc: saving model to " + abc_model_file) abc.SaveModel(abc_model_file) if test_SVC: svc = Classifiers.SVCClassifier() train_names = DataHelper.GetFileNamesInDir(g_train_dir)
def Predict(self, query_data): grids = SVCClassifier.SVCPreprocess(query_data) y_pred = self.__svc__.predict(grids) return BoardHelper.LabelArrayToL(y_pred)
def test_get_square_index(self): self.assertEqual(3, BoardHelper.get_square_index(2, 4)) self.assertEqual(5, BoardHelper.get_square_index(6, 3)) self.assertEqual(8, BoardHelper.get_square_index(8, 8))
def Predict(self, query_data): grids = CNNClassifier.PreprocessImage(query_data) y_pred = self.__model__.predict(grids).argmax(axis=1) return BoardHelper.LabelArrayToL(y_pred)