Skip to content

Commit 8556e1e

Browse files
committed
Improve UMS AI team detection
1 parent d7c70af commit 8556e1e

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

cmd/screp/screp.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424

2525
const (
2626
appName = "screp"
27-
appVersion = "v1.12.4"
27+
appVersion = "v1.12.5"
2828
appAuthor = "Andras Belicza"
2929
appHome = "https://github.com/icza/screp"
3030
)

rep/replay.go

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"bytes"
88
"fmt"
99
"math"
10+
"slices"
1011
"sort"
1112
"strings"
1213
"time"
@@ -291,6 +292,10 @@ cmdLoop:
291292
// Alliance commands in the first 115 seconds are checked; if they consistently denote 2 teams (and an optional observer team),
292293
// players are assigned team 1 and 2 respectively (and observers are assigned team 3, and marked as observers).
293294
//
295+
// As a special / fallback case, if only player(s) from one team checked alliance
296+
// (which results in a single known team), and the remaining non-obs players are of the same count,
297+
// accept this as the team setup: known team vs the rest as the other team.
298+
//
294299
// If teams can be computed, also rearranges Header.Players and Computed.PlayerDescs
295300
// according to new teams.
296301
func (r *Replay) computeUMSTeamsAI() {
@@ -381,7 +386,37 @@ func (r *Replay) computeUMSTeamsAI() {
381386
virtualTeamIDSlotIDs[virtualID] = slotIDs
382387
}
383388
if len(virtualTeamIDSlotIDs) != 2 {
384-
return // not 2 teams exactly
389+
// Not 2 teams exactly.
390+
// Check for the "special / fallback case": if only player(s) from one team checked alliance
391+
// (which results in a single known team), and the remaining non-obs players are of the same count,
392+
// accept this as the team setup: known team vs the rest as the other team.
393+
specialCase := false
394+
if len(virtualTeamIDSlotIDs) == 1 {
395+
// Need the one element from the map, build a set from it for easy lookup.
396+
knownTeamSlotIDs := map[byte]bool{}
397+
for _, slotIDs := range virtualTeamIDSlotIDs {
398+
for _, slotID := range slotIDs {
399+
knownTeamSlotIDs[slotID] = true
400+
}
401+
}
402+
// Collect remaining non-obs slotIDs
403+
remainingSlotIDs := make([]byte, 0, len(players))
404+
for _, p := range players {
405+
if p.Observer || knownTeamSlotIDs[byte(p.SlotID)] {
406+
continue
407+
}
408+
remainingSlotIDs = append(remainingSlotIDs, byte(p.SlotID))
409+
}
410+
if len(knownTeamSlotIDs) == len(remainingSlotIDs) {
411+
// Hooray! Sort slot IDs and add as a virtual team:
412+
specialCase = true
413+
slices.Sort(remainingSlotIDs)
414+
virtualTeamIDSlotIDs[fmt.Sprint(remainingSlotIDs)] = remainingSlotIDs
415+
}
416+
}
417+
if !specialCase {
418+
return
419+
}
385420
}
386421

387422
var team1SlotIDs, team2SlotIDs []byte

repparser/repparser.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ import (
6060

6161
const (
6262
// Version is a Semver2 compatible version of the parser.
63-
Version = "v1.12.4"
63+
Version = "v1.12.5"
6464
)
6565

6666
var (

0 commit comments

Comments
 (0)