2019-11-21 00:25:53 +01:00
|
|
|
extends Node2D
|
2019-11-22 13:38:50 +01:00
|
|
|
class_name Taquin
|
|
|
|
tool
|
2019-11-21 00:25:53 +01:00
|
|
|
|
2019-11-26 13:57:50 +01:00
|
|
|
signal solved
|
|
|
|
|
2019-11-25 01:16:06 +01:00
|
|
|
var Piece = preload("res://src/Piece.tscn")
|
|
|
|
|
2019-11-21 00:25:53 +01:00
|
|
|
export var rows: int = 4
|
|
|
|
export var columns: int = 4
|
2019-11-22 13:38:50 +01:00
|
|
|
export var width: int = 512
|
|
|
|
export var height: int = 512
|
2019-11-26 13:57:50 +01:00
|
|
|
export var difficulty: int = 10
|
|
|
|
|
2019-11-26 13:42:54 +01:00
|
|
|
var interpiece: int = 5
|
|
|
|
var padding = 10
|
2019-11-21 00:25:53 +01:00
|
|
|
|
2019-11-22 13:38:50 +01:00
|
|
|
var pieces: Array = []
|
2019-11-22 13:50:37 +01:00
|
|
|
var missing_piece: Vector2
|
2019-11-25 22:56:50 +01:00
|
|
|
var rng = RandomNumberGenerator.new()
|
2019-11-21 00:25:53 +01:00
|
|
|
|
2019-11-25 22:56:50 +01:00
|
|
|
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))
|
2019-11-22 13:38:50 +01:00
|
|
|
|
2019-11-25 22:56:50 +01:00
|
|
|
|
2019-11-22 13:38:50 +01:00
|
|
|
func _ready() -> void:
|
2019-11-27 00:50:35 +01:00
|
|
|
$ColorRect.rect_size.x = width
|
|
|
|
$ColorRect.rect_size.y = height
|
|
|
|
|
2019-11-25 22:56:50 +01:00
|
|
|
rng.randomize()
|
2019-11-26 13:42:54 +01:00
|
|
|
var piece_size: int = compute_piece_size()
|
2019-11-25 22:56:50 +01:00
|
|
|
|
2019-11-22 13:50:37 +01:00
|
|
|
for c in range(columns):
|
|
|
|
var pieces_row: Array = []
|
|
|
|
for r in range(rows):
|
2019-11-25 01:16:06 +01:00
|
|
|
var piece = Piece.instance()
|
|
|
|
|
2019-11-26 13:42:54 +01:00
|
|
|
piece.size = piece_size
|
2019-11-25 22:56:50 +01:00
|
|
|
piece.position = position_for_index(Vector2(c, r), piece.size)
|
2019-11-25 01:16:06 +01:00
|
|
|
piece.set_number(1 + c + r * columns)
|
2019-11-25 22:56:50 +01:00
|
|
|
|
2019-11-22 13:50:37 +01:00
|
|
|
if r == rows - 1 && c == columns - 1:
|
|
|
|
piece.visible = false
|
|
|
|
missing_piece.x = c
|
|
|
|
missing_piece.y = r
|
2019-11-25 01:16:06 +01:00
|
|
|
|
2019-11-27 00:50:35 +01:00
|
|
|
$ColorRect.add_child(piece)
|
2019-11-22 13:50:37 +01:00
|
|
|
pieces_row.append(piece)
|
2019-11-25 01:16:06 +01:00
|
|
|
|
2019-11-25 01:24:38 +01:00
|
|
|
pieces.append(pieces_row)
|
|
|
|
|
2019-11-26 13:57:50 +01:00
|
|
|
shuffle(difficulty)
|
2019-11-25 22:56:50 +01:00
|
|
|
|
2019-11-26 13:42:54 +01:00
|
|
|
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))
|
|
|
|
|
2019-11-25 01:24:38 +01:00
|
|
|
func _input(event):
|
|
|
|
if event.is_action_pressed("ui_up"):
|
2019-11-25 21:40:55 +01:00
|
|
|
move_piece(Direction.DOWN)
|
2019-11-25 22:56:50 +01:00
|
|
|
if event.is_action_pressed("ui_down"):
|
|
|
|
move_piece(Direction.UP)
|
2019-11-25 01:24:38 +01:00
|
|
|
if event.is_action_pressed("ui_left"):
|
2019-11-25 21:40:55 +01:00
|
|
|
move_piece(Direction.RIGHT)
|
2019-11-25 22:56:50 +01:00
|
|
|
if event.is_action_pressed("ui_right"):
|
|
|
|
move_piece(Direction.LEFT)
|
2019-11-25 21:40:55 +01:00
|
|
|
|
|
|
|
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
|
2019-11-25 22:56:50 +01:00
|
|
|
|
2019-11-25 21:40:55 +01:00
|
|
|
update()
|
2019-11-25 22:56:50 +01:00
|
|
|
if check_solved():
|
2019-11-26 13:57:50 +01:00
|
|
|
emit_signal("solved")
|
2019-11-25 22:56:50 +01:00
|
|
|
|
2019-11-25 21:40:55 +01:00
|
|
|
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)
|
2019-11-25 22:56:50 +01:00
|
|
|
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
|