etrobocon2018 feat.KatLab  770af34cce41ae9c30c41303275e1add2daae0c3 (with uncommitted changes)
 全て クラス 名前空間 ファイル 関数 変数 列挙型 列挙値 フレンド マクロ定義 ページ
Explorer.cpp
[詳解]
1 #include "Explorer.h"
2 
4 {
5  int nodeCount = neighborsIDList.size();
6 
7  // ノードのポインタのリストを作成
8  for(int i = 0; i < nodeCount; i++) {
9  Node node;
10  node.setNodeID(i);
11  nodeList.push_back(node);
12  nodePtrs.push_back(&nodeList[i]);
13  //nodePtrs.push_back(&node);
14  }
15  // 隣接ノードのポインタのリストをノード分リスト化
16  for(int i = 0; i < nodeCount; i++) {
17  for(int nodeID : neighborsIDList[i]) {
18  if(nodeID == EMPTY_ID) break;
19  neighborPtrs[i].push_back(nodePtrs[nodeID]);
20  }
21  }
22 
23  // 隣接ノードのポインタのリストを格納
24  for(int i = 0; i < nodeCount; i++) {
25  nodePtrs[i]->setNeighbors(&neighborPtrs[i]);
26  nodePtrs[i]->setPosition(positionList[i].x, positionList[i].y);
27  }
28 
29  // 各ノードのポインタを格納
30  blockAreaNodeList = &nodePtrs;
31 }
32 
34 {
35  for(auto itr = blockAreaNodeList->begin(); itr <= blockAreaNodeList->end(); itr++) {
36  (*itr)->setBeClosed(false);
37  (*itr)->setHasBlock(false);
38  (*itr)->setScore(0);
39  (*itr)->setRealCost(0);
40  (*itr)->setParentNode(nullptr);
41  }
42 }
43 
44 void Explorer::setHasBlockIn(std::int8_t blockID)
45 {
46  auto itr = blockAreaNodeList->begin() + blockID;
47  (*itr)->setHasBlock(true);
48 }
49 
50 bool Explorer::hasBlock(std::int8_t id)
51 {
52  auto itr = blockAreaNodeList->begin() + id;
53  return (*itr)->hasBlock();
54 }
55 
56 std::vector<int> Explorer::searchRoute(std::int8_t start, std::int8_t end)
57 {
58  auto startItr = blockAreaNodeList->begin() + start;
59  auto endItr = blockAreaNodeList->begin() + end;
60 
61  int estimatedCostX = std::abs((*endItr)->getPositionX() - (*startItr)->getPositionX());
62  int estimatedCostY = std::abs((*endItr)->getPositionY() - (*startItr)->getPositionY());
63  int score = estimatedCostX + estimatedCostY;
64  if((*startItr)->hasBlock()) score += 99;
65 
66  (*startItr)->setScore(score);
67  (*startItr)->setRealCost(0);
68  (*startItr)->setParentNode(nullptr);
69 
70  std::vector<Node*> around;
71  Node* endNode = calculateNeighborCost((*startItr), &around, 1, end);
72 
73  std::vector<int> route = { endNode->getNodeID() };
74  Node* parent = endNode->getParentNode();
75  while(parent != nullptr) {
76  route.push_back(parent->getNodeID());
77  parent = parent->getParentNode();
78  }
79 
80  std::reverse(route.begin(), route.end());
81 
82  return route;
83 }
84 
85 Node* Explorer::calculateNeighborCost(Node* parent, std::vector<Node*>* around,
86  std::int32_t realCost, std::int8_t end)
87 {
88  auto currentItr = blockAreaNodeList->begin() + parent->getNodeID();
89  auto endItr = blockAreaNodeList->begin() + end;
90 
91  parent->setBeClosed(true);
92 
93  for(auto itr = (*currentItr)->getNeighbors()->begin();
94  itr != (*currentItr)->getNeighbors()->end(); itr++) {
95  if((*itr)->isClosed() || (*itr) == parent->getParentNode()) continue;
96 
97  int estimatedCostX = std::abs((*endItr)->getPositionX() - (*itr)->getPositionX());
98  int estimatedCostY = std::abs((*endItr)->getPositionY() - (*itr)->getPositionY());
99  int score = realCost + estimatedCostX + estimatedCostY;
100  if((*itr)->hasBlock() && (*itr)->getNodeID() != end) score += 99;
101 
102  (*itr)->setScore(score);
103  (*itr)->setRealCost(realCost);
104  (*itr)->setParentNode(parent);
105  around->push_back((*itr));
106  }
107 
108  std::int32_t min = 999;
109  std::int32_t minCost = 999;
110  Node* minNode = nullptr;
111 
112  for(auto itr = around->begin(); itr != around->end(); itr++) {
113  if((*itr)->isClosed() || (*itr) == parent->getParentNode()) continue;
114 
115  int score = (*itr)->getScore();
116  if(score > min || (score == min && (*itr)->getRealCost() >= minCost)) continue;
117 
118  min = score;
119  minCost = (*itr)->getRealCost();
120  minNode = (*itr);
121  }
122 
123  if(minNode->getNodeID() != end) {
124  std::int8_t cost = 0;
125  Node* node = minNode;
126  while(node->getParentNode() == nullptr) {
127  cost++;
128  node = node->getParentNode();
129  }
130  minNode = calculateNeighborCost(minNode, around, realCost + 1, end);
131  }
132 
133  return minNode;
134 }
135 
136 std::vector<Node*>* Explorer::getBlockAreaNodeList()
137 {
138  return blockAreaNodeList;
139 }
void setNodeID(std::int8_t nodeNumber)
Definition: Node.cpp:13
Node * getParentNode()
Definition: Node.cpp:54
Definition: Node.h:142
void createBlockArea()
Definition: Explorer.cpp:3
std::vector< Node * > * getBlockAreaNodeList()
Definition: Explorer.cpp:136
bool hasBlock(std::int8_t id)
Definition: Explorer.cpp:50
Node * calculateNeighborCost(Node *parent, std::vector< Node * > *around, std::int32_t realCost, std::int8_t end)
Definition: Explorer.cpp:85
void setHasBlockIn(std::int8_t blockID)
Definition: Explorer.cpp:44
void setBeClosed(bool closed_)
Definition: Node.cpp:79
std::vector< int > searchRoute(std::int8_t start, std::int8_t end)
Definition: Explorer.cpp:56
std::int8_t getNodeID()
Definition: Node.cpp:18
ルート探索クラス
void resetBlockArea()
Definition: Explorer.cpp:33
std::int32_t getScore()
Definition: Node.cpp:64