# logic extends Node var done var moves: Array var materialized_a: Vector2 var materialized_b: Vector2 class Merge: var at: Vector2 var with: Vector2 class Move: var from: Vector2 var to: Vector2 func _init(a: Vector2, b: Vector2): self.from = a self.to = b func new_game(n: int) -> Array[PackedInt32Array]: var matrix: Array[PackedInt32Array] = [] for i in range(n): matrix.append(PackedInt32Array()) for _j in range(n): matrix[i].append(0) matrix = add_two(matrix) matrix = add_two(matrix) return matrix func add_two(mat: Array[PackedInt32Array]): var a = roundi(randf_range(0, mat.size() - 1)) var b = roundi(randf_range(0, mat.size() - 1)) while mat[a][b] != 0: a = roundi(randf_range(0, mat.size() - 1)) b = roundi(randf_range(0, mat.size() - 1)) mat[a][b] = 4 if randf_range(0, 1) > .9 else 2 materialized_a = Vector2(a / mat.size(), a % mat.size()) materialized_b = Vector2(b / mat.size(), b % mat.size()) return mat func game_state(mat: Array[PackedInt32Array]): # check for win cell var zero = false for i in range(mat.size()): for j in range(mat[0].size()): if mat[i][j] == 2048: return "win" elif zero == false and mat[i][j] == 0: zero = true if zero: return "not over" # check for same cells that touch each other for i in range(len(mat) - 1): # intentionally reduced to check the row on the right and below # more elegant to use exceptions but most likely this will be their solution for j in range(len(mat[0]) - 1): if mat[i][j] == mat[i + 1][j] or mat[i][j + 1] == mat[i][j]: return "not over" for k in range(len(mat) - 1): # to check the left/right entries on the last row if mat[len(mat) - 1][k] == mat[len(mat) - 1][k + 1]: return "not over" for j in range(len(mat) - 1): # check up/down entries on last column if mat[j][len(mat) - 1] == mat[j + 1][len(mat) - 1]: return "not over" return "lose" func reverse(mat: Array[PackedInt32Array]): for i in range(Constants.GRID_LEN): for j in range(Constants.GRID_LEN/2): var tmp = mat[i][j] mat[i][j] = mat[i][Constants.GRID_LEN - j - 1] mat[i][Constants.GRID_LEN - j - 1] = tmp moves.append(Move.new(Vector2(i,j), Vector2(j, Constants.GRID_LEN - j - i))) return mat func transpose(mat: Array[PackedInt32Array]): for i in range(Constants.GRID_LEN): for j in range(i + 1, Constants.GRID_LEN): var tmp = mat[i][j] mat[i][j] = mat[j][i] mat[j][i] = tmp moves.append(Move.new(Vector2(j,i), Vector2(i, j))) return mat func cover_up(mat, no_done = false): var new: Array[PackedInt32Array] = [] for _j in range(Constants.GRID_LEN): var partial_new = PackedInt32Array() for _i in range(Constants.GRID_LEN): partial_new.append(0) new.append(partial_new) if !no_done: done = false for i in range(Constants.GRID_LEN): var count = 0 for j in range(Constants.GRID_LEN): if mat[i][j] != 0: new[i][count] = mat[i][j] moves.append(Move.new(Vector2(i, j), Vector2(i, count))) if !no_done and j != count: done = true count += 1 return new func merge(mat: Array[PackedInt32Array]): for i in range(Constants.GRID_LEN): for j in range(Constants.GRID_LEN - 1): if mat[i][j] == mat[i][j + 1] and mat[i][j] != 0: mat[i][j] *= 2 mat[i][j + 1] = 0 var merge = Merge.new() merge.at = Vector2(i, j) merge.with = Vector2(i, j + 1) moves.append(merge) done = true func left(game: Array[PackedInt32Array]): print("<") moves.clear() # return matrix after shifting left transpose(game) game = cover_up(game) merge(game) game = cover_up(game, true) transpose(game) return [game, done] func right(game: Array[PackedInt32Array]): print(">") moves.clear() # return matrix after shifting right game = reverse(transpose(game.duplicate())) game = cover_up(game) merge(game) game = cover_up(game, true) game = transpose(reverse(game.duplicate())) return [game, done] func up(game: Array[PackedInt32Array]): print("^") moves.clear() # return matrix after shifting up game = cover_up(game) merge(game) game = cover_up(game, true) return [game, done] func down(game: Array[PackedInt32Array]): print("v") moves.clear() # return matrix after shifting down reverse(game) game = cover_up(game) merge(game) game = cover_up(game, true) reverse(game) return [game, done]