예제 #1
0
bool PlanetWarsGame::processOrders(const std::string &allOrders, Player *player) {
    std::vector<std::string> lines = Tokenize(allOrders, "\r\n");
    const int numLines = static_cast<int>(lines.size());

    //Indicator whether "go" message was encountered.
    bool foundGo = false;


    for (int i = 0; i < numLines; ++i) {
        std::string& line = lines[i];

        if (line.size() == 0) {
            //Skip empty lines.
            continue;

        } else if (line.compare("go") == 0) {
            foundGo = true;
            break;
        }
        else if (line[0] == '#') {
            if (line.size() < 2 || line[1] != '-')
                continue;
            std::vector<std::string> tokens = Tokenize(line, " ");
            tokens.erase(tokens.begin());
            if (tokens.size() == 4 && tokens[0] == "planet") {
                int planetId = atoi(tokens[1].c_str());
                const std::string& name = tokens[2];
                const std::string& value = tokens[3];

                Planet* planet = m_planets[planetId];
                planet->setProperty(name, value);
            }
            continue;
        }


        std::vector<std::string> tokens = Tokenize(line, " ");

        //Check whether the player bot output a bad thing.
        if (3 != tokens.size()) {
            std::stringstream message;
            message << "Error on line " << i << " of stdout output; expected 3 tokens on a move order line, have "
                    << tokens.size() << ".";
            player->logError(message.str());
            return false;
        }

        const int sourcePlanetId = atoi(tokens[0].c_str());
        const int destinationPlanetId = atoi(tokens[1].c_str());
        const int numShips = atoi(tokens[2].c_str());

        //Check whether the player has made any illegal moves.
        const int numPlanets = static_cast<int>(m_planets.size());

        if (sourcePlanetId < 0 || sourcePlanetId >= numPlanets) {
            std::stringstream message;
            message << "Error on line " << i << " of stdout output.  Source planet "
                    << sourcePlanetId << " does not exist.";
            player->logError(message.str());
            return false;
        }

        if (destinationPlanetId < 0 || destinationPlanetId >= numPlanets) {
            std::stringstream message;
            message << "Error on line " << i << " of stdout output.  Destination planet "
                    << destinationPlanetId << " does not exist.";
            player->logError(message.str());
            return false;
        }

        if (sourcePlanetId == destinationPlanetId) {
            std::stringstream message;
            message << "Error on line " << i
                    << " of stdout output.  Source planet and destination planet are the same. ";
            player->logError(message.str());
            return false;
        }

        Planet* sourcePlanet = m_planets[sourcePlanetId];
        Planet* destinationPlanet = m_planets[destinationPlanetId];

        if (sourcePlanet->getOwner()->getId() != player->getId()) {
            std::stringstream message;
            message << "Error on line " << i << " of stdout output.  Source planet "
                    << destinationPlanetId << " does not belong to this player.";
            player->logError(message.str());
            return false;
        }

        if (numShips > sourcePlanet->getNumShips() || numShips < 0) {
            std::stringstream message;
            message << "Error on line " << i << " of stdout output.  Cannot send " << numShips
                    << " ships from planet " << sourcePlanetId
                    << ".  Planet has " << sourcePlanet->getNumShips() << " ships.";
            player->logError(message.str());
            return false;
        }

        sourcePlanet->setNumShips(sourcePlanet->getNumShips() - numShips);

        //Create a new fleet.
        Fleet* fleet = new Fleet(this);
        fleet->setOwner(player);
        fleet->setSource(sourcePlanet);
        fleet->setDestination(destinationPlanet);
        fleet->setNumShips(numShips);
        const int distance = sourcePlanet->getDistanceTo(destinationPlanet);
        fleet->setTotalTripLength(distance);
        fleet->setTurnsRemaining(distance);

        m_newFleets.push_back(fleet);
        m_fleets.push_back(fleet);
    }

    if (!foundGo) {
        std::stringstream message;
        message << "Error: player did not send \"go\" within allotted time.";
        player->logError(message.str());
        return false;
    }

    return true;
}