Exemple #1
0
   def ModifiedMinMax(self, board, limit, player, checker = 0):
      global depth
      depth = depth + 1
      '''
      a recursive min-max function
      the function changes min/max utility based on the player passed
      the algorithm is modified such that the selection is made based on maximizing one score and minimizing a different score at each step
      '''

      #if the board is half empty the game is over 
      if board.isHalfEmpty():
         return 0

      max_score = float("-inf")
      max_move = 0
      moves = board.generateOptions(player)
      isCloneMove = True


      #check if the game state is in the level just above the limit in the min max tree
      #only check for maximum profit of the current player and return the best move
      if ((depth == (limit - 1)) or ((depth == limit) and (limit == 1))):
         for move_option in moves:         
            
            new_board = board.clone()
            new_board_score = new_board.move(move_option, isCloneMove)
                      
            if new_board_score > max_score:
               max_score = new_board_score
               max_move = move_option       

      #on any depth other than limit - 1 recursively call the function and get the best score of the opponent in the resulting stage of the current move
      #calculate the ratio of the addition to current player score by the move, to best potential addition to the opponent score of the resulting game state by the move
      #choose the move with maximum ratio
      else:
         max_ratio = float("-inf")
         for move_option in moves:
            new_board = board.clone()
            new_player = (player + 1) % 2
            score = new_board.move(move_option, isCloneMove)
            opponent_score = self.ModifiedMinMax(new_board, limit, new_player, depth)

            if opponent_score != 0:
               if float(score/opponent_score) > max_ratio:
                  max_score = score
                  max_ratio = float(score/opponent_score)
                  max_move = move_option
            else:
                  max_score = score
                  max_move = move_option

      if checker == 1:
            return max_move
      else:
            return max_score         
Exemple #2
0
 def pickMaxMin(self, board, marker):
     moves = board.getMoves()
     pairs = []
     for (x, y) in moves:
         temp = board.clone()
         temp.move(x, y, marker)
         if temp.finished():
             score = self.evalBoard(temp)
         else:
             pick = self.pickMaxMin(temp, self.flip(marker))
             score = pick[1]
         pairs.append(((x, y), score))
     pairs.sort(key=lambda x: x[1])
     if marker == self.marker:
         index = -1
     else:
         index = 0
     return pairs[index]
Exemple #3
0
 def pickMaxMin(self, board, marker):
     moves = board.getMoves()
     pairs = []
     for (x,y) in moves:
         temp = board.clone()
         temp.move(x,y,marker)
         if temp.finished():
             score = self.evalBoard(temp)
         else:
             pick = self.pickMaxMin(temp, self.flip(marker))
             score = pick[1]
         pairs.append(((x,y),score))
     pairs.sort(key=lambda x:x[1])
     if marker == self.marker:
     	  index = -1
     else:
       	index = 0
     return pairs[index]
Exemple #4
0
   def greedyPlay(self):
      '''
      plays the game
      heuristics: look ahead for one step and select the move with maximum score
      '''
   
      #choosing a pit
      max_score = float("-inf")
      max_move = 0
      moves = board.generateOptions(player)

      for move_option in moves:
         new_board = board.clone()
         new_board_score = new_board.move(move_option)
         if new_board_score > max_score:
            max_score = new_board_score
            max_move = move_option
               
      pit = max_move
      #make moves and update score   
      score = self.game_board.move(pit)
      self.updateScore(score)
      self.switchPlayer()
