prepared Shortcut rework for A* (working segment data)
This commit is contained in:
parent
1573598c2a
commit
1485621698
117
AdventureMap.cpp
117
AdventureMap.cpp
@ -170,26 +170,6 @@ TArray<AHexTile*> 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<AHexTile*> Path;
|
||||
if (!IsValid(Goal->CameFrom)) { return Path; }
|
||||
@ -200,72 +180,61 @@ TArray<AHexTile*> AAdventureMap::FindPathAStar(AHexTile* Start, AHexTile* Goal,
|
||||
}
|
||||
Algo::Reverse(Path);
|
||||
|
||||
if (bDiags) {
|
||||
Path = ShortcutAStar(Path);
|
||||
if (bDiags) {
|
||||
TArray<AHexTile*> PathS = ShortcutAStar(Path);
|
||||
}
|
||||
|
||||
return Path;
|
||||
}
|
||||
|
||||
|
||||
TArray<AHexTile*> AAdventureMap::ShortcutAStar(TArray<AHexTile*> Path)
|
||||
{
|
||||
TArray<AHexTile*> Shortcut;
|
||||
|
||||
int32 Len = Path.Num();
|
||||
AHexTile* Milestone = Path[0];
|
||||
int32 BeforeBend;
|
||||
int32 AfterBend;
|
||||
int32 HexIter = 1;
|
||||
FHexVector pDir;
|
||||
TArray<AHexTile*> 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<AHexTile*> WorkingSegment;
|
||||
for (int32 i = Path.Find(Milestone); i < HexIter; i++) { WorkingSegment.Add(Path[i]); }
|
||||
Milestone = WorkingSegment.Last();
|
||||
Current = WorkingSegment[0];
|
||||
bool bFirstDiagTaken = false;
|
||||
TArray<AHexTile*> 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;
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user