Example #1
0
def expectimax_calc(move, old_board, depth, isChance):
  board_to_check = util.execute_move(move, old_board)

  if depth == MAX_DEPTH:
    return heuristic_value(move, board_to_check, old_board)
  
  if isChance == 1:
    avg = 0
    ecc = util.cell_of_type_count(0, board_to_check)
    if ecc == 0:
      possibility_multiplier = 1
    else:
      possibility_multiplier = 1 / ecc

    for x in range(4):
      for y in range(4):
        if board_to_check[x][y] == 0:
          board_to_check[x][y] = 2
          avg += possibility_multiplier * CHANCE_2 * expectimax_calc(move, old_board, depth + 1, 0)
          board_to_check[x][y] = 4
          avg += possibility_multiplier * CHANCE_4 * expectimax_calc(move, old_board, depth + 1, 0)
          board_to_check[x][y] = 0

    return avg
  else:
    results = []
    for m in move_args:
      check_board = util.execute_move(m, board_to_check)
      if util.board_equals(check_board, board_to_check):
        results.append(0)
      else:
        results.append(expectimax_calc(m, board_to_check, depth + 1, 1))
        
    return max(results)
Example #2
0
def heuristics_combineable_cells_count(new_board, old_board):
    '''
    Clunky evaluation: what was the last move? UP/DOWN or LEFT/RIGHT?
    TODO: Refactoring
    '''
    if util.board_equals(util.execute_move(UP, old_board), new_board):
        move = UP
    elif util.board_equals(util.execute_move(DOWN, old_board), new_board):
        move = DOWN
    elif util.board_equals(util.execute_move(LEFT, old_board), new_board):
        move = LEFT
    else:
        move = RIGHT

    combineable_tiles_count = 0
    
    '''Check Directions'''
    if (move == UP) or (move == DOWN):
        '''0,1 = UP, DOWN'''
        for y in range(4):
            if (new_board[0][y] == new_board[1][y]) and (new_board[0][y] != 0):
                if (new_board[1][y] == new_board[2][y]) and (new_board[2][y] == new_board[3][y]):
                    # xxxx
                    combineable_tiles_count += 2
                else:
                    # xxab. xxxa
                    combineable_tiles_count += 1
            elif (new_board[1][y] == new_board[2][y]) and (new_board[1][y] != 0):
                # axxx, axxb
                combineable_tiles_count += 1
            elif (new_board[2][y] == new_board[3][y]) and (new_board[2][y] != 0):
                # abxx
                combineable_tiles_count += 1
    else:
        '''2,3 = LEFT, RIGHT'''
        for x in range(4):
            if (new_board[x][0] == new_board[x][1]) and (new_board[x][0] != 0):
                if (new_board[x][1] == new_board[x][2]) and (new_board[x][2] == new_board[x][3]):
                    # xxxx
                    combineable_tiles_count += 2
                else:
                    # xxab. xxxa
                    combineable_tiles_count += 1
            elif (new_board[x][1] == new_board[x][2]) and (new_board[x][1] != 0):
                # axxx, axxb
                combineable_tiles_count += 1
            elif (new_board[x][2] == new_board[x][3]) and (new_board[x][2] != 0):
                # abxx
                combineable_tiles_count += 1
                
    # return combineable_tiles_count
    return util.round_nearest(combineable_tiles_count/7, 0.01)
Example #3
0
def a_very_lauenchr_expectimax_calc(depth, new_board, isChance, old_board):
    if depth == MAX_DEPTH:
        return heuristic_value(new_board, old_board)
    
    if isChance == 1:
        avg = 0
        chance_2 = 0.9
        chance_4 = 0.1

        ecc = util.cell_of_type_count(0, new_board)
        if ecc == 0:
            chance_cel = 0
        else:
            chance_sel = 1 / heuristics_empty_cells_count(new_board)
        
        for x in range(4):
            for y in range(4):
                if new_board[x][y] == 0:
                    new_board[x][y] = 2
                    avg += chance_sel * chance_2 * a_very_lauenchr_expectimax_calc(depth + 1, new_board, 0, old_board)
                    new_board[x][y] = 4
                    avg += chance_sel * chance_4 * a_very_lauenchr_expectimax_calc(depth + 1, new_board, 0, old_board)
                    new_board[x][y] = 0
                    
        return avg
    else:
        results = []
        for m in move_args:
            results.append(a_very_lauenchr_expectimax_calc(depth + 1, util.execute_move(m, new_board), 1, new_board))
            
        return max(results)
