prepared Shortcut rework for A* (working segment data)
This commit is contained in:
parent
1573598c2a
commit
1485621698
115
AdventureMap.cpp
115
AdventureMap.cpp
@ -170,26 +170,6 @@ TArray<AHexTile*> AAdventureMap::FindPathAStar(AHexTile* Start, AHexTile* Goal,
|
|||||||
ToExamine.Add(Neighbor);
|
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;
|
TArray<AHexTile*> Path;
|
||||||
if (!IsValid(Goal->CameFrom)) { return Path; }
|
if (!IsValid(Goal->CameFrom)) { return Path; }
|
||||||
@ -201,71 +181,60 @@ TArray<AHexTile*> AAdventureMap::FindPathAStar(AHexTile* Start, AHexTile* Goal,
|
|||||||
Algo::Reverse(Path);
|
Algo::Reverse(Path);
|
||||||
|
|
||||||
if (bDiags) {
|
if (bDiags) {
|
||||||
Path = ShortcutAStar(Path);
|
TArray<AHexTile*> PathS = ShortcutAStar(Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Path;
|
return Path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TArray<AHexTile*> AAdventureMap::ShortcutAStar(TArray<AHexTile*> Path)
|
TArray<AHexTile*> AAdventureMap::ShortcutAStar(TArray<AHexTile*> Path)
|
||||||
{
|
{
|
||||||
TArray<AHexTile*> Shortcut;
|
TArray<AHexTile*> Shortcut;
|
||||||
|
|
||||||
int32 Len = Path.Num();
|
int32 Len = Path.Num();
|
||||||
AHexTile* Milestone = Path[0];
|
TArray<AHexTile*> WorkingSegment;
|
||||||
int32 BeforeBend;
|
AHexTile* Start = PCRef->CurrentHex;
|
||||||
int32 AfterBend;
|
WorkingSegment.Add(Start);
|
||||||
int32 HexIter = 1;
|
int32 i = 0;
|
||||||
FHexVector pDir;
|
|
||||||
|
FHexVector PrevDir = FHexVector(Path[0], Start);
|
||||||
FHexVector DirA;
|
FHexVector DirA;
|
||||||
FHexVector DirB;
|
int32 HexesBeforeBend = 1;
|
||||||
AHexTile* Current;
|
for (i; i < Len-1; i++) {
|
||||||
|
WorkingSegment.Add(Path[i]);
|
||||||
while (Milestone != Path[Len - 1]) {
|
DirA = FHexVector(Path[i+1], Path[i]);
|
||||||
// find Milestone (i.e. end of first curve) & determine curve data
|
if (DirA != PrevDir) { break; }
|
||||||
BeforeBend = 1;
|
HexesBeforeBend++;
|
||||||
for (HexIter; HexIter < Len; HexIter++) {
|
PrevDir = DirA;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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;
|
return Shortcut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,9 @@ public:
|
|||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Config")
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Config")
|
||||||
int32 TileSize = 100;
|
int32 TileSize = 100;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
|
||||||
|
AAdventurePlayerController* PCRef;
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Generation")
|
UFUNCTION(BlueprintCallable, Category = "Generation")
|
||||||
void MakeGrid();
|
void MakeGrid();
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "Generation")
|
UPROPERTY(BlueprintReadOnly, Category = "Generation")
|
||||||
|
Loading…
Reference in New Issue
Block a user