예제 #1
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);
        }
예제 #2
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);
                }
            }
        }
예제 #3
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);
        } //场地评分