#Railbound Solver [Python Script] COMPLETE! Working on Interface...

1 messages ยท Page 2 of 1

fervent tusk
#

heres to 1000 messages in this thread btw ๐ŸŽ‰ ๐ŸŽ‰ ๐ŸŽ‰

#

mashing the cars and decoys together is so frustrating theyre polar opposites but theyre so similar in how they work

#

considering ill still have to add in world 11's mechanic i might add a 6th variable to the cars just indicating what type it is

#

instead of relying solely on the car number

#

yeah

fervent tusk
#

i think to fix the whole issue of not being able to remove stuff while its generating i can iterate over a copy of the cars instead of the actual cars

#

i will try that

fervent tusk
#

doing the fencepost might cause some problems now that i think about it because cars dont check if the tile directly in front of them will crash it

#

cause it always checks if the tile 2 tiles in front will crash it to make the branches shorter when generating

#

ex. a car is following directly behind a decoy and the decoy crashes, there is now a fence in front of the car which it wont check because its directly in front of it

#

couldnt have seen it 2 tiles ahead either because the decoy is directly in front of it

fervent tusk
#

aghhh my need for optimization and for stuff to be as fast as possible is killing me

#

i think im going to go with the just looping over all the cars and if a decoy crashes then the tile it says it wants to place can be like -1 or 0 and the program picks that up and removes it from the list

#

i do a loop for switches before generation, then a loop for generation, and then a loop for checking crashes so it makes sense kinda

#

crashes for cars are detected in generation because its faster and they dont need to remove anything, they can just kill the program and be done there cause car crashes mean the level isnt gonna be completed

#

so decoys need their own crash handling after generation to actually alter the lists

#

i do the same thing with cars that have reached the finish because i cant alter the list to say they've finished it until its done generating

fervent tusk
#

will check for an iteration comparison actually and do that first

#

ALSO! another thing on checking the maximum heatmap limit for boards:
i think when i want to figure that out i can alter the system slightly so it doesnt check for the best track count but instead checks for the solution with the highest heatmap value and then figure out what the max is for levels

#

same-tile detection outside gen loop vs same-tile detection inside gen loop

#

very confused on why it has more iterations

#

ok the inside detection doesnt work one moment

#

accidentally used the list with the original cars instead of the ones that moved, since im doing the detection in the array now i have to compare a generating's car position ahead of it to a car that has already generated and check if theyre on the same tile

#

ok i fixed it

#

it has a few more iterations

#

i would expect it to have less

#

ya i have no idea

#

i shall move it out then i guess

#
  • doing the crash detection in the loop requires a looot more loops to go over all the cars and see if any are crashed
#

i dont think i can do the same for head-ons because generation is done in game movements so the cars just pass through each other

fervent tusk
#

i think for decoys crashing im just going to act like the car is stalled indefinitely

#

for now at least

#

mmm i cant do that because stalling works specifically for gates

#

i might need to add another variable

#

actually that wont be very ideal because ill have to continue to add the info to the cars being generated that its in the same position (that wastes time)

#

the fence idea could still work id just have to add in the thing that checks if the tile in front of it will crash it

fervent tusk
#

gahhh the board wont be displayed properly if i make the tile a fence...

#

youd have to guess what tile would be there which is not good in terms of readability

#

cause the tile that should be there would just look like a fence

#

it technically solved it though :)

#

(7-1)

#

i think ill inevitably just need to make an extra variable that marks where decoys have crashed

fervent tusk
#

only took a few additions of code gp_smile

#

i only added it for if the car hit the border though so i just need to add it for everything else

#

adding it for crashing is definitely going to be a bit more complicated though

#

gonna call for now until tomorrow though, should hope to see world 7 dominated by then

#

the speed at which i can do these new mechanics with v5.1 is insane

#

its so much simpler to manage because it uses actual game logic

fervent tusk
#

to move on 7-2's decoy solution requires that the decoy crashes into an empty tile which might be problematic

#

i could try and make it so placing an empty tile is an option but then it isn't technically placing a tile and making that one specifically not place while still being in the selection for tracks to generate would be annoying...

#

i dont really see any other solution though because placing nothing has to always be an option for decoy cars in case they can do that and have an extra track

#

the main problem is the system that kills boards if theyre under or equal to the minimum tracks solution

#

so actually.. i could easily check whether or not thats possible by just checking if placing a track wouldn't beat the best solution, in which case the only placing option would be an empty tile

#

the problem of branching with different available tracks is still a problem though

#

cause right now i can just pass a single available_tracks variable because of how generation works, there is never an instance where a car can both place a track and change one, it either changes tracks, leaves them the same, or places new ones. they never combine

#

but since decoys can do that i need to account for it...

#

i think during the final board setup for the next game movement of a generation if an empty tile is included in the board then ill add 1 to the available_tracks just for that branch

#

actually that wouldnt work cause theres still the option the only placable track is 0 in which the counter wouldnt go down so it cant be changed, but for the option where its 0 and the rest of the generatable tracks there then id need to detect the 0 to be changed

#

and there wouldnt be a difference between the 0 where the tracks dont need to be changed and the 0 where they do

fervent tusk
#

im gonna try negating it by 1 no matter what when it places 0's, ignore the thing that kills it if it's worse than the best solution, and then add 1 available track to any generation that places a 0

#

actually

#

i could just do another combination checker like i do for the entire generation system that provides different combinations of the tracks placed and cars it does for each game movement and add a combination for the tracks too

#

itd waste resources since it only applies for when a "0" track is placed (empty tile) but i think the combination maker is fast enough that it shouldnt matter

#

im gonna test a level that takes some time and see if there's any difference

#

actually appending it would take time

#

i wonder if there's any other way

#

i could add ANOTHER variable that tells whether or not to negate the tracks if a specific car chooses to place nothing

#

actually that'd work well

#

because i wouldnt need to pass it through to the next game movement

#

so it wouldnt be adding more variables to the generation ib_think

#

mmmm i just realized its even more complicated now because theres a chance the decoy either crashes or doesnt during a turn so i have to decide on that now too

#

actually

#

when i made the first board solver for decoys (7-1 i showed earlier) i made it so it only removes decoys that crash once the next game-movement has started, not after its been generated

#

that way a branch isnt needed and it still gets the job done

#

so that would solve the crashing aspect

#

i dont think i can do the same for 0 tiles though because they have to be done before the next game movement

#

i just cant winnn

#

so placing a 0 tile wont even work because how the tile placing works after all the generation is done it places the track for each car at their respective positions

#

but i cant place a 0 because the car needs to be on the same tile when it crashes, but if it were to place a 0 tile it would need to be on the tile in front which is impossible

#

i think what i can do is just make it so if the tile it wants to place is a 0 it doesnt do place it but still does all the other stuff

#

decoys r so annoying

#

theyre making everything complicated and not simple gp_dead

#

now that the 0 placing is figured out (i hope) i just need to make crashing work i think and the first version of decoys should be done

#

then a bunch of bug fixing

fervent tusk
#

good god

#

making it so the decoy can choose whether it wants to crash or not is actually messing everything up

#

i cant just return false if crashes happen now because the decoy can choose whether it wants to be on the tile its on or if it wants to be a tile ahead with how crashing is

#

the solution i did for all the branching stuff to prevent needing extra variables to pass on through generation was to do it all at the start of the next game movement instead of at the end of the first one

#

which is really annoying because it wastes resources going through a bunch of different branch combos of cars and tracks when theyre all gonna have a same-tile collision

#

previously i could do it right after a generation was complete but now that decoys exist and decide whether or not they wanna move or crash i need to do all of it on the next game movement

#

ughghghghghhhgjdalfgj

#

7-2 doesnt work

#

ok when the board is checked to see if its solved it does that by seeing if the final car going into the train matches the LAST CAR in the original cars from the data in the level

#

normally thatd work because the list would be like (0, 1, 2) for the original cars and then the solved order would be (0, 1, 2) and match because the last values are both 2

#

when i use decoys since the list has to contain both of them i mash it together

#

decoys are represented with their own numbers for when i do heatmaps too so the list would look like
(0, 1, 0) because car 1, car 2, then decoy 1 so the ends would never be 1 and 1 and it would never solve

#

i dont need to mash together the original cars list thankfully i can just put that value in for generation so it should be good

#

2 down so far

#

i still need to add all the heatmap stalling and looping shenanigans

#

ok for 7-3 it thinks the car is stalled and kills it after the decoy hits the switch

#

pretty sure its because the cars go one-by-one or something
i have a general idea of what the issue is but not precisely

#

the program removes crashed decoys before checking for any switch stuff

#

it can also do 7-3A but it crashed on 7-3B so now i have to add the loop stuff in

#

after that the only issue should be allowing decoys to crash with each other and then world 7 should be good

fervent tusk
#

im debating if i should add another variable to count the amount of looped cars every game movement or if i should use a slow numpy method

#

actually i can just use the numpy method once to test on the last decoy car to see if the others are also looped

