public override int Evaluate(PuzzleState state, PuzzleState goalState) { int manhanttanDist = 0; var possibleRowConflicts = new Dictionary <int, List <Tuple <int, int> > >(); var possibleColConflicts = new Dictionary <int, List <Tuple <int, int> > >(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { int val = state.Board[i, j]; if (val == 0) { continue; } var correctPos = goalState.GetSpace(val); manhanttanDist += ManhattanDistanceHeuristic.ManhattanDistance(i, j, correctPos.Row, correctPos.Col); // check for linear conflicts in the horizontal + vertical direction if (i == correctPos.Row && j != correctPos.Col) { if (!possibleRowConflicts.ContainsKey(i)) { possibleRowConflicts[i] = new List <Tuple <int, int> >(); } possibleRowConflicts[i].Add(Tuple.Create(j, correctPos.Col)); } if (j == correctPos.Col && i != correctPos.Row) { if (!possibleColConflicts.ContainsKey(j)) { possibleColConflicts[j] = new List <Tuple <int, int> >(); } possibleColConflicts[j].Add(Tuple.Create(i, correctPos.Row)); } } } // Calculate the # of linear conflicts int linearConflicts = 0; foreach (List <Tuple <int, int> > possibleConflicts in possibleRowConflicts.Values.Concat(possibleColConflicts.Values)) { Tuple <int, int> conflict = possibleConflicts.First(); linearConflicts += possibleConflicts.Skip(1).Count(x => (x.Item1 > conflict.Item1 && x.Item2 < conflict.Item2) || (x.Item1 <conflict.Item1 && x.Item2> conflict.Item2)); } return(manhanttanDist + 2 * linearConflicts); }
public override int Evaluate(PuzzleState state, PuzzleState goal) { var manhattanDistanceOff = 0; var possibleRowConflicts = new Dictionary <byte, List <Tuple <byte, byte> > >(); var possibleColConflicts = new Dictionary <byte, List <Tuple <byte, byte> > >(); for (byte i = 0; i < 4; i++) { for (byte j = 0; j < 4; j++) { var val = state.Board[i, j]; if (val == 0) { continue; // skip the blank } var correctPlace = goal.GetSpace(val); manhattanDistanceOff += ManhattanDistanceHeuristic.ManhattanDistance(i, j, correctPlace.Row, correctPlace.Col); // now check for linear conflicts // in correct row and wrong column? if (i == correctPlace.Row && j != correctPlace.Col) { if (!possibleRowConflicts.ContainsKey(i)) { possibleRowConflicts[i] = new List <Tuple <byte, byte> >(); } possibleRowConflicts[i].Add(Tuple.Create(j, correctPlace.Col)); } // in correct col and wrong row? if (j == correctPlace.Col && i != correctPlace.Row) { if (!possibleColConflicts.ContainsKey(j)) { possibleColConflicts[j] = new List <Tuple <byte, byte> >(); } possibleColConflicts[j].Add(Tuple.Create(i, correctPlace.Row)); } } } var linearConflicts = 0; foreach (var possibleConflicts in possibleRowConflicts.Values.Concat(possibleColConflicts.Values)) { var conflict = possibleConflicts.First(); linearConflicts += possibleConflicts.Skip(1).Count(x => (x.Item1 > conflict.Item1 && x.Item2 < conflict.Item2) || (x.Item1 <conflict.Item1 && x.Item2> conflict.Item2)); } return(manhattanDistanceOff + 2 * linearConflicts); }