#include "Main.h"
void App::Init()
{
srand(timeGetTime());
_parameters.Init("data/parameters.txt");
_cards.Init(_parameters.useCustomCards);
_game.Init(_cards);
_AITestResult = -1.0;
}
UINT32 App::ProcessCommand(const String &command)
{
Vector<String> parameters = command.Partition("@");
if(parameters[0] == "newKingdomCards")
{
_options = GameOptions();
if(parameters.Length() == 1)
{
_options.RandomizeSupplyPiles(_cards);
}
else
{
_options.SetupGame(_cards, parameters[1]);
}
Vector<PlayerInfo> playerList;
playerList.PushEnd(PlayerInfo(0, "Adam", new PlayerHuman));
playerList.PushEnd(PlayerInfo(1, "Beth", new PlayerHeuristic(new BuyAgendaExpensiveNovelties)));
logging = true;
decisionText = true;
_game.NewGame(playerList, _options);
AIUtility::AdvanceAIs(_game);
}
else if(parameters[0] == "newGame")
{
if(_options.supplyPiles.Length() == 0)
{
_options.RandomizeSupplyPiles(_cards);
}
Vector<PlayerInfo> playerList;
if(parameters.Length() == 1)
{
playerList.PushEnd(PlayerInfo(0, "Adam", new PlayerHuman));
playerList.PushEnd(PlayerInfo(1, "Beth", new PlayerHeuristic(new BuyAgendaExpensiveNovelties)));
}
else
{
if(parameters[1] == "Human") playerList.PushEnd(PlayerInfo(0, "Adam", new PlayerHuman));
else playerList.PushEnd(PlayerInfo(0, "Adam", new PlayerHeuristic(new BuyAgendaMenu(_cards, parameters[1].FindAndReplace("~","@")))));
if(parameters[2] == "Human") playerList.PushEnd(PlayerInfo(1, "Beth", new PlayerHuman));
else playerList.PushEnd(PlayerInfo(1, "Beth", new PlayerHeuristic(new BuyAgendaMenu(_cards, parameters[2].FindAndReplace("~","@")))));
}
logging = true;
decisionText = true;
_game.NewGame(playerList, _options);
AIUtility::AdvanceAIs(_game);
}
else if(parameters[0] == "testAIs")
{
Vector<PlayerInfo> playerList;
playerList.PushEnd(PlayerInfo(0, "Adam", new PlayerHeuristic(new BuyAgendaMenu(_cards, parameters[1].FindAndReplace("~","@")))));
playerList.PushEnd(PlayerInfo(1, "Beth", new PlayerHeuristic(new BuyAgendaMenu(_cards, parameters[2].FindAndReplace("~","@")))));
logging = true;
decisionText = true;
_game.NewGame(playerList, _options);
AIUtility::AdvanceAIs(_game);
TestChamber chamber;
TestParameters params;
params.minGameCount = 10000;
params.maxGameCount = 10000;
params.players[0] = playerList[0].controller;
params.players[1] = playerList[1].controller;
params.options = _game.data().options;
TestResult result = chamber.Test(_cards, params);
_AITestResult = result.winRatio[0];
}
else if(parameters[0] == "response")
{
auto &d = _game.state().decision;
if(d.type == DecisionGameOver || d.type == DecisionNone)
{
SignalError("response when no decision ready");
return 1;
}
else if(d.type == DecisionSelectCards)
{
Vector<String> cards;
if(parameters.Length() > 1) cards = parameters[1].Partition("|");
if(cards.Length() < d.minimumCards || cards.Length() > d.maximumCards)
{
SignalError("response with invalid number of cards");
return 1;
}
DecisionResponse response;
for(const String &s : cards)
{
response.cards.PushEnd(_game.data().cards->GetCard(s));
}
_game.state().ProcessDecision(response);
_game.state().AdvanceToNextDecision(0);
}
else if(d.type == DecisionDiscreteChoice)
{
int choice = parameters[1].ConvertToInteger();
if(choice < 0 || choice >= int(d.minimumCards))
{
SignalError("response with invalid choice");
return 1;
}
DecisionResponse response;
response.choice = choice;
_game.state().ProcessDecision(response);
_game.state().AdvanceToNextDecision(0);
}
AIUtility::AdvanceAIs(_game);
}
else if(parameters[0] == "debugAddCard")
{
Card *c = _game.data().cards->GetCard(parameters[1]);
if(c == NULL) return 1;
_game.state().players[_game.state().player].hand.PushEnd(c);
_game.state().players[_game.state().player].actions++;
}
else if(parameters[0] == "trainAIStart")
{
GameOptions options;
if(_game.data().options.supplyPiles.Length() == 0) options.RandomizeSupplyPiles(_cards);
else options = _game.data().options;
_chamber.StrategizeStart(_cards, options, parameters[1], parameters[2].ConvertToInteger());
}
else if(parameters[0] == "trainAIStep")
{
_chamber.StrategizeStep(_cards);
}
return 0;
}
int App::QueryIntegerByName(const String &s)
{
if(s == "layerCount")
{
return 0;
}
else
{
SignalError("Unknown integer");
return -1;
}
}
double App::QueryDoubleByName(const String &s)
{
if(s == "AITestResult")
{
return _AITestResult;
}
else
{
SignalError("Unknown double");
return -1.0;
}
}
const char* App::QueryStringByName(const String &s)
{
_queryString.FreeMemory();
const State &state = _game.state();
const GameData &data = _game.data();
if(data.supplyCards.Length() == 0) return _queryString.CString();
if(s.StartsWith("playerList"))
{
for(auto &p : data.players) _queryString += p.name + "@" + p.controller->ControllerName() + "|";
}
else if(s.StartsWith("supplyCards"))
{
for(auto &s : data.supplyCards) _queryString += s->name + "|";
}
else if(s.StartsWith("supplyState"))
{
for(UINT supplyIndex = 0; supplyIndex < data.supplyCards.Length(); supplyIndex++)
{
_queryString += String(state.supply[supplyIndex].count) + "|";
}
_queryString[_queryString.Length() - 1] = '@';
for(UINT supplyIndex = 0; supplyIndex < data.supplyCards.Length(); supplyIndex++)
{
_queryString += String(state.SupplyCost(supplyIndex)) + "|";
}
}
else if(s.StartsWith("basicState"))
{
_queryString = String(state.player) + "|" +
data.players[state.player].name + "|" +
String(state.phase) + "|" +
String(state.players[state.player].actions) + "|" +
String(state.players[state.player].buys) + "|" +
String(state.players[state.player].money);
}
else if(s.StartsWith("hand"))
{
int playerIndex = state.player;
if(s.Contains(" ")) playerIndex = s.Partition(" ")[1].ConvertToInteger();
auto &player = state.players[playerIndex];
for(auto &c : player.hand) _queryString += String(c->name) + "|";
}
else if(s.StartsWith("playArea"))
{
int playerIndex = state.player;
if(s.Contains(" ")) playerIndex = s.Partition(" ")[1].ConvertToInteger();
auto &player = state.players[playerIndex];
for(auto &c : player.playArea) _queryString += String(c.card->name) + "|";
}
else if(s.StartsWith("discard"))
{
int playerIndex = state.player;
if(s.Contains(" ")) playerIndex = s.Partition(" ")[1].ConvertToInteger();
auto &player = state.players[playerIndex];
for(auto &c : player.discard) _queryString += String(c->name) + "|";
}
else if(s.StartsWith("deck"))
{
int playerIndex = state.player;
if(s.Contains(" ")) playerIndex = s.Partition(" ")[1].ConvertToInteger();
auto &player = state.players[playerIndex];
for(auto &c : player.deck) _queryString += String(c->name) + "|";
}
else if(s.StartsWith("victoryPoints"))
{
int playerIndex = state.player;
if(s.Contains(" ")) playerIndex = s.Partition(" ")[1].ConvertToInteger();
_queryString += String(state.PlayerScore(playerIndex));
}
else if(s.StartsWith("log"))
{
for(const String &s : _game.data().log.Events())
{
_queryString += s;
_queryString.PushEnd('\n');
}
if(_queryString.EndsWith("\n")) _queryString.PopEnd();
_game.data().log.Reset();
}
else if(s.StartsWith("decision"))
{
auto &d = state.decision;
String cardString = "phase|" + String(state.phase);
if(d.activeCard != NULL) cardString = d.activeCard->name;
if(d.type == DecisionType::DecisionNone)
{
_queryString = "none";
}
if(d.type == DecisionType::DecisionGameOver)
{
_queryString = "gameover";
}
if(d.type == DecisionType::DecisionDiscreteChoice)
{
_queryString = "choice@" + String(d.controllingPlayer) + "@" + data.players[d.controllingPlayer].name + "@" + d.text + "@" + cardString;
}
if(d.type == DecisionType::DecisionSelectCards)
{
_queryString = "selectCard@" + String(d.controllingPlayer) + "@" + data.players[d.controllingPlayer].name + "@" + d.text +
"@" + String(d.minimumCards) + "@" + String(d.maximumCards) + "@" + cardString + "@";
for(auto &c : d.cardChoices)
{
_queryString += c->name + "|";
}
}
}
else if(s.StartsWith("kingdomDescription"))
{
_queryString = _options.ToString();
}
else
{
return NULL;
}
if(_queryString.Length() > 0 && _queryString.Last() == '|') _queryString.PopEnd();
return _queryString.CString();
}