J, 456 441 441399 bytes
0=[:+./@,@>(@><@(<4|.@|:@4 o@,&4(4|.@|:@4 o@,&0])13#.inv 36bdnnshw5d 85686 36ba491bbil 85686 36bbvydg17b)([:(([*0=[:+/@,[*(e.10&l)*(e.11&l)y*w)ur)@(([:><@]><@[([+({:-{.)~/@]*(={.))~&.>/@,~[:<"1@\:~@;o~@;e(]<@<@(l,.4-~[~])"~"{~4+[~+&4)[~])~ur)(4-[)o(o=:|.@|:~&0)(u=.([[*0=[:,+/3[\"1(@,|y*1|.(w=:)e.l&11)*0=p)@]([(]((*-.)+_1|.*)(2=[:r&z&.|.(p*0<[)>.2*(e.10&l)*1|.p)~)([*0=[y=:+/@,(e.10&ll&10)*1|.(e.11&l)*0=p=p=:((0=[:(r=z=:(2*4<3#.|:@,:)/\.)(0<[)+e*@[+e.)oe-.10&ll&10,12&l=:(o#~]el=:#&e@e.~(4+o=4+(e=:1+i.4)(,9&,.5)"0/[&,.)&12))~])(r=:3[\"1(,@,|.@|:~&0))@])&.>/@,~<"0@|.@])
Try it online!Try it online!
It goes quite well as an tacit definition, as we're just working on the matrix itself. It maps the characters to numbers according to the list in level
.
Ungolfed:
NB. level=. '.BFRWbfrwiynp' iNB. ([;._2)map 0stored :as 0
NB.base rip....RRR.
NB.13, ......R...R
NB.then biy.B.R.F.R
NB.padded ......R...R
NB.with fin....RRR.
NB.floors )
NB.and packedwalls
map=:4|.@|walls=:@4 rot@,&4(4|.@|:@4 rot@,&0])13#.inv 36bdnnshw5d 85686 36ba491bbil 85686 36bbvydg17b
NB. rotate matrix x times
rot=:|.@|:~&0
NB. BFRW as numbers
objs=:1 2 3 4
NB. get all 1x3 fieldslists (possibleof rules)the original and the transposed matrix
rules=:([: ,/ 3 [\"1 (,@,|:))
NB. BFRWcheck if rule exists, e.g isrule&10 -> things that can be pushed
objs=:1isrule 2=: 3(#&objs@e.~ (4 + objs ,. 5)&,.)
NB. 10 2 1 0 0 1 1 2 01 0 -> 0 2 2 0 0 2 2 2 0 0
NB. used for checking which fields can move/get pushed
red=:(2* 4< 3#. |: @ ,:)/\.
NB. bitmap of thingsplaces that can gobe downwalked into
pass=:((0 = [: red (0<[)*@[ + e.) objs -. 10&isruleisrule&10 , 12&isruleisrule&12)
NB. get the objectswin thatplace fulfillcan't abe rule
isrulewalked =:into (objs #~ ]e.~not (4pushable +or objsblocked) (,9&,)"0/[)
NB. if moving into anwith unpushablea winyou-entity object,that setwalks boarddown to-> 0won
wonpush=: ([ * 0 = [: +/@, (e. 10&isruleisrule&10) * 1 |. (e. 11&isruleisrule&11) * 0 = pass)
NB. if there is anexists objectentity that is win and you, set board toand 0win?
wonyou =: ([ * 0 = [: +/@, [ * (e. 10&isruleisrule&10) * (e. 11&isruleisrule&11))
NB. thingscalculate thatwhich willplaces begets movemoved or be pushed down in a step
shifts=:( 2 = [: red&.|. ( pass * 0 < [) >. 2 * (e. 10&isruleisrule&10) * 1 |. pass)~
NB. applyactually shiftsmove ondown matrixentities
move_down=:(][ ((*-.)+_1 |. *) shifts)
NB. findget all `rib`rules etc.of andthe replaceform in(objs alphabeticalis orderobjs), sort them, replace them
replace=: ([: > <@]<@[ ([ + ({: - {.)~/@] * (={.))~&.>/@,~ [: <"1@\:~@; objs (] <@(isrule ,. 4-~[~])~"_ 0~"{~ (4+[)+&4)~ [])
NB. gather rules, rotate matrix byso leftmovement handgoes sidedown,
NB. (with unrotated rules) check for wonpush, move down, rotate back,
NB. replace and, check wonyou
step=move=: ([: (] wonyou rules)@(rules replace ]rules) (4-[) |.@|:~&0rot rules@]rot ([wonpush move_down wonpush~]) |.@|:~&0rules@] )
NB. pack map andappend moves intoto athe listmatrix thatand getsreduce reducedfrom right to left: with move,
NB. e.g. 1 step 2 step0 2move step1 stepmove 0 stepmove mapwalls
sim2=: (<@map<@walls step&move&.>/@,~ <"0@|.@])
NB. check if the board was set toafter 0everything (sois itfinished, isdoes acontain winningmatrix state)
sim=:only (0? =if [:yes +./@,@>-> sim2)won
It goes quite well as an tacit definition, as we're just working on the matrix itself. It maps the characters to numbers according to the list in level
. Only the rule checking (the multiple (e.10&isrule)
) might be worth going for an explicit definition / having the matrix as a global.
replace
is probably more complicated then it has to be, as the order in step
with the similar checks wonpush
and wonyou
. Because of this the dense function is not golfed much further, just variables replaced with their definitions and spaces removed. :-)