#

that way it doesnt get used multiple times uselessely

#

on second thought since i use a car number of -1 to indicate a car is crashed ill just use -2 to indicate its looped

#

then i can just see if theyre all looped

fervent tusk
#

ok i was messing with a bunch of stuff, went back to confirm world 6 to make sure i didnt mess with any vital generational stuff

#

it did take x3 as long which is a let-down but it could be because i have steam and railbound open right now and frankly x3 is not bad when the program can go this fast so i dont really care

#

what i DO care about though...

#

i looked over the levels to make sure there wasnt anything sketchy and i actually noticed 6-9d has 1 more track to its solution than the guide

#

the guide says it has 1 but the solution says 2

#

yup!!! it works!!!

#

i feel so silly for putting it in but not checking if the tracks were better or not

#

guide is now down 6

#

i love finding better solutions it makes me so happy

#

@tranquil sinew not sure if you would consider this a "game-breaking" solution but i find it noteworthy as you dont need to use the left side at all

#

surprised it wasnt found at all when the solution is really straight...

#

i suppose it still does use the buttons on second thought which is a given so nevermind

#

back to picking apart world 7 with more motivation than before ib_icon

fervent tusk
#

i cant tell whether or not the game is wrong or the program is wrong here

#

im pretty sure the car is supposed to move, not crash

#

the frame the decoy touches the switch the first car should be ready to move the next turn and the 2nd car should just be following behind...

#

im so confused

#

are they supposed to crash?

#

are switches detected after the car exits that tile or something

#

yeah the car is supposed to move

#

?

#

im so confused rn

#

the car is 100% supposed to move wth

#

as soon as the switch is pressed the car should be able to move

fervent tusk
fervent tusk
#

i am now just realizing that the solution wouldnt work anyways because the gate at the end prevents the cars from continuing but my point still stands that they crash instead of car 1 moving forward

fervent tusk
#

are gates done after all the movement is done?

fervent tusk
#

ok 7-4 wasn't working and i think i figured out why

#

when the different combinations are made for all the boards and cars each game movement, for tracks they're just placed on the board over each other

#

so if the first combination was (1, 1) and the 2nd was (2, 2) then for the (2, 2) combo it would overwrite the (1, 1) combo by placing the 2's on those tiles

#

normally this works fine but when 0's are placed they arent placed because of all the decoy shenanigans it causes

#

so if a decoy is planning on placing a 0 ill just do some quick math to get the position ahead and set that to 0 i guess

fervent tusk
#

7-4 is killing me

#

the solution doesnt work because how the decoys crash is they go onto a tile, and then the next game movement they "decide" to crash which means a crash takes a game movement longer than it should

#

and if said decoy is on a switch when it chooses to crash it does it for both of those game movements

#

i can try saying the car is stalled for the first game movement so it cant press the switch again but idk if thatll backfire in the future

#

i shall try it for now

#

yesss

#

levels up to 7-5 work now

#

not sure why 7-5 doesnt work but ill figure it out next time

#

i really hope i dont have to change a bunch of stuff for the new gate order or whatever i just figured out

#

decoys are enough to handle

tranquil sinew
fervent tusk
tranquil sinew
# fervent tusk Luke please explain why this isnt valid

the gate is opened at the same time the crash detection occurs because the other car tried to enter the tile that was already occupied

IMO the logic is handled as expected, but it's not represented well visually through the game's graphics

fervent tusk
#

๐Ÿค” your crash detection might be different from mine then

#

i have a loop for all the cars to do anything with switches prior to movement, then a loop for all the game movement

#

for every car that does its game movement loop it checks for head-on collisions and tunnel crashes

#

then after the game movement loop it checks for any same-tile collisions before going to the next tile

#

i think what i can try is putting all the crash detection before the switch loop because head-ons can actually be outside of it possibly now that i think about it

#

tunnel collisions are still gonna have to be in the loop cause tunnel calculations should be done once and i cant think of any way a gate would cause a tunnel crash

fervent tusk
#

ok moving the crash detection sorta did its job but not really

#

its not really getting anything different for like world 6 but it found an impossible solution on 6-9C

#

yeah no its finding faulty solutions nevermind

#

ugh

#

im gonna deal with that new crashing stuff once world 7 is done

fervent tusk
fervent tusk
#

ok figured out why 7-5 wasnt working

#

the decoy attempts to make a 3-way that loops it back around which shouldnt happen

#

normally for other cars i have heatmaps on them that prevents them from making 3-way that mess car movement and other stuff up but since i removed the heatmaps from the decoy for looping it cant use it

#

so what i think ill do is use the heatmap for the decoy but not use it at all for the heat map limit or crashing or anything

#

plus i dont have to reset it because it still works as a loop detector after all the other cars crashed

#

the only thing i have to finish now is making it so decoys can crash i think

#

then i can finish up world 7 and figure out how to do the new gate thing i found

#

im gonna add the crash system before i do 7-5a because the level itself is really complicated

#

so ill do 7-6 and the levels after it then do the crash system and come back

fervent tusk
#

ok 7-6 and 7-5a didnt work firstly because theres 2 decoys and with how the list management works it doesnt do it properly so i just need to fix that and then do crashing

#

i think

#

the main problem was it removed list things in ascending order (1, 2, 3) so when it removed stuff from lists the indices would get messed up cause the list shifts when you remove something

#

so i just made it descending as that doesnt affect the list shifting

#

gonna try the rest of world 7 now.. only need crashing decoys added

fervent tusk
#

beat the guide by 3 more tracks racking it up to beating the guide by 9 now ib_wow

#

(7-7C)

#

@tranquil sinew sorry for the pings ib_bye
this solution doesnt need the decoy, not sure if you'd consider this one game-breaking? but at the same time i guess the decoy causes more confusion when solving? not sure

fervent tusk
#

i tried all of the levels but 7-5a didnt work so i just need to fix that one up, and then fix the gates and i can just chill through world 8 because theres no new mechanics there gp_smile

fervent tusk
#

figured out why 7-5a errored (the first time at least)

#

when checking for stalled stations, i have an if statement checking if the car number is station stalled, and also if it isnt a decoy

#

the problem is it checks for both of those at the same time, so if there were only 1 car (meaning the highest index in station stalled is 0) that means if a decoy tried to check the 1st index of station stalled itd error

#

normally it wouldnt be a probem because it doesnt work anyways if its a decoy but it still checks it so i just have to stack if statements

#

less clean but ib_happy

#

2nd error!

#

it thinks the decoy can reach the end which im pretty sure i prevented but i guess not gp_dead

fervent tusk
#

ok... another confusing game mechanic just hit me

#

for 7-5a (the one above i just sent) the solution was incorrectly done because the decoy reaches the end after the car finishes, and the program didnt check for it

#

so i added that in and...

#

7-4b doesnt work.

#

...but it kind of makes sense

#

if you think about it, it should technically be a faulty solution because the decoy would loop around again and connect to the train eventually

#

but it works.

#

the one i showed for 7-5a however, does not

#

so this begs another question for luke...
how does decoy finishing work?

#

what it seems to me like is that the decoy moves either 1 or 2 game movements and then finally stops

fervent tusk
#

ok... i added another variable that gets passed through generation (yippee...) that records the amount of game movements after all the cars have been solved

#

im gonna make it count to 2 before it counts the solution as valid but i still have to deal with some shenanigans cause after a car solves theres no cars in the cars to use and that can be problematic depending on if theres decoys or not

fervent tusk
#

...closer

#

it can do all the world 7 levels now but i have yet to add in decoy crashing which is why im not getting the 6 extra tracks i should be for 7-5a

#

42 minute level huh...

fervent tusk
#

ok... so while figuring out how to do decoy crashing i need to think about what tiles are inaccessible because of car crashing

#

in the case of head-ons the car is just on that tile so its simple

#

but for same-tile collisions its kind of on 2...

#

as shown in the video above i cant just do it where the same-tile crash makes just the tile where they collided inaccessible, because then another decoy coming up to that point would crash the tile behind, etc etc

#

the reason i cant do it is because then all the "inaccessible" tiles would be on the front half of the car, not caring about the back

fervent tusk
fervent tusk
#

i think what ill do is make the back half of the car inaccessible, and then the initial crash tile is also inaccessible

#

that should likely work

fervent tusk
#

ok, after some testing with all the same-tile stuff:
cars that collide at the same tile dont trigger switches, so it must mean same-tile collision is before gate detection

#

the reason i had to put it after is because on 7-3 it rams into the boundary of the level, in which case i crashed the car before it even hit the boundary, but setting the position where it crashed at the boundary

#

its kinda complicated but it made me have to put the decoy crashing after switches

#

i think i can make it only crash it on the movement where its actually trying to go into the wall though

#

that way i should be able to move the decoy crashing before gates (and switches), so that same-tile collisions dont trigger switches

fervent tusk
#

ok... to do same-tile collisions they absolutely need to be put after generation/movements

fervent tusk
#

