Skip to content

Commit cd571eb

Browse files
authored
Merge pull request #414 from CnCNet/develop
Logging for forced faction policy
2 parents c594683 + c7ac79a commit cd571eb

File tree

2 files changed

+82
-9
lines changed

2 files changed

+82
-9
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
docker/frankenphp/dev-entrypoint.sh text eol=lf

cncnet-api/app/Http/Services/FactionPolicyService.php

Lines changed: 81 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ class FactionPolicyService
1414
{
1515
protected function getForcedStats(Ladder $ladder, LadderHistory $history, QmMatchPlayer $player, int $forcedId): array
1616
{
17+
Log::debug('getForcedStats: start', [
18+
'ladder_id' => $ladder->id,
19+
'history_id' => $history->id,
20+
'player_id' => $player->player_id,
21+
'forcedId' => $forcedId,
22+
]);
23+
1724
$query = DB::table('player_game_reports')
1825
->join('game_reports', 'game_reports.id', '=', 'player_game_reports.game_report_id')
1926
->join('games', 'games.id', '=', 'game_reports.game_id')
@@ -23,11 +30,16 @@ protected function getForcedStats(Ladder $ladder, LadderHistory $history, QmMatc
2330
->where('game_reports.valid', 1)
2431
->where('game_reports.best_report', 1);
2532

33+
$sql = $query->toSql();
34+
Log::debug('getForcedStats: SQL', ['sql' => $sql, 'bindings' => $query->getBindings()]);
35+
2636
$row = $query
2737
->selectRaw('COUNT(*) AS total')
2838
->selectRaw('SUM(CASE WHEN stats2.cty = ? THEN 1 ELSE 0 END) AS forced_cnt', [$forcedId])
2939
->first();
3040

41+
Log::debug('getForcedStats: result row', (array)$row);
42+
3143
return [(int) ($row->total ?? 0), (int) ($row->forced_cnt ?? 0)];
3244
}
3345

@@ -36,38 +48,63 @@ protected function createCandidates(array $currentSides, MapPool $pool): array
3648
[$s1, $s2] = $currentSides;
3749
$forcedId = (int)$pool->forced_faction_id;
3850

51+
Log::debug('createCandidates: start', [
52+
'currentSides' => $currentSides,
53+
'forcedId' => $forcedId,
54+
]);
55+
3956
// Collect candidates.
4057
$candidates = [ [$s1, $s2] ];
4158
$candidates[] = [ $forcedId, $s2 ];
4259
$candidates[] = [ $s1, $forcedId ];
4360
$candidates[] = [ $forcedId, $forcedId ];
44-
61+
62+
Log::debug('createCandidates: raw candidates', $candidates);
63+
4564
// Remove forbidden pairs.
4665
$valid = [];
4766
foreach ($candidates as [$faction1, $faction2])
4867
{
49-
if (!$pool->isValidPair($faction1, $faction2))
68+
$isValid = $pool->isValidPair($faction1, $faction2);
69+
Log::debug('createCandidates: check isValidPair', [
70+
'pair' => [$faction1, $faction2],
71+
'isValid' => $isValid,
72+
]);
73+
if (!$isValid)
5074
{
75+
Log::debug('createCandidates: rejected pair', [$faction1, $faction2]);
5176
continue;
5277
}
5378
$valid[] = [$faction1, $faction2];
5479
}
5580

81+
Log::debug('createCandidates: valid candidates', $valid);
5682
return $valid;
5783
}
5884

5985
public function applyPolicy1v1(MapPool $pool, Ladder $ladder, LadderHistory $history, QmMap $qmMap, QmMatchPlayer $p1, QmMatchPlayer $p2): void
6086
{
6187
$forcedId = $pool->forced_faction_id !== null ? (int)$pool->forced_faction_id : null;
6288
$ratio = $pool->forced_faction_ratio !== null ? (float)$pool->forced_faction_ratio : null;
63-
89+
90+
Log::debug('applyPolicy1v1: start', [
91+
'forcedId' => $forcedId,
92+
'ratio' => $ratio,
93+
'map' => $qmMap->description,
94+
'p1_side' => $p1->actual_side,
95+
'p2_side' => $p2->actual_side,
96+
'map_sides'=> $qmMap->sides_array(),
97+
]);
98+
6499
if ($forcedId === null || $ratio === null)
65100
{
66101
// No existing policy.
102+
Log::debug('applyPolicy1v1: no policy set, abort');
67103
return;
68104
}
69105

70106
$currentSides = [$p1->actual_side, $p2->actual_side];
107+
Log::debug('applyPolicy1v1: currentSides', $currentSides);
71108

72109
if ($currentSides[0] < 0 || $currentSides[1] < 0)
73110
{
@@ -78,28 +115,46 @@ public function applyPolicy1v1(MapPool $pool, Ladder $ladder, LadderHistory $his
78115
$candidates = $this->createCandidates($currentSides, $pool);
79116

80117
// Now check which candidates are actually allowed for the map.
81-
$allowedSides = array_values(array_filter($qmMap->sides_array(), fn ($s) => $s >= 0));
118+
$allowedSides = array_values(array_map('intval', array_filter($qmMap->sides_array(), fn($s) => (int)$s >= 0)));
119+
Log::debug('applyPolicy1v1: allowedSides (after intval)', $allowedSides);
82120

83121
$filteredCandidates = [];
84122
foreach ($candidates as [$faction1, $faction2])
85123
{
86-
if (!in_array($faction1, $allowedSides, true) || !in_array($faction2, $allowedSides, true))
124+
$in1 = in_array($faction1, $allowedSides, true);
125+
$in2 = in_array($faction2, $allowedSides, true);
126+
Log::debug('applyPolicy1v1: candidate check', [
127+
'candidate' => [$faction1, $faction2],
128+
'inAllowed1' => $in1,
129+
'inAllowed2' => $in2,
130+
]);
131+
132+
if (!$in1 || !$in2)
87133
{
88134
// Candidates contain factions, which are not allowed on this map.
135+
Log::debug('applyPolicy1v1: rejected candidate (not in allowedSides)', [
136+
'f1' => $faction1,
137+
'f2' => $faction2
138+
]);
89139
continue;
90140
}
91141
$filteredCandidates[] = [$faction1, $faction2];
92142
}
143+
Log::debug('applyPolicy1v1: filteredCandidates', $filteredCandidates);
93144

94145
if (empty($filteredCandidates))
95146
{
96147
Log::info('applyPolicy1v1: cannot apply faction policy on map ' . $qmMap->description);
97148
return;
98149
}
99-
150+
100151
if (count($filteredCandidates) === 1)
101152
{
102153
[$faction1, $faction2] = $filteredCandidates[0];
154+
Log::debug('applyPolicy1v1: only one candidate left', [
155+
'candidate' => [$faction1, $faction2],
156+
'current' => $currentSides,
157+
]);
103158
if ($faction1 !== $currentSides[0] || $faction2 !== $currentSides[1])
104159
{
105160
$p1->actual_side = $faction1;
@@ -113,17 +168,23 @@ public function applyPolicy1v1(MapPool $pool, Ladder $ladder, LadderHistory $his
113168

114169
// Now go through all available pairs left and take the one with the minimal deviation
115170
// from forced faction ratio.
171+
116172
[$totalGames1, $forcedFaction1] = $this->getForcedStats($ladder, $history, $p1, $forcedId);
117173
[$totalGames2, $forcedFaction2] = $this->getForcedStats($ladder, $history, $p2, $forcedId);
118174

175+
Log::debug('applyPolicy1v1: forced stats', [
176+
'p1' => ['total' => $totalGames1, 'forced' => $forcedFaction1],
177+
'p2' => ['total' => $totalGames2, 'forced' => $forcedFaction2],
178+
]);
179+
119180
$bestPair = $currentSides;
120181
$lowestForcedRatioDeviation = INF;
121182
$bestChanges = PHP_INT_MAX;
122183

123184
foreach ($filteredCandidates as [$a, $b])
124185
{
125186
$err = 0.5;
126-
187+
127188
if ($a === $forcedId && $b !== $forcedId)
128189
{
129190
$err = abs((($forcedFaction1 + 1) / ($totalGames1 + 1)) - $ratio);
@@ -138,14 +199,25 @@ public function applyPolicy1v1(MapPool $pool, Ladder $ladder, LadderHistory $his
138199
$err2 = abs((($forcedFaction2 + 1) / ($totalGames2 + 1)) - $ratio);
139200
$err = ($err1 + $err2) / 2.0;
140201
}
141-
202+
142203
$changes = (int)($a !== $currentSides[0]) + (int)($b !== $currentSides[1]);
143204

205+
Log::debug('applyPolicy1v1: candidate evaluation', [
206+
'pair' => [$a, $b],
207+
'err' => $err,
208+
'changes' => $changes,
209+
]);
210+
144211
if ($err < $lowestForcedRatioDeviation || ($err == $lowestForcedRatioDeviation && $changes < $bestChanges))
145212
{
146213
$lowestForcedRatioDeviation = $err;
147214
$bestChanges = $changes;
148215
$bestPair = [$a, $b];
216+
Log::debug('applyPolicy1v1: new bestPair', [
217+
'bestPair' => $bestPair,
218+
'lowestErr'=> $lowestForcedRatioDeviation,
219+
'bestChanges' => $bestChanges,
220+
]);
149221
}
150222
}
151223

@@ -162,6 +234,6 @@ public function applyPolicy1v1(MapPool $pool, Ladder $ladder, LadderHistory $his
162234
{
163235
Log::info('applyPolicy1v1: keeping p1='. $p1->actual_side . ' and p2=' . $p2->actual_side);
164236
}
165-
166237
}
238+
167239
}

0 commit comments

Comments
 (0)