v3

#include <iostream>
#include <time.h>
#include "map"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "array"
using namespace std;

#define NULL                    (0)

#define OUT_X                               (0b1111)
#define OUT_POS                             (0b11111111)
#define OUT_BLK                             (0b11111111111111111111111111111111)

#define get_x_from_pos(pos)                   (((pos)>>4)&0b1111)
#define get_y_from_pos(pos)                   ((pos)&0b1111)

#define get_pos_from_xy(x,y)                 (((x)<<4)|(y))

#define get_u_pos_from_blk(stBlk)                (((stBlk)>>24)&0b11111111)
#define get_d_pos_from_blk(stBlk)                (((stBlk)>>16)&0b11111111)
#define get_l_pos_from_blk(stBlk)                (((stBlk)>>8)&0b11111111)
#define get_r_pos_from_blk(stBlk)                ((stBlk)&0b11111111)

#define get_blk_from_pos_u_d_l_r(u,d,l,r)       (((u)<<24)|((d)<<16)|((l)<<8)|(r))

#define set_u_pos_in_blk(stBlk,pos)          ((stBlk)=(((stBlk)&0b00000000111111111111111111111111)|(pos<<24)))
#define set_d_pos_in_blk(stBlk,pos)          ((stBlk)=(((stBlk)&0b11111111000000001111111111111111)|(pos<<16)))
#define set_l_pos_in_blk(stBlk,pos)          ((stBlk)=(((stBlk)&0b11111111111111110000000011111111)|(pos<<8)))
#define set_r_pos_in_blk(stBlk,pos)          ((stBlk)=(((stBlk)&0b11111111111111111111111100000000)|(pos)))

typedef unsigned char               pos;
typedef unsigned int                stBlk;
typedef unsigned int                color;



// global
array<array<color, 10>, 10>                 g_initColorMap;
array<array<stBlk, 10>, 10>                 g_initStateMap;
pos                                         g_initHeadPos;
map<array<array<stBlk, 10>, 10>, int>       g_SCORE;
int                                         g_BEST_SCORE;
int                                         g_mapSize, g_mapSize_old;


void globalInit()
{
    for (int i=1;i<=10;++i) g_initColorMap[i].fill(0);
    for (int i=1;i<=10;++i) g_initStateMap[i].fill(0);
    g_initHeadPos = 0;
    g_SCORE.clear();
    g_BEST_SCORE = 1;
    g_mapSize = 0;
    g_mapSize_old = 0;
}

void readInitMap()
{
        /*
        2441353511
        2122511244
        3444543422
        2131423443
        4241445212
        1122411534
        1251131145
        2441444415
        4254453131
        3321521455
        */
    string x = "2441353511212251124434445434222131423443424144521211224115341251131145244144441542544531313321521455";
    // read color map
    for (int i=0; i<=9; ++i) {
        for (int j=0; j<=9; ++j) {
            g_initColorMap[i][j] = x[i+10*(9-j)]-'0';
        }
    }
    // init state map
    for (int i=0; i<=9; ++i) {
        for (int j=0; j<=9; ++j) {
            pos up, down, left, right;
            if (j==9) up = OUT_POS; else up = get_pos_from_xy(i, j+1);
            if (j==0) down = OUT_POS; else down = get_pos_from_xy(i, j-1);
            if (i==0) left = OUT_POS; else left = get_pos_from_xy(i-1, j);
            if (i==9) right = OUT_POS; else right = get_pos_from_xy(i+1, j);
            //printf("g_initStateMap[%d][%d]=(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n", i, j, \
                                                 get_x_from_pos(up), get_y_from_pos(up), \
                                                 get_x_from_pos(down), get_y_from_pos(down), \
                                                                      get_x_from_pos(left), get_y_from_pos(left), \
                                                                             get_x_from_pos(right), get_y_from_pos(right));
            g_initStateMap[i][j] = get_blk_from_pos_u_d_l_r(up, down, left, right);
        }
    }
    g_initHeadPos = get_pos_from_xy(0, 0);
}

