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)
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)
def heuristic_empty_tiles(board): ''' Returns the amount of empty tiles in the given board, weighted to have a value between 0 (no spaces) and 1 (1 being an empty board) ''' empty_tiles_count_weighted = util.cell_of_type_count(0, board) / 15 return util.round_nearest(empty_tiles_count_weighted, 0.01)
def _empty_cells_weighted(board): ''' only used for expectimax calc ''' count = util.cell_of_type_count(0, board) if count == 0: return 1 return count
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)
def heuristics_empty_cells_count(board): return util.cell_of_type_count(0, board)
def heuristics_empty_cells_count(board): return util.round_nearest(util.cell_of_type_count(0, board) / 15, 0.01)
def heuristic_low_tiles(board): ''' Returns the amount of 2 and 4 tiles on the given board. ''' return (util.cell_of_type_count(2, board) + util.cell_of_type_count(4, board)) / 8 + 0.1