zoukankan      html  css  js  c++  java
  • botzone Tetris2

    为了证明窝最近没有颓废

    (并且为了多骗点访问量

    游戏链接:https://botzone.org/game/Tetris2

    大概就是先写个估价,然后剪剪枝搜它4步。

    #include<iostream>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<cstdlib>
    #include<ctime>
    #include<cstring>
    #define INF 1e180
    using namespace std;
     
    #define MAPWIDTH 10
    #define MAPHEIGHT 20
     
    //W1 防长条
    //W2、W3 优先放两边 
    //W4 forfuture
    //W5、W6 封顶
    //W7 多给长条 
    //W8 maxheiht 
    //W9、13 拒绝不可达行 
    //W10 高度系数 
    //W11 unreachable 
    //W12 奖励行 
    const int GO[7][4]={{1,1,1,1},{1,1,1,1},{1,1,0,0},{1,1,0,0},{1,1,1,1},{1,1,0,0},{1,0,0,0}};
    const bool TYPEwork[7]={0,0,0,0,1,1,0};
    const int M_DEEP=4,E_DEEP=2,RE=0,intwo=1;
    double W1=1.2,W2=0.998,W3=0.98,W4=3,W5=1.4,W6=1,prize=0,W7=30,W8=10,W9=1,W10=100,W11=2,W12=intwo?100:0,W13=1.4,paper=5;
    int Work_num=3,Type_num=3;
    #define CONDITION (x==5&&y==3&&o==1)||(x==1&&y==2&&o==1)
    // 我所在队伍的颜色(0为红,1为蓝,仅表示队伍,不分先后)
    int currBotColor;
    int enemyColor;
     
    // 先y后x,记录地图状态,0为空,1为以前放置,2为刚刚放置,负数为越界
    // (2用于在清行后将最后一步撤销再送给对方)
    int gridInfo[2][MAPHEIGHT + 2][MAPWIDTH + 2] = { 0 };
     
    // 代表分别向对方转移的行
    int trans[2][6][MAPWIDTH + 2] = { 0 };
     
    // 转移行数
    int transCount[2] = { 0 };
     
    // 运行eliminate后的当前高度
    int maxHeight[2] = { 0 };
     
    // 总消去行数的分数之和
    int elimTotal[2] = { 0 };
    
    // 连续几回合发生过消去了
    int elimCombo[2] = { 0 };
     
    // 一次性消去行数对应分数
    const int elimBonus[] = { 0, 1, 3, 5, 7 };
     
    // 给对应玩家的各类块的数目总计
    int typeCountForColor[2][7] = { 0 };
    int turnID, blockType;
    int nextTypeForColor[2];
    double MMH=0;
    int debug;
    #ifndef _BOTZONE_ONLINE
        FILE *DEBUG=fopen("b.out","w");
    #endif
    bool forsize[MAPHEIGHT+2][MAPWIDTH+2][4];
    const int blockShape[7][4][8] = {
        { { 0,0,1,0,-1,0,-1,-1 },{ 0,0,0,1,0,-1,1,-1 },{ 0,0,-1,0,1,0,1,1 },{ 0,0,0,-1,0,1,-1,1 } },
        { { 0,0,-1,0,1,0,1,-1 },{ 0,0,0,-1,0,1,1,1 },{ 0,0,1,0,-1,0,-1,1 },{ 0,0,0,1,0,-1,-1,-1 } },
        { { 0,0,1,0,0,-1,-1,-1 },{ 0,0,0,1,1,0,1,-1 },{ 0,0,-1,0,0,1,1,1 },{ 0,0,0,-1,-1,0,-1,1 } },
        { { 0,0,-1,0,0,-1,1,-1 },{ 0,0,0,-1,1,0,1,1 },{ 0,0,1,0,0,1,-1,1 },{ 0,0,0,1,-1,0,-1,-1 } },
        { { 0,0,-1,0,0,1,1,0 },{ 0,0,0,-1,-1,0,0,1 },{ 0,0,1,0,0,-1,-1,0 },{ 0,0,0,1,1,0,0,-1 } },
        { { 0,0,0,-1,0,1,0,2 },{ 0,0,1,0,-1,0,-2,0 },{ 0,0,0,1,0,-1,0,-2 },{ 0,0,-1,0,1,0,2,0 } },
        { { 0,0,0,1,-1,0,-1,1 },{ 0,0,-1,0,0,-1,-1,-1 },{ 0,0,0,-1,1,-0,1,-1 },{ 0,0,1,0,0,1,1,1 } }
    }; // 7种形状(长L| 短L| 反z| 正z| T| 直一| 田格),4种朝向(上左下右),8:每相邻的两个分别为x,y
    
    const int rotateBlank[7][4][10] = {
        { { 1,1,0,0 },{ -1,1,0,0 },{ -1,-1,0,0 },{ 1,-1,0,0 } },
        { { -1,-1,0,0 },{ 1,-1,0,0 },{ 1,1,0,0 },{ -1,1,0,0 } },
        { { 1,1,0,0 },{ -1,1,0,0 },{ -1,-1,0,0 },{ 1,-1,0,0 } },
        { { -1,-1,0,0 },{ 1,-1,0,0 },{ 1,1,0,0 },{ -1,1,0,0 } },
        { { -1,-1,-1,1,1,1,0,0 },{ -1,-1,-1,1,1,-1,0,0 },{ -1,-1,1,1,1,-1,0,0 },{ -1,1,1,1,1,-1,0,0 } },
        { { 1,-1,-1,1,-2,1,-1,2,-2,2 } ,{ 1,1,-1,-1,-2,-1,-1,-2,-2,-2 } ,{ -1,1,1,-1,2,-1,1,-2,2,-2 } ,{ -1,-1,1,1,2,1,1,2,2,2 } },
        { { 0,0 },{ 0,0 } ,{ 0,0 } ,{ 0,0 } }
    }; // 旋转的时候需要为空的块相对于旋转中心的坐标
     
    class Tetris
    {
    public:
        const int blockType;   // 标记方块类型的序号 0~6
        int blockX;            // 旋转中心的x轴坐标
        int blockY;            // 旋转中心的y轴坐标
        int orientation;       // 标记方块的朝向 0~3
        const int(*shape)[8]; // 当前类型方块的形状定义
     
        int color;
     
        Tetris(int t, int color) : blockType(t), shape(blockShape[t]), color(color)
        { }
     
        inline Tetris &set(int x = -1, int y = -1, int o = -1)
        {
            blockX = x == -1 ? blockX : x;
            blockY = y == -1 ? blockY : y;
            orientation = o == -1 ? orientation : o;
            return *this;
        }
     
        // 判断当前位置是否合法
        inline bool isValid(int x = -1, int y = -1, int o = -1)
        {
            x = x == -1 ? blockX : x;
            y = y == -1 ? blockY : y;
            o = o == -1 ? orientation : o;
            if (o < 0 || o > 3)
                return false;
     
            int i, tmpX, tmpY;
            for (i = 0; i < 4; i++)
            {
                tmpX = x + shape[o][2 * i];
                tmpY = y + shape[o][2 * i + 1];
                if (tmpX < 1 || tmpX > MAPWIDTH ||
                    tmpY < 1 || tmpY > MAPHEIGHT ||
                    gridInfo[color][tmpY][tmpX] != 0)
                    return false;
            }
            return true;
        }
     
        // 判断是否落地
        inline bool onGround()
        {
            if (isValid() && !isValid(-1, blockY - 1))
                return true;
            return false;
        }
     
        // 将方块放置在场地上
        inline bool place()
        {
            if (!onGround())
                return false;
     
            int i, tmpX, tmpY;
            for (i = 0; i < 4; i++)
            {
                tmpX = blockX + shape[orientation][2 * i];
                tmpY = blockY + shape[orientation][2 * i + 1];
                gridInfo[color][tmpY][tmpX] = 2;
            }
            return true;
        }
     
        // 检查能否逆时针旋转自己到o
        inline bool rotation(int o)
        {
            if (o < 0 || o > 3)
                return false;
     
            if (orientation == o)
                return true;
     
            int fromO = orientation;
            int i, blankX, blankY;
            while (true)
            {
                if (!isValid(-1, -1, fromO))
                    return false;
     
                if (fromO == o)
                    break;
                    
                // 检查旋转碰撞
                if (intwo) for (i = 0; i < 5; i++) {
                    blankX = blockX + rotateBlank[blockType][fromO][2 * i];
                    blankY = blockY + rotateBlank[blockType][fromO][2 * i + 1];
                    if (blankX == blockX && blankY == blockY)
                        break;
                    if (gridInfo[color][blankY][blankX] != 0)
                        return false;
                }
     
                fromO = (fromO + 1) % 4;
            }
            return true;
        }
    };
     
    // 围一圈护城河
    void init()
    {
        int i;
        for (i = 0; i < MAPHEIGHT + 2; i++)
        {
            gridInfo[1][i][0] = gridInfo[1][i][MAPWIDTH + 1] = -2;
            gridInfo[0][i][0] = gridInfo[0][i][MAPWIDTH + 1] = -2;
        }
        for (i = 0; i < MAPWIDTH + 2; i++)
        {
            gridInfo[1][0][i] = gridInfo[1][MAPHEIGHT + 1][i] = -2;
            gridInfo[0][0][i] = gridInfo[0][MAPHEIGHT + 1][i] = -2;
        }
    }
     
    inline bool isValid(int map[MAPHEIGHT+2][MAPWIDTH+2],int type,int x,int y,int o){
        if (o < 0 || o > 3)    return false;
     
        int i, tmpX, tmpY;
        for (i = 0; i < 4; i++){
            tmpX = x + blockShape[type][o][2 * i];
            tmpY = y + blockShape[type][o][2 * i + 1];
            if (tmpX < 1 || tmpX > MAPWIDTH ||tmpY < 1 || tmpY > MAPHEIGHT ||map[tmpY][tmpX] != 0)return false;
        }
        return true;
    }
    inline bool onGround(int map[MAPHEIGHT+2][MAPWIDTH+2],int type,int x,int y,int o){
        if (isValid(map,type,x,y,o) && !isValid(map,type,x,y-1,o))
            return true;
        return false;
    }
    inline bool rotation(int map[MAPHEIGHT+2][MAPWIDTH+2],int type,int x,int y,int o){
        if (intwo) for (int i = 0; i < 5; i++) {
            int blankX = x + rotateBlank[type][o][2 * i];
            int blankY = y + rotateBlank[type][o][2 * i + 1];
            if (blankX == x && blankY == y) break;
            if (map[blankY][blankX])
            return 0;
        }
        return 1;
    }
    namespace Util
    {
     
     
        // 检查能否从场地顶端直接落到当前位置
        inline bool checkDirectDropTo(int map[MAPHEIGHT+2][MAPWIDTH+2], int blockType, int x, int y, int o)
        {
            const int *def = blockShape[blockType][o];
            for (; y <= MAPHEIGHT; y++)
                for (int i = 0; i < 4; i++)
                {
                    int _x = def[i * 2] + x, _y = def[i * 2 + 1] + y;
                    if (_y > MAPHEIGHT)
                        continue;
                    if (_y < 1 || _x < 1 || _x > MAPWIDTH || map[_y][_x])
                        return false;
                }
            return true;
        }
        void dfs(int map[MAPHEIGHT+2][MAPWIDTH+2],bool bo[MAPHEIGHT+2][MAPWIDTH+2][4],int type,int x,int y,int o){
            //cout<<x<<y<<o<<endl;
            if (!isValid(map,type,x,y,o)) return;
            if (bo[y][x][o]) return;
            //if (debug) fprintf(DEBUG,"O_O::::%d %d %d %d %d
    ",x,y,o,bo[y][x][o],sizeof(bo));
            bo[y][x][o]=1;
            dfs(map,bo,type,x-1,y,o);dfs(map,bo,type,x+1,y,o);dfs(map,bo,type,x,y-1,o);
            if (rotation(map,type,x,y,o))dfs(map,bo,type,x,y,(o+1)%4);
        }
        void init(int map[MAPHEIGHT+2][MAPWIDTH+2],bool bo[MAPHEIGHT+2][MAPWIDTH+2][4],int type,bool de=0){
            debug=de;
            memset(bo,0,sizeof(forsize));
            //if (debug) fprintf(DEBUG,"%d
    ",type);
            for (int o=0;o<4;o++)
            for (int x=1;x<=MAPWIDTH; x++){
                if (checkDirectDropTo(map,type,x,MAPHEIGHT,o)) dfs(map,bo,type,x,MAPHEIGHT,o);
                if (checkDirectDropTo(map,type,x,MAPHEIGHT-1,o)) dfs(map,bo,type,x,MAPHEIGHT-1,o);
                if (type==5) if (checkDirectDropTo(map,type,x,MAPHEIGHT-2,o)) dfs(map,bo,type,x,MAPHEIGHT-2,o);
            }
            
        }
        // 检查能否从场地顶端直接落到当前位置
        inline bool checkDirectDropTo(int color, int blockType, int x, int y, int o)
        {
            auto &def = blockShape[blockType][o];
            for (; y <= MAPHEIGHT; y++)
                for (int i = 0; i < 4; i++)
                {
                    int _x = def[i * 2] + x, _y = def[i * 2 + 1] + y;
                    if (_y > MAPHEIGHT)
                        continue;
                    if (_y < 1 || _x < 1 || _x > MAPWIDTH || gridInfo[color][_y][_x])
                        return false;
                }
            return true;
        }
     
        // 消去行
        void eliminate(int color)
        {
            int &count = transCount[color] = 0;
            int i, j, emptyFlag, fullFlag, firstFull = 1, hasBonus = 0;
            maxHeight[color] = MAPHEIGHT;
            for (i = 1; i <= MAPHEIGHT; i++)
            {
                emptyFlag = 1;
                fullFlag = 1;
                for (j = 1; j <= MAPWIDTH; j++)
                {
                    if (gridInfo[color][i][j] == 0)
                        fullFlag = 0;
                    else
                        emptyFlag = 0;
                }
                if (fullFlag)
                {
                    if (intwo&&firstFull && ++elimCombo[color] >= 3)
                    {
                        // 奖励行
                        for (j = 1; j <= MAPWIDTH; j++)
                            trans[color][count][j] = gridInfo[color][i][j] == 1 ? 1 : 0;
                        count++;
                        hasBonus = 1;
                    }
                    firstFull = 0;
                    for (j = 1; j <= MAPWIDTH; j++)
                    {
                        // 注意这里只转移以前的块,不包括最后一次落下的块(“撤销最后一步”)
                        trans[color][count][j] = gridInfo[color][i][j] == 1 ? 1 : 0;
                        gridInfo[color][i][j] = 0;
                    }
                    count++;
                }
                else if (emptyFlag)
                {
                    maxHeight[color] = i - 1;
                    break;
                }
                else
                    for (j = 1; j <= MAPWIDTH; j++)
                    {
                        gridInfo[color][i - count + hasBonus][j] =
                            gridInfo[color][i][j] > 0 ? 1 : gridInfo[color][i][j];
                        if (count)
                            gridInfo[color][i][j] = 0;
                    }
            }
            if (count == 0)
                elimCombo[color] = 0;
            maxHeight[color] -= count - hasBonus;
            elimTotal[color] += elimBonus[count];
        }
     
        // 转移双方消去的行,返回-1表示继续,否则返回输者
        int transfer()
        {
            int color1 = 0, color2 = 1;
            if (transCount[color1] == 0 && transCount[color2] == 0)
                return -1;
            if (transCount[color1] == 0 || transCount[color2] == 0)
            {
                if (transCount[color1] == 0 && transCount[color2] > 0)
                    swap(color1, color2);
                int h2;
                maxHeight[color2] = h2 = maxHeight[color2] + transCount[color1];
                if (h2 > MAPHEIGHT)
                    return color2;
                int i, j;
     
                for (i = h2; i > transCount[color1]; i--)
                    for (j = 1; j <= MAPWIDTH; j++)
                        gridInfo[color2][i][j] = gridInfo[color2][i - transCount[color1]][j];
     
                for (i = transCount[color1]; i > 0; i--)
                    for (j = 1; j <= MAPWIDTH; j++)
                        gridInfo[color2][i][j] = trans[color1][i - 1][j];
                return -1;
            }
            else
            {
                int h1, h2;
                maxHeight[color1] = h1 = maxHeight[color1] + transCount[color2];//从color1处移动count1去color2
                maxHeight[color2] = h2 = maxHeight[color2] + transCount[color1];
     
                if (h1 > MAPHEIGHT) return color1;
                if (h2 > MAPHEIGHT) return color2;
     
                int i, j;
                for (i = h2; i > transCount[color1]; i--)
                    for (j = 1; j <= MAPWIDTH; j++)
                        gridInfo[color2][i][j] = gridInfo[color2][i - transCount[color1]][j];
     
                for (i = transCount[color1]; i > 0; i--)
                    for (j = 1; j <= MAPWIDTH; j++)
                        gridInfo[color2][i][j] = trans[color1][i - 1][j];
     
                for (i = h1; i > transCount[color2]; i--)
                    for (j = 1; j <= MAPWIDTH; j++)
                        gridInfo[color1][i][j] = gridInfo[color1][i - transCount[color2]][j];
     
                for (i = transCount[color2]; i > 0; i--)
                    for (j = 1; j <= MAPWIDTH; j++)
                        gridInfo[color1][i][j] = trans[color2][i - 1][j];
     
                return -1;
            }
        }
     
        // 颜色方还能否继续游戏
        inline bool canPut(int color, int blockType)
        {
            Tetris t(blockType, color);
            for (int y = MAPHEIGHT; y >= 1; y--)
                for (int x = 1; x <= MAPWIDTH; x++)
                    for (int o = 0; o < 4; o++)
                    {
                        t.set(x, y, o);
                        if (t.isValid() && checkDirectDropTo(color, blockType, x, y, o))
                            return true;
                    }
            return false;
        }
     
        // 打印场地用于调试
        inline void printField()
        {
    #ifndef _BOTZONE_ONLINE
            static const char *i2s[] = {
                "~~",
                "~~",
                "  ",
                "[]",
                "##"
            };
            cout << "~~:墙,[]:块,##:新块" << endl;
            for (int y = MAPHEIGHT + 1; y >= 0; y--)
            {
                for (int x = 0; x <= MAPWIDTH + 1; x++)
                    cout << i2s[gridInfo[0][y][x] + 2];
                for (int x = 0; x <= MAPWIDTH + 1; x++)
                    cout << i2s[gridInfo[1][y][x] + 2];
                cout << endl;
            }
    #endif
        }
    }
    int sum_n[21]={0,1,3,6,10,15,21,28,36,45,55,66,78,91,105,120,136,153,171,190,210};
    double GetBoardTransitions(int map[MAPHEIGHT+2][MAPWIDTH+2]){
        int mmh=0;
        
        for (int _y=1;_y<=MAPHEIGHT;_y++)
        for (int _x=1;_x<MAPWIDTH;_x++)
        if ((map[_y][_x]&&!map[_y][_x+1])||(!map[_y][_x]&&map[_y][_x+1])) mmh++;
        
        
        for (int _y=1;_y<MAPHEIGHT;_y++)
        for (int _x=1;_x<=MAPWIDTH;_x++)
        if ((map[_y][_x]&&!map[_y+1][_x])||(!map[_y][_x]&&map[_y+1][_x])) mmh++;
        
        return mmh;
    }
    double GetBoardBuriedHoles(int map[MAPHEIGHT+2][MAPWIDTH+2]){
        int mmh=0;
        
        for (int _x=1;_x<=MAPWIDTH;_x++){
            int _y;
            for (_y=MAPHEIGHT;_y;_y--) if (map[_y][_x]) break;
            for (;_y;_y--) if (!map[_y][_x]) mmh++;
        }
        
        return mmh;
    }
    double GetBoardWells(int map[MAPHEIGHT+2][MAPWIDTH+2]){
        double mmh=0,W;
        
        for (int _x=1;_x<=MAPWIDTH;_x++){
            int _y,wells=0,f=0;W=1.5;
            for (_y=MAPHEIGHT;_y>=0;_y--){
                if(map[_y][_x]==0){
                    if(map[_y][_x-1]!=0&&map[_y][_x+1]!=0) wells++;
                }else{
                    mmh+=sum_n[wells]*W;
                    wells=0;
                    if (f) W+=0.1;else W=0.8;
                    f=1;
                }
            }
        }
        
        return mmh;
    }
    int qx[300],qy[300],l,r;
    const int f[2][4]={{0,0,1,-1},{1,-1,0,0}};
    inline int bfs(int map[MAPHEIGHT+2][MAPWIDTH+2]){
        l=r=0;
        bool bo[MAPHEIGHT+2][MAPWIDTH+2];
        for (int _x=1;_x<=MAPWIDTH;_x++)
        for (int _y=1;_y<=MAPHEIGHT;_y++) bo[_y][_x]=0;
        
        for (int _x=1;_x<=MAPWIDTH;_x++) if (!map[MAPHEIGHT][_x]) qx[r]=_x,qy[r]=MAPHEIGHT,r++;
        while (l<r){
            for (int i=0;i<4;i++)
            if (!map[qy[l]+f[0][i]][qx[l]+f[1][i]]&&!bo[qy[l]+f[0][i]][qx[l]+f[1][i]])
            bo[qy[l]+f[0][i]][qx[l]+f[1][i]]=1,qy[r]=qy[l]+f[0][i],qx[r]=qx[l]+f[1][i],r++;
            l++;
        }
        double mmh=0;
        for (int _x=1;_x<=MAPWIDTH;_x++)
        for (int _y=1;_y<=MAPHEIGHT;_y++)
        mmh+=(!map[_y][_x])&&(!bo[_y][_x]);
        
        return mmh;
    }
    int finalX, finalY, finalO,_finalX,_finalY,_finalO;
    double work(int _map[MAPHEIGHT+2][MAPWIDTH+2],int ty,int deepth,double forfuture,bool currBotColor,int eRound);
    bool canreach[7][MAPHEIGHT+2][MAPWIDTH+2];
    double Mavis(int _map[MAPHEIGHT+2][MAPWIDTH+2],int type,int x,int y,int o,int deepth,double MMH,bool currBotColor,int eRound){
        bool _bo[MAPHEIGHT+2][MAPWIDTH+2][4],cell_reach[MAPHEIGHT+2][MAPWIDTH+2];
        int map[MAPHEIGHT+2][MAPWIDTH+2];
        int emptynum[MAPHEIGHT+2],sta[MAPHEIGHT+2];
        bool reach[MAPHEIGHT+2];
        double value[MAPHEIGHT+2][MAPWIDTH+2];
        memset(emptynum,0,sizeof(emptynum));
        memset(sta,0,sizeof(sta));
        memset(reach,1,sizeof(reach));
        memset(cell_reach,0,sizeof(cell_reach));
        for (int _y=0;_y<=MAPHEIGHT+1;_y++)
        for (int _x=0;_x<=MAPWIDTH+1;_x++) map[_y][_x]=_map[_y][_x];
        double holenum=1+prize*10;
        int ErodedPieceCellsMetric,erodedShape=0;
        
        
        bool myCount[7]={0,0,0,0,0,0,0};
        for (int i=0;i<7;i++){
            myCount[i]=1;
            for (int j=0;j<7;j++)
            if (i!=j&&typeCountForColor[currBotColor][i]+1-typeCountForColor[currBotColor][j]>2) myCount[i]=0;
        }
        for (int i=0;i<4;i++){
            int tmpX=x+blockShape[type][o][2*i];
            int tmpY=y+blockShape[type][o][2*i+1];
            map[tmpY][tmpX]=3;
        }
        
        
        int pop=0,O_O=0;
        for (int _y=1;_y<=MAPHEIGHT;_y++){
            int _x=1;
            for (_x=1;_x<=MAPWIDTH;_x++)
            if (!map[_y][_x]) break;
            if (_x==MAPWIDTH+1){
                holenum-=prize;pop++;
                for (_x=1;_x<=MAPWIDTH;_x++) erodedShape+=map[_y][_x]==3,map[_y][_x]=-1;
            }
        }
        ErodedPieceCellsMetric=pop*erodedShape;
        for (int _x=1;_x<=MAPWIDTH;_x++){
            int p=1;
            for (int i=1;i<=MAPHEIGHT;i++)
            if (map[i][_x]!=-1) map[p][_x]=map[i][_x],p++;
            for (;p<=MAPHEIGHT;p++) map[p][_x]=0;
        }
        
        double P_P=0;
        int max=0;
        for (int _x=1;_x<=MAPWIDTH;_x++){
            int _y=MAPHEIGHT;
            for (;_y;_y--) if (map[_y][_x]) break;
            double cost=_y*_y;
            int u=x<6?x:x-5;
            cost*=pow(1.05,u);
            P_P+=cost;
            if (max<_y) max=_y;
        }
        int BoardTransitions=GetBoardTransitions(map),BuriedHoles=GetBoardBuriedHoles(map),Wells=GetBoardWells(map),Bfs=bfs(map);
        
        holenum=sqrt(P_P)/3+2.5*max+2*BoardTransitions+7*BuriedHoles+2*Bfs+Wells;
        
        if (pop&&eRound>1) holenum-=W12;
        
    #ifndef _BOTZONE_ONLINE
        if (CONDITION) fprintf(DEBUG,">_<%d %d %d %d
    ",x,y,o,deepth);
        if (CONDITION){
            for (int y=MAPHEIGHT;y;y--,fprintf(DEBUG,"
    "))
            for (int x=1;x<=MAPWIDTH;x++)
            fprintf(DEBUG,"%c",map[y][x]?'#':'.');
            fprintf(DEBUG,"%d %d %d %d %d %lf
    ",x,y,o,deepth,type,holenum);
            fprintf(DEBUG,"ErodedPieceCellsMetric:%d
    ",ErodedPieceCellsMetric);
            fprintf(DEBUG,"BoardTransitions:%d
    ",BoardTransitions);
            fprintf(DEBUG,"BuriedHoles:%d
    ",BuriedHoles);
            fprintf(DEBUG,"Wells:%d
    
    ",Wells);
        }
    #endif
        //printf("%d %d %d %d
    ",x,y,o,deepth);
        if (deepth){
            if (deepth==1){
                double forfuture=-INF,test;
                for (int i=0;i<7;i++)
                if (myCount[i]){
                    typeCountForColor[currBotColor][i]++;
                    if ((test=work(map,i,deepth-1,forfuture,currBotColor,pop?eRound+1:0))>forfuture) forfuture=test;
                    typeCountForColor[currBotColor][i]--;
                }
                if (forfuture>=INF-1) return INF-1;
                holenum+=forfuture*W4;
                //printf("%d %d %d %lf %lf
    ",x,y,o,holenum,forfuture);
            }else{
                int type_num=Type_num;
                int TY[type_num];
                double Work[type_num];
                double forfuture=-INF,test;
                for (int j=0;j<type_num;j++) Work[j]=-INF;
                for (int i=0,j;i<7;i++)
                if (myCount[i]){
                    typeCountForColor[currBotColor][i]++;
                    
                    test=work(map,i,0,forfuture,currBotColor,pop?eRound+1:0);
                    for (j=0;j<type_num;j++) if (Work[j]<test) break;
                    if (j<type_num){
                        for (int k=type_num-1;k>j;k--) TY[k]=TY[k-1],Work[k]=Work[k-1];
                        Work[j]=test;TY[j]=i;
                    }
                    
                    typeCountForColor[currBotColor][i]--;
                }
                
                
                for (int i=0;i<type_num;i++)
                if (Work[i]>-INF+1){
                    if (Work[0]<0){
                        if (Work[i]<Work[0]*1.05-1) break;
                    }else if (Work[i]<Work[0]*0.95-1) break;
                    typeCountForColor[currBotColor][TY[i]]++;
                    if ((test=work(map,TY[i],deepth-1,forfuture,currBotColor,pop?eRound+1:0))>forfuture) forfuture=test;
                    typeCountForColor[currBotColor][TY[i]]--;
                }
                /*printf("%d
    ",type_num);
                for (int i=0;i<type_num;i++) printf("%lf ",Work[i]);puts("");
                */
                if (forfuture>=INF-1) return INF-1;
                holenum+=forfuture*W4;
                //printf("%d %d %d %lf %lf
    ",x,y,o,holenum,forfuture);
            }
        }
        holenum-=ErodedPieceCellsMetric;
        
        return holenum;
    }
    double work(int _map[MAPHEIGHT+2][MAPWIDTH+2],int ty,int deepth,double forfuture,bool currBotColor,int eRound){
        bool bo[MAPHEIGHT+2][MAPWIDTH+2][4];
        int fx=-1,fy,fo,i,work_num=Work_num;
        /*fprintf(DEBUG,">_<%d
    ",ty);
        for (int y=MAPHEIGHT;y;y--,fprintf(DEBUG,"
    "))
        for (int x=1;x<=MAPWIDTH;x++)
        fprintf(DEBUG,"%c",_map[y][x]?'#':'.');*/
        double MMH=INF,test;
        Util::init(_map,bo,ty);
        if (deepth){
            double work[work_num];
            int XX[work_num],YY[work_num],OO[work_num];
            for (i=0;i<work_num;i++) work[i]=INF;
            for (int y = 1; y <= MAPHEIGHT; y++)
            for (int x = 1; x <= MAPWIDTH; x++)
            for (int o = 0; o < 4; o++)
            if (GO[ty][o]&&onGround(_map,ty,x,y,o)&&bo[y][x][o]){
                test=Mavis(_map,ty,x,y,o,0,MMH,currBotColor,eRound);
                for (i=0;i<work_num;i++) if (test<work[i]) break;
                if (i==work_num) continue;
                for (int j=work_num-1;j>i;j--) work[j]=work[j-1],XX[j]=XX[j-1],YY[j]=YY[j-1],OO[j]=OO[j-1];
                work[i]=test;XX[i]=x;YY[i]=y;OO[i]=o;
            }
            for (int i=0;i<work_num;i++)
            if (work[i]<INF-1){
                if (work[0]<0){
                    if (work[i]>work[0]*0.8+10) break;
                }else if (work[i]>work[0]*1.2+10) break;
                if ((test=Mavis(_map,ty,XX[i],YY[i],OO[i],deepth,MMH,currBotColor,eRound))<MMH){
                    fx=XX[i];fy=YY[i];fo=OO[i];
                    MMH=test;
                    if (MMH<forfuture) return MMH;
                }
            }
            if (fx==-1) fx=XX[0],fy=YY[0],fo=OO[0];
        }else{
            for (int y = 1; y <= MAPHEIGHT; y++)
            for (int x = 1; x <= MAPWIDTH; x++)
            for (int o = 0; o < 4; o++)
            if (GO[ty][o]&&onGround(_map,ty,x,y,o)&&bo[y][x][o]&&(test=Mavis(_map,ty,x,y,o,0,INF,currBotColor,eRound))<MMH){
                fx=x;
                fy=y;
                fo=o;
                MMH=test;
                if (MMH<forfuture) return MMH;
            }
        }
        finalX=fx;finalY=fy;finalO=fo;
        //printf("%d %d %d %d %d
    ",ty,deepth,fx,fy,fo);
        //fprintf(DEBUG,"===================================%d %d %d %d %lf
    ",ty,finalX,finalY,finalO,MMH);
        return MMH;
    }
    double gain(int _map[MAPHEIGHT+2][MAPWIDTH+2],int x,int y,int o,int ty,int _ty,bool currBotColor,int DEEPTH){
        int map[MAPHEIGHT+2][MAPWIDTH+2];
        for (int _y=0;_y<=MAPHEIGHT+1;_y++)
        for (int _x=0;_x<=MAPWIDTH+1;_x++) map[_y][_x]=_map[_y][_x];
        for (int i=0;i<4;i++){
            int tmpX=x+blockShape[ty][o][2*i];
            int tmpY=y+blockShape[ty][o][2*i+1];
            map[tmpY][tmpX]=3;
        }
        
        
        int pop=0;
        for (int _y=1;_y<=MAPHEIGHT;_y++){
            int _x=1;
            for (_x=1;_x<=MAPWIDTH;_x++)
            if (!map[_y][_x]) break;
            if (_x==MAPWIDTH+1){
                pop++;
                for (_x=1;_x<=MAPWIDTH;_x++) map[_y][_x]=-1;
            }
        }
        for (int _x=1;_x<=MAPWIDTH;_x++){
            int p=1;
            for (int i=1;i<=MAPHEIGHT;i++)
            if (map[i][_x]!=-1) map[p][_x]=map[i][_x],p++;
            for (;p<=MAPHEIGHT;p++) map[p][_x]=0;
        }
        
        return work(map,_ty,DEEPTH,INF,currBotColor,pop?elimCombo[currBotColor]+1:0);
    }
    int blockForEnemy(int _map[MAPHEIGHT+2][MAPWIDTH+2],int ty,int DEEPTH){
        int minCount = 99,mmh=-1;
        for (int i = 0; i < 7; i++)
        if (typeCountForColor[enemyColor][i] < minCount) minCount = typeCountForColor[enemyColor][i];
        
        bool bo[MAPHEIGHT+2][MAPWIDTH+2][4];
        int fx=-1,fy,fo,i,work_num=Work_num;
            double MMH=INF,test;
            Util::init(_map,bo,ty);
            double work[work_num];
            int XX[work_num],YY[work_num],OO[work_num];
            for (i=0;i<work_num;i++) work[i]=INF;
            for (int y = 1; y <= MAPHEIGHT; y++)
            for (int x = 1; x <= MAPWIDTH; x++)
            for (int o = 0; o < 4; o++)
            if (onGround(_map,ty,x,y,o)&&bo[y][x][o]){
                test=Mavis(_map,ty,x,y,o,0,MMH,currBotColor,elimCombo[currBotColor]);
                for (i=0;i<work_num;i++) if (test<work[i]) break;
                if (i==work_num) continue;
                for (int j=work_num-1;j>i;j--) work[j]=work[j-1],XX[j]=XX[j-1],YY[j]=YY[j-1],OO[j]=OO[j-1];
                work[i]=test;XX[i]=x;YY[i]=y;OO[i]=o;
            }
        
        double _mmh=-INF;
        for (int _ty=0;_ty<7;_ty++)
        if (typeCountForColor[enemyColor][_ty]+1-minCount<=2){
            typeCountForColor[enemyColor][_ty]++;
            double _MMH=INF;
            for (int i=0;i<work_num;i++)
            if (work[i]<INF-1){
                if (work[0]<0){
                    if (work[i]>work[0]*0.8+10) break;
                }else if (work[i]>work[0]*1.2+10) break;
                if ((test=gain(_map,XX[i],YY[i],OO[i],ty,_ty,enemyColor,DEEPTH))<_MMH){
                    _MMH=test;
                    //printf("===%d %lf
    ",i,test);
                }
            }
            
            if (_MMH>_mmh) _mmh=_MMH,mmh=_ty;
            
            //printf("%d %lf
    ",_ty,_MMH);
            typeCountForColor[enemyColor][_ty]--;
        }
        return mmh;
    }
    int main(){
    #ifndef _BOTZONE_ONLINE
        freopen("a.in","r",stdin);
        //freopen("a.out","w",stdout);
    #endif
        // 加速输入
        istream::sync_with_stdio(false);
        srand(time(NULL));
        init();
     
        cin >> turnID;
     
        // 先读入第一回合,得到自己的颜色
        // 双方的第一块肯定是一样的
        cin >> blockType >> currBotColor;
        enemyColor = 1 - currBotColor;
        nextTypeForColor[0] = blockType;
        nextTypeForColor[1] = blockType;
        typeCountForColor[0][blockType]++;
        typeCountForColor[1][blockType]++;
     
        // 然后分析以前每回合的输入输出,并恢复状态
        // 循环中,color 表示当前这一行是 color 的行为
        // 平台保证所有输入都是合法输入
        for (int i = 1; i < turnID; i++){
            int currTypeForColor[2] = { nextTypeForColor[0], nextTypeForColor[1] };
            int x, y, o;
            // 根据这些输入输出逐渐恢复状态到当前回合
     
            // 先读自己的输出,也就是自己的行为
            // 自己的输出是自己的最后一步
            // 然后模拟最后一步放置块
            cin >> blockType >> x >> y >> o;
     
            // 我当时把上一块落到了 x y o!
            Tetris myBlock(currTypeForColor[currBotColor], currBotColor);
            myBlock.set(x, y, o).place();
     
            // 我给对方什么块来着?
            typeCountForColor[enemyColor][blockType]++;
            nextTypeForColor[enemyColor] = blockType;
     
            // 然后读自己的输入,也就是对方的行为
            // 裁判给自己的输入是对方的最后一步
            cin >> blockType >> x >> y >> o;
     
            // 对方当时把上一块落到了 x y o!
            Tetris enemyBlock(currTypeForColor[enemyColor], enemyColor);
            enemyBlock.set(x, y, o).place();
     
            // 对方给我什么块来着?
            typeCountForColor[currBotColor][blockType]++;
            nextTypeForColor[currBotColor] = blockType;
     
            // 检查消去
            Util::eliminate(0);
            Util::eliminate(1);
     
            // 进行转移
            Util::transfer();
        }
        
     
     
     
        // 做出决策(你只需修改以下部分)
        // 遇事不决先输出(平台上编译不会输出)
        work(gridInfo[currBotColor],blockType,M_DEEP,-INF,currBotColor,elimCombo[currBotColor]);
        _finalX=finalX;_finalY=finalY;_finalO=finalO;
        
            int currTypeForColor[2] = { nextTypeForColor[0], nextTypeForColor[1] };
            Tetris myBlock(currTypeForColor[currBotColor], currBotColor);
            myBlock.set(_finalX,_finalY,_finalO).place();
    #ifndef _BOTZONE_ONLINE
            Util::printField();
    #endif
        /*work(gridInfo[enemyColor],nextTypeForColor[enemyColor],1,-INF);
        
     
     
            Tetris enemyBlock(currTypeForColor[enemyColor], enemyColor);
            enemyBlock.set(finalX,finalY,finalO).place();
        //Util::printField();
            
            Util::eliminate(0);
            Util::eliminate(1);
            Util::transfer();
        */
        cout << blockForEnemy(gridInfo[enemyColor],nextTypeForColor[enemyColor],E_DEEP)<< " " << _finalX << " " << _finalY << " " << _finalO<<endl;
    }
    View Code
  • 相关阅读:
    activiti 用户手册中 10分钟 小例子 简单代码搭建 及 其中的 各种坑
    Eclipse启动项目正常,放到tomcat下单独启动就报错的 一例
    Project facet jst.web.jstl has not been defined.
    MySQL删除所有表的外键约束、禁用外键约束
    Unsupported major.minor version 52.0解决办法
    Could not update Activiti database schema: unknown version from database: '5.20.0.1'
    Android SDK下载地址
    Unity3d游戏中添加移动MM支付SDK问题处理
    Unity3d集成移动MM SDK 2.2的技术要点(坑爹的MM SDK)
    Android SDK更新 Connection to http://dl-ssl.google.com refused 解决方法
  • 原文地址:https://www.cnblogs.com/Enceladus/p/7909638.html
Copyright © 2011-2022 走看看