void printMap(array<array<stBlk, 10>, 10> stMp, pos RealHeadPos)
{
    if (stMp[get_x_from_pos(RealHeadPos)][get_y_from_pos(RealHeadPos)] == 0) {
        printf("printMap ERROR, RealHeadPos is NULL (%d,%d)\n", get_x_from_pos(RealHeadPos), get_y_from_pos(RealHeadPos));
        return;
    }
    array<array<color, 10>, 10> temp;
    for (int i=0; i<10; ++i) temp[i].fill(0);
    pos temp2[10][10];
    for(int i=0; i<10; ++i) for(int j=0; j<10; ++j) {
        temp2[i][j] = OUT_POS;
    }

    int xx = 0;
    pos p = RealHeadPos;
    while (p!=OUT_POS) {
        xx++;
        pos q = p;
        int yy = 0;
        while (q!=OUT_POS) {
            yy++;
            char qx = get_x_from_pos(q);
            char qy = get_y_from_pos(q);
            temp[xx-1][yy-1] = g_initColorMap[qx][qy];
            temp2[xx-1][yy-1] = q;
            q = get_u_pos_from_blk(stMp[qx][qy]);
        }
        p = get_r_pos_from_blk(stMp[get_x_from_pos(p)][get_y_from_pos(p)]);
    }

    cout << "Head Pos: (" << get_x_from_pos(RealHeadPos) << "," << get_y_from_pos(RealHeadPos) << ")" << endl;
    for (int j=9; j>=0; --j) {
        for (int i=0; i<=9; ++i) {
        //if (temp[i][j] == 0) cout<<" "; else cout<<temp[i][j];
        if (temp2[i][j] == OUT_POS) printf("      "); else printf("(%d,%d) ",get_x_from_pos(temp2[i][j]),get_y_from_pos(temp2[i][j]));
    }
        cout<<endl;
    }
    cout<<endl;
}

void tickOneBlk(array<array<stBlk, 10>, 10> &S, pos &Hp, pos tickP)
{
    char tickPx = get_x_from_pos(tickP);
    char tickPy = get_y_from_pos(tickP);

    stBlk tickBlk = S[tickPx][tickPy];
    if (tickBlk == 0) {
            for(int i=0;i<1000;++i) cout <<"fuck"<<endl;
            return;
    }

    pos up = get_u_pos_from_blk(tickBlk);
    char upx = get_x_from_pos(up);
    char upy = get_y_from_pos(up);
    pos dp = get_d_pos_from_blk(tickBlk);
    char dpx = get_x_from_pos(dp);
    char dpy = get_y_from_pos(dp);

    // at least 1 block below it.
    if (dp != OUT_POS) {
        if (up == OUT_POS) {
            set_u_pos_in_blk(S[dpx][dpy], OUT_POS);
        }
        else {
            set_u_pos_in_blk(S[dpx][dpy], up);
            set_d_pos_in_blk(S[upx][upy], dp);
        }
    }
    else if (dp == OUT_POS) { // it's the bottom block
        pos lp = get_l_pos_from_blk(tickBlk);
        char lpx = get_x_from_pos(lp);
        char lpy = get_y_from_pos(lp);
        pos rp = get_r_pos_from_blk(tickBlk);
        char rpx = get_x_from_pos(rp);
        char rpy = get_y_from_pos(rp);
        if (up == OUT_POS) {
            if (lp != OUT_POS) {
                if (rp == OUT_POS) {
                    set_r_pos_in_blk(S[lpx][lpy], OUT_POS);
                }
                else if (rp != OUT_POS) {
                    set_l_pos_in_blk(S[rpx][rpy], lp);
                    set_r_pos_in_blk(S[lpx][lpy], rp);
                }
            }
            else if (lp == OUT_POS) {
                if (rp == OUT_POS) {
                    Hp = OUT_POS;
                }
                else if (rp != OUT_POS) {
                    set_l_pos_in_blk(S[rpx][rpy], OUT_POS);
                    Hp = rp;
                }
            }
        }
        else if (up != OUT_POS){
            if (lp != OUT_POS) {
                if (rp == OUT_POS) {
                    set_r_pos_in_blk(S[lpx][lpy], up);
                    set_d_pos_in_blk(S[upx][upy], dp);
                    set_l_pos_in_blk(S[upx][upy], lp);
                    set_r_pos_in_blk(S[upx][upy], rp);
                }
                else if (rp != OUT_POS) {
                    set_r_pos_in_blk(S[lpx][lpy], up);
                    set_d_pos_in_blk(S[upx][upy], dp);
                    set_l_pos_in_blk(S[upx][upy], lp);
                    set_r_pos_in_blk(S[upx][upy], rp);
                    set_l_pos_in_blk(S[rpx][rpy], up);
                }
            }
            else if (lp == OUT_POS) {
                if (rp == OUT_POS) {
                    set_d_pos_in_blk(S[upx][upy], dp);
                    set_l_pos_in_blk(S[upx][upy], lp);
                    set_r_pos_in_blk(S[upx][upy], rp);
                    Hp = up;
                }
                else if (rp != OUT_POS) {
                    set_d_pos_in_blk(S[upx][upy], dp);
                    set_r_pos_in_blk(S[upx][upy], rp);
                    set_l_pos_in_blk(S[upx][upy], lp);
                    set_l_pos_in_blk(S[rpx][rpy], up);
                    Hp = up;
                }
            }
        }
    }
    // destroy this block
    S[tickPx][tickPy] = 0;
    //printMap(S, Hp);
}