since when they happen for decoys i need to make the tile "behind" the car inaccessible, i need the previous car's position 1 game movement ago to mark that tile inaccessible

#

actually i could just get the position ahead for each car before generation using math and id still have the previous car because its an unchangeable parameter passed through generation

#

crashing is going to have to be after gates/switches and right before movement generation though in that case

fervent tusk
#

nvm that doesnt work because a car only chooses to crash itself after the collision detection is done

#

so a decoy can bypass a collision by appearing that its going to move ahead the next movement, but it could crash itself and not move if it decides to

#

thus collision needs to be after it in case the car crashes itself

#

mmmm thats the reason i put it before movement actually because then i wouldnt need to account for all the branches

#

the problem is to properly mark which tiles are inaccessible i need both the previous car's position and the current car's position

#

its impossible to do it at the start because you cant tell where the previous car was thanks to 3-ways redirecting you in the same direction for 2 ways

#

i could add a parameter thats passed through generation with the previous car but thats annoying

#

actually no way because then id also have to do crasrhed decoys accounting for multiple pos aheads

#

i think ill have to just add the previous car positions to be passed through generation

#

making 12 variables passed through ๐Ÿ˜…

#

the biggest it gets should hopefully be 13 once i add semaphores

#

no actually i dont think that will work either

#

if i go through the entire process of moving every car and THEN crash them, i need the previous stuff because im essentially going back a game movement

#

so if there was a train of cars following behind each other and one of them crashed not all of them would crash because it checks the cars one at a time and its adding new inaccessible tiles to that list while going over it

#

basically if a car crashed and THEN added itself to the inaccessible tiles cars that were tested before ignore that inaccessible tile

#

i think the only solution is putting same-tile collisions into the movement loop

#

i will see if i can make it faster

#

reference before i change it to being in the loop

fervent tusk
#

so annoying

#

i cant put the same-tile collision after the branch starts (like testing each 0, 1, 5, 6 track individually next game movement) because then its doing the crash detection after everything from the previous game movement has been finalized and checked and its slower overall

#

so i have to deal with there being multiple different car positions because the decoys can crash themselves

#

๐Ÿฅฒ

fervent tusk
#

since i need to have 2 variants of the collision detection its difficult as i only want to perform a collision detection once, and as early as possible at that so it doesnt waste resources on checking stuff when a collision would be more important

#

i cant use the loop that confirms placable tracks because for a decoy itd look like (0, 1, 5, 6) meaning itd check for the no tile placed collision once, but check the other type 3 times

#

also thats later into the script than would be optimal to save time if i put it before like track picking

#

hm

#

i can make it so when a decoy is picking tiles it checks if not moving would cause any problems on second thought

#

i feel like other cars crashing into the decoy itself should make that impossible though

#

ugh the same goes for head-on crashing now that i think about it too

fervent tusk
#

actually what am i saying

#

if a decoy is placing nothing that means its going to crash

tranquil sinew
fervent tusk
#

forgot to check for collisions with stalled cars because the new collision system is inside the loop... woops

#

probably also goes for station stalled cars and a lot others too...

#

the reason why other cars dont detect theyre crashing with the stalled one is because when checking for same-tile collisions cars only check for collisions with previous cars that have generated (for example car 3 would only check for collisions with cars 2 and 1 because they have moved already)

#

which works because it essentially just creates the combinations to cross-check if each car works

#

but if car 2 is stalled and car 1 tries to ride into that tile it doesnt check for it because car 2 skipped the loop as it was stalled and car 1 only checked for no cars to collide with

#

instead of doing a list to make things easier im just going to create a function with the crash testing so i dont have to write it in there 9 different times

#

actually ill try making a list with list comprehension

fervent tusk
#

ok.. with how i put it in i thought i made it so decoys cant crash with cars but i guess they can so i shall fix that

#

before it was ordered that decoys would be done last so i could just check if it was a decoy that crashed with the unnamed car and it had to be a decoy because they were done after hte other cars

#

but now its the other way around where they check backwards so it cant work

#

cause the decoy checks original cars now too meaning i need an indicator for if its a car or a decoy its crashing with

fervent tusk
#

so close yet so far

#

it doesnt place tracks sometimes now fsr

#

ok its because decoys place 0s on top of cars that place stuff there

#

for example a car could place a straight track in front of it while a decoy 2 tiles ahead places nothing, overwriting that straight track and making it look incorrect

#

gonna try just doing it in reverse

fervent tusk
#

i think its fixed but running 7-5a for a while is showing no results.. all other levels in the game work fine

#

im skeptical because it didnt even find any solutions.. but

#

ok nvm

#

i originally ran it with a minimum tracks of -1 which goes for any level to solve it

#

but i set it to 5 instead so then it can find the solution with 6 extra tracks according to the guide and run faster knowing the limit is 6, didnt find anything

#

sigh

#

set it to 4 and it found one with 5 (it doesnt work)

fervent tusk
#

ok finally found out why it doesnt work

#

the ONE crash i didnt fix for decoys is if the permanent tile in front of it crashes it ๐Ÿ™ƒ

#

gonna make it so they can do that and i should finally be done

fervent tusk
#

finally got it so it considers the best solution viable..

#

after all of that the last thing i had to add was making it so if the decoys crashed before the 2 movements after the last car reaches the train the solution still counted

#

still doesnt find the right solution though...

fervent tusk
#

ok, the next biggest problem for 7-5a now is that decoys can place 0's over any tile they want (including permanent) which messes things up so much

#

the reason why it can do it at all in the first place is because how creating new boards from the chosen tracks work is placing them over each other

#

normally itd work because a board replaces all the tiles for the 1st branch it creates, overwrites all of those tracks with the 2nd branch, 3rd, etc.

#

but when it places nothing its not overwriting anything which becomes a problem

#

if multiple cars placed tracks on the same tile it wouldnt end up working because theyd end up inevitably crashing as both are going the same direction 1 tile away from each other

#

decoys can do that though

#

the method i do now though is much better because instead of making like 8 copies of the board and then modifying them i only have to make 1 and then overwrite stuff

fervent tusk
#

actually it makes 8 copies anyways because it needs to pass copies through generation

#

so i could copy and then place tracks versus overwriting tracks and then placing

#

in which case i can actually avoid having to place anything because its not overwriting

#

it can create the 7-5A best solution if you make it the only possible path to make (basically covering every unused tile with fences) but it still doesnt generate it if you do the level normally

#

will try making certain tiles accessible until something pops up

fervent tusk
#

for reference, here's the best solution, and where the fences would be on the hypothetical board i tested that can only result in the best solution

#

after some testing, removing either of these 2 fences results in the solution not being found, but it can generate the solution otherwise

#

curious as to why they're at the exit points but only 2 of them?

#

it doesnt make the 3-way at the end if one of the fences isnt there

fervent tusk
#

finally figured it out ๐Ÿคฆ

#

its another problem with decoys being able to crash or not and whatever

#

the solution doesnt work because the amount of available tracks arent correctly processed

#

i process it properly when i move onto the next generation but not when i move onto the next car

#

so it can be misrepresented

#

as a result, in this case, the program thought it had less tracks than it did

#

so it killed the branch prematurely

#

what i did originally was negate the tracks if the list had both the possibility of placing and crashing the decoy, and then making up for it the next generation by adding a track if it was going to crash (because it didnt place anything)

#

so what im going to do instead is the opposite which is not negate a track but the next generation if it places a track it negates it there

#

that way it shouldnt conflict

fervent tusk
#

ok.. it FINALLY found it but...

#

and i set the lowest tracks to 5

#

meaning any boards under that got killed

#

i set it to 4 and it took 60s and about 2.6m iterations

#

๐Ÿ˜ฌ

#

it works so im not complaining

#

gonna test world 7 in full now (with -1 lowest tracks so it works...) hopefully all goes well

fervent tusk
#

very doubtful it took 52m41s

#

will investigate if any levels take longer than this

#

besides that, the rest of the world 7 levels worked as intended ๐Ÿ˜„

#

took 54m15s overall

#

gonna work on fixing the one issue with 7-3B now and crashing before gates and whatever, i pray it doesnt take too long

fervent tusk
# fervent tusk very doubtful it took 52m41s

actually it makes some form of sense to me now that i think about it because the heatmap limit is 10 from having the swapping track in the bottom right so it has to loop the car around 10 times before it crashes, also taking into account all of the decoy shenanigans

#

still absurdly long

#

actually i just realized that the board isnt accurate

#

theres a vertical track in front of the ending track instead of a 3-way which should be impossible

#

sigh

#

fixing time

fervent tusk
#

14 (the 3-way) is now in front of the ending track as intended

#

the only other problem is i ran 7-8 and it said it saved a track when it didnt (the solution is the same though so no worries) probably just some oversight with me changing the decoy branch available tracks so it negates after generation instead of during

#

yup (kind of) just forgot to remove a variable from a list when cars finish

#

re-did all of the world 7 levels and they worked gp_cool

#

all thats left to do is fix the 7-3B thing with crash priority and then i can move onto world 8

fervent tusk
#

simply moved where the switch code was from before generation to after generation

#

and that seemed to fix it

#

thus crashes are detected before switches

#

im gonna run it through world 3 and 6 just to confirm it works properly though

#

yeah nope

#

sigh

#

so the order i put it in works as intended, but i think i just need to rearrange some variables like stalled and stuff to make it work properly

#

there might be some aspects of switches that are before and after but i have to look through the whole thing more in depth

fervent tusk
#

ACTUALLY

#

i just realized something thatd make things way easier

#

instead of changing literally everything so it works...

#

variables baby

#

i am going to see if i can add some variable indicating when a gate is lifted and crashes will work slightly differently on that frame to account for it

#

i have a list of stalled_cars that is added to the cars to check for when crashing

#

its updated after gates are done so i can just put it before and everything should work

#

im so smart oh my god

#

yeah thats literally all i had to do

#

tested 7-3b and it worked perfectly, tested worlds 3 and 6 and they worked perfectly

#

hallelujah we're going to world 8

#

Railbound Solver [Python Script] World 8/12

#

alllrighty

#

the main problem with world 8 is going to be time unfortunately

#

4 cars means exponentially more time

#

my program is still insanely fast though so it shouldnt be too much

#

im going to put the program onto my pc and run everything on there so its max speed

#

hopefully no problems arise, and if they do i pray that its just an input problem with setting the wrong values for the level like the board or cars

fervent tusk
#

at least none of the world 8 levels have decoys

fervent tusk
#

things of note:
8-4a has the highest time and iterations yet, at 3h47m17s and 797 million iterations
8-5b supposedly has a solution with 7 remaining tracks
8-6a has been running for over 8 hours now with no solutions found
the program has run for about 23 hours and is only at 8-6a

#

im gonna check all of the better solutions and then start working on world 9 while i wait for world 8 to finish

#

i am very surprised world 8-6a has been running for so long

#

it has 48 tracks though

#

im basically running a sandbox level.. (which isnt too far off because thats what world 8 used to be... lol)

#

having the switch rail set the heatmap limit to 10 probably doesnt help a whole ton either

#

im afraid i cant compare things to the guide any more because most world 8 levels are outdated from when it was made soo.. ill start searching the server for best solutions ๐Ÿ˜„

#

on 8-3a i put a tile in the incorrect place so ill have to fix that on a re-run

#

its so cool to think it spent 4 hours making it and it got it with 4 extra tracks

#

i love thinking about how long it took to do that massive board

#

i love that it got SEVEN tracks remaining

#

its so cool to see it do this amazing stuff and it actually works after all the debugging ive had to do it makes me so happy

#

i cannot stress enough how cool this is

#

yeah all the saved track solutions work

#

i love this program so much dear god

#

so now i just gotta wait for 8-6a and the rest to finish

#

im kind of excited to see 8-6a be in the billions ib_happy

#

well i guess ill get started on world 9 with that

#

gotta add all the levels into my solver first though

fervent tusk
#

finished adding all of world 9 and world 10

#

had to solve some of the levels to unlock every level so i could map it and something hit me with the semaphores

#

there can also be solutions that may use all tracks but have less semaphores

#

technically that counts towards minimum more so gp_smile

#

lowest tracks then lowest semaphores will be the best option

#

ok! getting started with semaphores im gonna have to figure out how they work in the first place

#

i can just add an extra level variable to tell how many semaphores the player has and then i can add another one that retains through generation

#

as for how they work: semaphores act as closed gates until a car passes in front of that semaphore

#

i can figure out what "in front of the semaphore" means once i establish the last criteria:
i need to find out where semaphores can be placed

#

at first glance it seems kinda random with turns and stuff but now that i look more at it it seems like semaphores can be placed at the edges of 3-ways

#

additionally they cant be placed on 3-ways

#

yeah i think thats it

#

semaphores are placed on the surrounding tiles of 3-ways if that tile is not a 3-way or already has an interactible on it

#

from what it looks like

#

and opening them is actually triggered by PASSING the semaphore

#

the next issue is figuring out what tiles are beside that semaphore however

#

actually i need to figure out how to know what 3 tiles are around a 3-way in the first place

#

instead of checking every angle the car car go into a 3-way from im just going to make a new list that tells what tiles adjacent to a 3-way can have a semaphore on them

#

and then i can check those 3 tiles for exceptions like having interactibles or having a car or being a 3-way

#

i could do the same thing to find the 2 adjacent tiles for a semaphore too but thatd be kinda lengthy and start to stop being worth it

#

for the semaphore's 2 adjacent tiles all those rules above apply as well as it cant be a track the car couldnt access

#

cause the car has to be able to ride through the semaphore fully without crashing

#

i think i might just end up having to make a list for all 14 different tracks

#

ah well

#

the biggest problem is figuring out how im going to generate semaphores

#

a car can't prematurely place a semaphore unless it places a 3-way the next frame

#

also placing semaphores during generation kinda breaks how it works overall

#

my generation system works exactly like the game as it is now, just doing it frame-by-frame

#

if it places semaphores during generation that'd be like placing a semaphore on frame 5 or something

#

but in the game semaphores are always placed on the first frame

#

this is going to be a massive problem

#

semaphores might be even worse than the decoys and i thought the decoys were the hardest part of this entire project

#

hold on

#

no. it can be done

#

i can check if a car has passed any tiles next to where the car wants to place the semaphore by checking the heat maps

#

so that solves the frame problem, i can just add an additional restriction saying adjacent tiles must have a total heat map value of 0 from cars passing them

#

but ill still need to figure out all the adjacent passing and opening stuff

fervent tusk
#

for placing semaphores i have a variable that says whether or not a 3-way can be placed 2 tiles ahead so i can also use that

fervent tusk
#

if a car is going on a straight track and it can place a 3-way 2 tracks ahead and it wants to place a semaphore then it can do that

#

im gonna start making semaphores work level-by-level

#

on 9-1 i just need to make it so if theres a 3-way 2 tiles ahead a car can choose to place a semaphore

#

and all the heatmap shenanigans too

fervent tusk
#

actually starting with 9-2 is smarter

#

ughghg i just realized something

#

assume the cars are here during generation

#

the 2nd car wants to place a semaphore in front of it for the solution

#

so it would have to place the semaphore and track next frame

#

however, to place a semaphore it needs to be adjacent to a 3-way

#

and my generation cant create a 3-way unless a 2nd car rides over previously placed tracks

#

so basically, to create the 3-way the 2nd car needs to cut through here into the 1st car's path

#

however, the solution requires that the semaphore is placed previously

#

but the solution also requires the 3-way

#

the 2nd car cant detect any 3-way to place the semaphore because the 1st car isnt there yet

#

so placing semaphores based on 3-ways is out of the question now

#

i need to be able to place them ignoring that rule but still apply it so it follows game logic

#

what i could do is make cars kinda like decoys where they can place a semaphore whenever (essentially chose to stall themselves whenever) but thatd be increasing the iterations counter a bunch and making a ton of useless iterations

#

i dont think theres any other solution though

#

ok, i have an idea i think

#

its not exactly ideal but its the best thing i can think of right now

#

a car can choose to place a semaphore with the track its going to place but it ALSO places a 3-way 2 tiles ahead of that semaphore

#

and it does a bunch of checks along with it to make sure the 3-way isnt useless etc etc

#

it still wastes a bunch of iterations but its the best thing i can think of

#

the biggest problem is going to be i can now let cars do the same thing as decoys where they can choose to stall themselves

#

which messes up with crashing so much

#

yeah this might be worse than the decoys

fervent tusk
#

there are 2 ways i can go about semaphore generation:

  1. place a random track AND a semaphore, then place a random track after and require the solved board have that tile be a 3-way
  2. place a random track AND a semaphore, then place a random 3-way after and require the solved board to have all sides of the 3-way be used
#

i like #1 more because it prevents the semaphore car from creating a useless 3-way that isnt playable, and it makes the whole pathway process simpler over all

#

i think ill try that

#

ill have to pass a few more variables through generation though (making it 13+ now...)

#

as for how the semaphore branching works... i need to incorporate it into the track selection branching somehow (ex. right now a track selection could be (2, 7, 8), so i need to be able to make it (2, s2, 7, s7, 8, s8) where the "s" adds a semaphore to that track)

#

i cant have any "s" in the actual number though the list would literally have to be (2, 2, 7, 7, 8, 8) so ill need an extra thing indicating which ones are a semaphore option

#

although honestly itll look more like (2, 7, 8, 2, 7, 8) because im gonna make semaphores get chosen last for time priority

#

doing the whole process first thing every frame would be looong

#

one of the other different things is semaphores are an interactible, not a track so i need to simply change that in the track placing process

#

as for how semaphores will get treated im just going to make it another interaction index and while that number is on the board it acts as a gate, but if a car passes by it to remove it it turns into a deactivated version of a semaphore with a different interaction index