Example #4
0
def build_heuristic_array(move_possible_array, board):
    heuristic_array = util.build_list(math.inf, 4)

    for i in range(4):
        if move_possible_array[i] > 0:
            board_to_check = util.execute_move(i, board)

            act = heuristics_combineable_cells_count(i, board)
            ndh = heuristics_neighbour_difference(board_to_check)
            ecc = heuristics_empty_cells_count(board_to_check)
            htic = heuristics_highest_tile_in_corner(board, board_to_check)

            # heuristic_array[i] = coeff[0] * act/7 + coeff[1] * (ndh/41) + coeff[2] * (ecc/15) + coeff[3] * htic + coeff[4] * (heuristics_monotonous_row(board_to_check) / heuristics_monotonous_row(board))
            heuristic_array[i] = coeff[0] * act + coeff[1] * ndh + coeff[
                2] * ecc + coeff[3] * htic + coeff[4] * (
                    heuristics_monotonous_row(board_to_check) /
                    heuristics_monotonous_row(board))

            # add heuristics together
            # heuristic_array[i] = (-2*act) + (4*ndh) - ecc - 50 * (heuristics_monotonous_row(board_to_check) / heuristics_monotonous_row(board)) # (1)
            # heuristic_array[i] = - (act/7) + 3*(ndh/41) - (ecc/15) + htic - heuristics_monotonous_row(board_to_check) / heuristics_monotonous_row(board) # (2) weighted
            # heuristic_array[i] = - 2*(act/7) + (ndh/41) - 4*(ecc/15) + htic - heuristics_monotonous_row(board_to_check) / heuristics_monotonous_row(board) # (3) weighted2
            # heuristic_array[i] = - (act/7) + 2*(ndh/41) - (ecc/15) + htic - 2 * heuristics_monotonous_row(board_to_check) / heuristics_monotonous_row(board) # (4) weighted3
            # heuristic_array[i] = 2*(ndh/41) + htic - 2 * heuristics_monotonous_row(board_to_check) / heuristics_monotonous_row(board) # (5) weighted4
            # heuristic_array[i] = (-2*act) + (4*ndh) - ecc - 100 * (heuristics_monotonous_row(board_to_check) / heuristics_monotonous_row(board)) # (6) weighted5

            # TODO!
            # ==============================
            # - each heuristic on its own with the monotonous row
            # ==============================

    return heuristic_array
Example #5
0
def score_toplevel_move(move, board):
    """Entry Point to score the first move."""
    board_to_check = util.execute_move(move, board)

    if util.board_equals(board, board_to_check):
        return 0

    expectimax_score = expectimax_calc(board_to_check, board, 0, 0)

    return expectimax_score
Example #6
0
def score_toplevel_move(move, board):
    """Entry Point to score the first move."""
    newboard = util.execute_move(move, board)

    if util.board_equals(board,newboard):
        return 0

    expectimax_score = a_very_lauenchr_expectimax_calc(0, newboard, 0, board)
    htic = heuristics_highest_tile_in_corner(newboard)

    return expectimax_score + coeff[3] * htic
Example #7
0
def score_toplevel_move(move, board):
  """Entry Point to score the first move."""
  board_to_check = util.execute_move(move, board)

  if util.board_equals(board, board_to_check):
    return -1

  htic = heuristics_highest_tile_in_corner(board_to_check)
  expectimax_score = expectimax_calc(0, board, 0, 0) + htic

  return expectimax_score
Example #8
0
def build_heuristic_array(move_possible_array, board):
    heuristic_array = util.build_list(math.inf, 4)
    
    for i in range(4):
        if move_possible_array[i] > 0:
            board_to_check = util.execute_move(i, board)
            
            act = heuristics_combineable_cells_count(i, board)
            ndh = heuristics_neighbour_difference(board_to_check)
            ecc = heuristics_empty_cells_count(board_to_check)
            htic = heuristics_highest_tile_in_corner(board, board_to_check)
                
            # add heuristics together
            heuristic_array[i] = (-2*act) + (4*ndh) - ecc + htic # => original (1)
            
    return heuristic_array