void printInfo(pos p, stBlk pb)
{
    printf("p:(%d,%d)\n", get_x_from_pos(p), get_y_from_pos(p));
    pos up = get_u_pos_from_blk(pb);
    pos dp = get_d_pos_from_blk(pb);
    pos lp = get_l_pos_from_blk(pb);
    pos rp = get_r_pos_from_blk(pb);
    printf("up:(%d,%d)\n", get_x_from_pos(up), get_y_from_pos(up));
    printf("dp:(%d,%d)\n", get_x_from_pos(dp), get_y_from_pos(dp));
    printf("lp:(%d,%d)\n", get_x_from_pos(lp), get_y_from_pos(lp));
    printf("rp:(%d,%d)\n", get_x_from_pos(rp), get_y_from_pos(rp));
}
void updateAllPos(array<array<stBlk, 10>, 10> &state, pos &RealHeadPos)
{
    array<array<pos, 10>, 10> temp;
    //for (int i=0; i<10; ++i) temp[i].fill(0);
    for(int i=0; i<10; ++i) for(int j=0; j<10; ++j) temp[i][j] = OUT_POS;

    int xx1 = 0;
    pos p1 = RealHeadPos;
    while (p1 != OUT_POS) {
        xx1++;
        pos q1 = p1;
        int yy1 = 0;
        //cout<<"fuck1"<<endl;
        while (q1 != OUT_POS) {
            //printf("%d\n", RealHeadPos);
            yy1++;
            //printMap(state, RealHeadPos);
            //printf("in p1=(%d,%d) q1=(%d,%d)\n",get_x_from_pos(p1), get_y_from_pos(p1), get_x_from_pos(q1), get_y_from_pos(q1));
            //printInfo(p1, state[get_x_from_pos(p1)][get_y_from_pos(p1)]);
            //printInfo(q1, state[get_x_from_pos(q1)][get_y_from_pos(q1)]);
            temp[xx1-1][yy1-1] = q1;
            q1 = get_u_pos_from_blk(state[get_x_from_pos(q1)][get_y_from_pos(q1)]);
        }
        p1 = get_r_pos_from_blk(state[get_x_from_pos(p1)][get_y_from_pos(p1)]);
        //printf("out p1=(%d,%d) q1=(%d,%d)\n",get_x_from_pos(p1), get_y_from_pos(p1), get_x_from_pos(q1), get_y_from_pos(q1));
    }
    //printf("im out.\n");
    for(int x=0; x<10; ++x) {
        if (OUT_POS == temp[x][0]) {
            break;
        }
        for(int y=0; y<10; ++y) {
            if (OUT_POS == temp[x][y]) {
                break;
            }
            //temp[x][y]--;
            if (9 == y) {
                set_u_pos_in_blk(state[get_x_from_pos(temp[x][y])][get_y_from_pos(temp[x][y])], OUT_POS);
            }
            else {
                set_u_pos_in_blk(state[get_x_from_pos(temp[x][y])][get_y_from_pos(temp[x][y])], temp[x][y+1]);
            }
            if (0 == y) {
                set_d_pos_in_blk(state[get_x_from_pos(temp[x][y])][get_y_from_pos(temp[x][y])], OUT_POS);
            }
            else {
                set_d_pos_in_blk(state[get_x_from_pos(temp[x][y])][get_y_from_pos(temp[x][y])], temp[x][y-1]);
            }
            if (0 == x) {
                set_l_pos_in_blk(state[get_x_from_pos(temp[x][y])][get_y_from_pos(temp[x][y])], OUT_POS);
            }
            else {
                set_l_pos_in_blk(state[get_x_from_pos(temp[x][y])][get_y_from_pos(temp[x][y])], temp[x-1][y]);
            }
            if (9 == x) {
                set_r_pos_in_blk(state[get_x_from_pos(temp[x][y])][get_y_from_pos(temp[x][y])], OUT_POS);
            }
            else {
                set_r_pos_in_blk(state[get_x_from_pos(temp[x][y])][get_y_from_pos(temp[x][y])], temp[x+1][y]);
            }
        }
    }
    return;
}

