/** * @brief Attack phase decision making */ std::pair<std::string, std::string> Defensive::attackPhase() { RiskMap* map = this->driver->getRiskMap(); std::string playerName = this->driver->getCurrentPlayerName(); std::set<std::string> countriesOwnedByPlayer = map->getCountriesOwnedByPlayer(playerName); std::pair<std::string, std::string> maxDifferencePair; int maxDifference = 0; for (const std::string &countryName : countriesOwnedByPlayer) { Country* country = map->getCountry(countryName); // Check if we have more armies than all of the neighbours opponents own bool moreArmiesThanNeighbours = true; for (const std::string &neighnourName : map->getNeighbours(country->getName())) { Country* neighbour = map->getCountry(neighnourName); if (neighbour->getPlayer() != playerName && neighbour->getArmies() > country->getArmies()) { moreArmiesThanNeighbours = false; break; } } // If we do, find the pair of countries with the greatest chance for success for (const std::string &neighnourName : map->getNeighbours(country->getName())) { Country* neighbour = map->getCountry(neighnourName); if (neighbour->getPlayer() != playerName) { int difference = neighbour->getArmies() - country->getArmies(); if (difference >= maxDifference) { maxDifference = difference; maxDifferencePair = std::pair<std::string, std::string>(country->getName(), neighbour->getName()); } } } } return maxDifferencePair; }
/** * @brief Removes a country from the map. */ void RiskMap::removeCountry(const Country& country){ std::string continent = (this->getContinentOfCountry(country.getName()))->getName(); countries.erase(country.getName()); if (mapGraph.removeNode(country.getName())){ continents.erase(continent); } this->notifyObservers(); }
//Add a new country to the list of adjacent countries void Country::addConnection(Country &conn) { connections.push_back(conn.getName()); if (!conn.isAdjacent(name)) { conn.addConnection(*this); } }
/** * @brief Reinforcement phase decision making. Places all reinforcements on the * country with the fewest armies. */ std::string Strategy::reinforcePhase() { RiskMap* map = this->driver->getRiskMap(); std::string playerName = this->driver->getCurrentPlayerName(); int minArmies = 10000; Country* minArmiesCountry = nullptr; // add the reinforcements to the player int numCardsSelected = map->getPlayer(playerName)->getCards(); int armiesEarned = convertCardsToReinforcements(numCardsSelected); if (armiesEarned > 0) { this->driver->addCardsTradeReinforcements(armiesEarned); this->driver->updatePlayerCards(-numCardsSelected); } // Reinforce the weakest country for (const std::string countryName : map->getCountriesOwnedByPlayer(playerName)) { Country* country = map->getCountry(countryName); int armies = country->getArmies(); if (armies < minArmies) { minArmies = armies; minArmiesCountry = country; } } if (minArmiesCountry == nullptr) { return ""; } return minArmiesCountry->getName(); }
/** * @brief Determines if the countries on the map are a connected graph. * @param limitTo Limits the search to the given continent (by string name) */ bool RiskMap::isConnectedGraph(const std::string& limitTo) { std::map<const Country*, bool> visited = std::map<const Country*, bool>(); for (auto const &ent1 : this->countries) { const Country& country = ent1.second; if (limitTo.size() > 0 && this->getContinentOfCountry(country.getName())->getName().compare(limitTo) != 0) { continue; } visited.insert(std::pair<const Country*, bool>(&country, false)); } Country* country = nullptr; if (limitTo.size() > 0) { country = this->getCountry(*this->getCountriesInContinent(limitTo).begin()); } else { country = &this->countries.begin()->second; } this->isConnectedGraphHelper(visited, country, limitTo); for (auto const &ent1 : visited) { if (!ent1.second) { Country country = *ent1.first; debug("Country " + country.getName() + " is not connected."); return false; } } return true; }
//Methods used to overwrite an existing object in the country or continent vectors. void Map::editCountry(Country& coun) { for (Country& c : countries) { if (c.getName() == coun.getName()) c = coun; } Notify(); }
/* * calculates the total reinforcements the player receives and stores that number */ void Reinforcement::calculateReinforcement(){ cout<< "Calculating Reinforcements for player \"" << currentplayer->getPlayerName() << "\"..." << endl; int countryreinforcements=0, continentreinforcements=0; for (int indexofcountries=0;indexofcountries<listofcountries.size();indexofcountries++)//checks ever { Country countryC = listofcountries[indexofcountries]; if (countryC.getOwner()->getPlayerName()==currentplayer->getPlayerName()) { countryreinforcements++; } } for (int indexofcontinents=0;indexofcontinents<listofcontinents.size();indexofcontinents++)//for all continent { int check=0; for (int indexofcountriesincontinent=0;indexofcountriesincontinent<listofcontinents[indexofcontinents].getNumCountries();indexofcountriesincontinent++)//looks at each continent's countries { Continent continentC = listofcontinents[indexofcontinents]; Country countriesInContient = continentC.getCountries()[indexofcountriesincontinent]; string countryincontinent = countriesInContient.getName(); for (int indexofcountries=0;indexofcountries<listofcountries.size();indexofcountries++) { Country countryC = listofcountries[indexofcountries]; if (countryC.getName()==countryincontinent && countryC.getOwner()->getPlayerName()==currentplayer->getPlayerName())//checks to see if the player owns the country { check++; } } } if (check==listofcontinents[indexofcontinents].getNumCountries())//if the player owns all the countries of the continent, he receives the army bonus { continentreinforcements+=listofcontinents[indexofcontinents].getArmyBonus(); } } int actualcountryrein=max(3,countryreinforcements/3);//player receives reinforcements equal to his countries count/3 rounded down OR 3, whichever is higher cout << currentplayer->getPlayerName() << " has received " << actualcountryrein << " reinforcements from their countries." <<endl; cout << currentplayer->getPlayerName() << " has received " << continentreinforcements << " reinforcements from their continents." <<endl; int totalreinforcements= (actualcountryrein +continentreinforcements); this->reinforcements=totalreinforcements; currentplayer->setCurrentReinforcements(totalreinforcements); }
bool World::pathFindCountry(Country* country1, Country* country2, Player* player) { cout << "DEbug country 1+++++++++++++++++++++++" << country1->getName() << endl; cout << "DEbug country 2+++++++++++++++++++++++" << country2->getName() << endl; if (country1->getName() == country2->getName() || isCountryAdjacent(country1, country2)) { return true; } queue<Country*> countryQueue; vector<Country*> boardersToCountry1 = country1->getBoarders(); countryQueue.push(country1); while (countryQueue.empty() == false) { Country* c = countryQueue.front(); countryQueue.pop(); if (c->getName() == country2->getName()) { //need to put marked back to false for every country //here but map iterator is my enemy for (std::map<string, Country*>::iterator it = _territories.begin(); it != _territories.end(); ++it) { it->second->marked = false; } return true; } for (int i = 0; i < c->getBoarders().size(); i++) { vector<Country*> allBoardersToC = c->getBoarders(); for (int k = 0; k < allBoardersToC.size(); k++) { for (int j = 0; j < player->getListCountriesOwned().size(); j++) { if (allBoardersToC.at(k)->getName() == player->getListCountriesOwned().at(j)->getName() && allBoardersToC.at(k)->marked == false) { countryQueue.push(allBoardersToC.at(k)); } } } } } /*for (int i = 0; i < boardersToCountry1.size(); i++) { for (int j = 0; j < player->getListCountriesOwned().size(); j++) { if (boardersToCountry1.at(i)->getName() == player->getListCountriesOwned().at(j)->getName()) { return pathFindCountry(boardersToCountry1.at(i), country2, player); } } }*/ }
/** * Add data from database into list view. */ void CountriesListScreen::addDataToListView() { // Clear data from map. mCountryMap.clear(); // Create first section. NativeUI::ListViewSection* section = NULL; MAUtil::String sectionTitle("A"); // For each country read create and add an ListViewItem widget. int countCountries = mDatabase.countCountries(); for (int index = 0; index < countCountries; index++) { // If index is invalid skip this country. Country* country = mDatabase.getCountryByIndex(index); if (!country) { continue; } // If country's name is an empty string skip this country. MAUtil::String countryName = country->getName(); if (countryName.length() == 0) { continue; } // Check if current country can go into current section. if (!section || countryName[0] != sectionTitle[0]) { // Create new section. sectionTitle[0] = countryName[0]; section = new NativeUI::ListViewSection( NativeUI::LIST_VIEW_SECTION_TYPE_ALPHABETICAL); section->setTitle(sectionTitle); section->setHeaderText(sectionTitle); mListView->addChild(section); } // Create and add list item for this country. NativeUI::ListViewItem* item = new NativeUI::ListViewItem(); item->setText(countryName); item->setFontColor(COLOR_WHITE); item->setSelectionStyle(NativeUI::LIST_VIEW_ITEM_SELECTION_STYLE_GRAY); item->setIcon(country->getFlagID()); section->addItem(item); mCountryMap.insert(item->getWidgetHandle(), country->getID()); } }
void drawCountry(Renderer* canvas, const Country &country, bool drawDescription) { /** Title area **/ Font fontCountryName("resources/fonts/FreeSansBold.ttf", 30); fontCountryName.setColor(Color(0xf0, 0xff, 0xff)); Text name(country.getName(), &fontCountryName); canvas->drawText(&name, Point(358, 105)); /* Photo area */ string photoPath = "data/countries/" + country.getIsoCode() + "/postal.png"; FileUtils fileUtils; if (!fileUtils.fileExists(photoPath.c_str())) { photoPath = "data/countries/default-photo.jpg"; } Surface photoSurface(photoPath); photoSurface.transform(4, 1, 1); Texture photoTexture(canvas->internal, photoSurface.toSDL()); canvas->drawTexture(&photoTexture, Point(47, 115)); Texture polaroidSurf(canvas->internal, "resources/images/game/polaroid.png"); canvas->drawTexture(&polaroidSurf, Point(30, 108)); string flagPath = "data/countries/" + country.getIsoCode() + "/flag.png"; Surface flagSurface(flagPath); flagSurface.transform(0, .5, 1); Texture flagTexture(canvas->internal, flagSurface.toSDL()); canvas->drawTexture(&flagTexture, Point(300, 110)); if (drawDescription) { Font descFont("resources/fonts/FreeSansBold.ttf", 14); descFont.setColor(Color(0xd3, 0xba, 0xa4)); Text description(country.getDescription(), &descFont); TextUtils textUtils; textUtils.drawLines(canvas, description, Point(358, 150), Dimension(360, 340)); } }
/** * @brief Parses the Conquest .map map file in the path indicated to populate the instance */ void RiskMap::loadMap(const std::string& path) { std::ifstream infile(path); std::string line; int mode = 0; while (std::getline(infile, line)) { std::string debug_str("Read line: "); debug_str.append(line); debug(debug_str); // Windows prefers /r/n, but getline() breaks only on \n. if (line.size() > 0 && line[line.size() - 1] == '\r') { line.resize(line.size() - 1); } // Set the mode for how we should process lines based on section headers if (line.compare("[Map]") == 0) { mode = MAP_PARSE_MODE_MAP; debug(" Parsing map metadata"); continue; } if (line.compare("[Continents]") == 0) { mode = MAP_PARSE_MODE_CONTINENTS; debug(" Parsing continents"); continue; } if (line.compare("[Territories]") == 0) { mode = MAP_PARSE_MODE_COUNTRIES; debug(" Parsing countries"); continue; } // Process lines per the current mode. std::string item; std::stringstream line_stream(line); std::vector<std::string> values; if (mode == MAP_PARSE_MODE_MAP || line.length() == 0) { debug_str = " Skipping: "; debug_str.append(line); debug(debug_str); continue; } else if (mode == MAP_PARSE_MODE_CONTINENTS) { while (std::getline(line_stream, item, '=')) { values.push_back(item); } debug_str = " Adding continent: "; debug_str.append(values[0]); debug(debug_str); Continent continent(values[0]); continent.setReinforcementBonus(atoi(values[1].c_str())); this->addContinent(continent); } else if (mode == MAP_PARSE_MODE_COUNTRIES) { while (std::getline(line_stream, item, ',')) { values.push_back(item); } std::string continentName(values[3]); debug_str = " Adding country: "; debug_str.append(values[0]); debug_str.append(" in continent "); debug_str.append(continentName); debug(debug_str); Country country(values[0]); country.setPositionX(atoi(values[1].c_str())); country.setPositionY(atoi(values[2].c_str())); country.setArmies(0); this->addCountry(country, continentName); } else { debug("Error parsing line: " + line); return; } } debug("Parsing file again to configure adjacencies"); infile.clear(); infile.seekg(0, std::ios_base::beg); while (std::getline(infile, line)) { std::string debug_str("Read line: "); debug_str.append(line); debug(debug_str); // Windows prefers /r/n, but getline() breaks only on \n. if (line.size() > 0 && line[line.size() - 1] == '\r') { line.resize(line.size() - 1); } // Set the mode for how we should process lines based on section headers if (line.compare("[Map]") == 0) { mode = MAP_PARSE_MODE_MAP; debug(" Parsing map metadata"); continue; } if (line.compare("[Continents]") == 0) { mode = MAP_PARSE_MODE_CONTINENTS; debug(" Parsing continents"); continue; } if (line.compare("[Territories]") == 0) { mode = MAP_PARSE_MODE_COUNTRIES; debug(" Parsing countries"); continue; } // Process lines per the current mode. std::string item; std::stringstream line_stream(line); std::vector<std::string> values; if (mode != MAP_PARSE_MODE_COUNTRIES || line.length() == 0) { debug_str = " Skipping: "; debug_str.append(line); debug(debug_str); continue; } else if (mode == MAP_PARSE_MODE_COUNTRIES) { while (std::getline(line_stream, item, ',')) { values.push_back(item); } Country* country = this->getCountry(values[0]); std::vector<std::string>::iterator iter; for (iter = values.begin() + 4; iter < values.end(); iter++) { Country* neighbour = this->getCountry(*iter); this->addNeighbour(country->getName(), neighbour->getName()); debug_str = " "; debug_str.append(country->getName()); debug_str.append(" touches "); debug_str.append(neighbour->getName()); debug(debug_str); } } else { debug("Error parsing line: " + line); return; } } debug("Finished parsing: " + path); }