예제 #1
0
        public void reset_stat(board a)
        {
            Board = a.tosimple();
            tree temp = boardtree.clone();

            temp.pieceidx   = boardtree.pieceidx;
            boardtree       = temp;
            boardtree.Board = Board.clone();
            extend_node();
        }
예제 #2
0
        // 洞判定部分可能更好


        //private static int evaldeephole(int width)
        //{
        //    for (int i = width - 1; i < 10; ++i)
        //    {

        //    }
        //}
        public int evalatkdef(tree node) // 哪些是直接继承 哪些需要处理
        {
            int score = 0;

            score += node.attack * W.atk;
            //score += node.def * W.def; // 在树中和取出是不一样的
            score += (node.maxattack - node.attack) * W.maxatk;
            score += (node.maxdef - node.def) * W.maxdef;
            return(score);
        }
예제 #3
0
 public void freenode(tree node)
 {
     foreach (tree chird in node.treenode)
     {
         freenode(chird);
     }
     node.useless = true;
     node.inplan  = false;
     node         = null;
 }
예제 #4
0
        public void init()
        {
            boardtree = new tree();
            board F = new board(new mino_gene(), new TopGarbage(), 5);

            boardtree.Board = Board.clone();
            //for (int i = 0; i < 15; ++i) F.add_garbage(1);
            //boardtree.Board = F.tosimple();
            //boardtree.ad
            //nodequeue.Add(boardtree);
        }
예제 #5
0
        public void reset_stat(bool[,] field, bool b2b, int combo)
        {
            Board.field         = field;
            Board.column_height = Board.updatecol();

            Board.isb2b     = b2b;
            Board.combo     = combo;
            boardtree       = new tree();
            boardtree.Board = Board.clone();
            extend_node();
        }
예제 #6
0
 public void runmove(tree move)
 {
     if (move.ishold)
     {
         runmove(6);
     }
     for (int i = 0; i < move.finmino.path.idx; ++i)
     {
         runmove(move.finmino.path.path[i]);
     }
     runmove(5);
 }
예제 #7
0
        //public bool findnextsol()
        //{
        //    for (; ; )
        //    yield return false; // pass
        //}

        public tree clone()
        {
            tree cp = new tree();

            cp.Board       = Board.clone();
            cp.garbage     = garbage; // 可能有抵消
            cp.attack      = attack;
            cp.holdpiece   = holdpiece;
            cp.battlescore = battlescore;
            // attack 可能继承
            return(cp);
        }
예제 #8
0
        //public void nodeadd(tree node)
        //{

        //    if (node.depth == calcdepth) nodequeue.Add(node);

        //    //if (node.treenode.Count == 0 && !node.useless && node.pieceidx < nextquene.Count && !node.isextend) nodequeue.Add(node);
        //    //cnt += node.treenode.Count;
        //    foreach (tree chird in node.treenode)
        //    {
        //        nodeadd(chird);

        //    }
        //}

        public void nodeadd(tree node)
        {
            if (node.inplan && node.pieceidx < nextcnt && !node.isextend)
            {
                nodequeue.Add(node);                                                           // 考虑遇到无用直接返回
            }
            //if (node.treenode.Count == 0 && !node.useless && node.pieceidx < nextquene.Count && !node.isextend) nodequeue.Add(node);
            //cnt += node.treenode.Count;
            foreach (tree chird in node.treenode)
            {
                nodeadd(chird);
            }
        }
예제 #9
0
        public int nodecnt(tree node)
        {
            int cnt = 0;

            if (node.depth == calcdepth)
            {
                cnt += 1;
            }
            //cnt += node.treenode.Count;
            foreach (tree chird in node.treenode)
            {
                cnt += nodecnt(chird);
            }
            return(cnt);
        }
예제 #10
0
        public int nodedep(tree node)
        {
            int cnt = 0;

            if (!node.useless)
            {
                cnt = node.depth;
                //cnt += node.treenode.Count;
                foreach (tree chird in node.treenode)
                {
                    cnt = Math.Max(nodedep(chird), cnt);
                }
            }
            return(cnt);
        }
예제 #11
0
        public void reset_stat(bool[,] field, bool b2b, int combo)
        {
            tree temp = boardtree.clone();

            temp.pieceidx       = boardtree.pieceidx;
            Board               = temp.Board.clone();
            Board.field         = field;
            Board.column_height = Board.updatecol();

            Board.isb2b     = b2b;
            Board.combo     = combo;
            boardtree       = temp;
            boardtree.Board = Board.clone();
            extend_node();
        }
예제 #12
0
        public void bot_run()
        {
            if (bot.isdead)
            {
                isdead = true;  return;
            }
            tree root = bot.requset_next_move();

            if (root.isdead)
            {
                isdead = true; return;
            }
            Board.Spawn_piece();
            runmove(root);
            int next = Minorule.genebag7int();

            bot.add_next(next);
            Board.add_next_piece(next);
            bot.extend_node();
        }
예제 #13
0
        public int evalbattle(tree node) // 相对值? 需要向下累加
        {
            int score = 0;

            score += W.movetime * node.finmino.path.movetime;

            if (node.finmino.name == "T" && (!node.finmino.Tspin || node.Board.clearrow == 0))
            {
                score += W.wastedT;
            }
            score += W.fewcombo * node.Board.combo;
            if (node.Board.isperfectclear)
            {
                score += W.perfectclear * 1000;
            }

            if (node.Board.isb2bclear)
            {
                score += W.b2b_clear;
            }
            if (node.finmino.Tspin && node.finmino.name == "T")
            {
                if (node.Board.piece.mini)
                {
                    score += W.tspin[0];
                }
                else
                {
                    score += W.tspin[node.Board.clearrow];
                }
            }
            else
            {
                score += W.clear[node.Board.clearrow];
            }



            //score
            return(score);
        }
