public ParContract GetDefense(int[,] ddTable, bool vulnerable) { int declarerIndex = Array.IndexOf(BCalcWrapper.PLAYERS, this.Declarer); int denominationIndex = Array.IndexOf(BCalcWrapper.DENOMINATIONS, this.Denomination); if (this.Level != 0 && this.Level + 6 <= ddTable[declarerIndex, denominationIndex]) { List <int> defendersIndexes = new List <int>(); defendersIndexes.Add((declarerIndex + 1) & 3); defendersIndexes.Add((declarerIndex + 3) & 3); List <ParContract> possibleDefense = new List <ParContract>(); int scoreSquared = this.Score * this.Score; for (int i = 0; i < 5; i++) { int level = this.Level; if (i <= denominationIndex) { level++; } if (level <= 7) { foreach (int defender in defendersIndexes) { if (level + 6 > ddTable[defender, i]) { ParContract defense = new ParContract(level, BCalcWrapper.DENOMINATIONS[i], BCalcWrapper.PLAYERS[defender], true, 0); defense.Score = defense.CalculateScore(ddTable[defender, i], vulnerable); if (scoreSquared > this.Score * defense.Score) { possibleDefense.Add(defense); } } } } } if (possibleDefense.Count > 0) { possibleDefense.Sort((x, y) => Math.Abs(x.Score - this.Score).CompareTo(Math.Abs(y.Score - this.Score))); ParContract optimumDefense = possibleDefense.Last(); possibleDefense = possibleDefense.FindAll(x => x.Score == optimumDefense.Score); foreach (ParContract defense in possibleDefense) { // Lowest from the most profitable sacrifices if (optimumDefense.Higher(defense)) { optimumDefense = defense; } } return(optimumDefense); } } return(null); }
public ParContract GetDDTableParContract(int[,] ddTable) { String dealer = this.board.GetDealer(); String vulnerability = this.board.GetVulnerable().ToUpper(); ParContract nsHighest = this.getHighestMakeableContract(ddTable, true, false); ParContract ewHighest = this.getHighestMakeableContract(ddTable, false, true); bool nsPlaying = ("N".Equals(dealer) || "S".Equals(dealer)); if (nsHighest == ewHighest) { return(nsPlaying ? nsHighest.Validate() : ewHighest.Validate()); } ParContract highest = nsHighest.Higher(ewHighest) ? nsHighest : ewHighest; ParContract otherSideHighest = nsHighest.Higher(ewHighest) ? ewHighest : nsHighest; nsPlaying = ('N'.Equals(highest.Declarer) || 'S'.Equals(highest.Declarer)); bool defenseVulnerability = this.determineVulnerability(vulnerability, nsPlaying ? 'E' : 'N'); ParContract highestDefense = highest.GetDefense(ddTable, defenseVulnerability); if (highestDefense != null) { // Highest contract has profitable defense return(highestDefense.Validate()); } int denominationIndex = Array.IndexOf(BCalcWrapper.DENOMINATIONS, highest.Denomination); int declarerIndex = Array.IndexOf(BCalcWrapper.PLAYERS, highest.Declarer); List <int> playerIndexes = new List <int>(); playerIndexes.Add(declarerIndex); playerIndexes.Add((declarerIndex + 2) & 3); bool vulnerable = this.determineVulnerability(vulnerability, highest.Declarer); int scoreSquared = highest.Score * highest.Score; List <ParContract> possibleOptimums = new List <ParContract>(); for (int i = 0; i < 5; i++) { foreach (int player in playerIndexes) { int level = highest.Level; if (i > denominationIndex) { level--; } while (level > 0) { ParContract contract = new ParContract(level, BCalcWrapper.DENOMINATIONS[i], BCalcWrapper.PLAYERS[player], false, 0); contract.Score = contract.CalculateScore(ddTable[player, i], vulnerable); if (otherSideHighest.Higher(contract)) { // Contract is lower than other side's contract break; } if (highest.Score * contract.Score > 0) { // Contract makes if (Math.Abs(contract.Score) >= Math.Abs(highest.Score)) { // Contract is profitable ParContract defense = contract.GetDefense(ddTable, defenseVulnerability); if (defense != null && (contract.Score * contract.Score > contract.Score * defense.Score)) { // Contract has defense possibleOptimums.Add(defense); // So lower contracts will too. break; } else { // Contract does not have defense possibleOptimums.Add(contract); } } else { // Contract is not profitable break; } } level--; } } } foreach (ParContract contract in possibleOptimums) { if ((Math.Abs(contract.Score) > Math.Abs(highest.Score))) { // Contract is more profitable highest = contract; } else { if (contract.Score == highest.Score) { if (highest.Higher(contract)) { // Equally profitable, but lower highest = contract; } } } } return(highest.Validate()); }