def getSuccessors(self,time=INFINITY,safe=0):
     #start count time 
     start_time=clock()
     #
     current_player = self.getCurrentPlayer()
     successors = {}
     for row, row_data in enumerate(self.board):
         for col, cell in enumerate(row_data):
             #check if time over
             if(timeLimit().time_over(time,start_time,safe)):
                 return successors
             #
             if cell == current_player:
                 for direction in DIRECTIONS:
                     time_left=time-clock()+start_time
                     action, state = self._getMoveAction(row, col, direction,time_left,safe)
                     if action is not None:
                         successors[action] = state
                     #check if time over
                     if(timeLimit().time_over(time,start_time,safe)):
                         return successors
                     #
                 for spin in [(row, col), (row - 1, col), (row, col - 1), (row - 1, col - 1)]:
                     action, state = self._getSpinAction(spin[0], spin[1])
                     if action is not None:
                         successors[action] = state
                     #check if time over
                     if(timeLimit().time_over(time,start_time,safe)):
                         return successors
                     #
     return successors
 def _getConnectiveComponent(self, initial_row, initial_col, player,time=INFINITY,safe=0):
     '''
     Performs BFS to traverse the connective component, beginning at the given coordinate.
     
     @param initial_row: The initial row coordinate.
     @param initial_col: The initial column coordinate.
     @param player: The player who's connective component we would like to traverse.
     @return: The closed set - the connective component.
     '''
     open = set()
     open.add((initial_row, initial_col))
     closed = set()
     start_time=clock()
     while len(open) > 0:
         (row, col) = open.pop()
         closed.add((row, col))
         for direction in DIRECTIONS:
             #check if time over
             if(timeLimit().time_over(time,start_time,safe)):
                 return closed
             #
             (neighbor_row, neighbor_col) = direction.move((row, col))
             if (0 <= neighbor_row < self.size) and (0 <= neighbor_col < self.size) \
                 and (self.board[neighbor_row][neighbor_col] == player) \
                 and ((neighbor_row, neighbor_col) not in closed):
                 open.add((neighbor_row, neighbor_col))
     
     return closed
 def utilityAnyTime(self, state,player,par,time,safe):
     start_time=clock()
     winner = state.getWinner()
     if winner == player:
        return 1
     if winner is not None:
        return -1
    
     Futility=0
     center=self.centralization(state,player) #(mycenter, enemycenter,utiltity)
     if(timeLimit().time_over(time, start_time, safe)):
         return Futility
     distance=self.getdistance(state,center[0],center[1],player) #(mydistance,enedistance)
     if(timeLimit().time_over(time, start_time, safe)):
         return Futility
     connect=self.getConnective(state, player) #(countB,countW,max_B,max_W,state.blacks,state.whites)
     if(timeLimit().time_over(time, start_time, safe)):
         return Futility
     blockW=par[0]
     centerW=par[1]
     myNumberConnectW=par[2]
     enemyNumberConnectW=par[3]
     myMaxConnectW=par[4]
     enemyMaxConnectW=par[5]
     threatW=par[6]
     materialW=par[7]
     #
     blockS=center[2]
     myCenterS=distance[0]
     enemyCenterS=distance[1]
     myNumberConnectS=connect[0]
     enemyNumberConnectS=connect[1]
     myMaxConnectS=connect[2]
     enemyMaxConnectS=connect[3]
     materialS=abs(connect[5]-connect[4])
     threatS=connect[5]-connect[3]
     #
     
     if(self.turn==-1):
         self.turn=state.turns_left
     Futility=(blockW*blockS)+(centerW*myCenterS)+(myNumberConnectW*myNumberConnectS)+(enemyNumberConnectW*enemyNumberConnectS)
     Futility+=(myMaxConnectW*myMaxConnectS)+(enemyMaxConnectW*enemyMaxConnectS)+(threatW*threatS)+(materialW*materialS)
     return Futility*1.0/(state.size*state.size*state.size*state.size*state.size) 
 def _getMoveAction(self, row, col, direction,time=INFINITY,safe=0):
     '''
     Checks the validity and the ramifications of performing a move action at the given location in the given direction.
     
     @param row: The row coordinate.
     @param col: The column coordinate.
     @param direction: The direction to move in.
     @return: The action and resulting state or None if illegal.
     '''
     distance = 1
     first_enemy = self.size
     start_time=clock()
     (i_row, i_col) = direction.move((row, col))
     while (0 <= i_row < self.size) and (0 <= i_col < self.size):
         cell = self.board[i_row][i_col]
         if cell != EMPTY:
             distance += 1
             if cell != self.getCurrentPlayer() and first_enemy == self.size:
                 first_enemy = max(abs(row - i_row), abs(col - i_col))
         #check if time over
         if(timeLimit().time_over(time,start_time,safe)):
             return None,None
         #
         (i_row, i_col) = direction.move((i_row, i_col))
     
     opposite_direction = Direction('temp', (-direction.delta[0], -direction.delta[1]))
     (i_row, i_col) = opposite_direction.move((row, col))
     while (0 <= i_row < self.size) and (0 <= i_col < self.size):
         if self.board[i_row][i_col] != EMPTY:
             distance += 1
         (i_row, i_col) = opposite_direction.move((i_row, i_col))
         #check if time over
         if(timeLimit().time_over(time,start_time,safe)):
             return None,None
         #
     
     if distance > first_enemy:
         return None, None
     
     (new_row, new_col) = (direction.delta[0]*distance + row, direction.delta[1]*distance + col)
     if not ((0 <= new_row < self.size) and (0 <= new_col < self.size)):
         return None, None
     
     new_cell = self.board[new_row][new_col]
     if new_cell == self.getCurrentPlayer():
         return None, None
     
     if new_cell == WHITE:
         new_whites = self.whites - 1
     else:
         new_whites = self.whites
     
     if new_cell == BLACK:
         new_blacks = self.blacks - 1
     else:
         new_blacks = self.blacks
     
     new_board = list(self.board)
     
     new_board[row] = list(new_board[row])
     new_board[row][col] = EMPTY
     new_board[row] = tuple(new_board[row])
     
     new_board[new_row] = list(new_board[new_row])
     new_board[new_row][new_col] = self.getCurrentPlayer()
     new_board[new_row] = tuple(new_board[new_row])
     
     state = LinesOfActionState(self.size, self.turns_left - 1, tuple(new_board), new_whites, new_blacks)
     return (MoveAction(row, col, direction), state)