Created
March 23, 2025 17:49
-
-
Save increpare/4a7c6cea5dd4f9a436396a68e8205815 to your computer and use it in GitHub Desktop.
susdfd (PuzzleScript Script)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Play this game by pasting the script in http://www.puzzlescript.net/editor.html |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
title susdfd | |
author David Skinner | |
homepage www.puzzlescript.net | |
verbose_logging | |
debug | |
======== | |
OBJECTS | |
======== | |
Background | |
lightgreen green | |
11111 | |
01111 | |
11101 | |
11111 | |
10111 | |
Target | |
darkblue | |
..... | |
.000. | |
.0.0. | |
.000. | |
..... | |
Wall | |
brown darkbrown | |
00010 | |
11111 | |
01000 | |
11111 | |
00010 | |
Player | |
black orange white blue | |
.000. | |
.111. | |
22222 | |
.333. | |
.3.3. | |
l4a | |
brown | |
l4b | |
brown | |
l4c | |
brown | |
l5a | |
brown | |
l5b | |
brown | |
l5c | |
brown | |
crate | |
red | |
crate2 | |
red | |
target2 | |
blue | |
======= | |
LEGEND | |
======= | |
. = Background | |
# = Wall | |
P = Player | |
player_alt=player | |
O = Target | |
wall_or_crate = wall or crate | |
crate_or_target = crate or Target | |
l4a_or_l5a = l4a or l5a | |
l4a_or_l4b = l4a or l4b | |
l4a_or_l4b_alt = l4a or l4b | |
l4c_and_15c = l4c and l5a | |
player_or_wall = player or wall | |
crate_or_crate2 = crate or crate2 | |
player_or_crate = player or crate | |
player_or_target = player or Target | |
crate2_or_Target2 = crate2 or target2 | |
player_and_target = player and target2 | |
crate_and_target = crate and Target | |
======= | |
SOUNDS | |
======= | |
================ | |
COLLISIONLAYERS | |
================ | |
Background | |
Target, target2 | |
Player, wall, crate, crate2 | |
l4a,l4b,l4c | |
l5a,l5b,l5c | |
====== | |
RULES | |
====== | |
[ l4a ] -> [ l4a no l4a_or_l4b ] | |
[ l4a ] -> [ l4a no l4a_or_l5a ] | |
[ l4a_or_l4b ] -> [ l4a_or_l4b no l4a ] | |
( TYPES OF ENTITY | |
object, single_layer_property, multi_layer_property, aggregates | |
object no object | |
object no single_layer_property | |
object no multi_layer_properly | |
single_layer_property no object | |
single_layer_property no single_layer_property | |
single_layer_property no multi_layer_property | |
multi_layer_property no object | |
multi_layer_property no single_layer_property | |
multi_layer_property no multi_layer_property | |
aggregates no object | |
aggregates no single_layer_property | |
aggreagtes no multi_layer_property | |
) | |
(object no object) | |
(no overlap) | |
[ player no crate ] -> cancel (handled correctly) | |
(overlap) | |
[ player_alt no player] -> cancel (nothing amiss detected - need to be better at handling synonyms I think!) | |
(object no single_layer_property) | |
(no overlap) | |
[ player no wall_or_crate ] -> cancel (handled correctly) | |
(overlap) | |
[ wall no wall_or_crate ] -> cancel (handled correctly) | |
(object no multi_layer_properly) | |
(no overlap) | |
[ player no crate_or_target ] -> cancel (could output warning that property could be simplifed) | |
(overlap) | |
[ crate no crate_or_target ] -> cancel (this rule vanishes without a trace...) | |
(single_layer_property no object) | |
(no overlap) | |
[ wall_or_crate no player ] -> cancel | |
(overlap) | |
[ wall_or_crate no crate ] -> cancel | |
(single_layer_property no single_layer_property) | |
(no overlap) | |
[ player_or_wall no wall_or_crate ] -> cancel | |
(overlap) | |
[ player_or_wall no wall_or_crate ] -> cancel | |
(single_layer_property no multi_layer_property) | |
(no overlap) | |
[ player_or_wall no crate_or_target ] -> cancel | |
(overlap) | |
[ player_or_crate no crate_or_target ] -> cancel | |
(multi_layer_property no object) | |
(no overlap) | |
[ crate_or_target no player ] -> cancel | |
(overlap) | |
[ crate_or_target no target ] -> cancel | |
(multi_layer_property no single_layer_property) | |
(no overlap) | |
[ crate_or_target no player_or_wall ] -> cancel | |
(overlap) | |
[ player_or_target no player_or_crate ] -> cancel | |
(multi_layer_property no multi_layer_property) | |
(no overlap) | |
[ crate_or_target no crate2_or_target2 ] -> cancel (no warning) | |
(overlap) | |
[ player_or_target no player_or_crate ] -> cancel (could warn about simplification possibility) | |
(aggregates no object) | |
(no overlap) | |
[ player_and_target no wall ] -> cancel | |
(overlap) | |
[ player_and_target no target ] -> cancel | |
(aggregates no single_layer_property) | |
(no overlap) | |
[ player_and_target no wall_or_crate ] -> cancel | |
(overlap) | |
[ player_and_target no player_or_crate ] -> cancel | |
(aggreagtes no multi_layer_property) | |
(no overlap) | |
[ player_and_target no crate2_or_target2 ] -> cancel | |
(overlap) | |
[ player_and_target no crate_or_target ] -> cancel | |
( The above is not exhaustive though! The general structure, because of the fundamental simplicity of 'no' statements is | |
[ <list of properties...> NO property ] | |
what I want to say, fundamentally is "you don't need to say 'no property', because you've already specified contents for all the property's layers. | |
No, this isn't right. There are cases like. | |
The simplest approach is to just ignore properties on the left - just have a strict | |
occupancy mask. | |
The next approach, which is nice, is to also allow single_layer_properties, but that's where the complexity begins: | |
) | |
[ player_or_crate no wall ] -> cancel (this is easy - no object overlap!) | |
[ player_or_crate no crate ] -> cancel (uh, possible simplification, but maybe not worth annoying the user about it) | |
[ player_or_crate no crate_or_target ] -> cancel (ditto) | |
(what algorithm takes into account both simple object and single_layer_properties? | |
1: calculate occupancy at entity and layer level for all objects, synonyms, aggregates, and single_layer_properties | |
2: for each'no' entity : | |
3a: check if is (object or property) is 'covered' by the layer mask, and doesn't intersect with the object mask. | |
3b: if so, can cull the 'no' bit. | |
IS IT BETTER TO PRECALCULATE THE NO MASK AND CHECK AGAINST INDIVIDUAL OBJECTS ON THE LEFT? (maybe this works far more generally! or maybe i need to do a second pass at the end with info about the 'no' object mask , going throuhg the 'yes' properties?) | |
this algorithm doesn't cover cases like | |
) | |
[ player_or_target no player_or_crate ] -> cancel | |
(could be simplified to "[ target no crate ] -> cancel" - which the compiler does, so you know fine. ) | |
(the following isn't getting caught...) | |
[ l4a_or_l4b_alt ] -> [ l4a_or_l4b_alt no l4a_or_l4b ] | |
[ l4a_or_l4b ] -> [ l4a_or_l4b no l4a_or_l5a ] | |
[ no l4a_or_l4b ] -> [ no l4a_or_l4b l4a ] | |
(WHEN CAN I REMOVE A NO X) | |
(CASE 1: OBJECT / NO OBJECT | |
l1_objectA no l1_objectB, where they are different objects | |
) | |
[ player no wall ] -> cancel | |
[ no l4a l4b ] -> cancel | |
(CASE 2: SINGLE_LAYER_PROPERTY / NO OBJECT | |
l1_single-layer-property no l1_object, where object doesn't overlap with property | |
) | |
[ l4a_or_l4b no l4c ] -> cancel | |
(CASE 3: MULTI_LAYER_PROPERTY / NO OBJECTS | |
IF NEGATIVE *OBJECT* MASK COVERS MULTI_LAYER_PROPERTY, IT'S GONE | |
) | |
[ l4a_or_l5a no l4a no l5a ] -> cancel | |
(CASE 4: OBJECT / NO SINGLE_LAYER_PROPERTY | |
OBJECT NOT IN PROPERTY | |
) | |
[ l4c no l4a_or_l4b ] -> cancel | |
(CASE 4: MULTI_LAYER_OCCUPANCY / NO SINGLE_LAYER_PROPERTY | |
OBJECT IN PROPERTY | |
) | |
[ l4a no l4a_or_l4b ] -> cancel | |
(CASE 5: MULTI_OCCUPANCY / NO MULTI_LAYER_OCCUPANCY) | |
[ l4c l5c no l4a_or_l5a ] -> cancel | |
(in general, in "X no Y", layer occupation is a big factor. If | |
X occupies all the same layers as Y, you'd think Y would be surperfluous. | |
However, if X overlaps with Y on a per-object level, it gets complicated.) | |
(So, what's my algorithm going to be? | |
X no Y (best usability wise, mid optimization wise, to do for each Y as written in code) | |
1: get layer occupancies, L(X) and L(Y), | |
2: If L(Y) is contained in L(X) calculate object-level occupancies. | |
3a: If O(X) and O(Y) disjoint, you can cull the 'no' statement, give warning. | |
3b: If O(X) overlaps with O(Y), in principle can subtract X from Y, and regenerate the negative statement. Dont give a warning. | |
) | |
[ no l4a_or_l4b l4c ] -> cancel | |
[ no l4a_or_l5a l4c ] -> cancel | |
[ no l4a_or_l5a l4a ] -> cancel | |
[ no l4a_or_l5a l4b l5b ] -> cancel | |
[ no l4a_or_l4b l5a ] -> cancel | |
(this technically should also vanish, perhaps harder to detect though) | |
( [ no l4a_or_l4b 14c_and_15c ] -> cancel ) | |
(RHS OVERLAP TEST) | |
[ l4a ] -> [ l4a l5a no l4a_or_l5a ] | |
(WHEN DELETING STUFF FROM THE LHS, SHOULD DELETE FROM THE RHS AS WELL IF IT'S THE SAME, RIGHT? this is true for 'nos' in general though...) | |
============== | |
WINCONDITIONS | |
============== | |
======= | |
LEVELS | |
======= | |
####.. | |
#.O#.. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment