Ik ben bezig met een oplosser te schrijven voor het spelletje Sokoban (http://en.wikipedia.org/wiki/Boxxle). Kort gezegd komt het erop neer dat je met een mannetje dozen door een doolhof moet schuiven totdat ze allemaal op een geldige lokatie staan. Alleen de dozen kunnen bewogen worden, en alle dozen zijn gelijk.
Een van de dingen die ik daarbij nodig heb is een datastructuur die subsets van doos-configuraties kan opslaan, en waarin ik vervolgens met een complete doos-configuratie als query efficient kan zoeken naar alle subsets die hieraan voldoen.
Minder abstract: stel dat een bepaald level 10 dozen bevat. Van dit level heb ik bepaald dat, als een subset van 4 dozen in een bepaalde configuratie CS staan (bijv. op de lokaties P0, P1, P2 en P3), dat het level dan al niet meer op te lossen valt. Nu zullen er meerdere van deze subset-configuraties CS0...CSn van dozen zijn waarvoor dit geldt (maar niet noodzakelijk met 4 dozen).
Nu wil ik deze subset-configuraties CS0...CSn op een intelligente manier opslaan in een datastructuur zodat ik, gegeven een complete configuratie C (in dit geval van 10 dozen), efficient alle* subset-configuraties CS kan vinden waarvan alle dozen in CS op dezelfde lokaties staan als in C. Nu heb ik mijn hoofd lopen breken over de opzet van zo'n datastructuur, maar ik kom er maar niet uit. Ik denk dat ik een variant van een hashmap of balanced binary tree wil gebruiken, maar de precieze details ontbreken nog.
(* - in principe zou het voldoende zijn om te bepalen of er minimaal 1 zo'n CS bestaat die op C van toepassing is).
Het probleem is dat als er in C een doos op lokatie P staat, dat CS niet per se ook een doos op lokatie P hoeft te hebben om een match op te kunnen leveren. De enige manier waarop een CS geen match oplevert, is wanneer het een doos op lokatie P heeft staan, en op diezelfde lokatie P in C geen doos staat.
Ik zat eraan te denken om alle posities in een level opeenvolgend te nummeren (een 'index' te geven), en elke CS op te slaan als de geordende reeks indexen van de dozen in CS. Binnen de datastructuur worden de CSen dan lexicografisch gesorteerd op hun indexen opgeslagen.
Het doorzoeken van de datastructuur met een query-configuratie C zou dan als volgt gaan. Neem de indexen I[0]...I[n] van alle dozen in C (I is oplopend gesorteerd)
Van x = 0 tot x = n
..ga op zoek naar alle matchende CSsen M = {CS0...CSn} die I[x] als hun eerste index hebben.
..Voor elke CS uit M:
....bepaal of de indexen van de dozen uit CS ook voorkomen in I[x]...I[n]. Zo ja, dan heb je een match.
Nu lijkt me dit wel een mogelijkheid, maar ik betwijfel of het erg efficient is. Heeft iemand misschien een beter idee?
Een van de dingen die ik daarbij nodig heb is een datastructuur die subsets van doos-configuraties kan opslaan, en waarin ik vervolgens met een complete doos-configuratie als query efficient kan zoeken naar alle subsets die hieraan voldoen.
Minder abstract: stel dat een bepaald level 10 dozen bevat. Van dit level heb ik bepaald dat, als een subset van 4 dozen in een bepaalde configuratie CS staan (bijv. op de lokaties P0, P1, P2 en P3), dat het level dan al niet meer op te lossen valt. Nu zullen er meerdere van deze subset-configuraties CS0...CSn van dozen zijn waarvoor dit geldt (maar niet noodzakelijk met 4 dozen).
Nu wil ik deze subset-configuraties CS0...CSn op een intelligente manier opslaan in een datastructuur zodat ik, gegeven een complete configuratie C (in dit geval van 10 dozen), efficient alle* subset-configuraties CS kan vinden waarvan alle dozen in CS op dezelfde lokaties staan als in C. Nu heb ik mijn hoofd lopen breken over de opzet van zo'n datastructuur, maar ik kom er maar niet uit. Ik denk dat ik een variant van een hashmap of balanced binary tree wil gebruiken, maar de precieze details ontbreken nog.
(* - in principe zou het voldoende zijn om te bepalen of er minimaal 1 zo'n CS bestaat die op C van toepassing is).
Het probleem is dat als er in C een doos op lokatie P staat, dat CS niet per se ook een doos op lokatie P hoeft te hebben om een match op te kunnen leveren. De enige manier waarop een CS geen match oplevert, is wanneer het een doos op lokatie P heeft staan, en op diezelfde lokatie P in C geen doos staat.
Ik zat eraan te denken om alle posities in een level opeenvolgend te nummeren (een 'index' te geven), en elke CS op te slaan als de geordende reeks indexen van de dozen in CS. Binnen de datastructuur worden de CSen dan lexicografisch gesorteerd op hun indexen opgeslagen.
Het doorzoeken van de datastructuur met een query-configuratie C zou dan als volgt gaan. Neem de indexen I[0]...I[n] van alle dozen in C (I is oplopend gesorteerd)
Van x = 0 tot x = n
..ga op zoek naar alle matchende CSsen M = {CS0...CSn} die I[x] als hun eerste index hebben.
..Voor elke CS uit M:
....bepaal of de indexen van de dozen uit CS ook voorkomen in I[x]...I[n]. Zo ja, dan heb je een match.
Nu lijkt me dit wel een mogelijkheid, maar ik betwijfel of het erg efficient is. Heeft iemand misschien een beter idee?