/*
    ダンジョン生成
    
    map : フィールドデータ
*/
void genDungeon(uchar map[FIELD_SZ][FIELD_SZ]){
    uchar dir, x, y;
    uint plen = 0;
    uint max_plen = FIELD_SZ * FIELD_SZ  * 4 / 9;
    uchar max[2], min[2];

    srand(seed);

    // 初期化
    for(y=0; y<FIELD_SZ; y++){
        for(x=0; x<FIELD_SZ; x++){
            map[y][x] = ID_WALL;
        }
    }

    x = rand() % (FIELD_SZ-1) + 1;      // 初期ポイントを設定
    y = rand() % (FIELD_SZ-1) + 1;
    map[y][x] = ID_PASSAGE;             // 通路にする
    plen ++;
    max[0] = min[0] = x;                // 範囲を更新
    max[1] = min[1] = y;                // 範囲を更新

    // 生成する
    while(plen <= max_plen){
        _wdt_reset();
        if(scanAround(map, x, y)){      // 周りに進められるところがあるか
            dir = nextDir();
            if(checkdig(map, x, y, dir)){   // その方向に進められるか
                dig(map, &x, &y, dir, &plen, max, min);     // 進める
            }
        }else{                          // ない
            findBranchPoint(map, &x, &y, max, min);     // 分岐点を決定
        }

    }

}
bool AiTankController::think(float gameTime, float deltaTime, bool bAvoidTimeConsumingMethod)
{
    deltaTime;

    if (!isAttached())
        return false;
    if (target.getObj())
    {
        Point2f posTank;
        Entity &e = entity->getEntity();
        if (e.getStatus(Entity::ESI_Position, &posTank))
            iRenderQueue::getSingleton().render(animPos, posTank, ARGB(255, 0, 0, 255));
    }
#ifdef PATH_FINDING_TOOL
//#ifndef NDEBUG
    

#endif

    if (!operates.empty())
    {
        Operate &op = operates.back();
        switch(op.commond)
        {
        case Operate::CI_MoveTo:
            if (!op.wayPoints.empty())
            {
                Point2f lastPos = moveToPos;
                for (list<Point2f>::iterator ip = op.wayPoints.begin(); ip != op.wayPoints.end(); ++ip)
                {
                    iRenderQueue::getSingleton().render(*ip, lastPos, ARGB(255, 128, 0, 0));
                    lastPos = *ip;
                }
            }
            break;
        }
    }
    // check for commands list
    if (bCheckMoveTo)
    {
        stepMoveTo();
    }
    else if (!operates.empty())
    {
        Operate &op = operates.front();
        switch(op.commond)
        {
        case Operate::CI_MoveTo:
            if (!op.wayPoints.empty())
            {
                Point2f pos = op.wayPoints.front();
                op.wayPoints.pop_front();
                if (op.wayPoints.empty())
                    moveTo(pos, pos);
                else
                    moveTo(pos, op.wayPoints.front());
            }
            else
            {
                operates.pop();
            }
            break;
        }
    }

    int r = rand() % 1000;
    // query environments (for updating covers and enemies)
    // determine the currently most important task(to track enemies or to escape from the enemies or go to the nearest supply zone, etc.)
    // generate path
    bool bRet = false;
    if (r > 500 && !bAvoidTimeConsumingMethod)
    {
        bRet = scanAround(gameTime);
    }

    // attack or rest
    if (target.getObj())
    {
        if (r < 5)
        {
            sendCommand(Tank::TCI_Fire, (void *)(bFire = !bFire));
        }
        else if (r < 20)
        {
            sendCommand(Tank::TCI_Shoot, (void *)(bShoot = !bShoot));
        }
    }
    else
    {
        // no target, seize fire
        if (bFire)
            sendCommand(Tank::TCI_Fire, (void *)(bFire = !bFire));
        if (bShoot)
            sendCommand(Tank::TCI_Shoot, (void *)(bShoot = !bShoot));
    }
    Entity *targetObj = (Entity *)target.getObj();
    if (targetObj)
    {
        if (targetObj->isActive())
        {
            Point2f posTank;
            Entity &e = entity->getEntity();
            if (e.getStatus(Entity::ESI_Position, &posTank))
            {
                Point2f ePos, eVel;
                if (targetObj->getStatus(Entity::ESI_Position, &ePos) &&
                    targetObj->getStatus(Entity::ESI_Velocity, &eVel))
                {
                    float distance = (ePos - posTank).Length();
                    if (distance < 300.f)
                    {
                        const float averWeaponSpeed = 300.0f;
                        float time = distance / averWeaponSpeed;
                        aimTo(ePos + eVel * time);
                    }
                    else
                    {
                        target.release();
                    }
                }
            }
        }
        else
        {
            target.release();
        }
    } 
    return bRet;
}