print rendering

This commit is contained in:
mehbark 2025-04-29 15:12:55 -04:00
parent 6e5f8415dc
commit 5978af026c
6 changed files with 183 additions and 0 deletions

42
main.gd Normal file
View file

@ -0,0 +1,42 @@
extends Node3D
var microban_1 := "
####
# .#
# ###
#*@ #
# $ #
# ###
####
"
var states: Array[State] = [State.from_string(microban_1)]
func current_state() -> State:
return states[-1]
func undo():
if states.size() == 1:
return
states.pop_back()
func step(move: Vector2i):
states.push_back(current_state().step(move))
func _ready() -> void:
print(State.from_string("\n#####\n#@$.#\n#####\n\n"))
func _input(event: InputEvent) -> void:
if event.is_action_pressed("u"):
step(Vector2i.UP)
elif event.is_action_pressed("d"):
step(Vector2i.DOWN)
elif event.is_action_pressed("l"):
step(Vector2i.LEFT)
elif event.is_action_pressed("r"):
step(Vector2i.RIGHT)
render()
func render() -> void:
print(current_state())

1
main.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://c707s0tgd88pg

15
main.tscn Normal file
View file

@ -0,0 +1,15 @@
[gd_scene load_steps=3 format=3 uid="uid://lrk2whqxl0w0"]
[ext_resource type="Script" uid="uid://c707s0tgd88pg" path="res://main.gd" id="1_ig7tw"]
[sub_resource type="BoxMesh" id="BoxMesh_0xm2m"]
size = Vector3(0.5, 0.5, 0.5)
[node name="Main" type="Node3D"]
script = ExtResource("1_ig7tw")
[node name="Camera3D" type="Camera3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 2.56036, 1.68081)
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
mesh = SubResource("BoxMesh_0xm2m")

View file

@ -11,9 +11,41 @@ config_version=5
[application]
config/name="sokoban poc"
run/main_scene="uid://lrk2whqxl0w0"
config/features=PackedStringArray("4.4", "GL Compatibility")
config/icon="res://icon.svg"
[input]
u={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":75,"key_label":0,"unicode":107,"location":0,"echo":false,"script":null)
]
}
d={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":74,"key_label":0,"unicode":106,"location":0,"echo":false,"script":null)
]
}
l={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":72,"key_label":0,"unicode":104,"location":0,"echo":false,"script":null)
]
}
r={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":76,"key_label":0,"unicode":108,"location":0,"echo":false,"script":null)
]
}
[rendering]
renderer/rendering_method="gl_compatibility"

92
state.gd Normal file
View file

@ -0,0 +1,92 @@
class_name State
extends Resource
@export var dims: Vector2i
@export var player_pos: Vector2i
@export var walls := BitMap.new()
@export var goals := BitMap.new()
@export var boxes := BitMap.new()
static func from_string(src: String) -> State:
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 state := State.new()
state.dims = dims
state.walls.create(dims)
state.goals.create(dims)
state.boxes.create(dims)
for y in range(lines.size()):
var line := lines[y]
for x in range(line.length()):
var pos := Vector2i(x, y)
match line[x]:
"#": state.walls.set_bitv(pos, true)
".": state.goals.set_bitv(pos, true)
"@":
assert(not state.player_pos)
state.player_pos = pos
"+":
assert(not state.player_pos)
state.goals.set_bitv(pos, true)
state.player_pos = pos
"$": state.boxes.set_bitv(pos, true)
"*":
state.goals.set_bitv(pos, true)
state.boxes.set_bitv(pos, true)
assert(state.player_pos)
return state
func solid_at(pos: Vector2i) -> bool:
return walls.get_bitv(pos) or boxes.get_bitv(pos)
func box_at(pos: Vector2i) -> bool:
return boxes.get_bitv(pos)
func passable_at(pos: Vector2i) -> bool:
return not solid_at(pos)
# todo: keep shared structure (e.g. walls are always the same)
func step(move: Vector2i) -> State:
var new: State = duplicate(true)
var p0 := new.player_pos
var p1 := p0 + move
var p2 := p1 + move
if passable_at(p1):
new.player_pos = p1
elif box_at(p1) and passable_at(p2):
new.boxes.set_bitv(p1, false)
new.boxes.set_bitv(p2, true)
new.player_pos = p1
return new
func _to_string() -> String:
var out := "#<<state:{0}>, {1}@{2}\n".format([get_instance_id(), dims, player_pos])
for y in range(dims.y):
out += " "
for x in range(dims.x):
if player_pos == Vector2i(x, y):
out += "+" if goals.get_bit(x, y) else "@"
continue
if walls.get_bit(x, y):
out += "#"
continue
match [goals.get_bit(x, y), boxes.get_bit(x, y)]:
[true, true ]: out += "*"
[true, false]: out += "."
[false, true ]: out += "$"
[false, false]: out += " "
out += "\n"
out += ">"
return out

1
state.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://bav3tjhu6anx