public void SensibleEnqueue(Jug3State candidate) { foreach (Jug3State state in _visited) { if (state.Equals(candidate)) { return; } } foreach (Jug3State state in _queue) { if (state.Equals(candidate)) { return; } } _queue.Enqueue(candidate); }
int?Generate() { Jug3State head = _queue.Dequeue(); _visited.Add(head); // for all states there are 2 actions // empty a Jug3State emptyA = StateClone(head); emptyA.JugA.Empty(); SensibleEnqueue(emptyA); // fill a Jug3State fillA = StateClone(head); fillA.JugA.Fill(); if (_target == fillA.JugA.Current) { return(fillA.Moves); } SensibleEnqueue(fillA); // if there are at least two jugs, there are 4 new actions if (_numberOfJugs >= 2) { // empty b Jug3State emptyB = StateClone(head); emptyB.JugB.Empty(); SensibleEnqueue(emptyB); // fill b Jug3State fillB = StateClone(head); fillB.JugB.Fill(); if (_target == fillB.JugA.Current) { return(fillB.Moves); } SensibleEnqueue(fillB); // transfer a->b Jug3State aToB = StateClone(head); aToB.JugA.TransferTo(aToB.JugB); if (_target == aToB.JugA.Current || _target == aToB.JugB.Current) { return(aToB.Moves); } SensibleEnqueue(aToB); // transfer b-> a Jug3State bToA = StateClone(head); bToA.JugB.TransferTo(bToA.JugA); if (_target == bToA.JugA.Current || _target == bToA.JugB.Current) { return(bToA.Moves); } SensibleEnqueue(bToA); } // inductively // if there are at least 3 jugs if (_numberOfJugs >= 3) { // empty c Jug3State emptyC = StateClone(head); emptyC.JugC.Empty(); SensibleEnqueue(emptyC); // fill C Jug3State fillC = StateClone(head); fillC.JugC.Fill(); if (_target == fillC.JugA.Current) { return(fillC.Moves); } SensibleEnqueue(fillC); // transfer a->c Jug3State aToC = StateClone(head); aToC.JugA.TransferTo(aToC.JugC); if (_target == aToC.JugA.Current || _target == aToC.JugC.Current) { return(aToC.Moves); } SensibleEnqueue(aToC); // transfer c-> a Jug3State cToA = StateClone(head); cToA.JugC.TransferTo(cToA.JugA); if (_target == cToA.JugA.Current || _target == cToA.JugC.Current) { return(cToA.Moves); } SensibleEnqueue(cToA); // transfer B->c Jug3State bToC = StateClone(head); bToC.JugB.TransferTo(bToC.JugC); if (_target == bToC.JugB.Current || _target == bToC.JugC.Current) { return(bToC.Moves); } SensibleEnqueue(bToC); // transfer c-> B Jug3State cToB = StateClone(head); cToB.JugC.TransferTo(cToB.JugB); if (_target == cToB.JugB.Current || _target == cToB.JugC.Current) { return(cToB.Moves); } SensibleEnqueue(cToB); } return(null); }
static Jug3State StateClone(Jug3State head) { return(new Jug3State(head.JugA.Clone(), head.JugB.Clone(), head.JugC.Clone(), head.Moves + 1)); }