bool checkIsSingle(array<array<stBlk, 10>, 10> &state, pos &ckPos)
{
    char ck_x = get_x_from_pos(ckPos);
    char ck_y = get_y_from_pos(ckPos);

    color cx = g_initColorMap[ck_x][ck_y];
    stBlk bx = state[ck_x][ck_y];

    pos up = get_u_pos_from_blk(bx);
    if (up!=OUT_POS && g_initColorMap[get_x_from_pos(up)][get_y_from_pos(up)]==cx){
        return false;
    }
    pos dp = get_d_pos_from_blk(bx);
    if (dp!=OUT_POS && g_initColorMap[get_x_from_pos(dp)][get_y_from_pos(dp)]==cx){
        return false;
    }
    pos lp = get_l_pos_from_blk(bx);
    if (lp!=OUT_POS && g_initColorMap[get_x_from_pos(lp)][get_y_from_pos(lp)]==cx){
        return false;
    }
    pos rp = get_r_pos_from_blk(bx);
    if (rp!=OUT_POS && g_initColorMap[get_x_from_pos(rp)][get_y_from_pos(rp)]==cx){
        return false;
    }

    return true;
}

int destroy(array<array<stBlk, 10>, 10> &state, pos &realHeadPos, pos realTickPos, array<array<stBlk, 10>, 10> &tmpState, pos &tmpRealHeadPos)
{
    pos toTick[105];
    int head=0, tail=1;
    toTick[tail] = realTickPos;

    bool vis[257];
    for(int i=0; i<257; ++i) vis[i] = 0;
    vis[realTickPos] = 1;

    while (head < tail) {
        pos pp = toTick[++head];
        char ppx = get_x_from_pos(pp);
        char ppy = get_y_from_pos(pp);
        color pc = g_initColorMap[ppx][ppy];

        stBlk ppb = state[ppx][ppy];
        pos up = get_u_pos_from_blk(ppb);
        if (up!=OUT_POS && !vis[up] && g_initColorMap[get_x_from_pos(up)][get_y_from_pos(up)]==pc){
            vis[up] = 1;
            toTick[++tail] = up;
        }
        pos dp = get_d_pos_from_blk(ppb);
        if (dp!=OUT_POS && !vis[dp] && g_initColorMap[get_x_from_pos(dp)][get_y_from_pos(dp)]==pc){
            vis[dp] = 1;
            toTick[++tail] = dp;
        }
        pos lp = get_l_pos_from_blk(ppb);
        if (lp!=OUT_POS && !vis[lp] && g_initColorMap[get_x_from_pos(lp)][get_y_from_pos(lp)]==pc){
            vis[lp] = 1;
            toTick[++tail] = lp;
        }
        pos rp = get_r_pos_from_blk(ppb);
        if (rp!=OUT_POS && !vis[rp] && g_initColorMap[get_x_from_pos(rp)][get_y_from_pos(rp)]==pc){
            vis[rp] = 1;
            toTick[++tail] = rp;
        }
    }
    for(int i=1; i<=tail; ++i) {
        tickOneBlk(state, realHeadPos, toTick[i]);
        tickOneBlk(tmpState, tmpRealHeadPos, toTick[i]);
    }
    return tail;
}

