def get_rand_move(self): rand_rot = 0 rand_sideways = 0 rand_score = -99 NextScore = (0, 0, -99) # rot,sideways, score # rot = 1-'O': 2-'I': 2-'Z': 4-'J': 4-'L': 4-'T' for rot in range(0, len(PIECES[self.falling_piece['shape']]) ): # per le rotazioni possibili su lpezzo corrente for sideways in range(-5, 6): # per i drop possibili sulla board move = [rot, sideways] # salvo la coppia corrente test_board = copy.deepcopy( self.board) # duplico la board corrente test_piece = copy.deepcopy( self.falling_piece) # duplico il pezzo corrente test_board = simulate_board( test_board, test_piece, move) # simulo il pezzo e la mossa sulla board test # Check NEXT if test_board is not None: # se la simulazione è andata a buon fine ## Chose the best after next # effettuo il calcolo con il pezzo successivo for rot2 in range(0, len(PIECES[self.next_piece['shape']])): for sideways2 in range(-5, 6): move2 = [rot2, sideways2] test_board2 = copy.deepcopy(test_board) test_piece2 = copy.deepcopy(self.next_piece) test_board2 = simulate_board( test_board2, test_piece2, move2) if test_board2 is not None: test_score2, nextLines = self.get_expected_score( test_board2) if NextScore[2] < test_score2: NextScore = [ rot2, sideways2, test_score2 ] # aggiorno il best local score (LV2) if rand_score < NextScore[2]: # confronto rand_score = NextScore[ 2] # aggiorno il best local score (LV1+LV2) rand_sideways = sideways # aggiorno il best sideway (LV1) rand_rot = rot # aggiorno il best rot (LV1) # finish = time.perf_counter() # print(f'Finished in {round(finish - start, 2)} second(s) with full') return rand_rot, rand_sideways, rand_score
def DFS_LV1Only(self, board, piece): """ Execute DFS at level 1 of depth Parameters ---------- board : Matrix (lists of lists) of strings piece : Object containing: 'shape', 'rotation', 'x', 'y', 'color' """ print("Shape: ", piece['shape']) strategy = None for rot in range(0, len(PIECES[piece['shape']])): for sideways in range(-5, 6): move = [rot, sideways] test_board = copy.deepcopy(board) test_piece = copy.deepcopy(piece) test_board = simulate_board(test_board, test_piece, move) DFSTreePlot.addedge( DFSTreePlot.ROOTZERO, str(piece['shape'] + ":" + str(sideways) + ":" + str(0))) if test_board is not None: test_score, _ = self.get_expected_score(test_board) print("Tested branch : [ rot= ", rot, "/sideway=", sideways, "] : scored = ", round(test_score, 3)) if not strategy or strategy[2] < test_score: strategy = (rot, sideways, test_score) if self.treePlot == 'yes': DFSTreePlot.plot() DFSTreePlot.Graph.clear() print("-- Winner Strategy = <", strategy[0], "/", strategy[1], ">\n") return [strategy[0], strategy[1]]
def MonteCarlo_MCTS(self, board, piece, NextPiece): """ Main Scanning function for Deep LV1 Parameters ---------- board : str Matrix (lists of lists) of strings piece : Object conteining 'shape', 'rotation', 'x', 'y', 'color' NextPiece : Object conteining 'shape', 'rotation', 'x', 'y', 'color' """ deep = 1 numIter = 0 print("Branch Deep :", deep, " Real piece: ", piece['shape']) self.action = str(piece['shape']) topStrategies = list() strategy = None for rot in range(0, len(PIECES[piece['shape']])): for sideways in range(-5, 6): numIter = numIter + 1 # print("<<<<<<<<<< Enter into branch n° ", numIter) move = [rot, sideways] test_board = copy.deepcopy(board) test_piece = copy.deepcopy(piece) test_board = simulate_board(test_board, test_piece, move) fatherName = str(piece['shape'] + ":" + str(sideways) + ":" + str(0)) MonteCarloPlot.addedge(MonteCarloPlot.ROOTZERO, fatherName) if test_board is not None: test_score, fullLines = self.get_expected_score(test_board) NextScore = 0 selfAction = "" # print("Tested branch : [ rot= ", rot, "/sideway=", sideways, "] : scored = ", round(test_score, 3)) if self.deepLimit > 1: NextScore, selfAction = self.MonteCarlo_MCTS_stepx( board, deep + 1, NextPiece, fatherName) print("Dreamed action : ", self.action) selfAction = self.action self.action = str(piece['shape']) NextScore = NextScore + test_score if not strategy or strategy[2] < NextScore: strategy = (rot, sideways, NextScore, selfAction) topStrategies.append(strategy) if self.treePlot == 'yes' and self.deepLimit < 3: MonteCarloPlot.plot() MonteCarloPlot.Graph.clear() print("--->> TOP STRATEGIES <<---") topStrategies = sorted(topStrategies, key=itemgetter(2), reverse=True) for x in range(len(topStrategies)): print(topStrategies[x]) print("---X>> Winner STRATEGY <<X---", topStrategies[0]) return [topStrategies[0][0], topStrategies[0][1]]
def find_best_moveLS(self, board, piece, NextPiece): """ It finds the best move to do according to the passed weights :param board: Matrix (lists of lists) of strings :param piece: Object containing: 'shape', 'rotation', 'x', 'y', 'color' :param NextPiece: Object containing: 'shape', 'rotation', 'x', 'y', 'color' :return:strategy2: a list that contains rot and sideway """ print("Current Piece: ", piece['shape']) strategy = (0, 0, -999) best_board = None for rot in range(0, len(PIECES[piece['shape']])): for sideways in range(-5, 6): move = [rot, sideways] test_board = copy.deepcopy(board) test_piece = copy.deepcopy(piece) test_board = simulate_board(test_board, test_piece, move) if test_board is not None: test_score, fullLines = self.get_expected_score(test_board) print("Tested branch : LV1 [ rot= ", rot, "/sideway=", sideways, "] : scored = ", round(test_score, 3)) if not strategy or strategy[2] < test_score: print("updated new max LV1") strategy = (rot, sideways, test_score) best_board = test_board print("--> LV1 Winner is: ", strategy) print(" Next Piece : ", NextPiece['shape']) strategy2 = (0, 0, -999) for rot in range(0, len(PIECES[NextPiece['shape']])): for sideways in range(-5, 6): move2 = [rot, sideways] test_board2 = copy.deepcopy(best_board) test_piece2 = copy.deepcopy(NextPiece) test_board2 = simulate_board(test_board2, test_piece2, move2) if test_board2 is not None: test_score2, fullLines2 = self.get_expected_score(test_board2) print("Tested branch : LV2 [ rot= ", rot, "/sideway=", sideways, "] : scored = ", round(test_score2, 3)) if not strategy2 or strategy2[2] < test_score2: print("updated = new max LV2") strategy2 = (rot, sideways, test_score2) print("----> LV2 Winner is: ", strategy2, "\n") return [strategy2[0], strategy2[1]]
def MonteCarlo_MCTS_stepx(self, board, deep, piece, fatherName): """ Recursive Scanning of Virtual Branches on Deep > 2 Parameters ---------- board : str type of piece used ('r' = random, 'p' = pi) deep : str type of function to use (randomScan or fullScan) piece : Object conteining 'shape', 'rotation', 'x', 'y', 'color' fatherName : str str used to have trace of the fatherName to print Tree Graphs """ if len(self.action.strip('-')) <= self.deepLimit: self.action = self.action + "-" + piece['shape'] strategy = None sidewaysIndex = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5] # 11 Sideways # if mode is random, BBMCTS remove a random number of sideways from the Tree Search if self.mode == 'random': if deep > 2: toRemove = random.randint(0, 5) # print("------------------- toKill ", toRemove) for z in range(toRemove): deathindex = random.randint(0, len(sidewaysIndex) - 1) sidewaysIndex.pop(deathindex) for rot in range(0, len(PIECES[piece['shape']])): for sideways in sidewaysIndex: move = [rot, sideways] test_board = copy.deepcopy(board) test_piece = copy.deepcopy(piece) test_board = simulate_board(test_board, test_piece, move) NameNode = str(piece['shape'] + ":" + str(sideways) + ":" + str(deep)) MonteCarloPlot.addedge(fatherName, fatherName + "_" + NameNode) if test_board is not None: test_score, fullLines = self.get_expected_score(test_board) # print("Tested branch : [ rot= ",rot ,"/sideway=",sideways," // deep= ",deep,"] : scored = ",round(test_score,3)) # print("yyyy: ", deep, " ",self.deepLimit) if deep < self.deepLimit: # print("dxxxxx: ", deep) RandPiece = self.__random() deepScore, pieceType = self.MonteCarlo_MCTS_stepx( board, deep + 1, RandPiece, fatherName + "_" + NameNode) test_score = test_score + deepScore if not strategy or strategy[2] < test_score: strategy = (rot, sideways, test_score) return strategy[2], self.action
def simulate_move(self, move, piece): """ test the move of the piece in a test_board :param move: [rotation, sideway] :param piece: current falling piece :return: score:int """ test_board = copy.deepcopy(self.board) test_piece = copy.deepcopy(piece) test_board = simulate_board(test_board, test_piece, move) if test_board is not None: test_score, _ = self.get_expected_score(test_board) return test_score else: return -99 # con questo punteggio una mossa non valida non verrà considerata
def DFS_full(self, board, piece, NextPiece): """ Execute DFS at level 2 of depth Parameters ---------- board : Matrix (lists of lists) of strings piece : Object conteining: 'shape', 'rotation', 'x', 'y', 'color' NextPiece : Object conteining: 'shape', 'rotation', 'x', 'y', 'color' """ best_rot = 0 best_sideways = 0 best_score = -99 NextScore = (0, 0, -99) # rot, sideways, score # rot = 1-'O': 2-'I': 2-'Z': 4-'J': 4-'L': 4-'T' print("Shape: ", piece['shape']) for rot in range(0, len(PIECES[piece['shape']]) ): # per le rotazioni possibili su lpezzo corrente for sideways in range(-5, 6): # per i drop possibili sulla board move = [rot, sideways] # salvo la coppia corrente test_board = copy.deepcopy(board) # duplico la board corrente test_piece = copy.deepcopy(piece) # duplico il pezzo corrente test_board = simulate_board( test_board, test_piece, move) # simulo il pezzo e la mossa sulla board test # Check NEXT fatherName = str(piece['shape'] + ":" + str(sideways) + ":" + str(0)) DFSTreePlot.addedge(DFSTreePlot.ROOTZERO, fatherName) if test_board is not None: for rot2 in range(0, len(PIECES[NextPiece['shape']])): for sideways2 in range(-5, 6): move2 = [rot2, sideways2] test_board2 = copy.deepcopy(test_board) test_piece2 = copy.deepcopy(NextPiece) test_board2 = simulate_board( test_board2, test_piece2, move2) NameNode = str(NextPiece['shape'] + ":" + str(sideways2) + ":" + str(1)) DFSTreePlot.addedge(fatherName, fatherName + "_" + NameNode) if test_board2 is not None: test_score2, nextLines = self.get_expected_score( test_board2) print("Tested branch : LV1[ rot= ", rot, "/sideway=", sideways, "] : LV2[ rot2= ", rot2, "/sideway2=", sideways2, "] : scored = ", round(test_score2, 3)) if NextScore[2] < test_score2: NextScore = [ rot2, sideways2, test_score2 ] # aggiorno il best local score (LV2) if best_score < NextScore[2]: # confronto best_score = NextScore[ 2] # aggiorno il best local score (LV1+LV2) best_sideways = sideways # aggiorno il best sideway (LV1) best_rot = rot # aggiorno il best rot (LV1) if self.treePlot == 'yes': DFSTreePlot.plot() DFSTreePlot.Graph.clear() print("-- Winner Strategy = <", best_rot, "/", best_sideways, ">\n") return [best_rot, best_sideways]