예제 #14
0
        public int evalmove(tree node) // 哪些是直接继承 哪些需要处理
        {
            int score = 0;

            // 加一个combo
            if (node.Board.combo > 0)
            {
                score += W.combo;
            }
            if (node.holdT)
            {
                score += W.holdT;
            }
            if (node.holdI)
            {
                score += W.holdI;
            }
            if (node.Board.isb2b)
            {
                score += W.b2b;
            }
            return(score);
        }
예제 #15
0
        public int evalparity(tree node) // 表面奇偶性
        {
            int parity = 0;

            for (int i = 0; i < node.Board.column_height.Length; ++i)
            {
                if ((node.Board.column_height[i] & 1) == 1)
                {
                    if ((i & 1) == 1)
                    {
                        parity += 1;
                    }
                }
                else
                {
                    if ((i & 1) == 1)
                    {
                        parity -= 1;
                    }
                }
            }
            return(Math.Abs(parity));
        }
예제 #16
0
        public void findalladd(Juraknifecore bot)
        {
            // 攻击力判定 + t旋只改场地分
            if (pieceidx >= bot.nextcnt)
            {
                return;
            }
            Tuple <int, int> res;

            this.nowpiece = bot.nextqueue[pieceidx % 30];
            isextend      = true;
            inplan        = false;
            Board.piece   = defaultop.demino.getmino(nowpiece);
            Board.piece.setpos(19, 3);
            List <mino> allpos   = seacher.findallplace(Board);
            int         chirdidx = pieceidx + 1;

            if (allpos == null)
            {
                tree chird = clone(); chird.isdead = true; chird.pieceidx = chirdidx; chird.inplan = false; chird.isextend = true; treenode.Add(chird); return;
            }
            ;
            foreach (mino m in allpos)
            {
                // 场外死亡判断
                tree chird = clone();
                chird.Board.piece = m;

                res                = lock_piece_calc(ref chird.Board);
                chird.attack       = chird.maxattack = res.Item1;
                chird.def          = chird.maxdef = res.Item1 + res.Item2; // 已经消除了 还能叫防御吗
                chird.finmino      = m;
                chird.father       = this;
                chird.ishold       = false;
                chird.isdead       = false;
                chird.holdpiece    = holdpiece;
                chird.pieceidx     = chirdidx;
                chird.depth        = depth + 1;
                chird.maxdepth     = chird.depth;
                chird.maxdepth     = chird.pieceidx;
                chird.inplan       = true;
                chird.res          = bot.evalweight.evalfield(chird);
                chird.fieldscore   = (int)chird.res.score;
                chird.battlescore += bot.evalweight.evalbattle(chird); // 相同的不要反复判了
                chird.movescore    = bot.evalweight.evalmove(chird);   // 相同的不要反复判了
                chird.atkscore     = bot.evalweight.evalatkdef(chird); // 相同的不要反复判了
                if (true || chird.holdT || hasnextT(bot, chirdidx))    // 当前块是t的时候
                {
                    tree Tchird1 = chird.clone();
                    Tchird1.Board.piece = defaultop.demino.getmino(2);
                    Tchird1.Board.piece.setpos(19, 3);
                    List <mino> Alltslot = search_tspin.findalltslot(Tchird1.Board); // 修改  /// 我是把tspin后的状态 提前压回该节点
                    if (Alltslot.Count != 0)
                    {
                        //List<mino> Alltslot = search_tspin.findalltslot(chird.Board);
                        tree bestT;
                        long minscore = chird.fieldscore;

                        foreach (mino t in Alltslot) // 超过一个 干掉
                        {
                            if (!t.Tspin)
                            {
                                continue;
                            }
                            tree Tchird = chird.clone();
                            Tchird.Board.piece = t;
                            Tchird.finmino     = t;
                            res = lock_piece_calc(ref Tchird.Board);

                            if (!t.mini)
                            {
                                Tchird.fieldscore  = bot.evalweight.evalfield(Tchird).score;
                                Tchird.fieldscore += bot.evalweight.W.tslot[res.Item2];
                            }
                            else
                            {
                                Tchird.fieldscore = chird.fieldscore + bot.evalweight.W.tslot[4];
                            }
                            //Tchird.score += bot.evalweight.evalbattle(Tchird); // 是否要battle也加上 // 其他节点借用了这个t的分值? 需不需要加入t坑评分
                            // 攻击也需要
                            if (Tchird.fieldscore > minscore && Tchird.Board.piece.Tspin)
                            {
                                minscore = Tchird.fieldscore;
                                bestT    = Tchird;
                            }
                        }
                        chird.fieldscore = minscore;
                    }
                }

                // 回传父节点

                chird.updatefather(); // check update
                treenode.Add(chird);
            }

            if (holdpiece == -1)
            {
                int holdidx = pieceidx + 1, nextnext = pieceidx + 2;

                if (holdidx < bot.nextcnt)
                {
                    // 保持连击的加分 // 防御是否应该削去
                    // 防御是给没打出攻击时才有的
                    // combo应该是个可延续状态

                    // 问题 特别喜欢打t1
                    // 不喜欢留防御

                    // todo T比较近的时候就可以开搜
                    // 优化

                    // 多next看t
                    // 为什么不喜欢堆防御

                    // keepcombo的 def
                    // 子节点也要前面的攻击
                    // 软降优化

                    // 扩展被选中的节点的所有子节点

                    // 需要参与排序的有 自身场地状态 从根到该节点所打出的攻击总数 该点的攻击,该点开始保持连击打出的最大防御数 路径总数(? 浪费t总数(这个不确定
                    //

                    Board.piece = defaultop.demino.getmino(bot.nextqueue[holdidx % 30]);
                    Board.piece.setpos(19, 3);
                    List <mino> allpos2 = seacher.findallplace(Board);
                    foreach (mino m in allpos2)
                    {
                        tree chird = clone();
                        chird.Board.piece = m;
                        res                = lock_piece_calc(ref chird.Board);
                        chird.attack       = chird.maxattack = res.Item1;
                        chird.def          = chird.maxdef = res.Item1 + res.Item2; // 已经消除了 还能叫防御吗
                        chird.finmino      = m;
                        chird.isdead       = false;
                        chird.ishold       = true;
                        chird.holdpiece    = nowpiece;
                        chird.father       = this;
                        chird.pieceidx     = nextnext;
                        chird.depth        = depth + 1;
                        chird.maxdepth     = chird.pieceidx;
                        chird.inplan       = true;
                        chird.res          = bot.evalweight.evalfield(chird);
                        chird.fieldscore   = (int)chird.res.score;
                        chird.battlescore += bot.evalweight.evalbattle(chird); // 作为攻击回传
                        chird.movescore    = bot.evalweight.evalmove(chird);   // 相同的不要反复判了
                        chird.atkscore     = bot.evalweight.evalatkdef(chird); // 相同的不要反复判了
                        if (true || chird.holdT || hasnextT(bot, nextnext))
                        {
                            tree Tchird1 = chird.clone();
                            Tchird1.Board.piece = defaultop.demino.getmino(2);
                            Tchird1.Board.piece.setpos(19, 3);
                            List <mino> Alltslot = search_tspin.findalltslot(Tchird1.Board);
                            //List<mino> Alltslot = search_tspin.findalltslot(chird.Board);
                            if (Alltslot.Count != 0)
                            {
                                tree bestT;
                                long minscore = chird.fieldscore;
                                foreach (mino t in Alltslot)
                                {
                                    if (!t.Tspin)
                                    {
                                        continue;
                                    }
                                    tree Tchird = chird.clone();
                                    Tchird.Board.piece = t;
                                    Tchird.finmino     = t;
                                    res = lock_piece_calc(ref Tchird.Board); // 作为防御回传

                                    Tchird.fieldscore = bot.evalweight.evalfield(Tchird).score;

                                    //Tchird.score += bot.evalweight.evalbattle(Tchird); // 是否要battle也加上
                                    if (!t.mini)
                                    {
                                        Tchird.fieldscore  = bot.evalweight.evalfield(Tchird).score;
                                        Tchird.fieldscore += bot.evalweight.W.tslot[res.Item2];
                                    }
                                    else
                                    {
                                        Tchird.fieldscore = chird.fieldscore + bot.evalweight.W.tslot[4];
                                    }
                                    if (Tchird.fieldscore > minscore && Tchird.Board.piece.Tspin)
                                    {
                                        minscore = Tchird.fieldscore;
                                        bestT    = Tchird;
                                    }
                                }
                                chird.fieldscore = minscore;
                            }
                        }
                        chird.updatefather();
                        // 回传父节点
                        treenode.Add(chird);
                    }
                    // 回传父节点
                }
            }
            else
            {
                int temp = nowpiece;
                nowpiece    = holdpiece;
                Board.piece = defaultop.demino.getmino(nowpiece);
                Board.piece.setpos(19, 3);
                List <mino> allpos1 = seacher.findallplace(Board);
                // 先对相对有用的节点更新
                foreach (mino m in allpos1)
                {
                    tree chird = clone();
                    chird.Board.piece = m;
                    res                = lock_piece_calc(ref chird.Board);
                    chird.attack       = chird.maxattack = res.Item1;
                    chird.def          = chird.maxdef = res.Item1 + res.Item2; // 已经消除了 还能叫防御吗
                    chird.finmino      = m;
                    chird.isdead       = false;
                    chird.ishold       = true;
                    chird.holdpiece    = temp; // oops
                    chird.pieceidx     = chirdidx;
                    chird.father       = this;
                    chird.depth        = depth + 1;
                    chird.maxdepth     = chird.depth;
                    chird.maxdepth     = chird.pieceidx;
                    chird.inplan       = true;
                    chird.res          = bot.evalweight.evalfield(chird);
                    chird.fieldscore   = (int)chird.res.score;
                    chird.battlescore += bot.evalweight.evalbattle(chird);
                    chird.movescore    = bot.evalweight.evalmove(chird);   // 相同的不要反复判了
                    chird.atkscore     = bot.evalweight.evalatkdef(chird); // 相同的不要反复判了
                    if (true || chird.holdT || hasnextT(bot, chirdidx))
                    {
                        tree Tchird1 = chird.clone();
                        Tchird1.Board.piece = defaultop.demino.getmino(2);
                        Tchird1.Board.piece.setpos(19, 3);
                        List <mino> Alltslot = search_tspin.findalltslot(Tchird1.Board);
                        //List<mino> Alltslot = search_tspin.findalltslot(chird.Board);
                        if (Alltslot.Count != 0)
                        {
                            tree bestT;
                            long minscore = chird.fieldscore;
                            foreach (mino t in Alltslot)
                            {
                                if (!t.Tspin)
                                {
                                    continue;           // 相同场地不要去 有些无用场地需要吗
                                }
                                tree Tchird = chird.clone();
                                Tchird.Board.piece = t;
                                Tchird.finmino     = t;
                                res = lock_piece_calc(ref Tchird.Board);
                                Tchird.fieldscore = bot.evalweight.evalfield(Tchird).score;
                                //Tchird.battlescore += bot.evalweight.evalbattle(Tchird); // 是否要battle也加上
                                if (!t.mini)
                                {
                                    Tchird.fieldscore  = bot.evalweight.evalfield(Tchird).score;
                                    Tchird.fieldscore += bot.evalweight.W.tslot[res.Item2];
                                }
                                else
                                {
                                    Tchird.fieldscore = chird.fieldscore + bot.evalweight.W.tslot[4];
                                }
                                if (Tchird.fieldscore > minscore && Tchird.Board.piece.Tspin) // 可以优化计算顺序
                                {
                                    minscore = Tchird.fieldscore;
                                    bestT    = Tchird;
                                }
                            }
                            chird.fieldscore = minscore;
                        }
                    }
                    chird.updatefather();
                    // 回传父节点
                    treenode.Add(chird);
                }
            }
        }
