/// <summary> /// Handles the complete Movement for any Dijkstra level - is checked if "isDijkstra" is set to true. /// </summary> /// <param name="destination">The path for which the hop will be evaluated.</param> public void CheckDijkstra(PathScript destination) { // Check if it is a valid hop. DijkstraStatus status = dijkstraManager.IsValidHop(destination); currentStatus = status; if (isLogEnabled) { Debug.Log("DijkstraMovementManager: IsValidHop returned: Status Code: " + status); } switch (status) { case DijkstraStatus.ERROR_RECOVERY: if (isLogEnabled) { Debug.Log("DijkstraMovementManager: In error recovery mode."); } // Perform error recovery hop. movePlayerAlongPath(destination); ErrorRecoveryStatus erStatus = dijkstraManager.PerformErrorRecoveryHop(destination); if (erStatus == ErrorRecoveryStatus.ERROR_NOT_RECOVERED) { // TODO change score to scorebeer // Display -5 score points on screen and update the score. scoreTexts.DisplayScoreText(ScoreText.Minus5); scoreBeer.UpdateScore(-5); countErrorRecovery++; WriteToLogAppendScore("Error Recovery;\tDid not recover from Error, ErrorRecoveryStatus=" + erStatus); } else { WriteToLogAppendScore("Error Recovery;\tRecovered from Error, ErrorRecoveryStatus=" + erStatus); } break; case DijkstraStatus.UNDISCOVERED_PATHS: if (isLogEnabled) { Debug.Log("DijkstraMovementManager: You need to perform path disvocery on every path from this router first."); } // TODO Unterscheidung Tutorial oder in game. movePlayerAlongPath(destination); dijkstraManager.PerformWrongHop(destination); // TODO change score to scorebeer // Show -10 score points on screen and update the score. scoreTexts.DisplayScoreText(ScoreText.Minus10); scoreBeer.UpdateScore(-10); countUndiscoveredPaths++; WriteToLogAppendScore("Undiscovered Paths;\tPlayer did not perform the complete discovery, destination=" + destination); // Change players mouth to angry. playerController.SetMouth(2); break; case DijkstraStatus.WRONG_HOP: if (isLogEnabled) { Debug.Log("DijkstraMovementManager: The dijkstra algorithm prohibits this hop."); } // TODO Unterscheidung Tutorial oder in game. movePlayerAlongPath(destination); dijkstraManager.PerformWrongHop(destination); // TODO change score to scorebeer // Show -20 score points on screen and update the score. scoreTexts.DisplayScoreText(ScoreText.Minus20); scoreBeer.UpdateScore(-20); countWrongHop++; WriteToLogAppendScore("Wrong Hop;\tPlayer did perform a wrong hop. destination=" + destination); // Change players mouth to angry. playerController.SetMouth(2); break; case DijkstraStatus.HOP_UNREACHABLE: if (isLogEnabled) { Debug.Log("DijkstraMovementManager: It is an invalid hop."); } WriteToLogAppendScore("Wrong Hop;\tPlayer did perform a wrong hop. destination=" + destination); break; case DijkstraStatus.NOP: countNoOp++; WriteToLogAppendScore("No Operation;\tPlayer travels through completely handled destination=" + destination); // Start moving the player object. movePlayerAlongPath(destination); // Perform the hop in the dijkstra algorithm. dijkstraManager.PerformHop(destination); break; case DijkstraStatus.VALID_HOP: if (isLogEnabled) { Debug.Log("DijkstraMovementManager: Performing the hop to the other router."); } // Start moving the player object. movePlayerAlongPath(destination); // TODO change score to scorebeer // Display +10 points and update the score. scoreTexts.DisplayScoreText(ScoreText.Plus10); scoreBeer.UpdateScore(10); // Perform the hop in the dijkstra algorithm. dijkstraManager.PerformHop(destination); // Change players mouth to happy. playerController.SetMouth(0); WriteToLogAppendScore("Valid Hop;\tPlayer did perform a valid hop. destination=" + destination); break; case DijkstraStatus.VALID_HOP_DISCOVERY: if (isLogEnabled) { Debug.Log("DijkstraMovementManager: Performing the path discovery."); } // Start path discovery. performPathDiscoveryMove(destination); // TODO change score to scorebeer // Display +5 points and update the score. scoreTexts.DisplayScoreText(ScoreText.Plus5); scoreBeer.UpdateScore(5); // Change players mouth to normal. playerController.SetMouth(1); // Perform a path discovery step in the dijkstra algorithm. dijkstraManager.PerformPathDiscovery(destination); WriteToLogAppendScore("Valid Hop Discovery;\tPlayer did perform a valid hop. destination=" + destination); break; } }
protected override void CalculateDistancesFromAPlayer(GameState gameState, PlayerType player, HashSet <CellState> reachableCells) { int nextDistance = 0; int numberOfCellsReachable = 0; int totalDegreesOfCellsReachable = 0; HashSet <CellState> cellsToExpand = new HashSet <CellState>(); DijkstraStatus dijkstraStatus = DijkstraStatus.NotCalculated; bool isPartiallyCalculated = false; int upToDateDijkstraDistance = 0; CellState playersCell; CompartmentStatus compartmentStatus; GetDistanceDelegate getDistance = null; SetDistanceDelegate setDistance = null; switch (player) { case PlayerType.You: compartmentStatus = CompartmentStatus.InYourCompartment; getDistance = GetDistanceFromYou; setDistance = SetDistanceFromYou; dijkstraStatus = gameState.YourDijkstraStatus; upToDateDijkstraDistance = gameState.YourUpToDateDijkstraDistance; playersCell = gameState.YourCell; break; case PlayerType.Opponent: compartmentStatus = CompartmentStatus.InOpponentsCompartment; getDistance = GetDistanceFromOpponent; setDistance = SetDistanceFromOpponent; dijkstraStatus = gameState.OpponentsDijkstraStatus; upToDateDijkstraDistance = gameState.OpponentsUpToDateDijkstraDistance; playersCell = gameState.OpponentsCell; break; default: throw new ApplicationException("The player must be specified when calculating distances"); } if (dijkstraStatus != DijkstraStatus.FullyCalculated) { if (player == PlayerType.You) { gameState.OpponentIsInSameCompartment = false; } isPartiallyCalculated = (dijkstraStatus == DijkstraStatus.PartiallyCalculated && upToDateDijkstraDistance > 0); if (isPartiallyCalculated) { nextDistance = upToDateDijkstraDistance; foreach (CellState cellState in gameState.GetAllCellStates()) { int distance = getDistance(cellState); if ((cellState.OccupationStatus == OccupationStatus.Clear) && (cellState.CompartmentStatus == compartmentStatus || cellState.CompartmentStatus == CompartmentStatus.InSharedCompartment) && (distance <= upToDateDijkstraDistance)) { if (reachableCells != null) { reachableCells.Add(cellState); } numberOfCellsReachable++; totalDegreesOfCellsReachable += cellState.DegreeOfVertex; if (distance == upToDateDijkstraDistance) { cellsToExpand.Add(cellState); } } else { cellState.ClearDijkstraStateForPlayer(player); } } } else { gameState.ClearDijkstraPropertiesForPlayer(player); cellsToExpand.Add(playersCell); } while (cellsToExpand.Any()) { nextDistance++; HashSet <CellState> nextLevelOfCells = new HashSet <CellState>(); foreach (CellState sourceCell in cellsToExpand) { CellState[] adjacentCells = sourceCell.GetAdjacentCellStates(); foreach (CellState adjacentCell in adjacentCells) { switch (adjacentCell.OccupationStatus) { case OccupationStatus.Opponent: if (player == PlayerType.You) { gameState.OpponentIsInSameCompartment = true; } break; case OccupationStatus.Clear: adjacentCell.CompartmentStatus |= compartmentStatus; int existingDistance = getDistance(adjacentCell); if (nextDistance < existingDistance) { setDistance(adjacentCell, nextDistance); // HashSets automatically filter out duplicates, so no need to check: nextLevelOfCells.Add(adjacentCell); if (reachableCells != null) { reachableCells.Add(adjacentCell); } } break; } } numberOfCellsReachable++; totalDegreesOfCellsReachable += sourceCell.DegreeOfVertex; } cellsToExpand = nextLevelOfCells; } switch (player) { case PlayerType.You: gameState.NumberOfCellsReachableByYou = numberOfCellsReachable; gameState.TotalDegreesOfCellsReachableByYou = totalDegreesOfCellsReachable; break; case PlayerType.Opponent: gameState.NumberOfCellsReachableByOpponent = numberOfCellsReachable; gameState.TotalDegreesOfCellsReachableByOpponent = totalDegreesOfCellsReachable; break; } switch (player) { case PlayerType.You: gameState.YourDijkstraStatus = DijkstraStatus.FullyCalculated; gameState.YourUpToDateDijkstraDistance = int.MaxValue; break; case PlayerType.Opponent: gameState.OpponentsDijkstraStatus = DijkstraStatus.FullyCalculated; gameState.OpponentsUpToDateDijkstraDistance = int.MaxValue; break; } } else { // Fix ClosestPlayer: foreach (CellState cellState in gameState.GetAllCellStates()) { if (cellState.ClosestPlayer == PlayerType.Unknown) { switch (cellState.CompartmentStatus) { case CompartmentStatus.InYourCompartment: cellState.ClosestPlayer = PlayerType.You; break; case CompartmentStatus.InOpponentsCompartment: cellState.ClosestPlayer = PlayerType.Opponent; break; case CompartmentStatus.InSharedCompartment: if (cellState.DistanceFromYou > cellState.DistanceFromOpponent) { cellState.ClosestPlayer = PlayerType.You; } else if (cellState.DistanceFromOpponent > cellState.DistanceFromYou) { cellState.ClosestPlayer = PlayerType.Opponent; } else { cellState.ClosestPlayer = gameState.PlayerToMoveNext; } break; } } } gameState.YourCell.ClosestPlayer = PlayerType.You; gameState.OpponentsCell.ClosestPlayer = PlayerType.Opponent; } }