コード例 #1
0
ファイル: double_array.c プロジェクト: qwertzuiop961/prgraas
double da_rnd(int index, double maximum) {
    return d_rnd(maximum); // index not used
}
コード例 #2
0
ファイル: RushingAI.cpp プロジェクト: ProjectKidona/game
// AIの処理
void RushingAI::setOperation(
    UserOperation* uope,
    const UnitSet& uset,
    const MapSet& mset) {
    // todo
    // 1. マンハッタン距離で最も近い順に敵を並べ変える from uset
    // 2. その敵が移動範囲+攻撃範囲にいるかを調べる
    //   => いる場合,情報をuopeに登録し終了.
    //   => いない場合,ランダムで動作.

    // UserOperationの初期化
    uope->dx = 0;
    uope->dy = 0;
    uope->targetX = 0;
    uope->targetY = 0;
    uope->actionSelectIdx = 2;
    uope->skillSelectIdx = 0;
    //uope->isOperable = true;
    mp_uope= uope;

    // 自ユニットの取得
    Unit* own = uope->unit;

    // 敵一覧を取得
    std::vector<Unit*> enemys;

    for (auto unit : uset) {
        if (unit->getPartyId() != own->getPartyId()) {
            enemys.push_back(unit);
        }
    }

    // マンハッタン距離で近い順に敵を並び替える
    std::sort(enemys.begin(), enemys.end(),
              [=](Unit* a, Unit* b) -> int {
        // マンハッタン距離の計算
        int da = std::abs(own->getAbsX() - a->getAbsX()) + std::abs(own->getAbsY() - a->getAbsY());
        int db = std::abs(own->getAbsX() - b->getAbsX()) + std::abs(own->getAbsY() - b->getAbsY());
        // 昇順に並べる
        return (da < db);
    });

    // 近い順に攻撃可能な範囲に敵がいるかを調べ,攻撃する.
    // まずは自分を中心とした移動範囲の取得
    MovableRegion reg(mset.getHeight(), mset.getWidth(), &uset);
    reg.calcuate(own->getAbsX(), own->getAbsY(), own->getParameters().mov, mset.getCostMap());
    std::unique_ptr<MapMatrix> movableMap(reg.createMovableMatrix(0x01));

    for (auto enemy : enemys) {
		Aliment* ali = enemy->getAliment();
		if (ali != nullptr) {
			if (ali->getName() == "dead") { continue; }
		}
        // 敵を中心とした攻撃範囲の取得
        AttackRegion* region = own->getWeapon()->region;
        MapMatrix* attackableMap = region->createAttackableMatrix(
            enemy->getAbsX(),
            enemy->getAbsY(),
            mset.getWidth(),
            mset.getHeight(),
            0x02);

        // 移動範囲と攻撃範囲の重なる点を調べる
        for (int i=0; i < mset.getHeight()*mset.getWidth(); i++) {
            if (movableMap->at(i) > 0 && attackableMap->at(i) > 0) {
                // 移動差分の設定
                uope->dx = (i % movableMap->getCol()) - own->getAbsX();
                uope->dy = (i / movableMap->getCol()) - own->getAbsY();
                // 攻撃対象の座標設定
                uope->targetX = enemy->getAbsX();
                uope->targetY = enemy->getAbsY();
                // MovedMenuの設定
                uope->actionSelectIdx = 0;    // 攻撃
                return;
            }
        }
    }

    // 移動可能リストの生成
    std::vector<int> indexs;
    for (int i=0; i < movableMap->getSize(); i++) {
        if (movableMap->at(i) > 0) { indexs.push_back(i); }
    }
    if (indexs.size() < 0) { return; }   // 移動可能な範囲がない場合終了

    // 攻撃する敵がいなかった場合,ランダムで動作.
    std::random_device rnd;
    std::mt19937 mt(rnd());
    std::uniform_real_distribution<double> d_rnd(0.0, 1.0);

    if (d_rnd(mt) <= m_randMove) {   // ランダムな座標に移動
        // 移動可能リストからランダムに1つ座標を選択する
        std::uniform_int_distribution<int> index_rnd(0, indexs.size() - 1);
        int movePoint = indexs[index_rnd(mt)];
        // 移動先登録
        uope->dx = (movePoint % movableMap->getCol()) - own->getAbsX();
        uope->dy = (movePoint / movableMap->getCol()) - own->getAbsY();
        return;
    }
    else if (d_rnd(mt) <= m_contactMove) {   // 最も近い敵の近くに移動
      // 敵の近くに移動
      // 最も近い敵を取得
        Unit* nearEnemy = enemys.front();
    }
    
}