double da_rnd(int index, double maximum) { return d_rnd(maximum); // index not used }
// 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(); } }