Exemple #5
0
def mainaction(board):
    score = []
    movescore = [1]
    allmoves = moves()

    for lists in allmoves:
        sandbox = board.clone()
        oldscore = sandbox.score
        hole = 0
        height = 24
        allheights, diff_in_height, var, num_of_blocks, allholes = [], [], [], [], []

        for move in lists:
            if sandbox.falling is None: continue
            elif isinstance(move, Rotation):
                sandbox.rotate(move)
            elif isinstance(move, Direction):
                sandbox.move(move)
            else:
                continue

        holes = 0
        for x in range(sandbox.width):
            min_y_seen = 24
            temp = 0
            for y in range(sandbox.height):
                if (x, y) in sandbox:
                    if y <= min_y_seen:

                        # OVERALL HEIGHT
                        min_y_seen = y
                        allheights.append((height - min_y_seen))

                        # HEIGHT DIFFERENCES
                        ma = max(y for (x, y) in sandbox.cells)
                        mi = min(y for (x, y) in sandbox.cells)
                        differences = (ma - mi)
                        diff_in_height.append(differences)

                        mean = (height - min_y_seen) / 10
                        difsq = (y - mean) * (y - mean)
                        var.append(difsq)

                        num_of_blocks.append(len(sandbox.cells))

                if (x, y) in sandbox.cells:
                    temp = temp + 1
                if (x, y) not in sandbox.cells and temp > 0:
                    holes = holes + 1
                    allholes.append(holes)

                    # # HOLES IN THE BOARD
                    # if y >= min_y_seen:
                    #     if (x, y) in sandbox.cells and (x, y + 1) not in sandbox.cells and (x, y + 2) in sandbox.cells:
                    #         hole = hole + 10
                    #         allholes.append(hole)
                    #     else:
                    #         allholes.append(0)
            # VARIANCE
            act_var = sum(var) / 10

        # STANDARD DIVIATION
        sd = []
        sd.append(statistics.stdev(allheights))

        # BUMPINESS
        bump = []
        for i in range(len(allheights) - 1):
            l = abs(allheights[i + 1] - allheights[i])
            bump.append(l)

        # GAME
        if sandbox.score - oldscore > 99:
            movescore.append(10)
        elif sandbox.score - oldscore > 199:
            movescore.append(5)
        else:
            movescore.append(0)

        # movescore = [float(i)/max(movescore) for i in movescore]
        sumofscores = sum(movescore)
        sumofheights = sum(allheights)
        sumofdifferences = sum(diff_in_height)
        sumofbump = sum(bump)
        sumofsd = sum(sd)
        sumofvar = sum(var) / 1000
        sumofblocks = sum(num_of_blocks) / 10
        sumofholes = sum(allholes)

        ok = [-0.5, 0.25, 0.29, 0.05, 0.35, 0, 0, 0.35]
        # Normalise the values of individual weights: sums up to 1
        s = [
            float(i) / sum(ok) for i in ok
        ]  # from https://stackoverflow.com/questions/26785354/normalizing-a-list-of-numbers-in-python

        heuristics = (s[0] * sumofheights, s[1] * sumofdifferences,
                      s[2] * sumofscores, s[3] * sumofbump, s[4] * sumofsd,
                      s[5] * sumofvar, s[6] * sumofblocks, s[7] * sumofholes)
        sum_of_heuro = sum(heuristics)

        # 2, 16, 1, 8 tuple move - score: 4440
        # 2, 0, 0, 8 tuples move - score: 5376
        # 10, 1, 1, 8 tuple move - score: 6874
        # 10, 1, 1, 10 tuple move - score:  8805
        # 10, 1, 10, 10 tuple move - score: 9699
        # 10, 1, 10, 1, 10 tuple move score: 10404 (with four heuristics)
        # 10, 1, 10, 1, 1, 0, 0, 0, 10 tuple move score: 17632 (left, right, left, right, clock, anti-clock)
        # 1.5, 0.5, 0.5, 0.1, 0, 0, 0,

        score.append(sum_of_heuro)
    lowestscoore = score.index(min(score))
    return allmoves[lowestscoore]
Exemple #6
0
 def set_board(self, board):
     self.board = board.clone()
     self.preview.board_drawer.set_board(self.board)
 def set_board(self, board):
     self.board = board.clone()
     self.preview.board_drawer.set_board(self.board)
Exemple #8
0
    def GetAlphaBetaScore(self, board, limit, player, alpha, beta, checker=0):
        # The function changes min/max utility with alpha beta prunning based on the player passed

        # Getting class depth value
        global depth
        depth = depth + 1

        # If the board is half empty the game is over
        if board.isEmptyBoard():
            return 0

        # Gets current choices for this agent
        max_score = float("-inf")
        max_move = 0
        moves = board.getCurrentChoices(player)
        isCloneMove = True

        # The algorithm take moves such that the selection is made based on maximizing one score and minimizing a different score at each step
        # Also it prunes the some of the tree to avoid bigger space requirement and to decrease time complexity
        # First of all check if the game state is in the level just above the limit in the min max tree
        # Then Only check for maximum profit of the current player and return the best move
        if ((depth == (limit - 1)) or ((depth == limit) and (limit == 1))):
            for move_option in moves:

                new_board = board.clone()
                new_board_score = new_board.move(move_option, isCloneMove,
                                                 self.current_score)

                if new_board_score > max_score:
                    max_score = new_board_score
                    max_move = move_option

        # On any depth other than limit - 1 recursively call the function and get the best score of the opponent in the resulting stage of the current move
        # Calculate the ratio of the addition to current player score by the move, to best potential addition to the opponent score of the resulting game state by the move
        # Choose the move with maximum ratio
        else:
            max_ratio = float("-inf")

            # Iterate over all of the choices
            for move_option in moves:
                new_board = board.clone()
                new_player = (player + 1) % 2
                score = new_board.move(move_option, isCloneMove,
                                       self.current_score)

                # if new score is smaller than alpha value then prune rest of tree branch
                if (score <= alpha):
                    return score
                # if new score is greater than beta value then prune rest of tree branch
                if (score >= beta):
                    return score

                # This is the recursion call for another player
                # This time will be minimizing the score for oppenents
                opponent_score = self.GetAlphaBetaScore(
                    new_board, limit, new_player, alpha + score, beta + score)

                if opponent_score != 0:
                    if float(score / opponent_score) > max_ratio:
                        max_score = score
                        max_ratio = float(score / opponent_score)
                        max_move = move_option
                else:
                    max_score = score
                    max_move = move_option

        if checker == 1:
            return max_move
        else:
            return max_score