#

i COULD simply remove them but the problem with that is tracks with semaphores on them arent allowed to become 3-ways

#

so just making it a "deactivated" index indicates there is a semaphore on there so i can make sure cars arent able to place 3-ways on them

fervent tusk
#

i think pycharm crashed on my pc

#

that is very not good

#

according to my brother it ran out of memory which is a huge problem

#

im gonna run all the other levels and then try 8-6a again

fervent tusk
#

i love that theres another one with 5+ extras (6 on 8-8a)

#

an intruiging thing about the 8-8a solution is that it doesnt require the tunnels which probably counts for luke's broken level critera but i dont think it matters as theyre working on the new game right now

#

im gonna re-check 8-6a to make absolute sure its entered right and then try generating it again

#

yeah no its entered fine the tracks and board size are just horrendous

#

im gonna try making the solver place turn tracks before straight tracks

#

so it doesnt take forever

#

hopefully it doesnt crash and finishes by tomorrow..

fervent tusk
#

it has been 11 hours and still no solution

#

im gonna look at the solution and think of what the most optimal track selection order is then put that in and try once more

#

ok, put the solution into a way the board can read it

#

going to make another program or just use my brain to figure out the optimal track order for each direction

#

on a side note i tested it and yes it works so generation is the problem

fervent tusk
#

yeah nvm the way i had it originally is still ideal

#

straight then either turn

#

too hard to think about what the best route would be

#

eventually i want to convert the whole solver into c++ but i want to do that at the very end when im done with everything

#

because c++ is waaaaay faster

#

but im not as knowledged in it and if i know the python one works fine and the c++ doesnt i know its an input problem and i dont have to debug it as much

#

oh! i know what i can do

#

heatmap limit

#

the max should be 3 for 8-6A because the switch track is right at the end

#

it can only pass through it 3 times at max to make the solution possible

#

i dont really know how to explain it but it just works

#

theres no reason why it would be over im pretty sure

#

4 technically

#

3 is the max, 4 is the limit

#

im gonna start generating it again with a heatmap limit of 4

#

actually it could be 5 or 6

#

meh

#

will try those if 4 works

#

oh actually i still have to figure out the whole heatmap thing

#

will run world 6 and look at some statistics

fervent tusk
#

the world 6 levels arent very insightful so i think im going to make some custom levels and analyze stuff

fervent tusk
#

yeah i have no idea

#

the custom levels cant be big because having heatmap limits be the goal factor isnt as good as tracks

#

tracks can restrict the generator, heatmap limit cant

fervent tusk
#

alright

#

8-6a still hasnt finished its been 2 days i think

#

my pc hasnt crashed yet though which is most of what i care about

#

as for semaphores, i need to do the following things to implement them:
make passing switch the interaction index โœ…
add extra numbers for the track generation to implement semaphores in the next generation based on number
make semaphores stall cars correctly โœ…
figure out how to detect passing โœ…
properly make the combinations for semaphores

fervent tusk
#

im gonna work on stalling and passing first

#

ill start with 9-1 but with the semaphore already placed

#

for passing the most important things is what tiles and what directions need to happen for a semaphore to flip

#

im gonna do what i said before and just make a massive list that indicates what tiles adjacent to the semaphore and what directions can happen for a flip

fervent tusk
#

actually

#

the position of the tile adjacent to the semaphore indicates what the passing direction are

#

because if a semaphore can be placed to the right of a tile that means it will ALWAYS be passing up/down

#

same with left

#

that makes this way easier

fervent tusk
#

this is with the semaphore pre-placed but the fact that it can handle processing them now is good

#

just gotta make it able to generate now is the 2nd half

#

what i can do is not add anything to the track combos and then just split the final track adding before the next generation into 2 parts where it adds a semaphore for every possible track or doesnt

#

that would work

#

however there can be more than 1 semaphore on some levels in which case it might want to place 2 on the same frame

#

oh ok ok

#

what i can do is for every track combination that wants to be used for the next generation

#

is then add ANOTHER semaphore combination onto that that determines which tracks can have semaphores for the next gen

#

i need multiple semaphore combinations for every track combination though

#

so just a little bit more effort

#

im gonna try and make semaphore stuff done absolutely last

#

idk how much of an issue itll be but we'll see

fervent tusk
#

i dont think theres any way i can use itertools to get an effective combination i want

#

because for the semaphore stuff lets assume i have 3 cars and 1 semaphore. a possible semaphore combo could be (False, False, True)
I could either: do False, True into itertools but that wont work because if i did any that allow duplicates to make that combination happen i'd also need to allow true to have duplicates. but since we only have 1 semaphore, it can't, which doesnt work with that method
or I could do False(1), False(2), True into itertools but that also wont work because then the combo could create duplicates like False(1) False(2) True and False(2) False(1) True

#

if i do it without itertools its gonna be way more time consuming and this is a process that needs to be done for every single iteration

fervent tusk
#

ok i think i know a workaround actually thatll work

#

i can start with a (False, False, False) empty list at the start each time and THEN do a permutation to add the true values

#

for example the Trues would be ([None], 0, 1, 2) here which i can make happen

#

or if i had 3 cars and 2 semaphores itd be (False, False, False,) and (None, (0), (1), (2), (0, 1), (0, 2), (1, 2))

#

the single and double semaphores in one move might be a problem though

#

theres no feasible solution for that other than just doing it multiple times with differing lengths

#

technically i could do (0, 0) and (1, 1) etc in place of it to make it 1

#

because they just overwrite each other

#

i think ill do that

fervent tusk
#

its been 4 or 5 days since i started generating 8-6a and it crashed on me just now

#

so i dont think its going to get solved

#

...yet

#

ill come back to it later

fervent tusk
#

tried making semaphore gen happen right as everything is getting passed on but i dont think itll work great

#

id have to use some more loops and make my own(ish) combination system

#

plus i need to change the cars position because all the stuff to move them has been done already and id have to change the cars twice before doing generation

#

so overall its a time waster so ill end up having to put semaphores inside of generation

fervent tusk
#

ok, i think the semaphore 3-way thing isnt going to be needed because the program inadvertently requires it to happen

#

if a car places a semaphore, a car HAS to pass in the tile in front of the semaphore to trigger it

#

and if that happens, one of the cars is going to end up making a semaphore because the cars cant go in the exact same direction when the semaphore is triggered

#

so 3-ways happen none-the-less

#

thus the only requirement i need is making it so if its already a tile with an interactible on it or if the tile ahead of the semaphore is permanent and not a 3-way because in that case its literally impossible for that semaphore to exist

#

also, just to simplify things i might just make 6 more tracks that are the exact same as base but new numbers indicating it also wants to place a semaphore

#

although if i do that i have to copy and paste all the 6 tracks' direction instructions which is wasteful at the same time

#

ohh i know what i can do
i can split the list in half because for every usable track there'll be a semaphore copy

#

actually no that still wont work because i need a special indicator for the track that says whether or not to place a semaphore (during generation)

#

so the 6 base tracks is actually my best bet

#

when i read the track number to place it i can just negate it by 20 or whatever to make it equal the correct track

#

so yeah 6 extras will actually work

#

the only problem with this whole thing is if i had 2 cars and 1 semaphore i need to prevent any combinations that let both cars place semaphores

#

i cant do that inside of the function so i either have to make my own or skip the ones that arent valid

#

additionally i have to make it so they barnch off and dont move including dealing with crashing etc

#

although i dont think crashing will be a problem at all because if a car is going to crash theres no point in placing a semaphore

#

its going to be even more of a problem with decoys though

#

im gonna make it so if a car is ever facing a semaphore without placing one then it kills that branch because its impossible for that semaphore to open and that car will get stalled indefinitely regardless

#

i dont think theres any point in decoys doing it either

#

actually no there is

#

it extends like the crash distance for decoys if that makes sense

#

so if a level had 3 decoys and 2 are facing a semaphore it extends the crash zone so the 3rd decoy might crash where it wouldnt have previously

#

ill deal with decoys in world 10

#

world 9 doesnt have any

fervent tusk
#

ok, i implemented some stuff so it should work now, but it wasnt working cause it triggered the heatmap limit

#

basically it added to heatmap, placed semaphore, ... , semaphore opened, added to heatmap again

#

normally it works for gates cause it stalls the car and then skips the heatmap, but then the gate is opened and it only adds 1 to heatmap

#

im not gonna create an additional thing to make different heatmap branches with 1 less on the semaphore ones

#

so instead i can just not add the 2nd heatmap val if its coming from an opened semaphore

#

only issue with that is theres no way to detect if its coming straight from an opened semaphore or if its just passing through an open semaphore

#

so instead actually when it changes the semaphore to open i think ill pre-emptively negate 1 from the heatmap counter so that way when it adds 1 on the 2nd time its a net 0 increase

#

will do that

#

it still doesnt really work properly but it can solve 9-1 without any assistance

#

