extends Node2D class_name Taquin tool signal solved var Piece = preload("res://src/Piece.tscn") export var rows: int = 4 export var columns: int = 4 export var width: int = 512 export var height: int = 512 export var difficulty: int = 10 var interpiece: int = 5 var padding = 10 var pieces: Array = [] var missing_piece: Vector2 var rng = RandomNumberGenerator.new() func position_for_index(index: Vector2, size: int) -> Vector2: var padding_w = (width - (size * columns)) / (columns + 1) var padding_h = (height - (size * rows)) / (rows + 1) return Vector2(padding_w + index.x * (size + padding_w), padding_h + index.y * (size + padding_h)) func _ready() -> void: $ColorRect.rect_size.x = width $ColorRect.rect_size.y = height rng.randomize() var piece_size: int = compute_piece_size() for c in range(columns): var pieces_row: Array = [] for r in range(rows): var piece = Piece.instance() piece.size = piece_size piece.position = position_for_index(Vector2(c, r), piece.size) piece.set_number(1 + c + r * columns) if r == rows - 1 && c == columns - 1: piece.visible = false missing_piece.x = c missing_piece.y = r $ColorRect.add_child(piece) pieces_row.append(piece) pieces.append(pieces_row) shuffle(difficulty) func compute_piece_size() -> int: var w_size: int = (width - (2 * padding) - ((columns - 1) * interpiece)) / columns var h_size: int = (height - (2 * padding) - ((rows - 1) * interpiece)) / rows return int(min(w_size, h_size)) func _input(event): if event.is_action_pressed("ui_up"): move_piece(Direction.DOWN) if event.is_action_pressed("ui_down"): move_piece(Direction.UP) if event.is_action_pressed("ui_left"): move_piece(Direction.RIGHT) if event.is_action_pressed("ui_right"): move_piece(Direction.LEFT) enum Direction { UP, DOWN, LEFT, RIGHT } func move_piece(direction) -> bool: var destination: Vector2 = missing_piece match direction: Direction.UP: print("up") destination.y -= 1 Direction.DOWN: destination.y += 1 print("down") Direction.LEFT: destination.x -= 1 print("left") Direction.RIGHT: destination.x += 1 print("right") print(destination) if (destination.x < 0 || destination.x >= columns || destination.y < 0 || destination.y >= rows): print("impossible move") return false swap(missing_piece, destination) missing_piece = destination update() if check_solved(): emit_signal("solved") return true func swap(src: Vector2, dst: Vector2) -> void: var tmp: Piece = pieces[src.x][src.y] pieces[src.x][src.y] = pieces[dst.x][dst.y] pieces[dst.x][dst.y] = tmp pieces[src.x][src.y].position = position_for_index(src, tmp.size) pieces[dst.x][dst.y].position = position_for_index(dst, tmp.size) func shuffle(count: int) -> void: while count > 0: count -= 1 var direction = rng.randi_range(Direction.UP, Direction.RIGHT) move_piece(direction) func check_solved() -> bool: for c in range(columns): for r in range(rows): if pieces[c][r].number != 1 + c + r * columns: return false return true