private int ToTeam(String name, int fromTeam, bool isReassign, out int diff, ref bool mustMove)
{
diff = 0;
if (fromTeam < 1 || fromTeam > 4) return 0;
List<PlayerModel>[] byId = new List<PlayerModel>[5]{null, fTeam1, fTeam2, fTeam3, fTeam4};
int biggestTeam = 0;
int smallestTeam = 0;
int winningTeam = 0;
int losingTeam = 0;
int[] ascendingSize = null;
int[] descendingTickets = null;
AnalyzeTeams(out diff, out ascendingSize, out descendingTickets, out biggestTeam, out smallestTeam, out winningTeam, out losingTeam);
// diff already set by AnalyzeTeams
if (mustMove) {
int disTeam = ToTeamByDispersal(name, fromTeam, byId);
if (disTeam == -1) {
// this player moved more than other dispersals, skip
DebugBalance("Exempting dispersal player ^b" + name + "^n, moved more than others");
// leave mustMove set to true so that caller does the right thing
return 0;
}
if (disTeam != 0) {
DebugWrite("^9(DEBUG) ToTeam for ^b" + name + "^n: dispersal returned team " + disTeam, 6);
return disTeam;
}
// fall thru if dispersal doesn't find a suitable team
mustMove = false;
}
DebugWrite("^9(DEBUG) ToTeam for ^b" + name + "^n: winning/losing = " + winningTeam + "/" + losingTeam, 8);
if (DebugLevel >= 8 && descendingTickets != null) {
String ds = "^9(DEBUG) ToTeam for ^b" + name + "^n: descendingTickets = [";
for (int k = 0; k < descendingTickets.Length; ++k) {
ds = ds + descendingTickets[k] + " ";
}
ds = ds + "]";
DebugWrite(ds, 8);
}
// diff is maximum difference between any two teams
if (!isReassign && diff <= MaxDiff()) return 0;
int superDiff = diff;
int targetTeam = smallestTeam;
// if teams are same size, send to losing team
if (biggestTeam != smallestTeam && byId[biggestTeam].Count == byId[smallestTeam].Count && losingTeam != fromTeam) {
DebugWrite("^9(DEBUG) ToTeam for ^b" + name + "^n: teams same size, so send to losing team: " + losingTeam, 8);
targetTeam = losingTeam;
}
if (targetTeam == fromTeam) return 0;
// Special handling for SQDM
bool isSQDM = IsSQDM();
if (isSQDM) {
int orig = targetTeam;
int i = 0;
// Don't send to the winning team, even if it is the smallest, unless reassigning
if (!isReassign && targetTeam == winningTeam) {
while (i < ascendingSize.Length) {
int aTeam = ascendingSize[i];
++i;
if (aTeam == orig || aTeam == winningTeam || aTeam == fromTeam) continue;
targetTeam = aTeam;
break;
}
}
if (targetTeam != orig) {
String szs = "(";
for (i = 1; i < byId.Length; ++i) {
szs = szs + byId[i].Count.ToString();
if (i == 4) {
szs = szs + ")";
} else {
szs = szs + ", ";
}
}
DebugBalance("ToTeam for ^b" + name + "^n: SQDM adjusted target from " + GetTeamName(orig) + " team to " + GetTeamName(targetTeam) + " team: " + szs);
}
}
// recompute diff to be difference between fromTeam and target team
diff = GetTeamDifference(ref fromTeam, ref targetTeam);
if (diff < 0) {
ConsoleDebug("ToTeam for ^b" + name + "^n: GetTeamDifference returned negative diff = " + diff);
diff = Math.Abs(diff);
}
// Fake out difference due to adjustment
if (isSQDM && diff < MaxDiff() && diff != 0) {
DebugBalance("ToTeam for ^b" + name + "^n: SQDM fake out diff due to adjustment, was " + diff + ", will be reported as " + superDiff);
diff = superDiff;
}
String tm = "(";
for (int j = 1; j <= 4; ++j) {
if (j == winningTeam) tm = tm + "+";
if (j == losingTeam) tm = tm + "-";
tm = tm + byId[j].Count;
if (j != 4) tm = tm + "/";
}
tm = tm + ")";
DebugWrite("^9(DEBUG) ToTeam for ^b" + name + "^n: analyze returned " + tm + ", " + fromTeam + " ==> " + targetTeam, 5);
return targetTeam;
}