TournamentPair* RoundRobinTournament::nextPair(int gameNumber) { if (gameNumber >= finalGameCount()) return 0; if (gameNumber % gamesPerEncounter() != 0) return currentPair(); if (m_pairNumber >= m_topHalf.size()) { m_pairNumber = 0; setCurrentRound(currentRound() + 1); m_topHalf.insert(1, m_bottomHalf.takeFirst()); m_bottomHalf.append(m_topHalf.takeLast()); } int white = m_topHalf.at(m_pairNumber); int black = m_bottomHalf.at(m_pairNumber); m_pairNumber++; // If 'white' or 'black' equals 'playerCount()' it means // that it's a "bye" player, that is an empty player that // makes the pairings easier to organize. In that case // no game is played and we skip to the next pair. if (white < playerCount() && black < playerCount()) return pair(white, black); else return nextPair(gameNumber); }
void basicFourWayExpander::getSuccessors(int a_currentPosition, int a_parent, int a_finalPosition, map& a_map, Direction* a_direction, std::vector<std::pair<int, Direction> >& a_successors) { const int* oneStepMove = a_map.getOneStepMove(); for (int j = 0; j < 4; j++) { int nextPos = a_currentPosition + oneStepMove[j]; Direction nextDir = a_direction[j]; std::pair<int, Direction> nextPair(nextPos, nextDir); a_successors.push_back(nextPair); } }
std::pair<int,int> CellList::nextPair() { //if we are looking in the same cell for neighbors if (_same_cell) { //if j exceeds the number of objects in cell c if (!(_j < _cell[_c].getNumberOfObjects())) { //reset j to zero for next time it enters _j = 0; //reset neighbor cell number and neighbor number to zero _n = 0; _k = 0; _same_cell = false; nextPair(); return _current_pair; } else { //otherwise skip objects w / >= sequencer if (_cell[_c].getContents()[_j] >= _current_pair.first) { _j++; nextPair(); return _current_pair; } else { _current_pair.second = _cell[_c].getContents()[_j]; _j++; return _current_pair; } } } else { //if k exceeds the number of objects in cell c neighbor n if(!(_k<_cell[_cell[_c].getNeighbors()[_n]].getNumberOfObjects())) { _n++; //move on to the next neighbor _k = 0; //reset k to zero //if n exceeds the number of neighboring cells if(!(_n < _cell[_c].getNumberOfNeighbors())) { _i++; //move on to the next object //if the next object does not exist if(!(_i < (int)_tag.size())) { _end = true; return _current_pair; } //otherwise move on to the next cell _current_pair.first = _tag[_i]; _same_cell = true; _c = _cell_containing[_current_pair.first]; } nextPair(); return _current_pair; } else { //get the next object in the cell _current_pair.second = _cell[_cell[_c].getNeighbors()[_n]].getContents()[_k++]; return _current_pair; } } }
// vanilla 8 direction search int aStarSearch::eightDirectionSearch(const int a_startX, const int a_startY, const int a_targetX, const int a_targetY, const int a_mapWidth, const int a_mapHeight, map& a_map, int* a_outBuffer, const int a_outBufferSize) { // create open set, priority queue returns the greater of the two compared elements, so tell it to use > instead of < to compare // the pair to be put in queue is the (f cost, position) std::priority_queue<std::pair<double,int>, std::vector<std::pair<double,int> >, std::greater<std::pair<double,int> > > openSet; std::unordered_map<int,int> cameFrom; std::unordered_map<int,double> costSoFar; // keep track of who is visited, the bool is sort of pointless.. std::unordered_map<int,bool> visited; // get heuristic octileHeuristic heuristic; int startPosition = a_startX + a_startY * a_mapWidth; int finalPosition = a_targetX + a_targetY * a_mapWidth; // start with initial condition and put it in queue std::pair<double,int> startPair(0,startPosition); cameFrom[startPosition] = startPosition; openSet.push(startPair); // one step in order: N S E W NE NW SE SW const int* oneStepMove = a_map.getOneStepMove(); while (!openSet.empty()) { // get best position so far int currentPosition = openSet.top().second; openSet.pop(); // never visited if (!visited.count(currentPosition)) { // put it in visited visited[currentPosition] = true; if (currentPosition == finalPosition) { return reconstructPath(startPosition, currentPosition, a_map, cameFrom, a_outBuffer, a_outBufferSize); } // consider the 8 possible moves double cost; for (int successor = 0; successor < 8; successor++) { int nextPos = currentPosition + oneStepMove[successor]; // check if move is possible if (a_map[nextPos]) { // for visualization purposes a_map[nextPos] = 2; // straight moves cost 1, diagonal moves cost sqrt(2) if (successor < 4) { cost = costSoFar[currentPosition] + 1; } else { cost = costSoFar[currentPosition] + sqrt(2); } // if the neighbor is not in open set or cost from this node is better if (!costSoFar.count(nextPos) || cost < costSoFar[nextPos]) { costSoFar[nextPos] = cost; double priority = cost + heuristic.estimateCost(nextPos, a_targetX, a_targetY, a_mapWidth); std::pair<double,int> nextPair(priority,nextPos); openSet.push(nextPair); cameFrom[nextPos] = currentPosition; } } } } } // couldn't find a solution return -1; }
// vanilla jps int aStarSearch::jumpPointSearch(const int a_startX, const int a_startY, const int a_targetX, const int a_targetY, const int a_mapWidth, const int a_mapHeight, map& a_map, int* a_outBuffer, const int a_outBufferSize) { // compute start and final positions int startPosition = a_startX + a_startY * a_mapWidth; int finalPosition = a_targetX + a_targetY * a_mapWidth; // create open set, priority queue returns the greater of the two compared elements, so tell it to use > instead of < to compare // the pair to be put in queue is the (f cost, position) std::priority_queue<std::pair<double,int>, std::vector<std::pair<double,int> >, std::greater<std::pair<double,int> > > openSet; std::unordered_map<int,int> cameFrom; std::unordered_map<int,double> costSoFar; // keep track of who is visited, the bool is sort of pointless.. std::unordered_map<int,bool> visited; // get heuristic octileHeuristic heuristic; double priority, cost; // get jump point finder jumpPointTools jpTools; /* // get dead end detector and detect deadend deadendDetector deDetector; std::vector<int> relevantZones(a_map.getNumZones()+1,0); deDetector.deadendSearch(a_map.getZone(startPosition), a_map.getZone(finalPosition), a_map.getZoneConnections(), relevantZones); */ cameFrom[startPosition] = startPosition; // one step in order: N S E W NE NW SE SW const int* oneStepMove = a_map.getOneStepMove(); Direction directions [] = { Direction::N, Direction::S, Direction::E, Direction::W, Direction::NE, Direction::NW, Direction::SE, Direction::SW}; // start problem off by moving one step in every direction from starting position visited[startPosition] = true; for (int successor = 0; successor < 8; successor++) { int nextPos = startPosition + oneStepMove[successor]; // check if move is possible if (a_map[nextPos]) { // for visualization purposes a_map[nextPos] = 2; // straight moves cost 1, diagonal moves cost sqrt(2) if (successor < 4) { cost = costSoFar[startPosition] + 1; } else { cost = costSoFar[startPosition] + sqrt(2); } costSoFar[nextPos] = cost; priority = cost + heuristic.estimateCost(nextPos, a_targetX, a_targetY, a_mapWidth); std::pair<double,int> nextPair(priority,nextPos); openSet.push(nextPair); cameFrom[nextPos] = startPosition; } } // look at open set while (!openSet.empty()) { // get best position so far int currentPosition = openSet.top().second; openSet.pop(); // haven't visited this node yet if (!visited.count(currentPosition)) { visited[currentPosition] = true; // check end condition if (currentPosition == finalPosition) { return reconstructPath(startPosition, currentPosition, a_map, cameFrom, a_outBuffer, a_outBufferSize); } // find out how parent got here, currentPosition = parent + parentDirection Direction parentDirection = jpTools.findParentDirection(currentPosition, cameFrom[currentPosition], oneStepMove, directions); // find successors! std::vector<std::pair<int, Direction> > successors; jpTools.findJumpPoints(currentPosition, a_map, parentDirection, finalPosition, oneStepMove, successors); for (int j = 0; j < successors.size(); j++) { // what is successor and what direction to get there int nextPos = successors[j].first; Direction nextDir = successors[j].second; // check if move is possible if (a_map[nextPos]) { // for visualization purposes a_map[nextPos] = 2; // find out how many jumps it took to get here int numOfJumps = 0; int temp = currentPosition; while (temp != nextPos) { numOfJumps++; temp += oneStepMove[nextDir]; } // straight moves cost 1, diagonal moves cost sqrt(2) if (nextDir < 4) { cost = costSoFar[currentPosition] + numOfJumps; } else { cost = costSoFar[currentPosition] + numOfJumps*sqrt(2); } // if the neighbor is not in open set or cost from this node is better if (!costSoFar.count(nextPos) || cost < costSoFar[nextPos]) { priority = cost + heuristic.estimateCost(nextPos, a_targetX, a_targetY, a_mapWidth); std::pair<double,int> nextPair(priority,nextPos); openSet.push(nextPair); // update entire path to the jump point for cost and came from for (int j = 1; j <= numOfJumps; j++) { int updatePos = currentPosition + j*oneStepMove[nextDir]; a_map[updatePos] = 2; if (nextDir < 4) { costSoFar[updatePos] = costSoFar[currentPosition] + j; } else { costSoFar[updatePos] = costSoFar[currentPosition] + j * sqrt(2); } cameFrom[updatePos] = updatePos - oneStepMove[nextDir]; } } } } } } // couldn't find a solution return -1; }