// // GridPositionTool.cpp // auto_fill_jewel_v3 // // Created by Red on 2024/12/4. // #include "GridPositionTool.hpp" #include #include using std::pair ; #include using std::cout; using std::endl; #define GRIDPOSITIONTOOL_BIG_GRID_NCOLS 3 #define GRIDPOSITIONTOOL_BIG_GRID_NROWS 3 #define GRIDPOSITIONTOOL_GAME_WIDTH 640 #define GRIDPOSITIONTOOL_GAME_HEIGHT 720 #define GRIDPOSITIONTOOL_LG_W 210 #define GRIDPOSITIONTOOL_LG_H 270 #define GRIDPOSITIONTOOL_MD_W 210 #define GRIDPOSITIONTOOL_MD_H 135 #define GRIDPOSITIONTOOL_SM_W 105 #define GRIDPOSITIONTOOL_SM_H 135 void GridPositionTool::solve(const bool movable, const string firstMoveTypeCode, const string secondMoveTypeCode, const vector& plateTypeIdArr , const vector& moveIdArr , vector>& resultPositions ) { resultPositions.resize(plateTypeIdArr.size()) ; string moveTypeCode = "" ;//no movement. if( movable ==true ) { moveTypeCode = firstMoveTypeCode + secondMoveTypeCode ;// A B C BA CB CA } auto fgc = FillGlobalConfig::getInstance() ; //先安排第一行移动大盘子 for(int iplate = 0 ; iplate < plateTypeIdArr.size();++ iplate ) { int plateTypeId = plateTypeIdArr[iplate] ; FillGlobalConfig::PlateItem* platePtr = fgc->getPlateItemById(plateTypeId) ; int moveid = moveIdArr[iplate] ;// 0-nomove, 1-firstmove , 2-secondmove int plateSize = platePtr->_size ; if( moveid==1 && plateSize == FILLGLOBALCONFIG_PLATESIZE_LG) { ContourData::Point lowerLeftPosition ; FillGlobalConfig::GridBoxCell* gbcPtr = fgc->getLowestUnfilledGridBox(moveTypeCode, moveid, plateSize, lowerLeftPosition); assert( gbcPtr != nullptr ) ; fgc->setFilled(gbcPtr, plateSize) ; resultPositions[iplate] = {(int)lowerLeftPosition.x, (int)lowerLeftPosition.y} ; } } //安排第一行移动中盘子 for(int iplate = 0 ; iplate < plateTypeIdArr.size();++ iplate ) { int plateTypeId = plateTypeIdArr[iplate] ; FillGlobalConfig::PlateItem* platePtr = fgc->getPlateItemById(plateTypeId) ; int moveid = moveIdArr[iplate] ;// 0-nomove, 1-firstmove , 2-secondmove int plateSize = platePtr->_size ; if( moveid==1 && plateSize == FILLGLOBALCONFIG_PLATESIZE_MD) { ContourData::Point lowerLeftPosition ; FillGlobalConfig::GridBoxCell* gbcPtr = fgc->getLowestUnfilledGridBox(moveTypeCode, moveid, plateSize, lowerLeftPosition); assert( gbcPtr != nullptr ) ; fgc->setFilled(gbcPtr, plateSize) ; resultPositions[iplate] = {(int)lowerLeftPosition.x, (int)lowerLeftPosition.y} ; } } //先安排第二行移动大盘子 for(int iplate = 0 ; iplate < plateTypeIdArr.size();++ iplate ) { int plateTypeId = plateTypeIdArr[iplate] ; FillGlobalConfig::PlateItem* platePtr = fgc->getPlateItemById(plateTypeId) ; int moveid = moveIdArr[iplate] ;// 0-nomove, 1-firstmove , 2-secondmove int plateSize = platePtr->_size ; if( moveid==2 && plateSize == FILLGLOBALCONFIG_PLATESIZE_LG) { ContourData::Point lowerLeftPosition ; FillGlobalConfig::GridBoxCell* gbcPtr = fgc->getLowestUnfilledGridBox(moveTypeCode, moveid, plateSize, lowerLeftPosition); assert( gbcPtr != nullptr ) ; fgc->setFilled(gbcPtr, plateSize) ; resultPositions[iplate] = {(int)lowerLeftPosition.x, (int)lowerLeftPosition.y} ; } } //安排第二行移动中盘子 for(int iplate = 0 ; iplate < plateTypeIdArr.size();++ iplate ) { int plateTypeId = plateTypeIdArr[iplate] ; FillGlobalConfig::PlateItem* platePtr = fgc->getPlateItemById(plateTypeId) ; int moveid = moveIdArr[iplate] ;// 0-nomove, 1-firstmove , 2-secondmove int plateSize = platePtr->_size ; if( moveid==2 && plateSize == FILLGLOBALCONFIG_PLATESIZE_MD) { ContourData::Point lowerLeftPosition ; FillGlobalConfig::GridBoxCell* gbcPtr = fgc->getLowestUnfilledGridBox(moveTypeCode, moveid, plateSize, lowerLeftPosition); assert( gbcPtr != nullptr ) ; fgc->setFilled(gbcPtr, plateSize) ; resultPositions[iplate] = {(int)lowerLeftPosition.x, (int)lowerLeftPosition.y} ; } } //安排不移动大盘子 for(int iplate = 0 ; iplate < plateTypeIdArr.size();++ iplate ) { int plateTypeId = plateTypeIdArr[iplate] ; FillGlobalConfig::PlateItem* platePtr = fgc->getPlateItemById(plateTypeId) ; int moveid = moveIdArr[iplate] ;// 0-nomove, 1-firstmove , 2-secondmove int plateSize = platePtr->_size ; if( moveid==0 && plateSize == FILLGLOBALCONFIG_PLATESIZE_LG) { ContourData::Point lowerLeftPosition ; FillGlobalConfig::GridBoxCell* gbcPtr = fgc->getLowestUnfilledGridBox(moveTypeCode, moveid, plateSize, lowerLeftPosition); assert( gbcPtr != nullptr ) ; fgc->setFilled(gbcPtr, plateSize) ; resultPositions[iplate] = {(int)lowerLeftPosition.x, (int)lowerLeftPosition.y} ; } } //安排不移动中盘子 for(int iplate = 0 ; iplate < plateTypeIdArr.size();++ iplate ) { int plateTypeId = plateTypeIdArr[iplate] ; FillGlobalConfig::PlateItem* platePtr = fgc->getPlateItemById(plateTypeId) ; int moveid = moveIdArr[iplate] ;// 0-nomove, 1-firstmove , 2-secondmove int plateSize = platePtr->_size ; if( moveid==0 && plateSize == FILLGLOBALCONFIG_PLATESIZE_MD) { ContourData::Point lowerLeftPosition ; FillGlobalConfig::GridBoxCell* gbcPtr = fgc->getLowestUnfilledGridBox(moveTypeCode, moveid, plateSize, lowerLeftPosition); assert( gbcPtr != nullptr ) ; fgc->setFilled(gbcPtr, plateSize) ; resultPositions[iplate] = {(int)lowerLeftPosition.x, (int)lowerLeftPosition.y} ; } } } bool GridPositionTool::getIndexPositionInGrid( const vector>& gridRows, const int index, int& col,int& row) { col = -1 ; row = -1 ; for(int irow = 0 ; irow < gridRows.size();++irow ) { for(int icol=0; icol < gridRows[irow].size(); ++ icol ) { if( gridRows[irow][icol] == index ) { col = icol ; row = irow ; return true ; } } } std::cout<<"error: could not found index from grid. "< GridPositionTool::computePositionByGridColRow(int plateSize, int col, int row ) { if( plateSize == FILLGLOBALCONFIG_PLATESIZE_LG ) { //将左上角原点的网格坐标换算成左下角原点网格坐标 row = GRIDPOSITIONTOOL_BIG_GRID_NROWS - 1 - row ; int x0 = 0 ; int y0 = GRIDPOSITIONTOOL_GAME_HEIGHT/2 - GRIDPOSITIONTOOL_BIG_GRID_NROWS*GRIDPOSITIONTOOL_LG_H/2; int widthAndMargin = GRIDPOSITIONTOOL_GAME_WIDTH / GRIDPOSITIONTOOL_BIG_GRID_NCOLS ; return { (int)(x0+(col+0.5)*widthAndMargin ) , (int)(y0+(row+0.5)*GRIDPOSITIONTOOL_LG_H) } ; }else if( plateSize==FILLGLOBALCONFIG_PLATESIZE_MD ) { //将左上角原点的网格坐标换算成左下角原点网格坐标 row = GRIDPOSITIONTOOL_BIG_GRID_NROWS*2 - 1 - row ; int x0 = 0 ; int y0 = GRIDPOSITIONTOOL_GAME_HEIGHT/2 - GRIDPOSITIONTOOL_BIG_GRID_NROWS * 2 * GRIDPOSITIONTOOL_MD_H/2; int widthAndMargin = GRIDPOSITIONTOOL_GAME_WIDTH / GRIDPOSITIONTOOL_BIG_GRID_NCOLS ; return { (int)(x0+(col+0.5)*widthAndMargin ) , (int)(y0+(row+0.5)*GRIDPOSITIONTOOL_MD_H) } ; }else { // FILLGLOBALCONFIG_JEWELSIZE_SM //将左上角原点的网格坐标换算成左下角原点网格坐标 row = GRIDPOSITIONTOOL_BIG_GRID_NROWS*2 - 1 - row ; int x0 = 0 ; int y0 = GRIDPOSITIONTOOL_GAME_HEIGHT/2 - GRIDPOSITIONTOOL_BIG_GRID_NROWS * 2 * GRIDPOSITIONTOOL_SM_H/2; int widthAndMargin = GRIDPOSITIONTOOL_GAME_WIDTH / (GRIDPOSITIONTOOL_BIG_GRID_NCOLS*2) ; return { (int)(x0+(col+0.5)*widthAndMargin ) , (int)(y0+(row+0.5)*GRIDPOSITIONTOOL_SM_H) } ; } }