예제 #17
0
        public void run()
        {
            while (true)
            {
                Juraknifecore bot = new Juraknifecore();
                bot.init();
                //bot.boardtree.Board.console_print(false);
                mino_gene mino_Gene = new mino_gene();
                Random    rand      = new Random();
                for (int i = 0; i < 3; ++i)
                {
                    //bot.add_next(rand.Next() % 7);
                    bot.add_next(mino_Gene.genebag7int());
                }
                //char a2 = Console.ReadKey().KeyChar;
                //bot.add_next(3);
                //bot.add_next(2);

                int t = 7;

                //int[] nextqq = { 3, 1, 6, 2, 0, 5, 2, 1, 4, 0, 1, 6, 5 };
                Queue <tree> ans = new Queue <tree>();
                while (true)
                //foreach (int q in nextqq)
                {
                    //bot.add_next(rand.Next() % 7);
                    bot.add_next(mino_Gene.genebag7int());
                    //bot.add_next(q);
                    bot.extend_node();
                    //if (bot.boardtree.treenode[0].res.score < -1000000)
                    {
                        Console.WriteLine("ressearch");
                        foreach (tree chird in bot.boardtree.treenode)

                        {
                            chird.Board.console_print(false);
                            Console.WriteLine("atk = {0}", chird.attack);
                            Console.WriteLine("maxattack = {0}", chird.maxattack);
                            Console.WriteLine("def = {0}", chird.def);
                            Console.WriteLine("maxdef = {0}", chird.maxdef);
                            Console.WriteLine("atkscore = {0}", chird.atkscore);
                            Console.WriteLine("battlescore = {0}", chird.battlescore);
                            Console.WriteLine("combo = {0}", chird.Board.combo);
                            Console.WriteLine("clearrow = {0}", chird.Board.clearrow);
                            Console.WriteLine("movetime = {0}", chird.finmino.path.movetime);
                            Console.WriteLine("name = {0}", chird.finmino.name);
                            Console.WriteLine("Tspin = {0}", chird.finmino.Tspin);
                            Console.WriteLine("isb2bclear = {0}", chird.Board.isb2bclear);

                            Console.WriteLine("nodebattlescore = {0}", bot.evalweight.evalbattle(chird));
                            Console.WriteLine(chird.score);
                            Console.WriteLine("maxdepth = {0}", chird.maxdepth);
                            //Console.WriteLine("scoreex = {0}", chird.scoreex);

                            //Console.WriteLine(chird.finmino.minopos.x);
                            //Console.WriteLine(chird.finmino.minopos.y);
                            //Console.WriteLine(chird.finmino.stat);
                            Console.WriteLine(chird.finmino.name);
                            //foreach (int a in chird.Board.column_height)
                            //{
                            //    Console.Write(a);
                            //    Console.Write(" ");
                            //}
                            //Console.WriteLine("");
                            chird.finmino.console_print();
                            if (chird.holdpiece != -1)
                            {
                                defaultop.demino.getmino(chird.holdpiece).console_print();
                            }
                            double kk = 0;
                            //eval.evalhole(chird, chird.Board.column_height, 0, ref kk);
                            //chird.res.print();
                            //char a1 = Console.ReadKey().KeyChar;
                        }
                    }
                    tree root = bot.requset_next_move();
                    if (root.isdead)
                    {
                        Console.WriteLine(root.pieceidx);; break;
                    }
                    ;
                    //ans.Enqueue(root);
                    //if (ans.Count > 200) ans.Dequeue();
                    //eval.evalfield(root);
                    //Console.Clear();
                    //root.Board.console_print(true, root.finmino);
                    //if (root.pieceidx % 1 == 0 || root.score < -1000000)
                    {
                        root.Board.console_print(false);
                        Console.WriteLine("resroot");
                        Console.WriteLine("atk = {0}", root.attack);
                        Console.WriteLine("maxattack = {0}", root.maxattack);
                        Console.WriteLine("def = {0}", root.def);
                        Console.WriteLine("maxdef = {0}", root.maxdef);
                        Console.WriteLine("atkscore = {0}", root.atkscore);
                        Console.WriteLine("battlescore = {0}", root.battlescore);
                        Console.WriteLine("combo = {0}", root.Board.combo);
                        Console.WriteLine("clearrow = {0}", root.Board.clearrow);
                        Console.WriteLine("movetime = {0}", root.finmino.path.movetime);
                        Console.WriteLine("name = {0}", root.finmino.name);
                        Console.WriteLine("Tspin = {0}", root.finmino.Tspin);
                        Console.WriteLine("isb2bclear = {0}", root.Board.isb2bclear);
                        Console.WriteLine("nodebattlescore = {0}", bot.evalweight.evalbattle(root));
                        Console.WriteLine(root.score);
                        Console.WriteLine("maxdepth = {0}", root.maxdepth);
                        //Console.WriteLine("scoreex = {0}", root.scoreex);
                        //Console.WriteLine(bot.nodequeue.Count);
                        //Console.WriteLine(root.pieceidx);
                        //Console.WriteLine(root.Board.piece.name);
                        //root.res.print();
                        //foreach (int a in root.Board.column_height)
                        //{
                        //    Console.Write(a);
                        //    Console.Write(" ");
                        //}
                    }

                    //foreach (int a in root.Board.column_height)
                    //{
                    //    Console.Write(a);
                    //    Console.Write(" ");
                    //}
                    Console.WriteLine("");
                    //root.res.print();
                    Console.WriteLine("-----------------------------------------------");
                    root.finmino.console_print();
                    if (root.holdpiece != -1)
                    {
                        defaultop.demino.getmino(root.holdpiece).console_print();
                    }
                    // char a1 = Console.ReadKey().KeyChar;

                    //char a2 = Console.ReadKey().KeyChar;
                    //foreach (tree a in bot.boardtree.treenode)
                    //{
                    //    //a.Board.console_print(false);
                    //    //char a1 = Console.ReadKey().KeyChar;
                    //}

                    //bot.add_next(2);
                    //foreach (tree a in bot.boardtree.treenode)
                    //{
                    //    bot.extend_node(a);
                    //    foreach (tree a1 in a.treenode)
                    //    {
                    //        a1.Board.console_print(false);
                    //        char a2 = Console.ReadKey().KeyChar;
                    //        //char a1 = Console.ReadKey().KeyChar;
                    //    }

                    //}
                }

                //foreach (tree root in ans)
                //{
                //    root.Board.console_print(false);
                //    Console.WriteLine("resroot");
                //    Console.WriteLine(root.score);
                //    Console.WriteLine(bot.nodequeue.Count);
                //    Console.WriteLine(root.pieceidx);
                //    Console.WriteLine(root.Board.piece.name);
                //    root.res.print();
                //}
            }
        }
