|
7 | 7 | "bytes" |
8 | 8 | "fmt" |
9 | 9 | "math" |
| 10 | + "slices" |
10 | 11 | "sort" |
11 | 12 | "strings" |
12 | 13 | "time" |
@@ -291,6 +292,10 @@ cmdLoop: |
291 | 292 | // Alliance commands in the first 115 seconds are checked; if they consistently denote 2 teams (and an optional observer team), |
292 | 293 | // players are assigned team 1 and 2 respectively (and observers are assigned team 3, and marked as observers). |
293 | 294 | // |
| 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 | +// |
294 | 299 | // If teams can be computed, also rearranges Header.Players and Computed.PlayerDescs |
295 | 300 | // according to new teams. |
296 | 301 | func (r *Replay) computeUMSTeamsAI() { |
@@ -381,7 +386,37 @@ func (r *Replay) computeUMSTeamsAI() { |
381 | 386 | virtualTeamIDSlotIDs[virtualID] = slotIDs |
382 | 387 | } |
383 | 388 | 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 | + } |
385 | 420 | } |
386 | 421 |
|
387 | 422 | var team1SlotIDs, team2SlotIDs []byte |
|
0 commit comments