etrobocon2018 feat.KatLab  770af34cce41ae9c30c41303275e1add2daae0c3 (with uncommitted changes)
 全て クラス 名前空間 ファイル 関数 変数 列挙型 列挙値 フレンド マクロ定義 ページ
Selector.cpp
[詳解]
1 #include "Selector.h"
2 
3 std::vector<int> Selector::exploreNextOperation(std::int8_t currentPosition, BlockColor color)
4 {
5  const std::int8_t shelterWhenPathBlocked = 12;
6  const std::int8_t shelterWhenAllNodeInitialPositionsIsFromCenter = 12;
7  const std::int8_t goal = 11;
8  auto nextBlock = searchBlockPosition(currentPosition);
9  auto nextMovedPosition = getPositionOfCenterQuadirilateral(color);
10  auto routeBeforeOne = extractRoute();
11  auto next = nextBlock;
12  auto start = currentPosition;
13  backsteppingFlag = false;
14  backsteppingBeforeNextOeperationFlag = false;
15  isClearGame = !isAlreadyMovedNode(EMPTY_ID);
16 
17  if(currentPosition == 8 && nextBlock == 8) {
18  if(color == Undefined) {
19  setNext(Moving);
20  } else {
21  if(explorer.hasBlock(4) && explorer.hasBlock(9) && explorer.hasBlock(13)) {
23  next = shelterWhenPathBlocked;
24  pushEvacuatedBlockPosition(shelterWhenPathBlocked);
25  } else if(explorer.hasBlock(nextMovedPosition)) {
27  next = searchMostPoorCostShelter(currentPosition);
29  }
30  // else if (explorer.hasBlock(4) && explorer.hasBlock(9) && explorer.hasBlock(12))
31  // {
32  // // もし最初の位置コード8のブロックを囲むように周りにブロックが存在した場合
33  // // 現在は未実装
34  // }
35  else {
37  next = nextMovedPosition;
38  }
39  }
40  } else if(lastBlock != EMPTY_ID
41  && std::distance(movedBlockPositionList.begin(),
42  std::find(movedBlockPositionList.begin(), movedBlockPositionList.end(),
43  EMPTY_ID))
44  == 3) {
45  setNext(Moving);
46  next = lastBlock;
47  lastBlock = EMPTY_ID;
48  } else if(!isClearGame) {
49  if(color == Undefined) {
50  if(evacuatedSize > 0 && carryingFlag) {
51  setNext(Moving);
53  } else if(evacuatedSize > 0 && isCarriedToShelter) {
54  setNext(Moving);
56  isCarriedToShelter = false;
57  } else {
58  setNext(Moving);
59  }
60  } else {
61  if(explorer.hasBlock(5) && explorer.hasBlock(6) && explorer.hasBlock(9)
62  && explorer.hasBlock(10)) {
64  next = shelterWhenAllNodeInitialPositionsIsFromCenter;
65  lastBlock = shelterWhenAllNodeInitialPositionsIsFromCenter;
66  } else if(explorer.hasBlock(nextMovedPosition)) {
67  if(canFindBlockInEvacuatedList(nextMovedPosition)) {
68  next = searchMostPoorCostShelter(currentPosition);
70  isCarriedToShelter = true;
71  } else {
72  pushEvacuatedBlockPosition(currentPosition);
73  start = routeBeforeOne[routeBeforeOne.size() - 2];
74  next = nextMovedPosition;
75  setNext(Moving);
76  backsteppingBeforeNextOeperationFlag = true;
77  }
78  } else {
80  next = nextMovedPosition;
81  }
82  }
83  } else // if (isClearGame)
84  {
85  setNext(Moving);
86  next = goal;
87  }
88 
89  if(evacuatingFlag || carryingFlag) backsteppingFlag = true;
90 
91  if((evacuatingFlag || carryingFlag) && !backsteppingBeforeNextOeperationFlag)
92  changeBlockPosition(currentPosition, next);
93 
94  explorer.resetBlockArea();
95  for(auto position : blockPositionList) explorer.setHasBlockIn(position);
96  std::vector<int> route = searchRoute(start, next);
97 
98  // updateRoute(route);
99  {
100  // updateRoute(std::vector<int>)を利用するとメモリ肥大化をしてしまう
101  // おそらく仮引数routeへの代入が問題
102  // 関数内の文字列をまるまるコピペし、中括弧でくくる突貫工事で対応した
103  for(auto itr = routeBeforeOne_.begin(); itr != routeBeforeOne_.end(); itr++) (*itr) = EMPTY_ID;
104 
105  int count = 0;
106 
107  for(auto node : route) {
108  routeBeforeOne_[count] = node;
109  count++;
110  }
111  }
112 
113  if(carryingFlag) addMovedBlockPosition(next);
114 
115  return route;
116 }
117 
118 std::int8_t Selector::searchBlockPosition(std::int8_t currentPosition)
119 {
120  std::int8_t blockPosition = -1;
121  int minCost = 9999;
122 
123  for(auto checkedBlock : blockPositionList) {
124  if(isAlreadyMovedNode(checkedBlock)) continue;
125 
126  explorer.resetBlockArea();
127  for(auto position : blockPositionList) explorer.setHasBlockIn(position);
128 
129  if(checkedBlock == currentPosition) {
130  minCost = 0;
131  blockPosition = checkedBlock;
132  break;
133  }
134 
135  auto route = explorer.searchRoute(currentPosition, checkedBlock);
136  int cost = route.size() - 1 + nodePositionCostList[checkedBlock];
137 
138  if(minCost > cost) {
139  minCost = cost;
140  blockPosition = checkedBlock;
141  }
142  }
143 
144  return blockPosition;
145 }
146 
147 std::int8_t Selector::searchMostPoorCostShelter(std::int8_t currentPosition)
148 {
149  std::int8_t blockPosition = -1;
150  int minCost = 9999;
151  std::vector<std::int8_t> shelters = { 0, 3, 12, 15 };
152 
153  for(auto shelter : shelters) {
154  explorer.resetBlockArea();
155  for(auto position : blockPositionList) explorer.setHasBlockIn(position);
156 
157  if(explorer.hasBlock(shelter)) continue;
158 
159  if(shelter == currentPosition) {
160  minCost = 0;
161  blockPosition = shelter;
162  break;
163  }
164 
165  auto route = explorer.searchRoute(currentPosition, shelter);
166  int cost = route.size() - 1;
167 
168  if(minCost > cost) {
169  minCost = cost;
170  blockPosition = shelter;
171  }
172  }
173 
174  return blockPosition;
175 }
176 
177 bool Selector::isAlreadyMovedNode(std::int8_t position)
178 {
179  auto itr = std::find(movedBlockPositionList.begin(), movedBlockPositionList.end(), position);
180  return itr != movedBlockPositionList.end();
181 }
182 
184 {
185  return isClearGame;
186 }
187 
188 void Selector::changeBlockPosition(std::int8_t beforePosition, std::int8_t afterPosition)
189 {
190  auto itr = std::find(blockPositionList.begin(), blockPositionList.end(), beforePosition);
191  auto index = std::distance(blockPositionList.begin(), itr);
192 
193  blockPositionList[index] = afterPosition;
194 }
195 
196 void Selector::setBlockPositionList(std::vector<std::int8_t> list)
197 {
198  for(unsigned int i = 0; i < blockPositionList.size(); i++) {
199  blockPositionList[i] = list[i];
200  }
201 }
202 
203 std::vector<std::int8_t> Selector::getBlockPositionList()
204 {
205  return blockPositionList;
206 }
207 
208 void Selector::addMovedBlockPosition(std::int8_t position)
209 {
210  movedBlockPositionList[movedCount] = position;
211  movedCount++;
212 }
213 
214 void Selector::pushEvacuatedBlockPosition(std::int8_t position)
215 {
216  evacuatedBlockPositionList[evacuatedSize] = position;
217  evacuatedSize++;
218 }
219 
221 {
222  evacuatedSize--;
223  return evacuatedBlockPositionList[evacuatedSize];
224 }
225 
226 bool Selector::canFindBlockInEvacuatedList(std::int8_t position)
227 {
228  auto itr
229  = std::find(evacuatedBlockPositionList.begin(), evacuatedBlockPositionList.end(), position);
230  return itr != evacuatedBlockPositionList.end();
231 }
232 
233 void Selector::prepareSearching(std::vector<std::int8_t> list)
234 {
235  explorer.resetBlockArea();
236 
237  for(auto id : list) {
238  explorer.setHasBlockIn(id);
239  }
240 }
241 
242 std::vector<int> Selector::searchRoute(std::int8_t start, std::int8_t end)
243 {
244  if(start == end) {
245  std::vector<int> only{ 1 };
246  only[0] = start;
247  return only;
248  } else {
249  return explorer.searchRoute(start, end);
250  }
251 }
252 
254 {
255  switch(next) {
256  case Evacuating:
257  evacuatingFlag = true;
258  movingFlag = false;
259  carryingFlag = false;
260  break;
261 
262  case Moving:
263  evacuatingFlag = false;
264  movingFlag = true;
265  carryingFlag = false;
266  break;
267 
268  case Carrying:
269  evacuatingFlag = false;
270  movingFlag = false;
271  carryingFlag = true;
272  break;
273 
274  default:
275  break;
276  }
277 }
278 
280 {
281  return evacuatingFlag;
282 }
283 
285 {
286  return movingFlag;
287 }
288 
290 {
291  return carryingFlag;
292 }
293 
295 {
296  return backsteppingFlag;
297 }
298 
300 {
301  return backsteppingBeforeNextOeperationFlag;
302 }
303 
305 {
306  std::int8_t node;
307 
308  switch(color) {
309  case Blue:
310  node = 10;
311  break;
312 
313  case Red:
314  node = 6;
315  break;
316 
317  case Yellow:
318  node = 9;
319  break;
320 
321  case Green:
322  node = 5;
323  break;
324 
325  case Undefined:
326  default:
327  node = EMPTY_ID;
328  break;
329  }
330 
331  return node;
332 }
333 
334 [[deprecated("memory is enlarged if this is used!!!")]] void Selector::updateRoute(
335  std::vector<int> route)
336 {
337  for(auto itr = routeBeforeOne_.begin(); itr != routeBeforeOne_.end(); itr++) (*itr) = EMPTY_ID;
338 
339  int count = 0;
340 
341  for(auto node : route) {
342  routeBeforeOne_[count] = node;
343  count++;
344  }
345 }
346 
347 std::vector<int> Selector::extractRoute()
348 {
349  std::vector<int> route(TOTAL_NODE_COUNT, EMPTY_ID);
350 
351  for(int i = 0; i < TOTAL_NODE_COUNT; i++) {
352  if(routeBeforeOne_[i] == EMPTY_ID)
353  route.pop_back();
354  else
355  route[i] = routeBeforeOne_[i];
356  }
357 
358  return route;
359 }
bool isBackstepping()
Definition: Selector.cpp:294
std::int8_t searchMostPoorCostShelter(std::int8_t currentPosition)
Definition: Selector.cpp:147
void prepareSearching(std::vector< std::int8_t > list)
Definition: Selector.cpp:233
std::vector< int > searchRoute(std::int8_t start, std::int8_t end)
Definition: Selector.cpp:242
void updateRoute(std::vector< int > route)
Definition: Selector.cpp:334
std::vector< std::int8_t > getBlockPositionList()
Definition: Selector.cpp:203
bool hasBlock(std::int8_t id)
Definition: Explorer.cpp:50
std::int8_t getPositionOfCenterQuadirilateral(BlockColor color)
Definition: Selector.cpp:304
std::int8_t popEvacuatedBlockPosition()
Definition: Selector.cpp:220
bool isCarryingWithNext()
Definition: Selector.cpp:289
void setHasBlockIn(std::int8_t blockID)
Definition: Explorer.cpp:44
bool canFindBlockInEvacuatedList(std::int8_t position)
Definition: Selector.cpp:226
void setBlockPositionList(std::vector< std::int8_t > list)
Definition: Selector.cpp:196
bool isEvacuatingWithNext()
Definition: Selector.cpp:279
bool isAlreadyMovedNode(std::int8_t position)
Definition: Selector.cpp:177
bool isMovingWithNext()
Definition: Selector.cpp:284
std::vector< int > extractRoute()
Definition: Selector.cpp:347
void pushEvacuatedBlockPosition(std::int8_t position)
Definition: Selector.cpp:214
std::vector< int > exploreNextOperation(std::int8_t currentPosition, BlockColor color)
Definition: Selector.cpp:3
std::vector< int > searchRoute(std::int8_t start, std::int8_t end)
Definition: Explorer.cpp:56
bool isAlreadyAllBlockMoved()
Definition: Selector.cpp:183
void resetBlockArea()
Definition: Explorer.cpp:33
bool isBacksteppingBeforeNextOperation()
Definition: Selector.cpp:299
NextOperationOfSearchingRouteIs
Definition: Selector.h:138
void setNext(NextOperationOfSearchingRouteIs next)
Definition: Selector.cpp:253
ブロック選択クラス
void changeBlockPosition(std::int8_t beforePosition, std::int8_t afterPosition)
Definition: Selector.cpp:188
void addMovedBlockPosition(std::int8_t position)
Definition: Selector.cpp:208
std::int8_t searchBlockPosition(std::int8_t currentPosition)
Definition: Selector.cpp:118