int explore(array<array<stBlk, 10>, 10> state, pos RealHeadPos)
{
    //cout<<RealHeadPos<<endl;
    int sco = g_SCORE[state];
    if ( sco != 0 ) {
        return sco;
    }

    //printMap(state, RealHeadPos);
    updateAllPos(state, RealHeadPos);

    array<array<stBlk, 10>, 10> tmpState = state;
    pos tmpRealHeadPos = RealHeadPos;
    int tmpMax = 1;

    while (tmpRealHeadPos != OUT_POS) {
        if (checkIsSingle(state, tmpRealHeadPos) == true) {
            tickOneBlk(tmpState, tmpRealHeadPos, tmpRealHeadPos);
        }
        else {
            array<array<stBlk, 10>, 10> state1 = state;
            pos RealHeadPos1 = RealHeadPos;
            pos RealTickPos = tmpRealHeadPos;
            int cnt = destroy(state1, RealHeadPos1, RealTickPos, tmpState, tmpRealHeadPos);
            tmpMax = max(tmpMax, explore(state1, RealHeadPos1)+5*cnt*cnt);
        }
    }
    g_SCORE[state] = tmpMax;
#if 0
    g_mapSize++;
#endif
    if(tmpMax > g_BEST_SCORE) {
        g_BEST_SCORE = tmpMax;
        cout << "---------------------------" << endl;
        cout << "Best Score: " << g_BEST_SCORE << endl;
        printMap(state, RealHeadPos);
        //g_BEST_SCORE = 999999;
    }
    //printt(state, g_BEST_SCORE);
    return tmpMax;
}

void proc()
{
    g_BEST_SCORE = explore(g_initStateMap, g_initHeadPos);
    cout << "BEST SCORE :" << g_BEST_SCORE << endl;
}


void random(pos a[], int n)
{
    srand((unsigned)time(NULL));
    for(int i=0; i<n; ++i) {
        int index = rand()%(n-i)+i;
        if (index != i) {
            pos tmp = a[i];
            a[i] = a[index];
            a[index] = tmp;
        }
    }
}

void test(array<array<stBlk, 10>, 10> S, pos H)
{
    pos tick[100];
    for(int i=0; i<100; ++i) {
        tick[i] = get_pos_from_xy(i/10, i%10);
    }
    random(tick, 100);
    for(int i=0; i<100; ++i) {
        int x;


        stBlk tB = S[get_x_from_pos(tick[i])][get_y_from_pos(tick[i])];
        pos uu = get_u_pos_from_blk(tB);
        pos dd = get_d_pos_from_blk(tB);
        pos ll = get_l_pos_from_blk(tB);
        pos rr = get_r_pos_from_blk(tB);
        printf("-----------------------------\n");
        printf("tick on (%d, %d)\n", get_x_from_pos(tick[i]), get_y_from_pos(tick[i]));
        printf("u:(%d,%d) d:(%d,%d) l:(%d,%d) r:(%d,%d)\n",\
               get_x_from_pos(uu), get_y_from_pos(uu),\
               get_x_from_pos(dd), get_y_from_pos(dd),\
               get_x_from_pos(ll), get_y_from_pos(ll),\
               get_x_from_pos(rr), get_y_from_pos(rr)
               );
        //cin >> x;
        tickOneBlk(S, H, tick[i]);
        printf("tick Done.\n");
        //printMap(S, H);
        printf("printMap Done.\n");
    }
    cout<<"test done"<<endl;
    printf("%d\n", H);
    //printMap(S, H);
}
int main()
{
    globalInit();
    readInitMap();
    printMap(g_initStateMap, g_initHeadPos);
    //test(g_initStateMap, g_initHeadPos);
    //tickOneBlk(g_initStateMap, g_initHeadPos, get_pos_from_xy(4, 7));
    //printMap(g_initStateMap, g_initHeadPos);
    proc();

    return 0;
}

 

posted @ 2017-06-08 08:39  fish7  阅读(174)  评论(0编辑  收藏  举报