i still need to:

  1. semaphores cant place more than they have โœ…
  2. semaphore placements must be legitimate (for permanent)
  3. deactivated semaphores can't be made into 3-ways
  4. semaphores can't be placed if a car has previously crossed, basically making the semaphore useless โœ…
#

but im glad it can solve a level

fervent tusk
#

(it also works on 9-2)

#

oh! i actually just realized it needs to be indicated where semaphores are

#

showing the interactions board probably isnt pretty so ill need some way to put it on there nicely

fervent tusk
#

i just realized i can maybe use coloring for when i print the final board so for aesthetics i might color stuff to look more like the map

#

included with that i can color code semaphores something specific

fervent tusk
#

cant color numpy arrays without graphing them literally so when i do that eventually ill incorporate it

#

so instead for now ill just have a thing beside it saying the coordinates and the tile number its on for convenience

#

oh and since I need to indicate those semaphore positions i also need a best_ints along with the best_board lol

#

i think thisll do for now

#

for now with extra semaphores i think ill just skip the combo if it has more-than-the-available semaphores but its a huge waste of resources

#

will see what i can do to improve it later

#

ok! there are no more semaphores appearing out of thin air in the progarm so its legitimate for now

#

so 1 requirement is finished

fervent tusk
#

i made some adjustments so now gates open properly and it looks like the semaphores are already coming together nicely

#

it can place them and solve levels up to 9-6

#

though it found an invalid solution on 9-2A so i have to fix that but

#

the fact that it can solve some of the boards now is exciting

#

also, on the best semaphore count thing i think im going to pass on it for now

#

because allowing the program to work with 1 extra track given the option not to makes it run a lot slower cause it can process more (for the most part usless) iterations

#

ill probably run the whole program and figure out the minimum tracks for each level then see after that if theres any better semaphore solution

#

oh the reason 9-2a found an invalid one is because i didnt make it so placing semaphores also checks if they are being previously activated and therefore useless

#

i can fix that i think

graceful raven
#

Do you have the code somewhere on GitHub?

fervent tusk
#

Nope

#

In all honesty idk how to use github i should probably learn

graceful raven
#

I was thinking about creating a solver myself, but Iโ€™ve just noticed that you had one almost ready. Iโ€™m curious how you approached solving the levels. Iโ€™d love to see the code if you make it public at some point.

fervent tusk
#

i think i posted a version of the old code a while back but its a completely different gen method

#

i can repost it

#

the new code

#

as for solving the levels i use recursive generation and just create every possible PLAYABLE board and then it tries them until it finds a solution

graceful raven
#

Are you planning on solving all the levels?

fervent tusk
#

and i have an extremely tight list of requirements for a generation to continue branching

#

yes

#

im at world 9 right now, if i get into the mood again of coding this next month probably then i should be able to finish it

graceful raven
#

Why are working on it? It seems like a lot of work?

fervent tusk
#

the only level i havent solved past world 8 is 8-6a because it took 4 days and my pc didnt generate it because pycharm crashed

#

im saving it for c++

fervent tusk
#

i like coding as a hobby

#

ive been working on this for like 8 months now i think

#

7?

#

7

graceful raven
#

Are you a professional programmer?

fervent tusk
#

Nope

#

im in high school

graceful raven
#

Good job then!

fervent tusk
#

i can go more in-depth about how the program works at a later time itd take like 30 mins

graceful raven
#

I wonder why the Afterburner folks havenโ€™t created a tool like this for themselves. It seems like it would save hours of time when designing new levels. Itโ€™s also not that hard when you have some experience with similar solvers.

fervent tusk
#

honestly i think itd seem insane if they made a solver

#

given it took me 7 months to get this far

#

well even if they have better experience

#

maybe 3 months...

#

i guess they know the inner workings of the game better too but thatd still be a month or 2

#
  • they have to maintain it when they add mechanics
graceful raven
#

And they could be working full time on it. I bet you donโ€™t spend 40h/week on your script.

fervent tusk
#

in all honesty i probably was at around 30h/week when i was making it

#

other people play video games with their free time but id usually work on this

fervent tusk
#

~25 actually but still

#

but yeah youre right

#

they have a team too

#

would you rather spend resources making a solver for a month or continue developing and fixing a new game

#

its not a necessity anyhow

#

would be cool tho.

graceful raven
#

I wonder how much time it took to design the levels manually when every new idea had to be tested whether it was solvable in the first place. They must have rejected many more levels than they put in the game.

fervent tusk
#

well, its a puzzle game

#

im sure they develop a cool solution or some wacky board and then start with that, and tinker the level until their solution is the only viable one

#

but yes many were probably rejected

graceful raven
#

Iโ€™ll ask them in the dev channel.

fervent tusk
#

ah wait

#

concerned about making a solver i think i asked luke once or he commented on it

#

or mirzka i cant remember

#

i can try and find the message but i think they said itd be too hard to maintain for the main point

#

thats a suited question nvm

graceful raven
#

I donโ€™t think it would be that hard to adjust the solver to new mechanics. You can probably vouch for it since you added them one by one.

fervent tusk
#

Haha ohhhhh nonono

#

the mechanics are what makes this solver so hard

#

i got the main game movement and track placement in a month or less

#

i had to remake the solver once for world 5

#

and twice more for world 6

graceful raven
#

How do you represent a level in Python?

fervent tusk
#

let me get my laptop

#

i can go on for 30 minutes about how this works

#

concerning levels, i have multiple arrays of numbers for the data of things in levels

#

i use numpy arrays btw

#

as for boards, i have a number indicating each track type

#

then the program does what it will with that number (track)

graceful raven
#

So you map sth like 1 to a straight track, 2 to a curved one, etc.?

fervent tusk
#

heres an example of 6-9d in the program

#

these are the cars (they get converted to numpy arrays during gen i think)

#

and then i also have an interactibles board for things like tunnels and switching tracks

graceful raven
#

Did you write unit tests to check whether the solver was still working after a new iteration?

fervent tusk
#

cause itd be dumb to have to make like 15 copies of each track for different gates

#

what is a unit test?

#

and then these are the interactible indices and board indices respectively

#

concerning the numbers for the board theyre on the right side i can talk about the rest of the numbers later

graceful raven
# fervent tusk what is a unit test?

A piece of code that runs some part of your code and then makes some assertions, e.g. tries to solve level 5-5 and asserts that a given solution is found.

fervent tusk
#

yup

graceful raven
#

I could help you out with GitHub if you ever want to put your code there. Itโ€™s pretty straightforward.

fervent tusk
#

ill do that once im done with the project, thanks ๐Ÿ˜

#

i can post what i have here if youd like

graceful raven
#

Iโ€™ll follow this thread and wait for the final version.

fervent tusk
#

tysm

graceful raven
#

Are you planning on describing your work on a blog or somewhere? Iโ€™d read it.

fervent tusk
#

yes!

#

once im done with the whole project i want to make a youtube video on it

#

i started a script for world 1 a while back

#

i can explain it if you want, itll take a bit

graceful raven
#

I think I get the idea already.

fervent tusk
#

ok!

#

thanks for showing interest

graceful raven
#

Good luck with finishing the project! Iโ€™ll be waiting for your updates.

graceful raven
fervent tusk
#

world 1 and 2 only

graceful raven
#

Do you have a YouTube channel?

fervent tusk
#

not really

#

i used to make roblox videos a long while back and i havent really made anything new

fervent tusk
#

anyways.
now back to semaphores, i still have to add the thing where it checks if placing a semaphore isnt useless/invalid

#

the only ways a semaphore can be invalid when placed is: a car has traveled adjacent to the semaphore, triggering it

#

since i have the list indicating the 2 triggering sides i just need to use that to check if there's any heatmap values on those sides

#

theres one problem however.

#

for some reason semaphores arent opened if they're right behind a starting car

fervent tusk
#

i think im thinking too far ahead and its messing me up im just gonna add in the limitation so i can work with this better

fervent tusk
#

for finding if the cars have passed the semaphore at all i just need to negate the total car visits there by 1 because the car placing the semaphore is technically adjacent to it and has a value of 1

fervent tusk
#

sigh

#

i have all the stuff to check adjacent tiles but for the semaphore to actually trigger properly i need to change stalling

#

because if a car places a semaphore, the frame it places the semaphore it isnt yet stalled

#

however, the next frame it isnt marked as stalled until after all the movement is done

#

the first frame the semaphore and 3-way is placed (NOT THE VERTICAL TRACK, its there so the semaphore can be placed)

#

car 2 is not technically stalled

#

the next frame, car 1 is facing downwards on top of the 3-way

#

semaphores are checked to be deactivated before the stalled stuff is added

#

so since on frame 2, when it checks for if adjacent semaphores should be activated, it doesnt do it because car 2 isnt technically stalled yet

#

yeah ok

#

im just gonna make it so cars get stalled immediately after placing a semaphore

#

that should be good?

#

idk if there could be any instances where multiple cars swap their stalled state like [False, True] to [True, False] that throw the program off