예제 #18
0
        } //场地评分

        //public static double evalhole(tree node)
        //{
        //    double score = 0;
        //    int roof = 0;
        //    foreach (int a in node.Board.column_height)
        //    {
        //        roof = Math.Max(a, roof);
        //    }
        //    int digrow = 0; // 上层被挖开的所需层数
        //    double[] DIG = new double[node.Board.column_height.Length];

        //    int[] fulldig = new int[40];

        //    for (int row = roof - 1; row >= 0; --row)
        //    {
        //        int nextdig = 0;// 该层被挖开的所需层数
        //        for (int cell = 0; cell < node.Board.column_height.Length; ++cell)
        //        {
        //            if (!node.Board.field[row, cell])
        //            {
        //                fulldig[row]++;
        //                //if (row + 1 < node.Board.column_height[cell])
        //                if (node.Board.field[row + 1, cell])
        //                {
        //                    int temp = Math.Max(digrow, fulldig[row + 1] - fulldig[node.Board.column_height[cell]]);
        //                    nextdig = Math.Max(temp, nextdig);
        //                    score += temp * W.downstack;
        //                }
        //                else
        //                {
        //                    if (DIG[cell] < 1000000)
        //                        DIG[cell] *= 5;
        //                    score += DIG[cell] * W.downstack;

        //                }
        //            }
        //        }
        //        fulldig[row] += fulldig[row + 1];
        //        for (int cell = 0; cell < node.Board.column_height.Length; ++cell)
        //        {
        //            if (node.Board.field[row + 1, cell])
        //            {
        //                DIG[cell] = nextdig;
        //            }

        //        }

        //           digrow = nextdig;


        //    }


        //    return score;
        //} // 空洞(可挖性评分;

        public evalresult evalnode(tree node)
        {
            return(new evalresult()); // pass
            // 评判场地 以及其他的各种状态
        }