Example #9
0
def heuristics_combineable_cells_count(move, board):
    new_board = util.execute_move(move, board)
    combineable_tiles_count = 0
    '''Check Directions'''
    if (move == UP) or (move == DOWN):
        '''0,1 = UP, DOWN'''
        for y in range(4):
            if (new_board[0][y] == new_board[1][y]) and (new_board[0][y] != 0):
                if (new_board[1][y]
                        == new_board[2][y]) and (new_board[2][y]
                                                 == new_board[3][y]):
                    # xxxx
                    combineable_tiles_count += 2
                else:
                    # xxab. xxxa
                    combineable_tiles_count += 1
            elif (new_board[1][y]
                  == new_board[2][y]) and (new_board[1][y] != 0):
                # axxx, axxb
                combineable_tiles_count += 1
            elif (new_board[2][y]
                  == new_board[3][y]) and (new_board[2][y] != 0):
                # abxx
                combineable_tiles_count += 1
    else:
        '''2,3 = LEFT, RIGHT'''
        for x in range(4):
            if (new_board[x][0] == new_board[x][1]) and (new_board[x][0] != 0):
                if (new_board[x][1]
                        == new_board[x][2]) and (new_board[x][2]
                                                 == new_board[x][3]):
                    # xxxx
                    combineable_tiles_count += 2
                else:
                    # xxab. xxxa
                    combineable_tiles_count += 1
            elif (new_board[x][1]
                  == new_board[x][2]) and (new_board[x][1] != 0):
                # axxx, axxb
                combineable_tiles_count += 1
            elif (new_board[x][2]
                  == new_board[x][3]) and (new_board[x][2] != 0):
                # abxx
                combineable_tiles_count += 1

    # return combineable_tiles_count
    return util.round_nearest(combineable_tiles_count / 7, 0.01)
Example #10
0
def find_best_move(board):
    global move_count
    global coeff
    global score
    '''Which moves are possible? 1 for possible, 0 for not possible'''
    possible_moves_array = util.build_possible_moves_list(board)
    if console_logging:
        print(f'possible_moves_array: {possible_moves_array}')
    '''What are the scores for each move?'''
    heuristic_array = build_heuristic_array(possible_moves_array, board)
    '''Choose the best move out of all possible'''
    best_move = util.index_min(heuristic_array)

    handle_logging(board, util.execute_move(best_move, board), best_move,
                   heuristic_array)

    move_count += 1
    return best_move
Example #11
0
def find_best_move(board):
  global move_count

  """find the best move for the next turn.
  It will split the workload in 4 process for each move."""
  bestmove = 0  
  result = [score_toplevel_move(i, board) for i in range(len(move_args))]

  bestmove = result.index(max(result))

  if console_logging:
    print(np.around(result,decimals=2))
    time.sleep(5)
  # time.sleep(move_count / 1000)

  handle_logging(util.execute_move(bestmove, board), bestmove)
  move_count += 1

  return bestmove
def find_best_move(board):
    '''Which moves are possible? 1 for possible, 0 for not possible'''
    possible_moves_array = util.build_possible_moves_list(board)
    if console_logging:
        print(f'possible_moves_array: {possible_moves_array}')
    '''What are the scores for each move?'''
    heuristic_array = build_heuristic_array(possible_moves_array, board)
    '''Choose the best move out of all possible'''
    best_move = util.index_min(heuristic_array)

    log.log(file_writer, [
        ai_id,
        heuristics_empty_cells_count(board),
        heuristics_neighbour_difference(board),
        util.highest_tile(board),
        heuristics_highest_tile_in_corner(
            board, util.execute_move(best_move, board)), best_move, score,
        heuristics_combineable_cells_count(best_move, board),
        possible_moves_array, heuristic_array
    ])  # logging
    return best_move
Example #13
0
def find_best_move(board):
    global move_count
    """
    find the best move for the next turn.
    It will split the workload in 4 process for each move.
    """
    bestmove = -1

    result = [score_toplevel_move(i, board) for i in range(len(move_args))]
    maxResult = max(result)

    if maxResult != 0:
        bestmove = result.index(maxResult)
        print(maxResult)

    #for m in move_args:
    #    print(m)
    #    print(result[m])

    handle_logging(util.execute_move(bestmove, board), bestmove)
    move_count += 1

    return bestmove
Example #14
0
def expectimax_calc(board_to_check, old_board, depth, isChance):
    # TODO: kann man bei der Suche abbrechen, :higest_tile aus der Ecke getrieben wird?
    # => welchen Einfluss hat dies auf Anfangsszenarien?

    if depth == MAX_DEPTH:
        return heuristic_value(board_to_check, old_board)

    if isChance == 1:
        avg = 0

        empty_cells_count = util.cell_of_type_count(0, board_to_check)
        if empty_cells_count == 0:
            moves_to_check_count = 0
            return 0
        else:
            possibility_multiplier = 1 / empty_cells_count

        for x in range(4):
            for y in range(4):
                if board_to_check[x][y] == 0:
                    board_to_check[x][y] = 2
                    avg += possibility_multiplier * CHANCE_2 * expectimax_calc(
                        board_to_check, old_board, depth + 1, 0)
                    board_to_check[x][y] = 4
                    avg += possibility_multiplier * CHANCE_4 * expectimax_calc(
                        board_to_check, old_board, depth + 1, 0)
                    board_to_check[x][y] = 0

        return avg
    else:
        results = []
        for m in move_args:
            results.append(
                expectimax_calc(util.execute_move(m, board_to_check),
                                board_to_check, depth + 1, 1))

        return max(results)