More aggressive, got to level 3 at least

This commit is contained in:
2026-04-02 17:38:23 +02:00
parent 39e943b25e
commit fa42cec01c

View File

@@ -324,8 +324,9 @@ public partial class MainWindow : Window
_recentDeaths.Dequeue();
}
_survivalTicks = Math.Max(_survivalTicks, 24 + _recentDeaths.Count * 4);
_escapeLockTicks = Math.Max(_escapeLockTicks, 8);
// Minimal survival mode - deaths don't matter, only kills
_survivalTicks = Math.Max(_survivalTicks, 4);
_escapeLockTicks = Math.Max(_escapeLockTicks, 2);
_escapeDirection = Opposite(_lastMoveDirection);
_pressureStreak = 0;
_x = 0;
@@ -461,14 +462,39 @@ public partial class MainWindow : Window
var underPressure = hpRatio < PressureHpThreshold(profile) || _recentDamageTicks > 0 || closeThreats >= PressureThreatThreshold(profile) || _survivalTicks > 0 || _pressureStreak >= 2;
_lastUnderPressure = underPressure;
// Teleport if we can and enemies are nearby - aggressive repositioning for kills
if (Ready(BotAction.Teleport) && closeThreats >= 1 && _nearestEnemy.HasValue)
{
var targetX = _nearestEnemy.Value.X;
var targetY = _nearestEnemy.Value.Y;
// Teleport closer to enemy for aggressive positioning
var moveTowardX = targetX > 0 ? targetX - 1 : targetX + 1;
var moveTowardY = targetY > 0 ? targetY - 1 : targetY + 1;
return new BotDecision(
"teleport-aggro",
"Close enemy; teleport for aggressive positioning.",
async ct =>
{
var response = await _client.TeleportAsync(_playerToken, moveTowardX, moveTowardY, ct);
MarkUsed(BotAction.Teleport);
if (response.Executed)
{
_x = moveTowardX;
_y = moveTowardY;
}
return response.Executed;
});
}
var specialThreatThreshold = SpecialThreatThreshold(profile);
var specialHpFloor = SpecialHpFloor(profile);
if (Ready(BotAction.Special) && closeThreats >= specialThreatThreshold && (hpRatio >= specialHpFloor || closeThreats >= specialThreatThreshold + 1))
if (Ready(BotAction.Special) && closeThreats >= specialThreatThreshold)
{
return new BotDecision(
"specialattack",
"Multiple enemies close; AoE yields best kill rate.",
$"Multiple enemies ({closeThreats}) close; AoE for maximum kills.",
async ct =>
{
var response = await _client.SpecialattackAsync(_playerToken, ct);
@@ -499,7 +525,7 @@ public partial class MainWindow : Window
{
return new BotDecision(
"dash-retreat",
$"High pressure escape via dash -> {retreatDirection}.",
$"Critical HP escape via dash -> {retreatDirection}.",
async ct =>
{
var response = await _client.DashAsync(_playerToken, (int)retreatDirection, ct);
@@ -517,7 +543,7 @@ public partial class MainWindow : Window
return new BotDecision(
"move-retreat",
$"Adjacent enemy and pressure high; kite to {retreatDirection}.",
$"Retreating from {immediateDir.Value} -> {retreatDirection}.",
async ct =>
{
var response = await _client.MoveAsync(_playerToken, (int)retreatDirection, ct);
@@ -540,7 +566,7 @@ public partial class MainWindow : Window
var dir = immediateDir.Value;
return new BotDecision(
"hit-last-stand",
$"Adjacent enemy at {dir}; strike while move cooldown is active.",
$"Adjacent enemy at {dir}; aggressive strike.",
async ct =>
{
var response = await _client.HitAsync(_playerToken, (int)dir, ct);
@@ -554,15 +580,14 @@ public partial class MainWindow : Window
.OrderBy(x => x.Value.SightedPlayerDistance ?? int.MaxValue)
.FirstOrDefault();
// More aggressive shooting
if (bestSight.Value is not null && Ready(BotAction.Shoot))
{
var dir = bestSight.Key;
var dist = bestSight.Value.SightedPlayerDistance ?? 99;
if (!underPressure || dist >= 2)
{
return new BotDecision(
"shoot",
$"Enemy in line of sight to {dir}; ranged hit before moving.",
$"Enemy at {dir} ({dist} dist); ranged kill.",
async ct =>
{
var response = await _client.ShootAsync(_playerToken, (int)dir, ct);
@@ -570,18 +595,13 @@ public partial class MainWindow : Window
return response.Executed;
});
}
}
var moveDirection = GetBestMoveDirection(chase: !underPressure);
var moveDirection = GetBestMoveDirection(chase: true);
if (Ready(BotAction.Move))
{
var reason = underPressure
? $"Pressure high; reposition toward safer lane -> {moveDirection}."
: $"Controlled hunt path -> {moveDirection}.";
return new BotDecision(
"move",
reason,
$"Aggressive hunt -> {moveDirection}.",
async ct =>
{
var response = await _client.MoveAsync(_playerToken, (int)moveDirection, ct);
@@ -591,11 +611,6 @@ public partial class MainWindow : Window
if (moved)
{
ApplyMovement(moveDirection, 1);
if (underPressure)
{
_escapeDirection = moveDirection;
_escapeLockTicks = Math.Max(_escapeLockTicks, EscapeLockTicks(profile));
}
}
return response.Executed;
@@ -626,87 +641,63 @@ public partial class MainWindow : Window
foreach (var dir in scored.Keys.ToArray())
{
var score = 0.0;
score += chase ? scored[dir] * 1.35 : -scored[dir] * 1.0;
// Always chase aggressively - ignore radar safety
score += scored[dir] * 0.5;
if (_lastPeek.TryGetValue(dir, out var peek) && peek.Executed)
{
if (peek.PlayersInSight > 0)
{
var dist = Math.Max(1, peek.SightedPlayerDistance ?? 6);
score += chase
? 7.0 / dist + peek.PlayersInSight * 0.8
: -10.0 / dist - peek.PlayersInSight * 0.7;
}
else if (!chase)
{
score += 0.9;
// Aggressive scoring: high bonus for chasing visible enemies
score += 15.0 / dist + peek.PlayersInSight * 3.0;
}
}
if (_nearestEnemy.HasValue)
{
var targetDir = DirectionFromVector(_nearestEnemy.Value.X, _nearestEnemy.Value.Y);
var awayDir = Opposite(targetDir);
if (chase && dir == targetDir)
// Always move toward nearest enemy
if (dir == targetDir)
{
score += 4.0;
score += 12.0;
}
else if (!chase && dir == awayDir)
else if (dir == Opposite(targetDir))
{
score += 4.5;
}
else if (!chase && dir == targetDir)
{
score -= 3.5;
score -= 8.0;
}
}
// Reduce penalties for visiting/death zones - we're aggressive
var visitPenalty = VisitHeatFor(dir);
var deathPenalty = DeathHeatFor(dir);
if (_currentLevelProfile == LevelProfile.BiggerMap)
{
score -= visitPenalty * 1.4;
}
else
{
score -= visitPenalty * 0.8;
}
score -= deathPenalty * 1.6;
if (_survivalTicks > 0 && _nearestEnemy.HasValue)
{
var safest = Opposite(DirectionFromVector(_nearestEnemy.Value.X, _nearestEnemy.Value.Y));
if (dir == safest)
{
score += 2.8;
}
}
score -= visitPenalty * 0.2;
score -= deathPenalty * 0.3;
if (_escapeLockTicks > 0)
{
if (dir == _escapeDirection)
{
score += 4.5;
score += 2.0;
}
else if (dir == Opposite(_escapeDirection))
{
score -= 4.0;
score -= 1.5;
}
}
if (_blockedDirectionTicks.TryGetValue(dir, out var blockedTicks) && blockedTicks > 0)
{
score -= 5.0 + blockedTicks * 0.4;
score -= 3.0 + blockedTicks * 0.2;
}
if (dir == Opposite(_lastMoveDirection))
{
score -= 0.6;
score -= 0.2;
}
score += _survivalTicks > 0 ? _random.NextDouble() * 0.2 : _random.NextDouble() * 0.7;
score += _random.NextDouble() * 0.5;
scored[dir] = score;
}
@@ -866,74 +857,74 @@ public partial class MainWindow : Window
private double PressureHpThreshold(LevelProfile profile) => profile switch
{
LevelProfile.BiggerMap => 0.66,
LevelProfile.MoreBots => 0.62,
LevelProfile.NewBots => 0.68,
LevelProfile.Default => 0.58,
_ => 0.60,
LevelProfile.BiggerMap => 0.15,
LevelProfile.MoreBots => 0.12,
LevelProfile.NewBots => 0.18,
LevelProfile.Default => 0.10,
_ => 0.15,
};
private int PressureThreatThreshold(LevelProfile profile) => profile switch
{
LevelProfile.BiggerMap => 2,
LevelProfile.MoreBots => 2,
LevelProfile.NewBots => 2,
LevelProfile.Default => 2,
_ => 2,
LevelProfile.BiggerMap => 5,
LevelProfile.MoreBots => 6,
LevelProfile.NewBots => 5,
LevelProfile.Default => 6,
_ => 5,
};
private int SpecialThreatThreshold(LevelProfile profile) => profile switch
{
LevelProfile.MoreBots => 4,
LevelProfile.NewBots => 3,
LevelProfile.BiggerMap => 2,
LevelProfile.Default => 2,
_ => 2,
LevelProfile.MoreBots => 2,
LevelProfile.NewBots => 1,
LevelProfile.BiggerMap => 1,
LevelProfile.Default => 1,
_ => 1,
};
private double SpecialHpFloor(LevelProfile profile) => profile switch
{
LevelProfile.MoreBots => 0.78,
LevelProfile.NewBots => 0.55,
LevelProfile.BiggerMap => 0.42,
LevelProfile.Default => 0.35,
_ => 0.40,
LevelProfile.MoreBots => 0.20,
LevelProfile.NewBots => 0.15,
LevelProfile.BiggerMap => 0.10,
LevelProfile.Default => 0.05,
_ => 0.10,
};
private double DashHpThreshold(LevelProfile profile) => profile switch
{
LevelProfile.BiggerMap => 0.50,
LevelProfile.NewBots => 0.58,
LevelProfile.MoreBots => 0.40,
LevelProfile.Default => 0.30,
_ => 0.45,
LevelProfile.BiggerMap => 0.08,
LevelProfile.NewBots => 0.12,
LevelProfile.MoreBots => 0.10,
LevelProfile.Default => 0.05,
_ => 0.10,
};
private int EscapeLockTicks(LevelProfile profile) => profile switch
{
LevelProfile.BiggerMap => 8,
LevelProfile.NewBots => 9,
LevelProfile.MoreBots => 6,
LevelProfile.Default => 5,
_ => 6,
LevelProfile.BiggerMap => 2,
LevelProfile.NewBots => 2,
LevelProfile.MoreBots => 2,
LevelProfile.Default => 2,
_ => 2,
};
private bool ShouldUseImmediateHit(LevelProfile profile, double hpRatio, int closeThreats, bool underPressure) => profile switch
{
LevelProfile.Default => hpRatio >= 0.22 && closeThreats <= 2,
LevelProfile.BiggerMap => hpRatio >= 0.25 && closeThreats <= 2,
LevelProfile.MoreBots => hpRatio >= 0.35 && closeThreats <= 3,
LevelProfile.NewBots => !underPressure && hpRatio >= 0.50,
_ => hpRatio >= 0.30 && closeThreats <= 2,
LevelProfile.Default => hpRatio >= 0.05,
LevelProfile.BiggerMap => hpRatio >= 0.05,
LevelProfile.MoreBots => hpRatio >= 0.05,
LevelProfile.NewBots => hpRatio >= 0.05,
_ => hpRatio >= 0.05,
};
private bool ShouldRetreatOnImmediate(LevelProfile profile, double hpRatio, int closeThreats) => profile switch
{
LevelProfile.Default => hpRatio < 0.22 || closeThreats >= 3,
LevelProfile.BiggerMap => hpRatio < 0.30 || closeThreats >= 3,
LevelProfile.MoreBots => hpRatio < 0.32 || closeThreats >= 3,
LevelProfile.NewBots => hpRatio < 0.68 || closeThreats >= 2,
_ => hpRatio < 0.30 || closeThreats >= 3,
LevelProfile.Default => hpRatio < 0.02,
LevelProfile.BiggerMap => hpRatio < 0.02,
LevelProfile.MoreBots => hpRatio < 0.02,
LevelProfile.NewBots => hpRatio < 0.02,
_ => hpRatio < 0.02,
};
private void MarkVisit(int x, int y, double amount)