예제 #19
0
        // 安全距离增加扣分

        //public static int evalTmino()
        //{

        //}



        public int evalhole(tree node, ref evalresult res) //问题很大。jpg 另外攻击意识修改
        {
            int[] colhight = node.Board.column_height;
            int   roof     = 0;
            int   score    = 0;

            for (int i = 0; i < colhight.Length; ++i)
            {
                roof = Math.Max(colhight[i], roof);
            }
            int nextsafedis = 0;
            int safedis     = 0; // 该行的安全堆叠层数基数 即上一次层的挖开数 + 1

            // 加入dig

            int[] Dig     = new int[10];
            int[] fulldig = new int[40];
            for (int row = roof - 1; row >= 0; --row)
            {
                bool canclear = true;
                safedis          = nextsafedis;
                res.safedis[row] = safedis;
                int downcnt = safedis;
                for (int i = 0; i < 10; ++i)
                {
                    if (!node.Board.field[row, i]) // colh
                    {
                        fulldig[row]++;
                        if (colhight[i] >= row + 1)
                        {
                            canclear = false; // 最好检测一下是否封闭
                            if (node.Board.field[row + 1, i])
                            {
                                int temp = Math.Max(downcnt, colhight[i] - row - 1) + 1;
                                //score += W.safecost * temp;
                                score        += W.linefull * (fulldig[row + 1] - fulldig[row + temp]);
                                res.linefull += W.linefull * (fulldig[row + 1] - fulldig[row + temp]);
                                nextsafedis   = Math.Max(nextsafedis, downcnt + 1);
                                nextsafedis   = Math.Max(nextsafedis, colhight[i] - row - 1); // 这个safedis需不需要下传 不依托与上层传递时 挖开这层的最少消行数
                                                                                              // 安全距离失误?
                            }
                            else
                            {
                                // 与上一个洞连接 理应传递上一层洞的挖开数
                                //score += W.safecost * safedis;
                                int temp = Math.Max(downcnt - 1, colhight[i] - row - 1) + 1;
                                score        += W.linefull * (fulldig[row + 1] - fulldig[row + temp]);
                                res.linefull += W.linefull * (fulldig[row + 1] - fulldig[row + temp]);
                                nextsafedis   = Math.Max(nextsafedis, downcnt);
                            }
                        }

                        //if (colhight[i] == h + 1) // 这东西有啥用
                        //{
                        //    // 露天
                        //    holecnt++;
                        //}
                        //else if (colhight[i] >= h)
                        //{
                        //    canclear = false;
                        //    holecnt++;
                        //    // 依托于顶部
                        //}
                    }
                }
                // 空格数目
                // 如果顶上也是洞 再减
                fulldig[row] += fulldig[row + 1];
                if (canclear)
                {
                    nextsafedis = safedis + 1; // 思考
                    //safedis = 0;
                }

                for (int i = 0; i < 10; ++i)       //洞的层数 需要增加
                {
                    if (!node.Board.field[row, i]) // colh 检查!! 检查算法
                    {
                        if (colhight[i] >= row + 1)
                        {
                            score    += W.safecost * safedis /**  Math.Max(nextsafedis - safedis, 0)*/;
                            res.safe += W.safecost * safedis; // 似乎有失误
                            if (colhight[i] - row - 1 > (int)(1.5 * (safedis - row - 1)))
                            {
                                score += W.downstack * (colhight[i] - row - 1 - (int)(1.5 * (safedis - row - 1)));
                            }
                            else if (colhight[i] - row - 1 < (int)((safedis - row - 1)))
                            {
                                score += W.downstack * ((int)((safedis - row - 1)) - colhight[i] + row + 1);
                            }
                        }
                    }
                }
            }
            return(score);
        }
