|
@@ -223,6 +223,194 @@ bool LevelGenerate::generate( FillGlobalConfig::LevelData levelData,
|
|
|
return true ;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+bool LevelGenerate::generate_v2(
|
|
|
+ const LevelInputData& indata,
|
|
|
+ const LevelExtInputData& extdata,
|
|
|
+ vector<PlateFillResult>& resultPlateFillResults,
|
|
|
+ vector<ContourData::Point>& resultPlateCenterPointArr,
|
|
|
+ string& error )
|
|
|
+{
|
|
|
+ FillGlobalConfig::getInstance()->clearGridBoxFilledStatus() ;
|
|
|
+ resultPlateFillResults.clear() ;
|
|
|
+ resultPlateCenterPointArr.clear() ;
|
|
|
+
|
|
|
+ auto ms0 = std::chrono::system_clock::now().time_since_epoch() ;
|
|
|
+ uint64_t ms00 = std::chrono::duration_cast<chrono::milliseconds>(ms0).count() ;
|
|
|
+
|
|
|
+ srand( extdata._seed );
|
|
|
+ unordered_map<int,tuple<int,int> > jewIdSzCntStorageMap ;// unordered_map<宝石ID,tuple<尺寸,库存数量> >
|
|
|
+ FillGlobalConfig* fgc = FillGlobalConfig::getInstance() ;
|
|
|
+ int bigJewelCnt = 0 ;
|
|
|
+ int midJewelCnt = 0;
|
|
|
+ int smlJewelCnt = 0 ;
|
|
|
+ for(int ij = 0 ; ij < indata._jewels.size() ;++ ij ) {
|
|
|
+ int jewId = indata._jewels[ij]._jewelId ;
|
|
|
+ int cnt = indata._jewels[ij]._count ;
|
|
|
+ FillGlobalConfig::JewelItem* jewItem = fgc->getJewelItemById(jewId) ;
|
|
|
+ jewIdSzCntStorageMap[jewId] = {jewItem->_size,cnt} ;
|
|
|
+ if( jewItem->_size == FILLGLOBALCONFIG_JEWELSIZE_SM ) {
|
|
|
+ smlJewelCnt+=cnt ;
|
|
|
+ }else if( jewItem->_size == FILLGLOBALCONFIG_JEWELSIZE_MD ) {
|
|
|
+ midJewelCnt += cnt ;
|
|
|
+ }else if( jewItem->_size == FILLGLOBALCONFIG_JEWELSIZE_LG ) {
|
|
|
+ bigJewelCnt += cnt ;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //每个盘子类型小号宝石承载量
|
|
|
+ //按顺序分别为大和中
|
|
|
+ FillGlobalConfig::PlateItem* bigPlateH = fgc->getPlateItemBySzNDirection(FILLGLOBALCONFIG_PLATESIZE_LG, 1) ;
|
|
|
+ FillGlobalConfig::PlateItem* midPlateH = fgc->getPlateItemBySzNDirection(FILLGLOBALCONFIG_PLATESIZE_MD, 1) ;
|
|
|
+ FillGlobalConfig::PlateItem* bigPlateV = fgc->getPlateItemBySzNDirection(FILLGLOBALCONFIG_PLATESIZE_LG, 0) ;
|
|
|
+ FillGlobalConfig::PlateItem* midPlateV = fgc->getPlateItemBySzNDirection(FILLGLOBALCONFIG_PLATESIZE_MD, 0) ;
|
|
|
+
|
|
|
+ //FillGlobalConfig::PlateItem* smlPlate = fgc->getPlateItemBySzNIndex(FILLGLOBALCONFIG_PLATESIZE_SM, 0) ;
|
|
|
+ vector<FillGlobalConfig::PlateItem*> usedPlates = {bigPlateH,midPlateH,bigPlateV,midPlateV} ;//{bigPlate,midPlate,smlPlate} ;
|
|
|
+ int maxSmlJewCapPerPlate = 0;
|
|
|
+ int minSmlJewCapPerPlate = 99999 ;
|
|
|
+ for(int ip=0;ip<usedPlates.size();++ip ) {
|
|
|
+ maxSmlJewCapPerPlate = fmax( usedPlates[ip]->_bigJewCap*4 , maxSmlJewCapPerPlate) ;
|
|
|
+ minSmlJewCapPerPlate = fmin( usedPlates[ip]->_bigJewCap*4 , minSmlJewCapPerPlate) ;
|
|
|
+ }
|
|
|
+ //等效小宝石数量
|
|
|
+ int effSmallJewelsCount = bigJewelCnt*4 + midJewelCnt*2 + smlJewelCnt ;
|
|
|
+ if( effSmallJewelsCount==0 ) {
|
|
|
+ error = "equv small jewel count is zero." ;
|
|
|
+ return false ;
|
|
|
+ }
|
|
|
+
|
|
|
+ //构建符合难度条件的盘子和层数组合(包括可移动的盘子)
|
|
|
+ bool isMovable = (extdata._hasMovement==1)?true:false ;
|
|
|
+ FillGlobalConfig::MultiMoveConfig* mulMoveConfigPtr = nullptr ;
|
|
|
+ FillGlobalConfig::MultiMoveConfig mulMoveConfig;
|
|
|
+ if( isMovable ) {
|
|
|
+ vector<FillGlobalConfig::MoveConfig*> mc1arr = FillGlobalConfig::getInstance()->getMoveConfigDatasByTypeAndNLayers(extdata._firstMoveType, extdata._firstMoveLyrCnt) ;
|
|
|
+ if( mc1arr.size()==0 ) {
|
|
|
+ error = string("failed to get first move config data by move type '")+extdata._firstMoveType+"'." ;
|
|
|
+ return false ;
|
|
|
+ }
|
|
|
+ mulMoveConfig._first = mc1arr[0] ;
|
|
|
+ if( extdata._secondMoveType.compare("") != 0 ) {
|
|
|
+ vector<FillGlobalConfig::MoveConfig*> mc2arr = FillGlobalConfig::getInstance()->getMoveConfigDatasByTypeAndNLayers(extdata._secondMoveType, extdata._secondMoveLyrCnt) ;
|
|
|
+ if( mc2arr.size()==0 ) {
|
|
|
+ error = string("failed to get second move config data by move type '")+extdata._secondMoveType+"'." ;
|
|
|
+ return false ;
|
|
|
+ }
|
|
|
+ mulMoveConfig._second = mc2arr[0] ;
|
|
|
+ }else{
|
|
|
+ mulMoveConfig._second = nullptr ;
|
|
|
+ }
|
|
|
+ mulMoveConfigPtr = &mulMoveConfig;
|
|
|
+ }
|
|
|
+
|
|
|
+ vector<PlateIdAndLayerCnt> resPlateNLyrCnt = generatePlateTypeAndLayerCnts3(
|
|
|
+ isMovable,
|
|
|
+ mulMoveConfigPtr,
|
|
|
+ indata._difficulty,
|
|
|
+ effSmallJewelsCount,
|
|
|
+ extdata
|
|
|
+ );
|
|
|
+ if( resPlateNLyrCnt.size()==0 ) {
|
|
|
+ error = string("failed on generatePlateTypeAndLayerCnts3.") ;
|
|
|
+ return false ;
|
|
|
+ }
|
|
|
+
|
|
|
+ //计算盘子的最大层数
|
|
|
+ int maxLyrCnt = 0;
|
|
|
+ for(auto it = resPlateNLyrCnt.begin();it!=resPlateNLyrCnt.end();++it ) maxLyrCnt=fmax(maxLyrCnt,it->_layerCnt) ;
|
|
|
+
|
|
|
+ //对每个盘子组合进行填充宝石
|
|
|
+ RandomGridFiller filler ;
|
|
|
+ filler._seed = extdata._seed ;
|
|
|
+ srand(filler._seed);
|
|
|
+
|
|
|
+ //构建每个盘子每个层的填充结果容器
|
|
|
+ vector< tuple<int,int,vector<FillResult>,int> > plateIdLyrFillResultsMoveIdArray ;// tuple<plateId, layerIndex, fillresults_array ,moveId>
|
|
|
+
|
|
|
+
|
|
|
+ //从顶到底部,逐层进行填充
|
|
|
+ int residues = 0 ;
|
|
|
+ for(int nlayer = maxLyrCnt; nlayer > 0 ; nlayer-- ) {
|
|
|
+ //cout<<"for layer "<<nlayer<<endl;
|
|
|
+
|
|
|
+ //满足该层数的所有盘子ID
|
|
|
+ vector<int> plateIdArr ;//临时符合当前层次的盘子类型ID
|
|
|
+ vector<int> moveIdArr ;//临时保存对应盘子是否是可移动的,0-不可移动,1-第一移动行,2-第二移动行
|
|
|
+ for(auto it = resPlateNLyrCnt.begin();it!=resPlateNLyrCnt.end();++it )
|
|
|
+ {
|
|
|
+ if(it->_layerCnt>=nlayer) {
|
|
|
+ plateIdArr.push_back(it->_plateId) ;
|
|
|
+ moveIdArr.push_back( it->_moveId ) ;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //该层总计需要填充多少小宝石
|
|
|
+ int currLyrNeedEquvSmlCnt = 0 ;
|
|
|
+ for(int ip=0;ip<plateIdArr.size();++ip ) {
|
|
|
+ currLyrNeedEquvSmlCnt += fgc->getPlateItemById(plateIdArr[ip])->_bigJewCap*4 ;
|
|
|
+ }
|
|
|
+ //cout<<"layer need eqsmCnt "<<currLyrNeedEquvSmlCnt<<endl;
|
|
|
+
|
|
|
+ //根据所需数量和所需求解百分比,计算从库存取出每类宝石多少个。
|
|
|
+ float solPercent = 0.7 ;//根据需求文档,每层可解百分比都是70%.
|
|
|
+ unordered_map<int, int> chosenJewIdNCnt = randPickJewels(currLyrNeedEquvSmlCnt, solPercent, jewIdSzCntStorageMap) ;
|
|
|
+ int choseEqSmCnt=0;
|
|
|
+ for(auto itp=chosenJewIdNCnt.begin();itp!=chosenJewIdNCnt.end();++itp) {
|
|
|
+ choseEqSmCnt += jewSz2SmlCnt( fgc->getJewelItemById(itp->first)->_size) * itp->second ;
|
|
|
+ }
|
|
|
+ //cout<<"layer choose eqsmCnt "<<choseEqSmCnt<<endl;
|
|
|
+
|
|
|
+ //逐个盘子填充
|
|
|
+ for(int ipid = 0 ; ipid !=plateIdArr.size();++ipid) {
|
|
|
+ int plateId1 = plateIdArr[ipid] ;
|
|
|
+ int moveId1 = moveIdArr[ipid] ;
|
|
|
+ vector<FillResult> fr = fillPlateOneLayer(filler, plateId1 , chosenJewIdNCnt) ;
|
|
|
+ tuple<int,int,vector<FillResult>,int> plateLyrFillResult={plateId1 , nlayer , fr , moveId1 } ;
|
|
|
+ plateIdLyrFillResultsMoveIdArray.push_back(plateLyrFillResult);
|
|
|
+ }
|
|
|
+
|
|
|
+ //检查为该层挑选的宝石是不是全部填完了,如果没有填完还要还给库存,给下一轮填充用
|
|
|
+ residues = 0 ;
|
|
|
+ for(auto itjn = chosenJewIdNCnt.begin();itjn!=chosenJewIdNCnt.end();++itjn){
|
|
|
+ if( itjn->second>0 ) {
|
|
|
+ residues+=itjn->second;
|
|
|
+ std::get<1>(jewIdSzCntStorageMap[itjn->first]) += itjn->second ;//剩余的加回到库存里
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //cout<<"layer chosen jewels residues "<<residues<<endl;
|
|
|
+ }
|
|
|
+
|
|
|
+ //查看库存是否全部用掉了
|
|
|
+ if( residues>0 ) {
|
|
|
+ int extraPlateCnt = 0 ;
|
|
|
+ //剩了,添加一个小盘子和层,仍然剩了再继续加盘子加层
|
|
|
+ unordered_map<int, int> residueJewIdAndCnts = findUnfilledInStorages(jewIdSzCntStorageMap) ;
|
|
|
+ while( residueJewIdAndCnts.size()>0 ) {
|
|
|
+ //新建一个中盘子
|
|
|
+ extraPlateCnt++;
|
|
|
+ //cout<<"add extra plate "<< extraPlateCnt <<endl;
|
|
|
+ int plateId = midPlateH->_id ;
|
|
|
+ for(int ilyr = 1 ; ilyr <= maxLyrCnt; ++ ilyr ) {
|
|
|
+ vector<FillResult> frs = fillPlateOneLayer(filler, plateId, residueJewIdAndCnts) ;
|
|
|
+ plateIdLyrFillResultsMoveIdArray.push_back( {plateId,ilyr,frs, MOVEID_NO_MOVE } );
|
|
|
+ //cout<<"add extra lyr "<<endl;
|
|
|
+ if( residueJewIdAndCnts.size()==0 ) break ;
|
|
|
+ }
|
|
|
+ if( residueJewIdAndCnts.size()==0 ) break ;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //整理数据
|
|
|
+ regroupPlateLyrFillResults(plateIdLyrFillResultsMoveIdArray, resultPlateFillResults);
|
|
|
+ //摆放盘子
|
|
|
+ {
|
|
|
+ placePlates(isMovable,mulMoveConfigPtr, resultPlateFillResults, resultPlateCenterPointArr) ;
|
|
|
+ }
|
|
|
+ auto ms1 = std::chrono::system_clock::now().time_since_epoch() ;
|
|
|
+ uint64_t ms11 = std::chrono::duration_cast<chrono::milliseconds>(ms1).count() ;
|
|
|
+ cout<<"duration(ms): "<<ms11-ms00<<endl;
|
|
|
+ return true ;
|
|
|
+}
|
|
|
+
|
|
|
// this method is deprecated, use generatePlateTypeAndLayerCnts2()
|
|
|
[[deprecated]]
|
|
|
vector<LevelGenerate::PlateIdAndLayerCnt> LevelGenerate::generatePlateTypeAndLayerCnts(const int difficulty,const int totEquvSmallJewelCnt)
|
|
@@ -442,6 +630,202 @@ vector<LevelGenerate::PlateIdAndLayerCnt> LevelGenerate::generatePlateTypeAndLay
|
|
|
}
|
|
|
|
|
|
|
|
|
+
|
|
|
+vector<LevelGenerate::PlateIdAndLayerCnt> LevelGenerate::generatePlateTypeAndLayerCnts3(
|
|
|
+ const bool isMovable,
|
|
|
+ const FillGlobalConfig::MultiMoveConfig* mulMoveConfig,
|
|
|
+ const int difficulty,
|
|
|
+ const int totEquvSmallJewelCnt,
|
|
|
+ const LevelExtInputData& extdata )
|
|
|
+{
|
|
|
+ const int MID_PLATE_CAP = 12 ;//中盘子对小宝石的容量
|
|
|
+ //一个关卡最多出现大、中个数
|
|
|
+ int tempBigPlateCnt1 = 9 ;// 1个大盘子=2两个中盘子
|
|
|
+ int tempMidPlateCnt1 = 0 ;
|
|
|
+ computePlateCount(mulMoveConfig, tempBigPlateCnt1, tempMidPlateCnt1) ;
|
|
|
+ int equvMidPlateMaxCnt = tempBigPlateCnt1 * 2 + tempMidPlateCnt1 ;//大盘子数量换算成中盘子
|
|
|
+
|
|
|
+ FillGlobalConfig* fgc = FillGlobalConfig::getInstance() ;
|
|
|
+ FillGlobalConfig::PlateItem* bigPlateH = fgc->getPlateItemBySzNDirection(FILLGLOBALCONFIG_PLATESIZE_LG, 1) ;
|
|
|
+ FillGlobalConfig::PlateItem* midPlateH = fgc->getPlateItemBySzNDirection(FILLGLOBALCONFIG_PLATESIZE_MD, 1) ;
|
|
|
+ FillGlobalConfig::PlateItem* bigPlateV = fgc->getPlateItemBySzNDirection(FILLGLOBALCONFIG_PLATESIZE_LG, 0) ;
|
|
|
+ FillGlobalConfig::PlateItem* midPlateV = fgc->getPlateItemBySzNDirection(FILLGLOBALCONFIG_PLATESIZE_MD, 0) ;
|
|
|
+
|
|
|
+ //如果是移动关卡,先构建移动盘子
|
|
|
+ int totEquvSmallJewelCnt2 = totEquvSmallJewelCnt ;
|
|
|
+ vector<LevelGenerate::PlateIdAndLayerCnt> results ;
|
|
|
+ //剩余可以用的中盘子个数
|
|
|
+ if( isMovable ) {
|
|
|
+ int residueEquvSmlJewelCnt = 0 ;
|
|
|
+ results = generatePlateTypeAndLayerCntsForMovablePlates(mulMoveConfig, totEquvSmallJewelCnt2, residueEquvSmlJewelCnt) ;
|
|
|
+ totEquvSmallJewelCnt2 = residueEquvSmlJewelCnt ;
|
|
|
+ //减去移动的盘子
|
|
|
+ for(int ir = 0 ; ir < results.size(); ++ ir ){
|
|
|
+ if( fgc->getPlateItemById(results[ir]._plateId)->_size == FILLGLOBALCONFIG_PLATESIZE_LG ) {
|
|
|
+ equvMidPlateMaxCnt-=2 ;//减去移动的盘子
|
|
|
+ }else if(fgc->getPlateItemById(results[ir]._plateId)->_size == FILLGLOBALCONFIG_PLATESIZE_MD) {
|
|
|
+ equvMidPlateMaxCnt-=1 ;//减去移动的盘子
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 本关需要多少个一层中盘子的总数量,
|
|
|
+ // 已经去掉了移动盘子所用的宝石(如果有移动盘子的话)
|
|
|
+ int equvMidPlateCntOneLyr = ceil( totEquvSmallJewelCnt2 * 1.0 / MID_PLATE_CAP) ;
|
|
|
+
|
|
|
+ int bigPlateCntL1 = 0 ;
|
|
|
+ int midPlateCntL1 = equvMidPlateCntOneLyr ;
|
|
|
+ if( extdata._bigPlatePercent > 0 ) {
|
|
|
+ float bigPercent = extdata._bigPlatePercent*1.0/(extdata._bigPlatePercent+extdata._midPlatePercent) ;
|
|
|
+ float midPercent = 1.0 - bigPercent ;
|
|
|
+ bigPlateCntL1 = ceil( equvMidPlateCntOneLyr * 1.0 / (2.0+midPercent/bigPercent) ) ;
|
|
|
+ midPlateCntL1 = fmax(0, equvMidPlateCntOneLyr - bigPlateCntL1*2 ) ;
|
|
|
+ }
|
|
|
+
|
|
|
+ int layerCnt0 = 1 ;//盘子层数下限
|
|
|
+ int layerCnt1 = 3 ;//盘子层数上限
|
|
|
+ //计算可能的层取值范围
|
|
|
+ {
|
|
|
+ layerCnt0 = fmax(1 , totEquvSmallJewelCnt2 / (equvMidPlateCntOneLyr*MID_PLATE_CAP) ) ;
|
|
|
+ if( layerCnt0<3 ) layerCnt1 = 3 ;
|
|
|
+ else layerCnt1 = layerCnt0 + 1 ;
|
|
|
+ }
|
|
|
+
|
|
|
+ int bigPlateCnt0 = bigPlateCntL1 * 1.0 / layerCnt1 ; //大盘子最少需要数量
|
|
|
+ int bigPlateCnt1 = bigPlateCntL1 * 1.0 / layerCnt0 + 1; //大盘子最多需要数量
|
|
|
+ int midPlateCnt0 = midPlateCntL1*1.0/layerCnt1 ;
|
|
|
+ int midPlateCnt1 = midPlateCntL1*1.0/layerCnt0 + 1 ;
|
|
|
+
|
|
|
+ bool findFirstAvailableComb = false ;//第一个完全放入宝石的组合,用于当不满足任何条件时,至少返回一个可装入全部宝石的默认方案
|
|
|
+ vector<vector<LevelGenerate::PlateIdAndLayerCnt>> possibleResults ;//满足全部百分比要求的组合
|
|
|
+ vector<LevelGenerate::PlateIdAndLayerCnt> firstAvailablePlateComb ;//第一个满足全部宝石填充的组合,如果需要移动还要考虑最小移动盘子个数的条件
|
|
|
+ int firstAvailableLyrCnt = 0 ;
|
|
|
+
|
|
|
+ //难度对盘子数量的限制 普通 难 极难
|
|
|
+ //vector< vector<float> > hardPlateCntPercent0 = { {0.3,0.3}, {0.2,0.4}, {0.1,0.5} } ;
|
|
|
+ //vector< vector<float> > hardPlateCntPercent1 = { {0.7,0.7}, {0.6,0.8}, {0.5,0.9} } ;
|
|
|
+ //这个数据不需要了,通过extdata中直接获取这个数据。
|
|
|
+
|
|
|
+ //穷举全部盘子和层的组合找到符合条件的组合
|
|
|
+ for(int ibig = bigPlateCnt0; ibig <= bigPlateCnt1; ++ ibig ) {
|
|
|
+ for(int imid = midPlateCnt0; imid <= midPlateCnt1 ; ++ imid ) {
|
|
|
+ int currEquvMidPlateCnt = imid+ibig*2 ;
|
|
|
+ if( currEquvMidPlateCnt==0 ) continue ;
|
|
|
+
|
|
|
+ if( findFirstAvailableComb==false || (findFirstAvailableComb && firstAvailableLyrCnt>3 ) ) {
|
|
|
+ //保证至少有一个可以满足宝石的盘子组合,优先保存总层数大于3的情况
|
|
|
+ //当前盘子组合下最小满足的层数
|
|
|
+ int upperLyrCnt = ceil( totEquvSmallJewelCnt2 * 1.0 / (currEquvMidPlateCnt*MID_PLATE_CAP) ) ;
|
|
|
+ bool upperLyrCntOk = true ;
|
|
|
+ if( findFirstAvailableComb ) {
|
|
|
+ if( upperLyrCnt >= firstAvailableLyrCnt ) {
|
|
|
+ upperLyrCntOk = false ;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ vector<int> pidArr ;
|
|
|
+ vector<int> capArr ;
|
|
|
+ vector<int> lyrArr ;
|
|
|
+ //根据需求文档,非移动盘子,大盘子只用竖的,中盘子只用横的。
|
|
|
+ for(int it=0;it<ibig;++it) { pidArr.push_back(bigPlateV->_id);capArr.push_back(bigPlateV->_bigJewCap*4); lyrArr.push_back(upperLyrCnt); }
|
|
|
+ for(int it=0;it<imid;++it) { pidArr.push_back(midPlateH->_id);capArr.push_back(midPlateH->_bigJewCap*4); lyrArr.push_back(upperLyrCnt); }
|
|
|
+ bool lyrOk = isJustFilledAll2(capArr, lyrArr, totEquvSmallJewelCnt2) ;
|
|
|
+ if( lyrOk==false && upperLyrCnt>1 ) {
|
|
|
+ for(int it=0;it<lyrArr.size();++it ) {
|
|
|
+ lyrArr[it] -= 1 ;
|
|
|
+ lyrOk = isJustFilledAll2(capArr, lyrArr, totEquvSmallJewelCnt2) ;
|
|
|
+ if( lyrOk ) break ;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if( lyrOk && upperLyrCntOk ){
|
|
|
+ findFirstAvailableComb = true ;
|
|
|
+ firstAvailableLyrCnt = upperLyrCnt ;
|
|
|
+ //保存结果
|
|
|
+ firstAvailablePlateComb.resize(capArr.size());
|
|
|
+ for(int it = 0 ; it < capArr.size(); ++ it ) {
|
|
|
+ firstAvailablePlateComb[it]._plateId = pidArr[it] ;
|
|
|
+ firstAvailablePlateComb[it]._layerCnt = lyrArr[it] ;
|
|
|
+ firstAvailablePlateComb[it]._moveId = MOVEID_NO_MOVE ;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //计算每个类型的层数
|
|
|
+ if( difficulty== FILLGLOBALCONFIG_DIFFCULTY_NORM ) {
|
|
|
+ //全部两层
|
|
|
+ vector<int> pidArr ;
|
|
|
+ vector<int> capArr ;
|
|
|
+ vector<int> lyrArr ;
|
|
|
+ //根据需求文档,非移动盘子,大盘子只用竖的,中盘子只用横的。
|
|
|
+ for(int it=0;it<ibig;++it) { pidArr.push_back(bigPlateV->_id);capArr.push_back(bigPlateV->_bigJewCap*4); lyrArr.push_back(2); }
|
|
|
+ for(int it=0;it<imid;++it) { pidArr.push_back(midPlateH->_id);capArr.push_back(midPlateH->_bigJewCap*4); lyrArr.push_back(2); }
|
|
|
+ bool lyrOk = isJustFilledAll2(capArr, lyrArr, totEquvSmallJewelCnt2) ;
|
|
|
+ if(!lyrOk) continue;
|
|
|
+
|
|
|
+ //保存结果
|
|
|
+ vector<LevelGenerate::PlateIdAndLayerCnt> tres(capArr.size()) ;
|
|
|
+ for(int it = 0 ; it < capArr.size(); ++ it ) {
|
|
|
+ tres[it]._plateId = pidArr[it] ;
|
|
|
+ tres[it]._layerCnt = lyrArr[it] ;
|
|
|
+ tres[it]._moveId = MOVEID_NO_MOVE ;//不会移动的盘子
|
|
|
+ }
|
|
|
+ possibleResults.push_back(tres) ;
|
|
|
+
|
|
|
+ }else if( difficulty==FILLGLOBALCONFIG_DIFFCULTY_HARD2 ) {
|
|
|
+ //全部3层
|
|
|
+ vector<int> pidArr ;
|
|
|
+ vector<int> capArr ;
|
|
|
+ vector<int> lyrArr ;
|
|
|
+ //根据需求文档,非移动盘子,大盘子只用竖的,中盘子只用横的。
|
|
|
+ for(int it=0;it<ibig;++it) { pidArr.push_back(bigPlateV->_id);capArr.push_back(bigPlateV->_bigJewCap*4); lyrArr.push_back(3); }
|
|
|
+ for(int it=0;it<imid;++it) { pidArr.push_back(midPlateH->_id);capArr.push_back(midPlateH->_bigJewCap*4); lyrArr.push_back(3); }
|
|
|
+ //cout<<"debug big "<<ibig<<" mid "<<imid<<" sml "<<isml<<endl;
|
|
|
+ bool lyrOk = isJustFilledAll2(capArr, lyrArr, totEquvSmallJewelCnt2) ;
|
|
|
+ if(!lyrOk) continue;
|
|
|
+ //保存结果
|
|
|
+ vector<LevelGenerate::PlateIdAndLayerCnt> tres(capArr.size()) ;
|
|
|
+ for(int it = 0 ; it < capArr.size(); ++ it ) {
|
|
|
+ tres[it]._plateId = pidArr[it] ;
|
|
|
+ tres[it]._layerCnt = lyrArr[it] ;
|
|
|
+ tres[it]._moveId = MOVEID_NO_MOVE ;//不会移动的盘子
|
|
|
+ }
|
|
|
+ possibleResults.push_back(tres) ;
|
|
|
+ }else{
|
|
|
+ //50% 2层, 50% 3层
|
|
|
+ vector<int> pidArr ;
|
|
|
+ vector<int> capArr ;
|
|
|
+ vector<int> lyrArr ;
|
|
|
+ //根据需求文档,非移动盘子,大盘子只用竖的,中盘子只用横的。
|
|
|
+ for(int it=0;it<ibig;++it) { pidArr.push_back(bigPlateV->_id);capArr.push_back(bigPlateV->_bigJewCap*4); lyrArr.push_back((rand()%2==0)?2:3); }
|
|
|
+ for(int it=0;it<imid;++it) { pidArr.push_back(midPlateH->_id);capArr.push_back(midPlateH->_bigJewCap*4); lyrArr.push_back((rand()%2==0)?2:3); }
|
|
|
+ bool lyrOk = isJustFilledAll2(capArr, lyrArr, totEquvSmallJewelCnt2) ;
|
|
|
+ if(!lyrOk) continue;
|
|
|
+ //保存结果
|
|
|
+ vector<LevelGenerate::PlateIdAndLayerCnt> tres(capArr.size()) ;
|
|
|
+ for(int it = 0 ; it < capArr.size(); ++ it ) {
|
|
|
+ tres[it]._plateId = pidArr[it] ;
|
|
|
+ tres[it]._layerCnt = lyrArr[it] ;
|
|
|
+ tres[it]._moveId = MOVEID_NO_MOVE ;//不会移动的盘子
|
|
|
+ }
|
|
|
+ possibleResults.push_back(tres) ;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //随机挑选一个结果返回
|
|
|
+ if( possibleResults.size()> 0 ) {
|
|
|
+ int randindex = rand() % possibleResults.size();
|
|
|
+ for(int ip = 0 ; ip < possibleResults[randindex].size();++ ip ) {
|
|
|
+ results.push_back(possibleResults[randindex][ip]) ;
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ for(int ip = 0 ; ip < firstAvailablePlateComb.size();++ ip ) {
|
|
|
+ results.push_back(firstAvailablePlateComb[ip]) ;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return results ;//
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
//随机排序数组索引值
|
|
|
vector<int> LevelGenerate::randIndices(const int count0 ) {
|
|
|
int count = count0 ;
|