예제 #1
0
        private void MenuContinuousEval_Click(object sender, EventArgs e)
        {
            App_inGame = false;
            string        fileName = @"G:\象棋\全局\1-23届五羊杯\第01届五羊杯象棋赛(1981)\第01局-胡荣华(红先负)柳大华.PGN";
            PgnFileStruct pgn      = pos.ReadPgnFile(fileName);

            pos.FromFEN(pgn.StartFEN);
            engine.FromFEN(pgn.StartFEN);
            engine.SearchQuiesce(-5000, 5000, 10, 0);
            for (int i = 1; i < pgn.MoveList.Count; i++)
            {
                MOVE step = pgn.MoveList[i];
                engine.MakeMove(step);
                int score = -engine.SearchQuiesce(-5000, 5000, 10, 0);
                if (i % 2 == 1)
                {
                    Console.Write("{0}. {1}  ", (i + 1) / 2, score);
                }
                else
                {
                    Console.WriteLine(score);
                }
            }

            //Write2Csv(@"G:\xqtest\eval.csv", pos.ivpc, totalMoves, 48);

            /* 用顶级人类选手的对局来测试评估审局函数的有效性。
             * 理想情况下,双方分数应呈锯齿状交替上升,除去吃子的步骤,应该稳定渐变。
             */
        }
예제 #2
0
        //http://blog.sina.com.cn/s/blog_5fd97aa90100vq5p.html
        public RepititionResult RuleTest(string filename)
        {
            Debug.Assert(filename != null);
            PgnFileStruct pgn = ReadPgnFile(filename);

            FromFEN(pgn.StartFEN);
            foreach (MOVE mv in pgn.MoveList)
            {
                Console.WriteLine(mv);
                MakeMove(mv, true);
                RepititionResult rep = Repitition();
                switch (rep)
                {
                case RepititionResult.WIN:
                    if (sdPlayer == 0)
                    {
                        Console.WriteLine("黑方负");
                    }
                    else
                    {
                        Console.WriteLine("红方负");
                    }
                    break;

                case RepititionResult.LOSE:
                    if (sdPlayer == 0)
                    {
                        Console.WriteLine("黑方胜");
                    }
                    else
                    {
                        Console.WriteLine("红方胜");
                    }
                    break;

                case RepititionResult.DRAW:
                    Console.WriteLine("不变作和");
                    break;

                default:
                    break;
                }
            }
            return(RepititionResult.NONE);
        }
예제 #3
0
        bool ReadPGN(string filename, int maxHeight)
        {
            POSITION      pos = new POSITION();
            PgnFileStruct pgn = pos.ReadPgnFile(filename);

            if (pgn.StartFEN != POSITION.cszStartFen)
            {
                Console.WriteLine("非开局或全局谱");
                return(false);
            }
            int result;

            switch (pgn.Result)
            {
            case "0-1":
                result = -1;
                break;

            case "1-0":
                result = 1;
                break;

            case "1/2-1/2":
                result = 0;
                break;

            default:
                return(false);
            }
            pos.FromFEN(pgn.StartFEN);

            int height = 0;

            foreach (MOVE mv in pgn.MoveList)
            {
                pos.MakeMove(mv, false);
                ulong key = pos.Key;

                if (Book.TryGetValue(key, out BookEntry entry))
                {
                    switch (result)
                    {
                    case 1:
                        entry.win++;
                        Debug.Assert(entry.win < ushort.MaxValue);
                        break;

                    case 0:
                        entry.draw++;
                        Debug.Assert(entry.loss < ushort.MaxValue);
                        break;

                    case -1:
                        entry.loss++;
                        Debug.Assert(entry.draw < ushort.MaxValue);
                        break;

                    default:
                        Debug.Fail("Unknown result");
                        break;
                    }
                    Book[key] = entry;
                }
                else
                {
                    ulong mirror_key = pos.CalculateZobrist(true);
                    if (Book.TryGetValue(mirror_key, out entry))
                    {
                        switch (result)
                        {
                        case 1:
                            entry.win++;
                            Debug.Assert(entry.win < ushort.MaxValue);
                            break;

                        case 0:
                            entry.draw++;
                            Debug.Assert(entry.loss < ushort.MaxValue);
                            break;

                        case -1:
                            entry.loss++;
                            Debug.Assert(entry.draw < ushort.MaxValue);
                            break;

                        default:
                            Debug.Fail("Unknown result");
                            break;
                        }
                        Book[mirror_key] = entry;
                    }
                    else
                    {
                        entry = new BookEntry();
                        switch (result)
                        {
                        case 1:
                            entry.win = 1;
                            break;

                        case 0:
                            entry.draw = 1;
                            break;

                        case -1:
                            entry.loss = 1;
                            break;

                        default:
                            Debug.Fail("Unknown result");
                            return(false);
                        }
                        Book.Add(key, entry);
                    }
                }
                height++;
                if (height > maxHeight)
                {
                    return(true);
                }
            }
            return(true);
        }