예제 #20
0
        public int evalhole(tree node, int[] colhight, int h, ref int score) // 造洞的分析 边缘空洞
        {
            if (h >= 27)
            {
                return(0);         // 或直接对堵洞判断
            }
            bool canclear = true;
            int  holecnt  = 0;


            int downcnt     = evalhole(node, colhight, h + 1, ref score);
            int nextsafedis = downcnt;
            int safedis     = downcnt; // 该行的安全堆叠层数基数 即上一次层的挖开数 + 1

            for (int i = 0; i < 10; ++i)
            {
                if (!node.Board.field[h, i]) // colh
                {
                    if (colhight[i] >= h + 1)
                    {
                        canclear = false; // 最好检测一下是否封闭
                        if (node.Board.field[h + 1, i])
                        {
                            nextsafedis = Math.Max(nextsafedis, downcnt + 1);
                            nextsafedis = Math.Max(nextsafedis, colhight[i] - h - 1); // 这个safedis需不需要下传 不依托与上层传递时 挖开这层的最少消行数
                            // 安全距离失误?
                        }
                        else
                        {
                            // 与上一个洞连接 理应传递上一层洞的挖开数
                            nextsafedis = Math.Max(nextsafedis, downcnt);
                        }
                        holecnt++;
                    }

                    //if (colhight[i] == h + 1) // 这东西有啥用
                    //{
                    //    // 露天
                    //    holecnt++;
                    //}
                    //else if (colhight[i] >= h)
                    //{
                    //    canclear = false;
                    //    holecnt++;
                    //    // 依托于顶部
                    //}
                }
            }
            // 空格数目
            // 如果顶上也是洞 再减

            if (canclear)
            {
                nextsafedis = 0;
                safedis     = 0;
            }

            for (int i = 0; i < 10; ++i)     //洞的层数 需要增加
            {
                if (!node.Board.field[h, i]) // colh 检查!! 检查算法
                {
                    if (colhight[i] >= h + 1)
                    {
                        score += W.safecost * safedis /**  Math.Max(nextsafedis - safedis, 0)*/;
                        if (colhight[i] - h - 1 > (int)(1.3 * (safedis - h - 1)))
                        {
                            score += W.downstack * (colhight[i] - h - 1 - (int)(1.3 * (safedis - h - 1)));
                        }
                    }
                }
            }
            return(nextsafedis);
        }