#

i know i fixed that for gates but ill do it for semaphores and hope for the best

#

will see in later worlds

#

YES!

#

instead of changing the stalled after generation and having to deal with different car position branches i just made it so there needs to be a semaphore in front of the car

#

cause if there's a semaphore its stalled anyways

#

sweet

#

now the levels up to 9-6 are solved

#

nvm 9-6 also works i just forgot to make the tunnels face the right way in the level.. gp_tongue

#

its still generating 9-11 (which makes sense because its a larger level) and some levels didnt work properly

#

i dont think you can place a semaphore on a 3-way

#

also that track count is misrepresented

#

so it's placing invalid semaphores on 3-ways is the only issue i can think of now

fervent tusk
#

it found a legitimate 9-10B solution with 2 extra tracks which is pretty cool

#

im gonna fix the semaphores and then it should be good

#

i can make it so semaphores cant place on permanent tiles with interactibles very easily

#

the 3-way thing is only slightly more challenging because a car can place a semaphore on the same frame another car makes that tile the semaphore will be placed on into a 3way

#

but i can just check it after generation is done once the semaphore actually gets placed during the final generation branching

#

wait no im stupid

#

that cant happen because 3-ways can only be placed on already placed tracks

#

cant be done on the same frame as another track getting placed cause its not technically there

#

oh i also have to add a new interaction index indicating where the starting tiles of cars are

#

because semaphores cant be placed on tiles with interaction indices on them

#

so thats just a more convenient way of not allowing them to be placed there

#

nvm that isnt needed because those tiles will always have a heatmap value of 1+ from the cars being on them, and semaphores cant be placed on tiles with any heat

#

all the levels up to 9-8 work now, 9-8 is now not finding a solution for some reason

fervent tusk
#

the problem comes from not being able to place the semaphore... the program cant complete the level even if all the tracks are placed in the right order, but if you force it to place there then it works

#

i think i see now

#

a car can get onto a switch tile as seen here, and then choose to place a semaphore

#

again, the semaphore doesnt stall instantly so it triggers the switch a 2nd time when it places the semaphore

#

ill make it so it instantly stalls now

#

2 cases of it being needed is enough

#

just gotta add 2 lines

fervent tusk
#

9-8A also doesnt work unless you specify the semaphore is there during level setup

#

the cars refuse to place it

#

..oh

#

๐Ÿ˜ฌ

#

its behind another car

#

so i finally have to deal with the thing i mentioned earlier i forgot about

#

it cant place the semaphore because that track under the 3rd car has a heatmap of 1 from being there on the first game movement

#

but the game is goofy and doesnt register semaphore closings on the first game movement

#

one thing i could technically do is just make it so when generation recursively calls itself it has an extra false variable but when i start the entire generation from the first function its true

#

and then read that variable to check whether or not semaphores can do anything the first frame

#

the only weird thing would be if someone were to make a custom level with a car starting on a 3-way in which case it should maybe trigger it because it could approach from the side but the vanilla game doesnt do that so i cant tes it

fervent tusk
#

in the game semaphores exist on the first frame, in my program they're placed during generation

#

adding the 27th index to excuse a tile's heat or just excusing a tile's heat at all isnt the way to go

#

because a 2nd car could come down and still trigger it

#

i can just check if the heat is above 1 nvm

#

yeah that should work

fervent tusk
#

i made it only check the opposing side for the behind-the-car semaphore because if a car, on the first frame, placing a semaphore behind another car then both sides would be starting cars

#

the problem with that is if theres a starting car track i want to negate 1 because it technically shouldnt count

#

...but if the car that wants to place the semaphore IS a starting car, it still has a value of 1

#

and i negate another 1 for the car itself because it also gets checked

#

i cant allow for a total value check for semaphores to be -1 OR 0 because theres a possibility all that happens, it gets -1 partially, and then some other car visited a tile twice and it magically turns into a 0 which is still valid when it shouldnt be

#

for a semaphore to be placed, the total surrounding heatmap value (the total heatmap vals of every direction on both tiles adjacent to the semaphore) needs to be 1, and then negate by 1 to make 0 as the car placing the semaphore will always give a heatmap value of 1 for existing adjacent to the semaphore when placing it

#

if theres a first-frame car tile, then it needs to be excused and negate another 1 from the counter because the surrounding heatmap should then be 2

#

if the placing car is on its first frame, it will still have a heatmap value of 1 and negating by 2 makes that -1

#

to make things simpler i could technically change the index to like a "semaphore can be placed here because its behind a car" thing and then put it on those tiles behind cars

#

but thatd be incredibly inconvenient to make, first of all, and if people wanted to make custom levels itd be even more challenging

#

actually i could automate it when the program starts and just add it in during the program instead of setup ๐Ÿค”

#

if thats the case though then the semaphore needs to be able to place on 27 indices in addition to 0

#

if 2 cars are facing with their backs to each other with a 1 car gap like on world 8 then thats pointless because id need to indicate to negate 2 heatmap values since theres 2 starting tracks there

fervent tusk
#

no ive got it

#

ok

#

instead of adding the values to the interactions board im gonna have them in a separate list i can just look at

#

itll just have the original starting position of every car

#

if the car placing the semaphore is on its original starting position, it doesnt negate 1

#

otherwise it does

#

and then i can negate all the other starting tiles around the semaphore

fervent tusk
#

yes i think this should work

#

yup it managed to place the semaphore with the given solution

#

just have to automate the starting indices being added

fervent tusk
#

yesssss

#

it solved 9-8a on its own

#

couldve taken less time had i closed some stuff but meh

#

i hope everything else works

#

the only thing im worried about is im pretty sure the massive amounts of variables i added to calculate if placing a semaphore is valid is taking wayyy more time

#

ill probably try to simplify stuff later

#

its slower somehow

#

the speed is faster because i closed some stuff but the iterations is higher

#

๐Ÿฅฒ

#

its not too bad for now i guess

#

back to seeing if world 9 works...

#

aaaand it placed on a switch for 9-10

#

forgot to put parentheses around an or statement ๐Ÿคฆ

fervent tusk
#

9-11 has an extra track :)

#

9-11 took a while as is 9-11A and probably B, so im going to run it on my faster pc and start working on world 10

#

i now have usable semaphores, but applying any mechanic to decoys is bounds harder

#

alright!

#

theres 7 non-decoy levels in world 10 and 6 with decoys

#

so i think the first 7 should be fine and then ill have to deal with the last 6

#

10-1a is also massive so ill leave that for my pc later

fervent tusk
#

9-11a worked, 9-11b failed because i forgot to put the tunnels in ๐Ÿ˜…

fervent tusk
#

well thats a first

#

tunnels are in and im confident the board is shown exactly correct

#

dont think thats supposed to happen

fervent tusk
#

sigh

#

since i added semaphores cars can create multiple branches

#

...i forgot to account for it in crashing

#

oh how i hate the option to be able to have multiple futures

#

why cant cars have a decided fate...

#

semaphores still dont technically stall cars instantly i think was the problem actually

#

yup think that fixed it

#

1 track saved

#

world 9 is now solved gp_smile

#

im gonna count it for now as this far because 8-6a is a special exception... it takes too long

#

Railbound Solver [Python Script] World 10/12

fervent tusk
#

only 4 tracks saved which is pretty impressive imo considering semaphores can be placed anywhere you want

#

longest level only took 15 minutes which is pretty tame compared to some other stuff ๐Ÿ˜„

fervent tusk
#

trying to add 10-5 in and theres one problem now

#

the thing about decoys looping is they dont kill themselves from the heatmap

#

they cant

#

usually that works because cars will inevitably finish and decoys wont loop forever

#

but if a car stalls on a gate or sempahore then it never ends because the car cant increase heatmap (doing that while stalled is stupid) and the decoy will never end the program cuz its looped

#

i never had this problem cause there wasnt a level where the car gets stuck on a gate and has a looping decoy

fervent tusk
#

i think what ill do is if all the cars are stalled then it starts a check to see if all the decoys are also looping or invalid

#

that way is the shortest path i think

#

adding a limit to how long a car can stay stalled for isnt great because shorter vs longer loops will take that much longer

#

same for a higher decoy limit

fervent tusk
#

i can:

  • make the decoys have a heatmap limit but make it much higher than cars (10+)
  • have a list that records whether or not decoys are looping
  • give decoys a heatmap limit after all cars are stalled
  • give decoys the looping list after all cars are stalled
fervent tusk
#

the problem with the first one is that it wastes an incredible amount of resources running the loops over and over and over until it reaches the limit so thats probably not happening

#

the 2nd one is kinda hard to tell during the program because of switching tracks from buttons

#

the 3rd and 4th ones are kinda the same now that i think about it

#

but i feel like the best concept would be waiting for all the cars to stall and then testing the remaining decoys to see if they get back to the same position (loop)

#

the only problem is that still wastes resources waiting for the cars to finish looping..

#

