def heuristic_low_tiles_gradient(board, old_board): ''' Similar to :heuritic_gradient, we check for 2 and 4 tiles in the given board and gradient-weight them depending on their position and the importance of them being there. The value is divided by the value of the old board and stays around 1. ''' low_board = board.copy() for row in low_board: for cell in row: if util._to_val(cell) > 4: cell = 0 low_old_board = old_board.copy() for row in low_old_board: for cell in row: if util._to_val(cell) > 4: cell = 0 board_low_gradient = sum([b*g for b,g in zip(low_board.flatten(), low_goal_flat)]) old_board_low_gradient = sum([o*g for o,g in zip(low_old_board.flatten(), low_goal_flat)]) if (board_low_gradient == 0) or (old_board_low_gradient == 0): return 1 return board_low_gradient / old_board_low_gradient
def _evaluate_tile_ratio(cell, neighbour_cell): '''Compares two cells and returns their absolute difference in exponent''' current_tile_exp = math.frexp(util._to_val(cell))[1] neighbour_tile_exp = math.frexp(util._to_val(neighbour_cell))[1] if neighbour_tile_exp == 0: return current_tile_exp ratio = current_tile_exp - neighbour_tile_exp return math.fabs(ratio)
def heuristic_weighted_merge(move, board): ''' Checks all possible tile-merges with the given move and board and returns the score that is gained. ''' score = 0.01 if move < 2: '''UP/DOWN''' for y in range(4): if (board[0][y] == board[1][y]) and (util._to_val(board[0][y]) != 0): '''merge in top spots, nonzero => XX??''' score += board[0][y] if (board[2][y] == board[3][y]) and (util._to_val(board[2][y]) != 0): '''merge in whole row, nonzero => XXYY''' score += board[2][y] elif (board[1][y] == board[2][y]) and (util._to_val(board[1][y]) != 0): '''merge in middle spots, nonzero => AXX?''' score += board[1][y] elif (board[2][y] == board[3][y]) and (util._to_val(board[2][y]) != 0): '''merge in bottom spots, nonzero => ABXX''' score += board[2][y] else: '''LEFT/RIGHT''' for x in range(4): if (board[x][0] == board[x][1]) and (util._to_val(board[x][0]) != 0): '''merge in left spots, nonzero => XX??''' score += board[x][0] if (board[x][2] == board[x][3]) and (util._to_val(board[x][2]) != 0): '''merge in whole column, nonzero => XXYY''' score += board[x][2] elif (board[x][1] == board[x][2]) and (util._to_val(board[x][1]) != 0): '''merge in middle spots, nonzero => AXX?''' score += board[x][1] elif (board[x][2] == board[x][3]) and (util._to_val(board[x][2]) != 0): '''merge in right spots, nonzero => ABXX''' score += board[x][2] '''x2 to match the resulting tile value instead of source tile values''' return 2 * score
def heuristic_merge_count(move, board): ''' TODO ''' merges = 0 if move < 2: '''UP/DOWN''' for y in range(4): if (board[0][y] == board[1][y]) and (util._to_val(board[0][y]) != 0): '''merge in top spots, nonzero => XX??''' merges += 1 if (board[2][y] == board[3][y]) and (util._to_val(board[2][y]) != 0): '''merge in whole row, nonzero => XXYY''' merges += 1 elif (board[1][y] == board[2][y]) and (util._to_val(board[1][y]) != 0): '''merge in middle spots, nonzero => AXX?''' merges += 1 elif (board[2][y] == board[3][y]) and (util._to_val(board[2][y]) != 0): '''merge in bottom spots, nonzero => ABXX''' merges += 1 else: '''LEFT/RIGHT''' for x in range(4): if (board[x][0] == board[x][1]) and (util._to_val(board[x][0]) != 0): '''merge in left spots, nonzero => XX??''' merges += 1 if (board[x][2] == board[x][3]) and (util._to_val(board[x][2]) != 0): '''merge in whole column, nonzero => XXYY''' merges += 1 elif (board[x][1] == board[x][2]) and (util._to_val(board[x][1]) != 0): '''merge in middle spots, nonzero => AXX?''' merges += 1 elif (board[x][2] == board[x][3]) and (util._to_val(board[x][2]) != 0): '''merge in right spots, nonzero => ABXX''' merges += 1 '''x2 to match the resulting tile value instead of source tile values''' return merges