예제 #21
0
        public tree requset_next_move(int jeo = 0)
        {
            // movereslut
            //if (boardtree.treenode.Count == 0)
            //    return false;

            foreach (tree node in boardtree.treenode)
            {
                node.atkscore = evalweight.evalatkdef(node);

                if (node.attack > 0)
                {
                    node.atkscore += Math.Min(node.def + node.maxdef - jeo, 0) * (-9999);
                }
                else
                {
                    node.atkscore += -9999 * jeo;
                }
            }
            boardtree.treenode.Sort((a, b) =>
            {
                long o = (b.score - a.score);
                var q  = b.maxdepth - a.maxdepth;
                if (q != 0)
                {
                    return(q);
                }
                if (o == 0)
                {
                    return(0);
                }
                return(o > 0 ? 1 : -1);
            });
            // 用不同方式排序
            //int aa = nodedep(boardtree);

            for (int i = 1; i < boardtree.treenode.Count; ++i)
            {
                freenode(boardtree.treenode[i]);
            }
            //aa = nodedep(boardtree);
            if (boardtree.treenode.Count == 0)
            {
                Board.isdead = true;
                return(boardtree);
            }
            boardtree        = boardtree.treenode[0]; // 节点不存在的问题
            boardtree.father = null;
            if (!boardtree.isextend)
            {
                Console.WriteLine("当前节点未扩展");
                boardtree.inplan = true;
            }
            //else
            int lastscore = 498;

            //for (int i = 0, cnt = 0; cnt < 20 && i < boardtree.treenode.Count; ++i)
            //{
            //    if (lastscore == boardtree.treenode[i].res.score) continue;
            //    cnt++;
            //    if (!boardtree.treenode[i].isextend) { boardtree.treenode[i].inplan = true; }
            //    lastscore = boardtree.treenode[i].res.score;
            //}
            //extend_node();
            //   aa = nodedep(boardtree);
            System.GC.Collect();
            //eval.evalfield(boardtree);
            // 重置nodequeue
            return(boardtree);
        }
예제 #22
0
        public void extend_node() // 前两层可能可以放宽要求 // 考虑给tspin单独一层循环
        {
            //
            bool flag = true;

            //while (calcdepth < nextquene.Count - 1) // 能够保持combo的要继续计算 无hold 会少计算一片
            while (true) // 能够保持combo的要继续计算 无hold 会少计算一片
            {
                nodequeue = new List <tree>();
                nodeadd(boardtree);
                if (nodequeue.Count == 0)
                {
                    break;                       // 异步时改为continue;
                }
                calcdepth += 1;
                flag       = false;
                List <tree> nextpiece = new List <tree>();

                int limit = 5;

                int qq = nodecnt(boardtree); // 会浪费时间吗
                limit = Math.Min(nodequeue.Count, 6);
                nodequeue.Sort((a, b) =>
                {
                    long o = (b.score - a.score);
                    var q  = b.maxdepth - a.maxdepth;
                    if (q != 0)
                    {
                        return(q);
                    }
                    if (o == 0)
                    {
                        return(0);
                    }
                    return(o > 0 ? 1 : -1);
                }
                               );
                // 全重置 haishinodequeue
                int            lastscore  = 498;
                HashSet <tree> nodefather = new HashSet <tree>();

                for (int j = 0, cnt = 0; j < nodequeue.Count; ++j) // 剪枝思考 深度和分数的符合思考
                {
                    // cnt < Math.Max(nodequeue.Count / 20 + 1, limit) &&
                    //if (cnt > 10)
                    //{
                    //    //nodequeue[j].useless = true;
                    //    continue;
                    //}



                    if (nextcnt <= nodequeue[j].pieceidx || !nodequeue[j].inplan)
                    {
                        continue;
                    }
                    //nodequeue[j].inplan = false;
                    //if (lastscore == nodequeue[j].res.score)
                    //{
                    //    //bool tag = true;
                    //    //for (int i = 0; i < 10; ++i)
                    //    //{
                    //    //    if (nodequeue[j - 1].Board.column_height[i] != nodequeue[j].Board.column_height[i] )
                    //    //    {
                    //    //        tag = false;
                    //    //    }
                    //    //}
                    //    //if (tag) {
                    //    nodequeue[j].fieldscore = -9999999;
                    //    nodequeue[j].useless = true;
                    //    //}

                    //}
                    if (cnt >= 6)
                    {
                        //nodequeue[j].inplan = false;
                        break;
                    }
                    if (lastscore == nodequeue[j].res.score)
                    {
                        continue;
                    }
                    lastscore = nodequeue[j].res.score;
                    flag      = true;
                    tree node = nodequeue[j];
                    if (node == null || node.useless)
                    {
                        nodequeue[j] = null;
                        continue;
                    }
                    ;  // 等下打上无用标记

                    // 好节点后可跟2层无用节点
                    if (nodequeue[j].father != null)
                    {
                        nodefather.Add(nodequeue[j].father);
                    }


                    cnt++;
                }
                if (nodefather.Count == 0)
                {
                    if (!nodequeue[0].isextend)
                    {
                        nodequeue[0].findalladd(this);
                    }
                    //if (node.isdead) return;
                    nodequeue[0].isextend = true;
                    nodequeue[0].treenode.Sort((a, b) =>
                    {
                        long o = (b.score - a.score);
                        var q  = b.maxdepth - a.maxdepth;
                        if (q != 0)
                        {
                            return(q);
                        }
                        if (o == 0)
                        {
                            return(0);
                        }
                        return(o > 0 ? 1 : -1);
                    });
                }

                foreach (tree father in nodefather)
                {
                    for (int j = 0, cnt = 0; j < father.treenode.Count; ++j)
                    {
                        if (nextcnt <= father.treenode[j].pieceidx || !father.treenode[j].inplan)
                        {
                            continue;
                        }
                        //father.treenode[j].inplan = false;

                        if (cnt >= 6)
                        {
                            //nodequeue[j].inplan = false;
                            break;
                        }
                        if (lastscore == father.treenode[j].res.score)
                        {
                            continue;
                        }
                        lastscore = father.treenode[j].res.score;
                        flag      = true;
                        tree node = father.treenode[j];
                        //if (node == null || node.useless)
                        //{
                        //    nodequeue[j] = null;
                        //    continue;

                        //};
                        cnt++;
                        if (!node.isextend)
                        {
                            node.findalladd(this);
                        }
                        //if (node.isdead) return;
                        node.isextend = true;
                        node.treenode.Sort((a, b) =>
                        {
                            long o = (b.score - a.score);
                            var q  = b.maxdepth - a.maxdepth;
                            if (q != 0)
                            {
                                return(q);
                            }
                            if (o == 0)
                            {
                                return(0);
                            }
                            return(o > 0 ? 1 : -1);
                        });
                    }
                }
                foreach (tree node in nodequeue)
                {
                    node.inplan = false;
                }
            }
        }
