80 lines
2 KiB
GDScript
80 lines
2 KiB
GDScript
class_name Board
|
|
extends Node3D
|
|
|
|
@export var dims: Vector2i
|
|
|
|
# idea: board has very little logic, delegates to something else
|
|
# l8r tho
|
|
|
|
# literally just linearly search to find pieces at a position
|
|
# children
|
|
|
|
# for zooming out to see the whole puzzle
|
|
func top_left_aabb() -> AABB:
|
|
return AABB(position-Vector3(1,0,1), Vector3.ONE*0.1)
|
|
|
|
func bottom_right_aabb() -> AABB:
|
|
return AABB(position + Vector3(dims.x, 0, dims.y), Vector3.ONE*0.1)
|
|
|
|
# todo: Array[Piece]
|
|
func pieces() -> Array:
|
|
return get_children()
|
|
|
|
func pieces_at(pos: Vector2i) -> Array[Piece]:
|
|
var out: Array[Piece] = []
|
|
for piece in get_children():
|
|
if piece.lpos == pos:
|
|
out.push_back(piece)
|
|
return out
|
|
|
|
func find_piece_at(pos: Vector2i, filter: Callable) -> Piece:
|
|
var at := pieces_at(pos)
|
|
var idx := at.find_custom(filter)
|
|
if idx < 0: return
|
|
return at[idx]
|
|
|
|
func any_at(pos: Vector2i, filter: Callable) -> bool:
|
|
return pieces_at(pos).any(filter)
|
|
|
|
func solid_at(pos: Vector2i) -> bool:
|
|
return any_at(pos, func(p): return p.type == Piece.Type.Wall or p.type == Piece.Type.Box)
|
|
|
|
func passable_at(pos: Vector2i) -> bool:
|
|
return not solid_at(pos)
|
|
|
|
func remove_piece(piece: Piece):
|
|
remove_child(piece)
|
|
|
|
func add_piece(piece: Piece):
|
|
add_child(piece)
|
|
|
|
func add_pieces(piece: Array[Piece]):
|
|
for p in piece:
|
|
add_piece(p)
|
|
|
|
static func from_string(src: String) -> Board:
|
|
var lines := src.lstrip("\n").rstrip("\n").split("\n")
|
|
|
|
var width := 0
|
|
for line in lines:
|
|
width = max(width, line.length())
|
|
|
|
var dims := Vector2i(width, lines.size())
|
|
|
|
var board := Board.new()
|
|
board.dims = dims
|
|
|
|
for y in range(lines.size()):
|
|
var line := lines[y]
|
|
for x in range(line.length()):
|
|
var c := line[x]
|
|
var pos := Vector2i(x, y)
|
|
match c:
|
|
".": board.add_piece(Piece.goal(pos))
|
|
"*": board.add_pieces([Piece.goal(pos), Piece.box(pos)])
|
|
"+": board.add_pieces([Piece.goal(pos), Piece.player(pos)])
|
|
"$": board.add_piece(Piece.box(pos))
|
|
"@": board.add_piece(Piece.player(pos))
|
|
"#": board.add_piece(Piece.wall(pos))
|
|
return board
|