protected bool IsTerminalWithoutMoves(ref MoveState state, Node node) { // Update current hash key for node. #if USE_INCREMENTAL_PATH_FINDER state.Find(ref current); #else pathFinder.Find(current.SokobanRow, current.SokobanColumn); #endif #if USE_INCREMENTAL_HASH_KEY Coordinate2D proxySokobanCoord = pathFinder.GetFirstAccessibleCoordinate(); current.HashKey ^= HashKey.GetSokobanHashKey(proxySokobanCoord.Row, proxySokobanCoord.Column); #else current.HashKey = GetSlowHashKey(); #endif #if DEBUG ValidateHashKey(node); #endif // Look up the current hash key in the transposition table. Node other; if (transpositionTable.TryGetValue(current.HashKey, out other)) { duplicates++; // Choose which node to pursue. if (Node.IsEmpty(other) || other.Pushes <= node.Pushes) { // The other node is deadlocked or as good as this one. return true; } // This node is better than the other one, which is not deadlocked. transpositionTable[current.HashKey] = node; node.InTable = true; other.InTable = false; if (other.Dormant) { nodes.Release(other); } else { other.Terminal = true; } #if DEBUG ValidateNotDeadlocked(); #endif return false; } if (deadlockFinder.IsDeadlocked(current.SokobanRow, current.SokobanColumn)) { transpositionTable.Add(current.HashKey, Node.Empty); return true; } transpositionTable.Add(current.HashKey, node); node.InTable = true; return false; }
protected bool IsTerminalWithMoves(ref MoveState state, Node node) { // Update current hash key for node. #if USE_INCREMENTAL_HASH_KEY current.HashKey ^= HashKey.GetSokobanHashKey(current.SokobanRow, current.SokobanColumn); #else current.HashKey = GetSlowHashKey(); #endif #if DEBUG ValidateHashKey(node); #endif // Look up the current hash key in the transposition table. Node other; if (transpositionTable.TryGetValue(current.HashKey, out other)) { duplicates++; // Choose which node to pursue. if (optimizePushes) { if (Node.IsEmpty(other) || other.Pushes < node.Pushes || other.Pushes == node.Pushes && other.Moves <= node.Moves) { // The other node is deadlocked or as good as than this one. return true; } } else { if (Node.IsEmpty(other) || other.Moves <= node.Moves) { // The other node is deadlocked or as good as than this one. return true; } } // This node is better than the other one, which is not deadlocked. transpositionTable[current.HashKey] = node; node.InTable = true; other.InTable = false; if (other.Dormant) { nodes.Release(other); } else { other.Terminal = true; } // This is no longer a duplicate and not deadlocked, so run the finder. #if USE_INCREMENTAL_PATH_FINDER state.Find(ref current); #else pathFinder.Find(current.SokobanRow, current.SokobanColumn); #endif #if DEBUG ValidateNotDeadlocked(); #endif return false; } if (deadlockFinder.IsDeadlocked(current.SokobanRow, current.SokobanColumn)) { transpositionTable.Add(current.HashKey, Node.Empty); return true; } // This is a brand new position, so record it. transpositionTable.Add(current.HashKey, node); node.InTable = true; // This is not a duplicate and not deadlocked, so run the finder. #if USE_INCREMENTAL_PATH_FINDER state.Find(ref current); #else pathFinder.Find(current.SokobanRow, current.SokobanColumn); #endif return false; }