C ++ 11, CalculatedFail
dopo aver provato alcune cose con il piccolo Java che conosco e non ero abbastanza in grado di ottenere ciò che volevo, ho scelto di riscriverlo in C ++ e aggiungere la gestione dei file. il problema era che il mio C ++ è piuttosto arrugginito e non molto migliore, quindi alcune parti sono state messe insieme e solo la prima soluzione in Google, quindi non proprio il codice di qualità ...
tuttavia, sono stato in grado di ottenere almeno un risultato funzionante che non fa molto schifo, vince almeno occasionalmente, ma non posso provarlo perfettamente perché non sono in grado di eseguire tutti gli altri invii su questo pc. Probabilmente riscriverò del tutto il targeting e lo aggiungerò come un'altra risposta più tardi oggi o domani.
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <cmath>
#include <ratio>
#include <fstream>
#include <algorithm>
using namespace std;
class Town {
public:
Town(int owner, int townId, int knights, int population, int roundToDefBonus);
int getOwner();
int getId();
int getKnights();
int getPopulation();
int getFreeKnights();
int neededConquer();
int getKnightsStable();
int getRoundToDef();
bool operator< (const Town &other) const {
return townId < other.townId;
}
private:
int owner;
int townId;
int knights;
int population;
int roundToDefBonus;
double defBonus;
};
Town::Town(int inOwner, int inTownId, int inKnights, int inPopulation, int inRoundToDefBonus) {
owner = inOwner;
townId = inTownId;
knights = inKnights;
population = inPopulation;
roundToDefBonus = inRoundToDefBonus;
if(roundToDefBonus > 0) {
defBonus = 1;
}
else{
defBonus = 1.2;
}
}
int Town::getOwner() {
return owner;
}
int Town::getId() {
return townId;
}
int Town::getKnights() {
return knights;
}
int Town::getPopulation() {
return population;
}
int Town::getFreeKnights() {
return knights - population / 2;
}
int Town::neededConquer() {
return max(static_cast<int>(ceil(knights * defBonus + population / 2)), 1);
}
int Town::getKnightsStable() {
return population / 2;
}
int Town::getRoundToDef() {
return roundToDefBonus;
}
int gameRound;
int myId;
int thisTownId;
Town* thisTown;
vector <Town> myTowns;
vector <Town> enemyTowns;
vector <Town> lastTime;
string turn();
Town* bestTarget(int knights);
Town* bestSafe(int knights);
Town* biggestTarget(int knights);
Town* biggestSafe(int knights);
string out(string, int, int);
string attack(Town*);
string safe(Town*);
bool sortTowns(const Town & t1, const Town & t2);
vector <string> stringSplit(string input, string delimeter);
int main(int argc, char* argv[]) {
if(argc < 2){
cout << "100 100 100";
ofstream myFile;
myFile.open("CalculatedFail.txt");
myFile << "0\n";
myFile.close();
}
else{
if(argc == 2){
string input = argv[1];
vector <string> params = stringSplit(input, ";");
gameRound = atoi(params.at(0).c_str());
myId = atoi((params.at(1)).c_str());
thisTownId = atoi(params.at(2).c_str());
ifstream myfile("CalculatedFail.txt");
if(myfile.is_open()){
string line;
getline(myfile, line);
bool newRound = false;
if(atoi(line.c_str()) > gameRound) {
newRound = true;
}
vector <string> oldVals;
if(!newRound) {
while (getline(myfile, line)) {
oldVals = stringSplit(line, "_");
int playerId = atoi(oldVals.at(0).c_str());
int townId = atoi(oldVals.at(1).c_str());
int knights = atoi(oldVals.at(2).c_str());
int population = atoi(oldVals.at(3).c_str());
int roundToDefBonus = atoi(oldVals.at(4).c_str());
lastTime.push_back(Town(playerId, townId, knights, population, roundToDefBonus));
oldVals.clear();
}
}
else {
while (getline(myfile, line)) {
oldVals = stringSplit(line, "_");
int playerId = atoi(oldVals.at(0).c_str());
int townId = atoi(oldVals.at(1).c_str());
int knights = atoi(oldVals.at(2).c_str());
int population = atoi(oldVals.at(3).c_str());
int roundToDefBonus = atoi(oldVals.at(4).c_str());
if(roundToDefBonus) { //if round def bonus > 0, decrement because new round
roundToDefBonus --;
}
lastTime.push_back(Town(playerId, townId, knights, population, roundToDefBonus));
oldVals.clear();
}
}
std::sort(lastTime.begin(), lastTime.end());
}
if(lastTime.size() > 0) {
vector <string> values;
for(int i = 3; i < params.size(); i++) {
values = stringSplit(params.at(i), "_");
int playerId = atoi(values.at(0).c_str());
int townId = atoi(values.at(1).c_str());
int knights = atoi(values.at(2).c_str());
int population = atoi(values.at(3).c_str());
int roundsToDef = lastTime.at(townId).getRoundToDef();
if(playerId != lastTime.at(townId).getOwner()) {
roundsToDef = 2;
}
if(playerId == myId){
if(thisTownId != townId)
myTowns.push_back(Town(playerId, townId, knights, population, roundsToDef));
else{
thisTown = new Town(playerId, townId, knights, population, roundsToDef);
}
}
else{
enemyTowns.push_back(Town(playerId, townId, knights, population, roundsToDef));
}
values.clear();
}
}
else {
vector <string> values;
for(int i = 3; i < params.size(); i++) {
values = stringSplit(params.at(i), "_");
int playerId = atoi(values.at(0).c_str());
int townId = atoi(values.at(1).c_str());
int knights = atoi(values.at(2).c_str());
int population = atoi(values.at(3).c_str());
if(playerId == myId){
if(thisTownId != townId)
myTowns.push_back(Town(playerId, townId, knights, population, 0));
else{
thisTown = new Town(playerId, townId, knights, population, 0);
}
}
else{
enemyTowns.push_back(Town(playerId, townId, knights, population, 0));
}
values.clear();
}
}
string tmp = turn();
cout << tmp;
ofstream writeFile("CalculatedFail.txt");
if(writeFile.is_open()) {
writeFile << gameRound <<"\n";
writeFile << thisTown->getOwner() <<"_"<<thisTown->getId()<<"_"<<thisTown->getKnights()<<"_"<< thisTown->getPopulation()<<"_"<<thisTown->getRoundToDef()<<"\n";
for(vector<Town>::size_type i = 0; i != myTowns.size(); i++) {
writeFile << myTowns[i].getOwner() <<"_"<<myTowns[i].getId()<<"_"<<myTowns[i].getKnights()<<"_"<< myTowns[i].getPopulation()<<"_"<<myTowns[i].getRoundToDef()<<"\n";
}
for(vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
writeFile << enemyTowns[i].getOwner() <<"_"<<enemyTowns[i].getId()<<"_"<<enemyTowns[i].getKnights()<<"_"<< enemyTowns[i].getPopulation()<<"_"<<enemyTowns[i].getRoundToDef()<<"\n";
}
}
}
else{
cout<<"error, wrong parameter";
}
}
delete thisTown;
return 0;
}
string turn() {
Town* safeTarget;
Town* attackTarget;
if(thisTown->getFreeKnights() < 0) { //evacuate
safeTarget = biggestSafe(thisTown->getKnights());
attackTarget = biggestTarget(thisTown->getKnights());
if(safeTarget != nullptr && attackTarget != nullptr){
if(safeTarget->getPopulation() > attackTarget->getPopulation()) {
return out("S", safeTarget->getId(), thisTown->getKnights());
}
else {
return out("A", attackTarget->getId(), thisTown->getKnights());
}
}
if(safeTarget){
return out("S", safeTarget->getId(), thisTown->getKnights());
}
if(attackTarget){
return out("A", attackTarget->getId(), thisTown->getKnights());
}
Town* target = &myTowns.at(0);
for(vector<Town>::size_type i = 1; i != myTowns.size(); i++) {
if(target->getPopulation() < myTowns[i].getPopulation())
target = &myTowns[i];
}
return out("S", target->getId(), thisTown->getKnights());
}
safeTarget = biggestSafe(thisTown->getFreeKnights());
attackTarget = bestTarget(thisTown->getFreeKnights());
if(safeTarget != nullptr && attackTarget != nullptr){
if(safeTarget->getPopulation() > attackTarget->getPopulation()) {
return safe(safeTarget);
}
else {
return attack(attackTarget);
}
}
if(safeTarget){
return safe(safeTarget);
}
if(attackTarget){
return attack(attackTarget);
}
return "W";
}
Town* bestTarget(int knights) {
Town* target = nullptr;
double ratio = -1;
for(vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
if(enemyTowns[i].neededConquer() < knights) {
if(enemyTowns[i].getPopulation() / enemyTowns[i].neededConquer() > ratio) {
target = &enemyTowns[i];
ratio = enemyTowns[i].getPopulation() / enemyTowns[i].neededConquer();
}
}
}
return target;
}
Town* biggestTarget(int knights) {
Town* target = nullptr;
int population = -1;
for(vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
if(enemyTowns[i].neededConquer() < knights) {
if(enemyTowns[i].getPopulation() > population) {
target = &enemyTowns[i];
population = target->getPopulation();
}
}
}
return target;
}
Town* biggestSafe(int knights) {
Town* target = nullptr;
int population = -1;
for(vector<Town>::size_type i = 0; i != myTowns.size(); i++) {
if(myTowns[i].getFreeKnights() < 0 && myTowns[i].getFreeKnights() + knights >= 0){
if(myTowns[i].getPopulation() > population) {
target = &myTowns[i];
population = target->getPopulation();
}
}
}
return target;
}
string attack(Town* target){
int knights;
if(thisTown->getPopulation() > target->getPopulation()) {
knights = target->neededConquer();
}
else{
knights = thisTown->getFreeKnights();
}
return out("A", target->getId(), knights);
}
string safe(Town* target){
int knights;
if(thisTown->getPopulation() > target->getPopulation()) {
knights = target->getFreeKnights() * -1;
}
else{
knights = thisTown->getFreeKnights();
}
return out("S", target->getId(), knights);
}
string out(string order, int targedId, int knights) {
stringstream tmp;
tmp << order << " " << targedId << " " << knights;
return tmp.str();
}
vector <string> stringSplit(string input, string delimeter) {
stringstream tmp(input);
vector <string> splitted;
string pushThis;
while (getline(tmp, pushThis, delimeter.at(0))){
splitted.push_back(pushThis);
}
return splitted;
}
compilare con: g++ -std=c++11 CalculatedFail.cpp -o CalculatedFail.exe
google dice su linux che è CalculatedFail.out invece di .exe, ma non riesco a provarlo.
e corri
CalculatedFail.exe
poiché utilizza un file per verificare il bonus def, eseguire il gioco contemporaneamente più volte può causare errori ...
spero che funzioni correttamente senza troppi problemi
A
sostiene un'altra cittàB
, il dato numero di cavalieri viene semplicemente trasferito daA
aB
, dopo di che sono controllati dal proprietario diB
, corretto?