diff --git a/AdventureMap.cpp b/AdventureMap.cpp index 0742030..3ac076a 100644 --- a/AdventureMap.cpp +++ b/AdventureMap.cpp @@ -170,26 +170,6 @@ TArray AAdventureMap::FindPathAStar(AHexTile* Start, AHexTile* Goal, ToExamine.Add(Neighbor); } } } - /* - if (bDiags) { - for (AHexTile* Diag : FreeDiagonals(Candidate)) { - if (!Diag->bFree) { continue; } - if (Processed.Contains(Diag)) { continue; } - - bool bInToExamine = ToExamine.Contains(Diag); - float NewGCost = Candidate->GCost + Diag->MoveCost; - - if (NewGCost < Diag->GCost || !bInToExamine) { - Diag->GCost = NewGCost; - Diag->CameFrom = Candidate; // chain - Diag->bDiagMove = true; - - if (!bInToExamine) { - Diag->HCost = Diag->Distance(Goal); - ToExamine.Add(Diag); - } } - } - }*/ } TArray Path; if (!IsValid(Goal->CameFrom)) { return Path; } @@ -200,72 +180,61 @@ TArray AAdventureMap::FindPathAStar(AHexTile* Start, AHexTile* Goal, } Algo::Reverse(Path); - if (bDiags) { - Path = ShortcutAStar(Path); + if (bDiags) { + TArray PathS = ShortcutAStar(Path); } return Path; } - TArray AAdventureMap::ShortcutAStar(TArray Path) { TArray Shortcut; + int32 Len = Path.Num(); - AHexTile* Milestone = Path[0]; - int32 BeforeBend; - int32 AfterBend; - int32 HexIter = 1; - FHexVector pDir; + TArray WorkingSegment; + AHexTile* Start = PCRef->CurrentHex; + WorkingSegment.Add(Start); + int32 i = 0; + + FHexVector PrevDir = FHexVector(Path[0], Start); FHexVector DirA; - FHexVector DirB; - AHexTile* Current; - - while (Milestone != Path[Len - 1]) { - // find Milestone (i.e. end of first curve) & determine curve data - BeforeBend = 1; - for (HexIter; HexIter < Len; HexIter++) { - pDir = FHexVector(Path[HexIter], Path[HexIter - 1]); - DirA = FHexVector(Path[HexIter + 1], Path[HexIter]); - if (DirA == pDir) { BeforeBend++; } - else { break; } - } - AfterBend = 1; - for (HexIter; HexIter < Len; HexIter++) { - pDir = FHexVector(Path[HexIter], Path[HexIter - 1]); - DirB = FHexVector(Path[HexIter + 1], Path[HexIter]); - if (DirB == pDir) { AfterBend++; } - else { break; } - } - FHexVector Diag = UnitDiagFromUnitNB(DirA, DirB); // (exact diagonal) cardinal direction for shortcut - TArray WorkingSegment; - for (int32 i = Path.Find(Milestone); i < HexIter; i++) { WorkingSegment.Add(Path[i]); } - Milestone = WorkingSegment.Last(); - Current = WorkingSegment[0]; - bool bFirstDiagTaken = false; - TArray NewSegment; // ideally the entire shortcut (ends at bBlock, whence we continue by A*) - - // link from Current to Milestone - for (int32 i = 0; i < BeforeBend; i++) { - Current = WorkingSegment[i]; - AHexTile* NewCandidate = Grid[GridIndex(Current->Q + Diag.Q, Current->R + Diag.R)]; - if (!DiagIsReachable(Current, Diag) || !NewCandidate->bFree) { - if (bFirstDiagTaken) { break; } - NewSegment.Add(Current); - continue; - } - NewSegment.Add(NewCandidate); - bFirstDiagTaken = true; - } - - // Check how much remains until we reach milestone and - // Connect the rest recursively via A* (with shortcuts) - // Consider whether the resulting path really is shorter - - Shortcut.Append(NewSegment); + int32 HexesBeforeBend = 1; + for (i; i < Len-1; i++) { + WorkingSegment.Add(Path[i]); + DirA = FHexVector(Path[i+1], Path[i]); + if (DirA != PrevDir) { break; } + HexesBeforeBend++; + PrevDir = DirA; } + PrevDir = DirA; + FHexVector DirB; + int32 HexesAfterBend = 0; + for (i; i < Len - 1; i++) { + WorkingSegment.Add(Path[i+1]); + DirB = FHexVector(Path[i+1], Path[i]); + if (DirB != PrevDir) { break; } + HexesAfterBend++; + PrevDir = DirB; + } + if (HexesAfterBend == 0) { return Path; } + + // debug + UE_LOG(LogTemp, Warning, TEXT("Before bend: %d"), HexesBeforeBend); + UE_LOG(LogTemp, Warning, TEXT("After bend: %d"), HexesAfterBend); + UE_LOG(LogTemp, Warning, TEXT("Working segment length: %d"), WorkingSegment.Num()); + for (AHexTile* HexDebug : WorkingSegment) { UE_LOG(LogTemp, Warning, TEXT("HexID: %d"), HexDebug->Index); } + + + FHexVector UnitDiag = UnitDiagFromUnitNB(DirA, DirB); + AHexTile* Milestone = WorkingSegment.Last(); + + // Try adding diagonal Hexes to Shortcut from Start until Milestone (if BeforeBend>=AferBend: do this AfterBend times, else: BeforeBend) + // Set a bool to 'true' as soon as the first Hex is added; Set CurrentHex to that; + // if the path is blocked and the bool is 'false': Set CurrentHex to the next in WorkingSegment; Retry. + // if the path is blocked and the bool is 'true': Append the rest recursively calling A*(Shortcut.Last(), Path.Last(), true); + // when iterated AfterBend (or BeforeBend) times: Append the rest recursively calling A*(Shortcut.Last(), Path.Last(), true); - // Construct shortcut return Shortcut; } diff --git a/AdventureMap.h b/AdventureMap.h index 3121fae..c42cf5c 100644 --- a/AdventureMap.h +++ b/AdventureMap.h @@ -30,6 +30,9 @@ public: UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Config") int32 TileSize = 100; + UPROPERTY(VisibleAnywhere, BlueprintReadWrite) + AAdventurePlayerController* PCRef; + UFUNCTION(BlueprintCallable, Category = "Generation") void MakeGrid(); UPROPERTY(BlueprintReadOnly, Category = "Generation") diff --git a/HexTile.h b/HexTile.h index b8ca315..eb20bdf 100644 --- a/HexTile.h +++ b/HexTile.h @@ -58,7 +58,7 @@ public: UPROPERTY() float GCost; UPROPERTY() - float HCost; + float HCost = 9999; // MapObject Placement UPROPERTY(BlueprintReadWrite, VisibleAnywhere)