std::string PlanetWarsGame::toString(Player* pov) const { std::stringstream gameState; const int numPlanets = static_cast<int>(m_planets.size()); //Write the planets. for (int i = 0; i < numPlanets; ++i) { Planet* planet = m_planets[i]; gameState << "P " << planet->getX() << " " << planet->getY() << " " << pov->povId(planet->getOwner()) << " " << planet->getNumShips() << " " << planet->getGrowthRate() << std::endl; } //Write the fleets. for (FleetList::const_iterator it = m_fleets.begin(); it != m_fleets.end(); ++it) { Fleet* fleet = (*it); gameState << "F " << pov->povId(fleet->getOwner()) << " " << fleet->getNumShips() << " " << fleet->getSource()->getId() << " " << fleet->getDestination()->getId() << " " << fleet->getTotalTripLength() << " " << fleet->getTurnsRemaining() << std::endl; } gameState << "go" << std::endl; return gameState.str(); }
void Planet::welcomeArrivedFleets() { const int ownerId = m_owner->getId(); //Tally up the ships for each force. const int numArrivedFleets = static_cast<int>(m_landedFleets.size()); if (numArrivedFleets == 0) { return; } int playerShips[3]; playerShips[0] = (ownerId == 0) ? m_numShips : 0; playerShips[1] = (ownerId == 1) ? m_numShips : 0; playerShips[2] = (ownerId == 2) ? m_numShips : 0; for (int i = 0; i < numArrivedFleets; ++i) { Fleet* fleet = m_landedFleets[i]; playerShips[fleet->getOwner()->getId()] += fleet->getNumShips(); } m_landedFleets.clear(); //Check who won. //Check whether the owner stays the same. if (playerShips[ownerId] >= std::max(playerShips[(ownerId+1)%3], playerShips[(ownerId+2)%3])) { this->setNumShips(playerShips[ownerId] - std::max(playerShips[(ownerId+1)%3], playerShips[(ownerId+2)%3])); return; } //Otherwise, find the new owner. if (playerShips[1] > playerShips[2]) { this->setOwner(m_game->getFirstPlayer()); const int remainingShips = playerShips[1] - std::max(playerShips[2], playerShips[0]); this->setNumShips(remainingShips); } else if (playerShips[2] > playerShips[1]) { this->setOwner(m_game->getSecondPlayer()); const int remainingShips = playerShips[2] - std::max(playerShips[1], playerShips[0]); this->setNumShips(remainingShips); } else if (ownerId == 0 && playerShips[2] == playerShips[1]) { //The invading fleets are larger than the neutral planet, but equal in size. //Planet stays neutral. this->setNumShips(0); } //There should be no other cases. }
void PlanetWarsGame::completeStep() { //Proceed only if there's an unfinished step. if (STEPPING != m_state) { return; } m_state = PROCESSING; //Clear the old new fleets. m_newFleets.clear(); //Read and process the the responses from each of the players. std::string firstPlayerOutput(m_firstPlayer->readCommands()); std::string secondPlayerOutput(m_secondPlayer->readCommands()); bool isFirstPlayerRunning = this->processOrders(firstPlayerOutput, m_firstPlayer); bool isSecondPlayerRunning = this->processOrders(secondPlayerOutput, m_secondPlayer); //Check whether the players are still alive. if (!isFirstPlayerRunning || !isSecondPlayerRunning) { this->stop(); return; } this->advanceGame(); //Check each player's position. int firstPlayerShips = 0; int secondPlayerShips = 0; const int numPlanets = static_cast<int>(m_planets.size()); for (int i = 0; i < numPlanets; ++i) { Planet* planet = m_planets[i]; const int ownerId = planet->getOwner()->getId(); if (1 == ownerId) { firstPlayerShips += planet->getNumShips(); } else if (2 == ownerId) { secondPlayerShips += planet->getNumShips(); } } for (FleetList::iterator it = m_fleets.begin(); it != m_fleets.end(); ++it) { Fleet* fleet = *it; if (1 == fleet->getOwner()->getId()) { firstPlayerShips += fleet->getNumShips(); } else { secondPlayerShips += fleet->getNumShips(); } } emit turnEnded(); //Check for game end conditions. bool isGameOver = false; if (firstPlayerShips == 0 && secondPlayerShips == 0) { this->logMessage("Draw."); isGameOver = true; } else if (firstPlayerShips == 0) { this->logMessage("Player 2 wins."); isGameOver = true; } else if (secondPlayerShips == 0) { this->logMessage("Player 1 wins."); isGameOver = true; } else if (m_turn >= m_maxTurns) { if (firstPlayerShips > secondPlayerShips) { this->logMessage("Player 1 wins."); isGameOver = true; } else if (firstPlayerShips < secondPlayerShips) { this->logMessage("Player 2 wins."); isGameOver = true; } else { this->logMessage("Draw."); isGameOver = true; } } if (isGameOver) { this->stop(); return; } //Game is not over. m_state = READY; this->continueRunning(); }
void GameController::onChangeTurn() { currentTurn++; /* impose production on owned planets */ for(int i=0; i<players.size(); i++) { Player* tempP = players[i]; for(int j=0; j<players[i]->getPlanets().size(); j++) { Planet* tempPl = tempP->getPlanets()[j]; tempPl->setShips( tempPl->getShips() + tempPl->getProduction()); } } for(int k=0; k<fleets.size(); k++) { Fleet* tempF = fleets[k]; /* fleet has arrived */ if(fleets[k]->getArrivalTurn() == currentTurn) { /* fleet owner same as destination owner, so reinforcing a planet */ if(tempF->getOwner() == tempF->getDestination()->getOwner()) { tempF->getDestination()->setShips(tempF->getDestination()->getShips() + tempF->getNumShips()); } else /* attacking planet */ { double attackScore, defenseScore; attackScore = tempF->getNumShips()*tempF->getKillPercent(); defenseScore = tempF->getDestination()->getShips()*tempF->getDestination()->getKillPercent(); if(attackScore >= defenseScore) /* attackers win */ { if(tempF->getDestination()->getOwner() != NULL) tempF->getDestination()->getOwner()->removeFromPlanets(tempF->getDestination()); tempF->getOwner()->addToPlanets(tempF->getDestination()); tempF->getDestination()->setOwner(tempF->getOwner()); tempF->getDestination()->setShips((int)attackScore-defenseScore); emit displayInfo(QString("Turn %1: Planet %2 has fallen to %3").arg(currentTurn).arg(tempF->getDestination()->getName()).arg(tempF->getOwner()->getName())); } else /* defense wins */ { tempF->getDestination()->setShips((int)defenseScore-attackScore); emit displayInfo(QString("Turn %1: Planet %2 has held against an attack from %3.").arg(currentTurn).arg(tempF->getDestination()->getName()).arg(tempF->getOwner()->getName())); } } /* processed fleet, so remove it */ fleets.removeAt(k); } } if(currentPlayer < players.size() - 1) currentPlayer++; else currentPlayer = 0; emit displayControl(QString("<font color=%1>%2</font>:Select source planet").arg(players[currentPlayer]->getColor().name()).arg(players[currentPlayer]->getName())); }