예제 #1
0
        public ParContract GetPBNParContract()
        {
            String contractField = this.board.GetOptimumResult();

            if ("Pass".Equals(contractField))
            {
                return(new ParContract());
            }
            Match contractMatch = ParScore.pbnContractPattern.Match(contractField);

            if (!contractMatch.Success)
            {
                throw new ParScoreInvalidException("Invalid format for OptimumResult field: " + contractField);
            }
            String scoreField = this.board.GetOptimumScore();
            Match  scoreMatch = ParScore.pbnScorePattern.Match(scoreField);

            if (!scoreMatch.Success)
            {
                throw new ParScoreInvalidException("Invalid format for OptimumScore field: " + scoreField);
            }
            int score = Int16.Parse(scoreMatch.Groups[2].Value);

            if ("EW".Equals(scoreMatch.Groups[1].Value))
            {
                score = -score;
            }
            ParContract contract = new ParContract(Int16.Parse(contractMatch.Groups[1].Value),
                                                   contractMatch.Groups[2].Value[0],
                                                   contractMatch.Groups[4].Value[0],
                                                   "X".Equals(contractMatch.Groups[3].Value),
                                                   score);

            return(contract.Validate());
        }
예제 #2
0
        private ParContract getHighestMakeableContract(int[,] ddTable, bool forNS = true, bool forEW = true)
        {
            ParContract contract = new ParContract();
            int         tricks   = 0;

            for (int i = 3; i >= 0; i--)
            {
                if ((i % 2 == 0 && forNS) ||
                    (i % 2 == 1 && forEW))
                {
                    for (int j = 0; j < 5; j++)
                    {
                        int level = ddTable[i, j] - 6;
                        if (level > contract.Level ||
                            (level == contract.Level && j > Array.IndexOf(BCalcWrapper.DENOMINATIONS, contract.Denomination)))
                        {
                            contract.Level        = level;
                            contract.Denomination = BCalcWrapper.DENOMINATIONS[j];
                            contract.Declarer     = BCalcWrapper.PLAYERS[i];
                            tricks = ddTable[i, j];
                        }
                    }
                }
            }
            String vulnerability = this.board.GetVulnerable().ToUpper();
            bool   vulnerable    = this.determineVulnerability(vulnerability, contract.Declarer);

            contract.Score = contract.CalculateScore(tricks, vulnerable);
            return(contract);
        }
예제 #3
0
파일: PBNBoard.cs 프로젝트: emkael/bcdd
 public void SaveParContract(ParContract contract)
 {
     this.DeleteOptimumScore();
     this.WriteOptimumScore(contract); // we're not writing DDS custom fields, just parse them
     this.DeleteMinimax();
     this.WriteMinimax(contract);
 }
예제 #4
0
        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);
        }
예제 #5
0
파일: PBNBoard.cs 프로젝트: emkael/bcdd
        public void WriteMinimax(ParContract contract)
        {
            String minimax;

            if (contract.Score == 0)
            {
                minimax = "7NS0";
            }
            else
            {
                minimax = String.Format("{0}{1}{2}{3}{4}", contract.Level, contract.Denomination, contract.Doubled ? "D" : "", contract.Declarer, contract.Score);
            }
            this.Fields.Add(new PBNField("Minimax", minimax));
        }
예제 #6
0
        public ParContract GetJFRParContract()
        {
            String parString = this.board.GetMinimax();
            Match  parMatch  = ParScore.jfrContractPattern.Match(parString);

            if (!parMatch.Success)
            {
                throw new ParScoreInvalidException("Invalid format for Minimax field: " + parString);
            }
            if ("0".Equals(parMatch.Groups[4].Value))
            {
                return(new ParContract()); // pass-out
            }
            ParContract contract = new ParContract(Int16.Parse(parMatch.Groups[1].Value),
                                                   parMatch.Groups[2].Value[0],
                                                   parMatch.Groups[4].Value[0],
                                                   "D".Equals(parMatch.Groups[3].Value),
                                                   Int16.Parse(parMatch.Groups[5].Value));

            return(contract.Validate());
        }
예제 #7
0
파일: Program.cs 프로젝트: emkael/bcdd
        static void Main(string[] args)
        {
            List <String> files  = Program.getFiles(args);
            List <String> errors = new List <String>();

            if (files.Count > 0)
            {
                foreach (String filename in files)
                {
                    try
                    {
                        Console.WriteLine("Analyzing " + filename);
                        PBNFile file = new PBNFile(filename);
                        foreach (PBNBoard board in file.Boards)
                        {
                            DDTable table = new DDTable(board);
                            String  boardNo;
                            try
                            {
                                boardNo = board.GetNumber();
                            }
                            catch (FieldNotFoundException)
                            {
                                boardNo = "?";
                            }
                            try
                            {
                                int[,] ddTable = table.GetDDTable();
                                if (ddTable != null)
                                {
                                    Console.WriteLine("Board " + boardNo);
                                    DDTable.PrintTable(ddTable);
                                    ParScore    par      = new ParScore(board);
                                    ParContract contract = par.GetParContract(ddTable);
                                    Console.WriteLine(contract);
                                    Console.WriteLine();
                                    board.SaveDDTable(ddTable);
                                    board.SaveParContract(contract);
                                }
                                else
                                {
                                    String error = "unable to determine DD table for board " + boardNo;
                                    errors.Add(String.Format("[{0}] {1}", filename, error));
                                    Console.WriteLine("ERROR: " + error);
                                }
                            }
                            catch (DllNotFoundException)
                            {
                                throw;
                            }
                            catch (Exception e)
                            {
                                errors.Add(String.Format("[{0}:{1}] {2}", filename, boardNo, e.Message));
                                Console.WriteLine("ERROR: " + e.Message);
                            }
                            file.WriteBoard(board);
                        }
                        file.Save();
                    }
                    catch (DllNotFoundException e)
                    {
                        errors.Add("libbcalcdds.dll could not be loaded - make sure it's present in application directory!");
                        Console.WriteLine("ERROR: " + e.Message);
                        break;
                    }
                    catch (Exception e)
                    {
                        errors.Add(e.Message);
                        Console.WriteLine("ERROR: " + e.Message);
                    }
                }
                if (errors.Count > 0)
                {
                    Console.WriteLine("Following ERRORs occured:");
                    foreach (String error in errors)
                    {
                        Console.WriteLine(error);
                    }
                    Console.WriteLine("Press any key to continue...");
                    Console.ReadKey();
                }
            }
        }
예제 #8
0
        public override bool Equals(object other)
        {
            ParContract obj = (ParContract)(other);

            return(this.Level == obj.Level && this.Denomination == obj.Denomination && this.Score == obj.Score);
        }
예제 #9
0
 public bool Higher(ParContract obj)
 {
     return(this.Level > obj.Level ||
            (this.Level == obj.Level &&
             Array.IndexOf(BCalcWrapper.DENOMINATIONS, this.Denomination) > Array.IndexOf(BCalcWrapper.DENOMINATIONS, obj.Denomination)));
 }
예제 #10
0
        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());
        }
예제 #11
0
파일: PBNBoard.cs 프로젝트: emkael/bcdd
 public void WriteOptimumScore(ParContract contract)
 {
     this.Fields.Add(new PBNField("OptimumScore", String.Format("NS {0}", contract.Score)));
 }