im not sure what the best way to do this is without wasting resources

#

it needs to guarantee the decoy is looping as soon as the car is stalled but thats hard to figure out

#

cant try to figure it out before because cars are still in motion but if you do it after youre progressively wasting resources

#

i could do it beforehand easily by just checking if decoys have heatmaps above 1 but switching tracks makes that useless

#

i think the best bet i have right now is waiting for cars to stall and then waiting for decoys to make a full loop back to the position they were at when the car stalled

#

ACTUALLY

#

bringing all this up gives me an idea to make the program even faster overall

#

usually the heatmap for levels is 1 because if a car has a heatmap of 2 (it is in the same exact position twice) that means its going to proceed along the same course as before and loop

#

but if there are switching tracks that allow the car to be in the same exact position but not proceed along the same course then i set it to 10

#

which goes well because i am confident there is NO level in the game that would need a heatmap above 10

#

the highest i think ive ever seen is 7

#

this is also bad though because in the case of looping, a car has to loop 10 times on a level with that even if it doesnt ride over a switching track

#

so i can probably implement some method to where the heatmap limit is kinda raised every time a car passes on a switching track

#

but the raising cap is then 10

#

i think when i made world 5 waaaay back in v4 that was one of the methods i did where when the heatmap was worse i made it so it kills the branch if a car goes over a swapping track over 5 times

#

the only problem then is i have to format the heatmap differently

#

because the limit wouldnt always be 1 on a level with switching tracks to kill a car

#

i have to account for whatever the car was on before

fervent tusk
#

actually no itll always be 1

#

if a car passes on a switch track how do i then determine which tracks are allowed to be above 1 though

#

for now ill just use the horrible solution i thought of initially of decoys having a larger heatmap

#

because it works for now and i can ponder on this later

#

albeit slow...

#

it works!

#

2 saved tracks is always a pleasant sight

#

so thats one semaphore decoy level down and 5 to go

#

theres still a lot more to be done, i know i have to make it so they cant just place semaphores without 3-ways because decoys would be able to do that and still get a solution opposed to cars

#

as well as allow decoys to stall together on a semaphore but that might already be done with how the code is for decoys

#

ill bet theres more gate stuff that isnt coded for decoys though

fervent tusk
#

maybe not

#

i ran the solver for all the world 10 levels except 10-5A, 10-1A, and 10-2B (because those are really long) and they all worked gp_cool

#

im gonna run those all through my computer which can do it faster and then make some custom levels to add in the decoy gate stuff

fervent tusk
#

actually i cant think of a board that would have a solution with decoys both on a semaphore

#

the entire solution would have to be based upon it

#

the biggest problem is decoys... dont really need to do that

#

they can just crash themselves

#
  • if a decoy was going to place a semaphore, it would need to be on newly placed track which removes the necessity for needing a semaphore because to even have a point to having 2 decoys stuck on a semaphore a decoy needs to cause a bad solution (ex. beating a car to the train) without a semaphore, where that semaphore would stall it
#

it just

#

i cant think of a board that could possibly accomodate that and it seems extremely unlikely and not useful

#

i will code whatever gives me an error

#

im gonna try and implement the new heatmap system with swapping tracks and figure it out before i move onto world 11

#

the main problem with it is figuring out which tracks to excuse

#

i know that 3-ways are the entry and exit points of loops though

fervent tusk
#

shrug

#

im going to implement the heatmap after all cars are stalled i guess

#

not ideal but it works better than what i have now

fervent tusk
#

actually even that takes some effort

#

womp womp

#

i feel like implementing world 11's mechanic more right now

#

it should be extremely easy... i just have to make any decoy-to-car interactions also valid for the numeral cars as i will call them

#

luckily with how i set up decoys and cars way back in world 7 i can just make it so numeral cars are type 2

#

cars are type 0, decoys type 1, and numeral cars type 2

#

other than that i need to add a numeral train tile which will be 21

#

but that should be it

#

the most frustrating part is adding every level ๐Ÿฅฒ

#

worlds 11 and 12 are massive

fervent tusk
#

actually the one problem i just realized is numeral cars can have their train on both the left and right

#

...im going to have 2 different tile types for the trains just to make it simpler

fervent tusk
#

finished adding in world 11, world 12 should take another hour

#

inputting numbers over and over and over is an experience...

fervent tusk
#

finally finished adding world 12 ib_sleep

#

12_8b has to be the biggest level ive ever seen

#

12_10 is also extremely massive and it has sooo many different mechanics its insane

#

it literally has every single mechanic from every single world

fervent tusk
#

ok, i have to add probably the last variable that retains through recursion which will be solved_ncars, pairing with solved

#

actually i can put the numeral cars in solved too and just have 2 lists

#

scrap that

#

adding all the stuff for cars to numeral cars is gonna be a huge pain

#

im gonna have to make a lot of new if statements because of the car number calculations ib_angry

fervent tusk
#

nvm it wasnt too difficult

#

just 1 if statement added

#

otherwise a lot of number offsetting

fervent tusk
#

ok, i think i have half of it set up but one thing is eluding me now

#

when a car reaches the end i remove some of its data then and there before it does the generation branching because its pointless to have it accounted in all of that

#

normally i can do it easily because the solved car should always be the first one in the list (cause the order is 1, 2, 3) but with numeral cars thats not always the case so i have to waste resources finding the first numeral car

#

...unless i think of another way

#

i think i can have a list of all the cars that get solved in a frame and then iterate over them to remove it

#

that way ill have the data for which cars to remove no matter what

fervent tusk
#

it can solve the pure basics at least

#

past 11-2 it failed

#

...think i forgot to make them test for collisions

#

actually no it should still test for them

#

hm

fervent tusk
#

10-1a has been running for about 12 hours now

#

it found a solution at 3 hours in but hasnt finished yet

#

i pray it isnt another 8-6a incident...

#

ok, the problem for 11-2a is the numeral car placed a 3-way that messes up with car travel timelines (it placed a 3-way that interferes with another car's path)

#

so its probably just one of the things in the code i didnt account for multiple car types

#

the normal cars didnt add to their heatmap

#

thats why

#

i made the car_index for numeral cars apply to normal cars too

#

...i also made it so they can arrive at either train

#

should hopefully be the last fix ๐Ÿคž

#

i also need to make it so if a car goes to the incorrect train it counts as a failure

fervent tusk
#

ok, 11-2a made me realize quite possibly the stupidest thing ive ever seen from this program

#

...i forgot to make the game correctly process placing 3-ways

#

sigh

#

im not sure how major of a fix thisll be but ill rerun some levels for good measure

#

2 things:

#

for 1, i made checking for if "placing" a 3-way affects another path always check even if a car is riding over the 3-way NOT for the first time (remember that cars running over tracks technically place them again)
for 2, i guess i didnt format the code correctly to properly find 3-way collisions

#

this is basically what the program is doing

#

the order of generation is normal car -> numeral car

#

so when the normal car places the 3-way it checks for if any cars going that way will have their paths messed up by referring to the heatmap

#

since the numeral car hasn't taken its turn yet (and heatmaps are added at the beginning of a turn), the tile the numeral car is on doesnt have any heatmap value to it, making the 3-way placement valid

#

the normal car now has a generated path where it is on the numeral car.

#

the numeral car then takes its turn, adding the heatmap, and then checks for same-tile collisions

#

it doesnt capture anything because when same-tile collisions are checked it looks to see if the position AHEAD of the car is colliding with anything generated

#

since the position ahead of the numeral car isnt colliding with the generated car, it continues with the program

#

im just going to make it so same-tile collisions also check for if any generated cars are on top of the car...

fervent tusk
#

actually no that doesnt solve it

#

in fact that breaks the program

#

so i just need to make heatmaps get added all at the same time

#

...it shouldnt affect the program i hope

#

with that i finally got it to work

#

im not sure if what i did makes the program slightly faster or slower but it can properly solve now

#

gonna test some of the previous worlds to make sure nothing is awry

#

i find it strange that i completely forget how parts of my code work way back from worlds 5 and below when i come back to them

fervent tusk
#

alright, pretty sure the heatmap change has been resolved for the whole program now(?)

#

all the worlds i tested worked

#

back to 11...

#

aaaand 11-2b infinitely loops

#

it solves it but then keeps running it after its solved gp_lol

#

ah

#

when it checks for solved cars the solved list is 2x2 (2 cars and 2 numeral cars) where there could be 2 cars and 1 numeral car so it will nnever think its solved because the "2nd numeral car" never solved but it doesnt exist

#

so i just need to make the list a unique shape

fervent tusk
#

i love finding extra track solutions

#

didnt properly do stations for numeral cars but i think thats the last thing

#

world 11 should be finished

fervent tusk
#

forgot that i made the interaction index 27 a car starting tile for semaphores ๐Ÿคฆ

#

made the nmeral car stations overlap with that and take indices 27-30

#

going to change it to 28-31 then world 11 should be done

fervent tusk
#

11-9a 3 saved gp_smile