예제 #23
0
        public evalresult evalfield(tree node)
        {
            int        score      = 0;
            evalresult evalresult = new evalresult();

            if (node.finmino.minopos.x >= 18)
            {
                node.isdead      = true;
                evalresult.score = -99999999;
                return(evalresult);
            }
            int[] colh = new int[node.Board.column_height.Length + 2];
            for (int i = 0; i < node.Board.column_height.Length; ++i)
            {
                colh[i + 1] = node.Board.column_height[i];
            }

            colh[0] = colh[colh.Length - 1] = 60;
            int height = Math.Max(Math.Max(colh[4], colh[5]), Math.Max(colh[6], colh[7]));

            // 高度评分

            evalresult.height = height * W.height[height / 7];
            score            += height * W.height[height / 7];

            // 场地最低点
            int minhigh = 40;

            for (int i = 1; i < colh.Length - 1; ++i)
            {
                minhigh = Math.Min(minhigh, colh[i]);
            }


            int minidx = 1; // 场地最低点
            int mindel = 0;

            for (int i = 1; i < colh.Length - 1; ++i)
            {
                if (minhigh == colh[i] && Math.Min(colh[i - 1], colh[i + 1]) - colh[i] >= mindel)
                {
                    minidx = i;
                    mindel = Math.Min(colh[i - 1], colh[i + 1]) - colh[i];
                }
            }
            evalresult.minidx  = minidx;
            evalresult.minhigh = colh[minidx];
            score += W.dephigh * colh[minidx];
            score += W.col_minhigh[minidx - 1] * Math.Min(mindel, 5);
            if (mindel > 7)
            {
                score -= Math.Abs(W.col_minhigh[minidx - 1]) * mindel;
            }
            // 长洞(?
            // 深洞本身高度扣分 过深扣分

            Queue <int> deepholequeue = new Queue <int>();

            for (int i = 1; i < colh.Length - 1; ++i)
            {
                int left  = colh[i - 1] - colh[i];
                int right = colh[i + 1] - colh[i];

                if (left >= 2 && right >= 2) // 都大于5制裁
                {
                    if (i != minidx || minhigh != 0)
                    {
                        //score += W.deephole * Math.Min(left, right);
                        //evalresult.deephole += W.deephole * Math.Min(left, right); // duojinzhicai
                        deepholequeue.Enqueue(Math.Min(left, right) /**+ Math.Max(left, right) / 2.0**/);
                    }
                }
            }

            foreach (int a in deepholequeue)
            {
                //score += W.deephole * a; // 加入深洞底部厚度
                score += W.deephole * a * deepholequeue.Count;
                evalresult.deephole += W.deephole * a * deepholequeue.Count; // duojinzhicai
            }
            deepholequeue.Clear();

            // 凹形判定 // 单长洞考虑不扣


            int lefidx = minidx - 1, ritidx = minidx + 1;
            int lefhig = colh[lefidx], rithig = colh[ritidx];



            while (lefidx > 1)
            {
                if (colh[lefidx - 1] >= lefhig) // 大于太多也扣分(?
                {
                    lefhig = colh[lefidx - 1];
                }
                else
                {
                    evalresult.wide += W.wide * (lefhig - colh[lefidx - 1]);
                    score           += W.wide * (lefhig - colh[lefidx - 1]);
                }
                lefidx -= 1;
            }

            while (ritidx < colh.Length - 1)
            {
                if (colh[ritidx + 1] >= rithig)
                {
                    rithig = colh[ritidx + 1];
                }
                else
                {
                    evalresult.wide += W.wide * (rithig - colh[ritidx + 1]);
                    score           += W.wide * (rithig - colh[ritidx + 1]);
                }
                ritidx += 1;
            }

            // 连续性判定

            for (int i = 2; i < colh.Length - 1; ++i)
            {
                int del;

                del = colh[i] - colh[i - 1];
                //right = colh[i + 1] - colh[i];
                //if (left >= 3 && right >= 3)

                score += Math.Abs(del) * W.deltcol;
                evalresult.Continuity += Math.Abs(del) * W.deltcol;
            } // 连续性



            double avg = 0;

            for (int i = 1; i < colh.Length - 1; ++i)
            {
                avg += colh[i];
            } // 平均值

            // 是否减去最低点
            //avg = (avg - minhigh) / (node.Board.column_height.Length - 1);
            avg /= node.Board.column_height.Length;
            // 方差 标准差
            double bus_sq = 0, bus = 0;

            for (int i = 1; i < colh.Length - 1; ++i)
            {
                bus_sq += Math.Pow(colh[i] - avg, 2);
            }
            //bus_sq -= Math.Pow(minhigh - avg, 2);
            //bus = Math.Sqrt(bus_sq);
            // 方差 标准差

            //score += bus * W.bus + bus_sq * W.bus_sq;
            //score += (int)(bus * W.bus);
            //

            // 奇偶性

            int parity = evalparity(node);

            score             += parity * W.parity;
            evalresult.parity += parity * W.parity;
            evalresult.hole    = evalhole(node, ref evalresult);
            //evalhole(node, node.Board.column_height, 0, ref evalresult.hole);
            score           += evalresult.hole;
            evalresult.score = score;



            return(evalresult);
        } //场地评分