@@ -18,23 +18,26 @@ case class Impossible() extends SolverStepResult derives ReadWriter
1818case class LabelInput (roomFromLabel : Int , doorIdx : Int , roomToLabel : Int ) derives ReadWriter
1919case class StepInput (roomFromUid : Int , doorIdx : Int , roomToLabel : Int ) derives ReadWriter
2020
21+ case class Offsets (roomOffset : Int , doorOffset : Int ) derives ReadWriter
22+
2123object DynamicSolver {
22- def processStep (g : MyGraph , input : StepInput , targetRoomOffset : Int = 0 , targetDoorOffset : Int = 0 ) : SolverStepResult =
23- println(s " Try: from room # ${input.roomFromUid}, via door # ${input.doorIdx}, to room labeled ${input.roomToLabel}, room offset = $targetRoomOffset , door offset = $targetDoorOffset " )
24- if (targetRoomOffset > g.rooms.length - 1 ) {
24+ def processStep (g : MyGraph , input : StepInput , offset : Offsets ) : SolverStepResult =
25+ println(s " Try: from room # ${input.roomFromUid}, via door # ${input.doorIdx}, to room labeled ${input.roomToLabel}, room offset = ${offset.roomOffset} , door offset = ${offset.doorOffset} " )
26+ if (offset.roomOffset > g.rooms.length - 1 ) {
2527 TargetRoomsExhausted ()
26- } else if (targetDoorOffset > 5 ) {
28+ } else if (offset.doorOffset > 5 ) {
2729 TargetDoorsExhausted ()
2830 } else {
2931 val existingLinkedRoom = g.adjacentRoom(g.doors(input.roomFromUid)(input.doorIdx))
3032 existingLinkedRoom match {
3133 case None => {
32- val existingCandidateRooms = g.findRoomsByLabel(input.roomToLabel)
34+ val existingCandidateRoomsWithDoors = g.findRoomsByLabelWithFreeDoors(input.roomToLabel)
35+ val existingCandidateRooms = existingCandidateRoomsWithDoors.keys.toSeq.sortBy(_.uid)
3336 println(s " Rooms already labeled ${input.roomToLabel}: $existingCandidateRooms" )
34- if (existingCandidateRooms.length > targetRoomOffset ) {
35- val existingCandidateDoors = g.findFreeDoors (existingCandidateRooms(targetRoomOffset).uid )
36- if (existingCandidateDoors.length > targetDoorOffset ) {
37- val nextDoor = existingCandidateDoors(targetDoorOffset )
37+ if (existingCandidateRooms.length > offset.roomOffset ) {
38+ val existingCandidateDoors = existingCandidateRoomsWithDoors (existingCandidateRooms(offset.roomOffset) )
39+ if (existingCandidateDoors.length > offset.doorOffset ) {
40+ val nextDoor = existingCandidateDoors(offset.doorOffset )
3841 println(s " Connect room # ${input.roomFromUid} door ${input.doorIdx} to room ${nextDoor.roomUid}, door ${nextDoor.idx}" )
3942 StepApplied (
4043 g.connectRooms(input.roomFromUid, input.doorIdx, nextDoor.roomUid, nextDoor.idx),
@@ -45,7 +48,7 @@ object DynamicSolver {
4548 }
4649 } else {
4750 val freeRooms = g.findUnlabeledRooms
48- val freeRoomOffset = targetRoomOffset - existingCandidateRooms.length
51+ val freeRoomOffset = offset.roomOffset - existingCandidateRooms.length
4952 if (freeRooms.length > freeRoomOffset) {
5053 val freeRoom = freeRooms(freeRoomOffset)
5154 val labeledGraph = g.setRoomLabel(freeRoom.uid, Some (input.roomToLabel))
@@ -71,39 +74,40 @@ object DynamicSolver {
7174 }
7275 }
7376
74- def processStepEnumerating (graph : MyGraph , inputs : Seq [LabelInput ], currentRoomUid : Int = 0 , roomOffset : Int = 0 , doorOffset : Int = 0 ) : SolverStepResult =
77+ def processStepRecursiveEnumerate (graph : MyGraph , currentRoomUid : Int , inputs : Seq [LabelInput ], offsets : Seq [Offsets ] = Seq ()) : SolverStepResult =
78+ var iteration = 0
79+ var subRoomOffset = 0
80+ var subDoorOffset = 0
81+ while (iteration < 100 )
82+ val subOffsets = Offsets (subRoomOffset, subDoorOffset) +: offsets
83+ println(f " Step into, iteration $iteration; remaining length is ${inputs.tail.length}; offsets: $subOffsets" )
84+ val subResult = processStepRecursive(graph, inputs, currentRoomUid = currentRoomUid, offsets = subOffsets)
85+ println(s " Returning from recursive call: $subResult" )
86+ subResult match {
87+ case StepApplied (_,_) => return subResult
88+ case TargetRoomsExhausted () => return Contradiction ()
89+ case TargetDoorsExhausted () =>
90+ subRoomOffset += 1
91+ subDoorOffset = 0
92+ case Contradiction () =>
93+ subDoorOffset += 1
94+ }
95+ iteration += 1
96+ Impossible ()
97+
98+ def processStepRecursive (graph : MyGraph , inputs : Seq [LabelInput ], currentRoomUid : Int = 0 , offsets : Seq [Offsets ] = Seq (Offsets (0 ,0 ))) : SolverStepResult =
7599 if (inputs.length == 0 ) {
76100 println(" no inputs left" )
77101 StepApplied (graph, DoorVertex (currentRoomUid, 0 ))
78102 } else {
79103 val stepInput = StepInput (currentRoomUid, inputs.head.doorIdx, inputs.head.roomToLabel)
80- val stepResult = processStep(graph, stepInput, roomOffset, doorOffset)
104+ val stepResult = processStep(graph, stepInput, offsets.head)
105+ println(s " Returning from single step call: $stepResult" )
81106 stepResult match {
82107 case StepApplied (newGraph, door) =>
83- println(f " Step into; remaining length is ${inputs.tail.length}" )
84- val subResult = processStepEnumerating(newGraph, inputs.tail, currentRoomUid = door.roomUid)
85- println(s " Returning from recursive call: $subResult" )
86- subResult match {
87- case StepApplied (_,_) => return subResult
88- case _ =>
89- println(s " Do rollback; remaining length is ${inputs.length}" )
90- return processStepEnumerating(graph, inputs, currentRoomUid, roomOffset = roomOffset, doorOffset = doorOffset+ 1 )
91- }
92- case TargetDoorsExhausted () =>
93- println(" Doors exhausted" )
94- return processStepEnumerating(graph, inputs, 0 , roomOffset+ 1 , 0 )
95- case TargetRoomsExhausted () =>
96- println(" Rooms exhausted" )
97- return TargetRoomsExhausted ()
98- case Contradiction () =>
99- println(" Contradiction" )
100- // return processStepEnumerating(graph, inputs, currentRoomUid, roomOffset = roomOffset, doorOffset = doorOffset+1)
101- return Rollback ()
102- case Rollback () =>
103- println(" Rollback" )
104- return processStepEnumerating(graph, inputs, currentRoomUid, roomOffset = roomOffset, doorOffset = doorOffset+ 1 )
108+ processStepRecursiveEnumerate(newGraph, door.roomUid, inputs = inputs.tail, offsets= offsets)
109+ case _ => stepResult
105110 }
106- Impossible ()
107111 }
108112
109113 def makeInput (plan : Seq [Int ], roomLabels : Seq [Int ]) : Seq [LabelInput ] =
@@ -119,6 +123,6 @@ object DynamicSolver {
119123
120124 def processPlanAndRooms (graph : MyGraph , srcRoomUid : Int , plan : Seq [Int ], roomLabels : Seq [Int ]) : SolverStepResult =
121125 val inputs = makeInput(plan, roomLabels)
122- processStepEnumerating (graph, inputs, currentRoomUid = srcRoomUid)
126+ processStepRecursiveEnumerate (graph, currentRoomUid = srcRoomUid, inputs )
123127
124128}
0 commit comments