예제 #4
0
        //暂不支持(变招)识别
        public PgnFileStruct ReadPgnFile(string szFileName)
        {
            Debug.Assert(szFileName != null);
            PgnFileStruct PGN = new PgnFileStruct();

            FromFEN(cszStartFen);
            PGN.StartFEN    = cszStartFen;
            PGN.MoveList    = new List <MOVE>();
            PGN.CommentList = new List <string>();

            using (StreamReader fp = new StreamReader(szFileName, Encoding.GetEncoding("GB2312")))
            {
                string pattern = @"\A\[(\w+)\s""(.*)""\]\Z";
                Regex  reg     = new Regex(pattern);
                Match  m;
                string line = "";
                while (fp.Peek() > -1)
                {
                    line = fp.ReadLine();
                    m    = reg.Match(line);
                    if (m.Success)
                    {
                        switch (m.Groups[1].Value)
                        {
                        case "Format":
                            PGN.Format = m.Groups[2].Value;
                            break;

                        case "Game":
                            if (m.Groups[2].Value != "Chinese Chess")
                            {
                                Console.WriteLine("非中国象棋棋谱");
                                return(PGN);
                            }
                            break;

                        case "Event":
                            PGN.Event = m.Groups[2].Value;
                            break;

                        case "Date":
                            PGN.Date = m.Groups[2].Value;
                            break;

                        case "Round":
                            PGN.Round = m.Groups[2].Value;
                            break;

                        case "FEN":
                            FromFEN(m.Groups[2].Value);
                            PGN.StartFEN = m.Groups[2].Value;
                            break;

                        case "Result":
                            PGN.Result = m.Groups[2].Value;
                            break;

                        case "Site":
                            PGN.Site = m.Groups[2].Value;
                            break;

                        case "RedTeam":
                            PGN.RedTeam = m.Groups[2].Value;
                            break;

                        case "BlackTeam":
                            PGN.BlackTeam = m.Groups[2].Value;
                            break;

                        case "Red":
                            PGN.Red = m.Groups[2].Value;
                            break;

                        case "Black":
                            PGN.Black = m.Groups[2].Value;
                            break;

                        case "ECCO":
                            PGN.ECCO = m.Groups[2].Value;
                            break;

                        case "Opening":
                            PGN.Opening = m.Groups[2].Value;
                            break;

                        case "Variation":
                            PGN.Variation = m.Groups[2].Value;
                            break;

                        case "BlackElo":
                            PGN.BlackElo = m.Groups[2].Value;
                            break;

                        case "RedElo":
                            PGN.RedElo = m.Groups[2].Value;
                            break;

                        default:
                            Debug.WriteLine("Unknown label {0}", m.Groups[2].Value);
                            break;
                        }
                    }
                    else
                    {
                        //Now comes the move and comment list
                        line += "\n" + fp.ReadToEnd();
                    }
                }
                int    index;
                string comment = "";
                //int phase = 2; //phase = 0是序号,1是move#1,2是 move#2
                do
                {
                    //get move list till next comment
                    index = line.IndexOf('{');
                    string content;
                    if (index < 0)
                    {
                        content = line;
                    }
                    else if (index == 0)
                    {
                        int index1 = line.IndexOf('}');
                        if (index1 > 0)
                        {//is comment
                            comment = line.Substring(1, index1 - 1);
                            line    = line.Substring(index1 + 1);
                        }
                        continue;
                    }
                    else
                    {
                        content = line.Substring(0, index);
                        line    = line.Substring(index);
                    }
                    string[] words = content.Split(new char[] { ' ', '\n', '\r', '.' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string s in words)
                    {
                        pattern = @"\A(\d+)\Z";
                        m       = Regex.Match(s, pattern);
                        if (m.Success)
                        {//is a move number
                         //Debug.WriteLine(m.Groups[1].Value);
                         //if (phase != 2 && m.Groups[1].Value != "2")//第一回合如果黑方先走,只有move#2
                         //{
                         //    Console.WriteLine("棋谱错误,缺少着法");
                         //    return false;
                         //}
                         //phase = 0;
                        }
                        else if (s.Length == 4)
                        {//is a Chinese move
                            //Debug.WriteLine(s);
                            MOVE mv = ParseWord(s);
                            if (mv.pcSrc == 0)
                            {
                                Console.WriteLine("警告:棋谱错误!");
                                return(PGN);
                            }
                            MakeMove(mv);
                            PGN.CommentList.Add(comment);
                            PGN.MoveList.Add(mv);
                            comment = null;
                            //phase++;
                        }
                        else if (s.Length == 5)
                        {// is a ICCS format move
                            Tuple <int, int> coord = ICCS2Move(s);
                            MOVE             mv    = new MOVE(coord.Item1, coord.Item2, pcSquares[coord.Item1], pcSquares[coord.Item2]);
                            MakeMove(mv);
                            PGN.CommentList.Add(comment);
                            PGN.MoveList.Add(mv);
                            comment = null;
                        }
                        else
                        {
                            PGN.CommentList.Add(comment);
                            if (s != PGN.Result)
                            {
                                Debug.WriteLine(s);
                            }

                            goto CHECK_RESULT;
                        }
                    }
                } while (line.Length > 0 & index >= 0);
            }

CHECK_RESULT:
            //Sometime the result is recorded in the last comment
            if (PGN.Result == "*")
            {
                string s = PGN.CommentList[PGN.CommentList.Count - 1];
                if (s != null)
                {
                    if (s.Contains("红胜") || s.Contains("黑负"))
                    {
                        PGN.Result = "1-0";
                    }
                    else if (s.Contains("和"))
                    {
                        PGN.Result = "1/2-1/2";
                    }
                    else if (s.Contains("红负") || s.Contains("黑胜"))
                    {
                        PGN.Result = "0-1";
                    }
                }
            }
            return(PGN);
        }
예제 #5
0
        public void TestEval()
        {
            //int Compare(KeyValuePair<string, int> a, KeyValuePair<string, int> b)
            //{
            //    return a.Value.CompareTo(b.Value);
            //}
            string sourceDirectory        = @"G:\象棋\全局\1-23届五羊杯";
            IEnumerable <string> pgnFiles = Directory.EnumerateFiles(sourceDirectory, "*.pgn", SearchOption.AllDirectories);
            int           nFile           = 0;
            int           totalMoves      = 0;
            int           totalSteps      = 0;
            List <double> redDelta        = new List <double>();
            List <double> blackDelta      = new List <double>();
            List <double> seq             = new List <double>();

            foreach (string fileName in pgnFiles)
            {
                Console.WriteLine(fileName.Substring(sourceDirectory.Length + 1));
                PgnFileStruct pgn       = ReadPgnFile(fileName);
                List <MOVE>   iMoveList = pgn.MoveList;
                nFile++;
                int nSteps = iMoveList.Count;
                totalSteps += nSteps;
                bool[] captures = new bool[nSteps];
                FromFEN(pgn.StartFEN);
                ivpc = new int[nSteps, 48];
                Complex_Evaluate();
                List <KeyValuePair <string, int> > mv_vals = new List <KeyValuePair <string, int> >();
                for (int i = 1; i < nSteps; i++)
                {
                    MOVE step = iMoveList[i];
                    captures[i] = pcSquares[step.sqDst] > 0;
                    if (pcSquares[step.sqDst] == 0)
                    {
                        mv_vals.Clear();
                        //List<MOVE> moves = GenerateMoves();
                        int    bookmovevalue = 0;
                        string bookmovekey   = step.ToString();
                        foreach (MOVE move in GenerateMoves())
                        {
                            if (move.pcDst == 0)
                            {
                                MovePiece(move);
                                string key = move.ToString();
                                int    val = Complex_Evaluate();
                                mv_vals.Add(new KeyValuePair <string, int>(key, val));
                                UndoMovePiece(move);
                                if (key == bookmovekey)
                                {
                                    bookmovevalue = val;
                                }
                            }
                        }
                        if (i % 2 == 0) //从小到大排序
                        {
                            mv_vals.Sort(delegate(KeyValuePair <string, int> a, KeyValuePair <string, int> b)
                                         { return(a.Value.CompareTo(b.Value)); });
                        }
                        else  //从大到小排序
                        {
                            mv_vals.Sort(delegate(KeyValuePair <string, int> a, KeyValuePair <string, int> b)
                                         { return(b.Value.CompareTo(a.Value)); });
                        }
                        int index = mv_vals.IndexOf(new KeyValuePair <string, int>(bookmovekey, bookmovevalue));
                        seq.Add(index);
                        //totalMoves += moves.Count;
                        Console.WriteLine("{0}. Book move: {1} {2}", i, bookmovekey, index);
                        foreach (var m in mv_vals)
                        {
                            //Console.WriteLine("{0}. {1} {2} / {3}", j++, m.Key, m.Value, moves.Count);
                        }
                    }

                    MakeMove(step, true);
                    Console.WriteLine("-------------------");
                }
                for (int i = 1; i < nSteps; i += 2)
                {
                    if (!captures[i])
                    {
                        redDelta.Add(ivpc[i, 1] - ivpc[i - 1, 1]);
                    }
                }

                for (int i = 2; i < nSteps; i += 2)
                {
                    if (!captures[i])
                    {
                        blackDelta.Add(ivpc[i, 1] - ivpc[i - 1, 1]);
                    }
                }
                break;
            }
            double redMean = Statistics.Mean(redDelta);
            double redVar  = Statistics.Variance(redDelta);

            Console.WriteLine("Red mean:{0}, var:{1}", redMean, redVar);
            double blackMean = Statistics.Mean(blackDelta);
            double blackVar  = Statistics.Variance(blackDelta);

            Console.WriteLine("Black mean:{0}, var:{1}", blackMean, blackVar);
            Console.WriteLine("Score: red{0}, black{1}, average{2}", redVar / redMean, blackVar / blackMean, (redVar + blackVar) / (redMean - blackMean));
            Console.WriteLine("Move average sequence: {0} of {1}", Statistics.Mean(seq), totalMoves / totalSteps);
        }