Erwan
- Fix issue 194 - Attempt at doing basic AI tests
This commit is contained in:
@@ -73,14 +73,13 @@ beacon_of_unrest.txt
|
||||
belligerent_hatchling.txt
|
||||
benalish_knight.txt
|
||||
blessed_wine.txt
|
||||
blinking_spirit.txt
|
||||
bloodfire_colossus.txt
|
||||
bloodhall_ooze.txt
|
||||
body_double.txt
|
||||
boggart_arsonists.txt
|
||||
borderland_behemoth.txt
|
||||
bottle_gnomes.txt
|
||||
bottle_gnomes2.txt
|
||||
boggart_arsonists.txt
|
||||
brass_man.txt
|
||||
cage_of_hands.txt
|
||||
Call_to_Heel_1.txt
|
||||
@@ -105,8 +104,8 @@ counterspell.txt
|
||||
counterspell2.txt
|
||||
counterspell3.txt
|
||||
counterspell4.txt
|
||||
creature_bond.txt
|
||||
crimson_kobolds.txt
|
||||
creature_bond.txt
|
||||
dauntless_escort.txt
|
||||
dauthi_embrace.txt
|
||||
death_ward.txt
|
||||
@@ -127,17 +126,16 @@ elvish_promenade.txt
|
||||
emblem_of_the_warmind.txt
|
||||
enervate.txt
|
||||
erg_raiders_i157.txt
|
||||
farhaven_elf.txt
|
||||
farmstead.txt
|
||||
flagstones.txt
|
||||
farhaven_elf.txt
|
||||
fastbond.txt
|
||||
fastbond2.txt
|
||||
fault_line.txt
|
||||
fists_of_ironwood.txt
|
||||
flagstones.txt
|
||||
flare.txt
|
||||
fledgling_imp.txt
|
||||
fledgling_imp2.txt
|
||||
flowstone_hellion.txt
|
||||
flowstone_slide.txt
|
||||
foratog.txt
|
||||
force_of_nature.txt
|
||||
@@ -160,14 +158,12 @@ harpoon_sniper.txt
|
||||
hellfire.txt
|
||||
howl_from_beyond.txt
|
||||
howl_of_the_night_pack.txt
|
||||
hyalopterous_lemure.txt
|
||||
hymn_of_rebirth.txt
|
||||
hypnotic_specter.txt
|
||||
icatian_priest.txt
|
||||
imaginary_pet.txt
|
||||
immaculate_magistrate.txt
|
||||
instill_energy_i166.txt
|
||||
jodahs_avenger.txt
|
||||
jump.txt
|
||||
keldon_warlord.txt
|
||||
keldon_warlord2.txt
|
||||
@@ -239,26 +235,26 @@ seedcradle_witch.txt
|
||||
seismic_assault.txt
|
||||
seismic_spike_i191.txt
|
||||
selesnya_guildmage.txt
|
||||
siege_gang_commander.txt
|
||||
shepherd_of_rot.txt
|
||||
shivan_hellkite.txt
|
||||
shock.txt
|
||||
shock2.txt
|
||||
siege_gang_commander.txt
|
||||
slate_of_ancestry.txt
|
||||
sleeper_agent.txt
|
||||
slith_bloodletter.txt
|
||||
soulblast.txt
|
||||
spark_elemental.txt
|
||||
sphinx_summoner.txt
|
||||
spirit_link.txt
|
||||
spitting_earth.txt
|
||||
spark_elemental.txt
|
||||
spirit_link.txt
|
||||
spoils_of_evil.txt
|
||||
stasis.txt
|
||||
steelclad_serpent1.txt
|
||||
steelclad_serpent2.txt
|
||||
stillmoon_cavalier.txt
|
||||
stonebrow2.txt
|
||||
stonebrow_i159.txt
|
||||
stonebrow2.txt
|
||||
stronghold_discipline.txt
|
||||
sword_to_plowshares.txt
|
||||
symbiotic_wurm.txt
|
||||
@@ -271,9 +267,10 @@ titanic_ultimatum.txt
|
||||
torture.txt
|
||||
tranquil_domain.txt
|
||||
twitch.txt
|
||||
unstable_mutation.txt
|
||||
unstable_mutation2.txt
|
||||
unwilling_recruit.txt
|
||||
unstable_mutation.txt
|
||||
unstable_mutation2.txt
|
||||
vampire_bats.txt
|
||||
vampiric_link.txt
|
||||
volcanic_eruption.txt
|
||||
@@ -292,3 +289,7 @@ zombify.txt
|
||||
########################
|
||||
momir/keldon_warlord.txt
|
||||
momir/overcost.txt
|
||||
########################
|
||||
#AI Tests
|
||||
########################
|
||||
ai/goblin_artillery.txt
|
||||
22
projects/mtg/bin/Res/test/ai/goblin_artillery.txt
Normal file
22
projects/mtg/bin/Res/test/ai/goblin_artillery.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
#Bug:ai uses goblin artilery on own creature
|
||||
# http://code.google.com/p/wagic/issues/detail?id=194
|
||||
FORCEABILITY
|
||||
RValues:2
|
||||
AICALLS 10
|
||||
[INIT]
|
||||
FIRSTMAIN
|
||||
[PLAYER1]
|
||||
inplay:,grizzly bears,goblin artillery
|
||||
[PLAYER2]
|
||||
inplay:raging goblin
|
||||
[DO]
|
||||
ai
|
||||
ai
|
||||
[ASSERT]
|
||||
FIRSTMAIN
|
||||
[PLAYER1]
|
||||
life:17
|
||||
inplay:goblin artillery,grizzly bears
|
||||
[PLAYER2]
|
||||
graveyard:raging goblin
|
||||
[END]
|
||||
@@ -21,16 +21,20 @@ class AIStats;
|
||||
class AIAction{
|
||||
protected:
|
||||
int efficiency;
|
||||
static int currentId;
|
||||
static MTGAbility * getCoreAbility(MTGAbility * a);
|
||||
public:
|
||||
MTGAbility * ability;
|
||||
Player * player;
|
||||
int id;
|
||||
MTGCardInstance * click;
|
||||
MTGCardInstance * target; // TODO Improve
|
||||
AIAction(MTGAbility * a, MTGCardInstance * c, MTGCardInstance * t = NULL):ability(a),click(c),target(t){player = NULL; efficiency = -1;};
|
||||
AIAction(MTGCardInstance * c, MTGCardInstance * t = NULL):click(c),target(t){player = NULL; ability = NULL; efficiency = -1;};
|
||||
AIAction(MTGAbility * a, MTGCardInstance * c, MTGCardInstance * t = NULL):ability(a),click(c),target(t){player = NULL; efficiency = -1; id = currentId++;};
|
||||
AIAction(MTGCardInstance * c, MTGCardInstance * t = NULL):click(c),target(t){player = NULL; ability = NULL; efficiency = -1; id = currentId++;};
|
||||
AIAction(Player * p):player(p){ability = NULL; target = NULL; click = NULL; efficiency = -1;};
|
||||
int getEfficiency();
|
||||
int Act();
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -39,7 +43,7 @@ class CmpAbilities { // compares Abilities efficiency
|
||||
bool operator()(AIAction * a1, AIAction * a2) const {
|
||||
int e1 = a1->getEfficiency();
|
||||
int e2 = a2->getEfficiency();
|
||||
if (e1 == e2) return a1 > a2; //TODO improve
|
||||
if (e1 == e2) return a1->id < a2->id;
|
||||
return (e1 > e2);
|
||||
}
|
||||
};
|
||||
@@ -59,7 +63,9 @@ class AIPlayer: public Player{
|
||||
int effectBadOrGood(MTGCardInstance * card, int mode = MODE_PUTINTOPLAY, TargetChooser * tc = NULL);
|
||||
int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES , int untapMode = 0, int canAttack = 0);
|
||||
AIStats * getStats();
|
||||
//Variables used by Test suite
|
||||
public:
|
||||
bool forceBestAbilityUse;
|
||||
void End(){};
|
||||
virtual int displayStack() {return 0;};
|
||||
int receiveEvent(WEvent * event);
|
||||
|
||||
@@ -48,6 +48,7 @@ class GameStateDuel: public GameState, public JGuiListener
|
||||
virtual void End();
|
||||
virtual void Update(float dt);
|
||||
virtual void Render();
|
||||
void initRand (unsigned seed = 0);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -51,8 +51,11 @@ class TestSuite{
|
||||
public:
|
||||
MTGAllCards* collection;
|
||||
int summoningSickness;
|
||||
bool forceAbility;
|
||||
int gameType;
|
||||
float timerLimit;
|
||||
unsigned int seed;
|
||||
int aiMaxCalls;
|
||||
int currentAction;
|
||||
TestSuiteState initState;
|
||||
TestSuiteState endState;
|
||||
@@ -60,7 +63,7 @@ class TestSuite{
|
||||
string files[1024];
|
||||
int nbfiles;
|
||||
int currentfile;
|
||||
int nbFailed, nbTests;
|
||||
int nbFailed, nbTests, nbAIFailed, nbAITests;
|
||||
int load(const char * filename);
|
||||
TestSuite(const char * filename,MTGAllCards* _collection);
|
||||
void initGame();
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
@@ -34,8 +35,12 @@ using std::string;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int loadRandValues(string s);
|
||||
int filesize(const char * filename);
|
||||
int fileExists(const char * filename);
|
||||
int WRand();
|
||||
|
||||
#ifdef LINUX
|
||||
void dumpStack();
|
||||
|
||||
@@ -40,7 +40,7 @@ int AIMomirPlayer::momir(){
|
||||
int converted = potentialMana->getConvertedCost();
|
||||
SAFE_DELETE(potentialMana);
|
||||
int efficiency = 100;
|
||||
int chance = 1 + (rand() % 100);
|
||||
int chance = 1 + (WRand() % 100);
|
||||
if (converted == 5 && myCreatures > opponentCreatures && game->hand->nb_cards<4) efficiency = 5 ; //Strategy: skip 5 drop
|
||||
if (converted == 7 && myCreatures > opponentCreatures && game->hand->nb_cards<2) efficiency = 50; //Strategy: 7 drops have bad upkeep costs and the AI doesn't handle those right now...
|
||||
if (converted > 8 ) converted = 8;
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
const char * const MTG_LAND_TEXTS[] = {"artifact","forest","island","mountain","swamp","plains","other lands"};
|
||||
|
||||
int AIAction::currentId = 0;
|
||||
|
||||
int AIAction::Act(){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
if (player){
|
||||
@@ -30,6 +32,7 @@ AIPlayer::AIPlayer(MTGPlayerCards * deck, string file, string fileSmall) : Playe
|
||||
nextCardToPlay = NULL;
|
||||
stats = NULL;
|
||||
agressivity = 50;
|
||||
forceBestAbilityUse = false;
|
||||
}
|
||||
|
||||
AIPlayer::~AIPlayer(){
|
||||
@@ -139,6 +142,18 @@ int AIPlayer::canHandleCost(MTGAbility * ability){
|
||||
return 1;
|
||||
}
|
||||
|
||||
MTGAbility * AIAction::getCoreAbility(MTGAbility * a){
|
||||
GenericTargetAbility * gta = dynamic_cast<GenericTargetAbility*>(a);
|
||||
if (gta) return getCoreAbility(gta->ability);
|
||||
|
||||
GenericActivatedAbility * gaa = dynamic_cast<GenericActivatedAbility*>(a);
|
||||
if (gaa) return getCoreAbility(gaa->ability);
|
||||
|
||||
if (MultiAbility * abi = dynamic_cast<MultiAbility*>(a)) return getCoreAbility(abi->abilities[0]);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
int AIAction::getEfficiency(){
|
||||
//TODO add multiplier according to what the player wants
|
||||
if (efficiency != -1) return efficiency;
|
||||
@@ -148,12 +163,7 @@ int AIAction::getEfficiency(){
|
||||
Player * p = g->currentlyActing();
|
||||
if (s->has(ability)) return 0;
|
||||
|
||||
MTGAbility * a = ability;
|
||||
GenericTargetAbility * gta = dynamic_cast<GenericTargetAbility*>(a);
|
||||
if (gta) a = gta->ability;
|
||||
|
||||
GenericActivatedAbility * gaa = dynamic_cast<GenericActivatedAbility*>(a);
|
||||
if (gaa) a = gaa->ability;
|
||||
MTGAbility * a = getCoreAbility(ability);
|
||||
|
||||
if (!a){
|
||||
OutputDebugString("FATAL: Ability is NULL in AIAction::getEfficiency()");
|
||||
@@ -197,10 +207,10 @@ int AIAction::getEfficiency(){
|
||||
if ((suggestion == BAKA_EFFECT_BAD && p==target->controller()) ||(suggestion == BAKA_EFFECT_GOOD && p!=target->controller())){
|
||||
efficiency =0;
|
||||
}else{
|
||||
efficiency = rand() % 5; //Small percentage of chance for unknown abilities
|
||||
efficiency = WRand() % 5; //Small percentage of chance for unknown abilities
|
||||
}
|
||||
}else{
|
||||
efficiency = rand() % 10;
|
||||
efficiency = WRand() % 10;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -262,7 +272,8 @@ int AIPlayer::selectAbility(){
|
||||
|
||||
if (ranking.size()){
|
||||
AIAction * a = ranking.begin()->first;
|
||||
int chance = 1 + rand() % 100;
|
||||
int chance = 1;
|
||||
if (!forceBestAbilityUse) chance = 1 + WRand() % 100;
|
||||
if (getEfficiency(a) < chance){
|
||||
a = NULL;
|
||||
}else{
|
||||
@@ -354,7 +365,7 @@ int AIPlayer::chooseTarget(TargetChooser * tc){
|
||||
}
|
||||
}
|
||||
if (nbtargets){
|
||||
int i = rand() % nbtargets;
|
||||
int i = WRand() % nbtargets;
|
||||
int type = potentialTargets[i]->typeAsTarget();
|
||||
switch(type){
|
||||
case TARGET_CARD:
|
||||
@@ -575,7 +586,7 @@ AIPlayer * AIPlayerFactory::createAIPlayer(MTGAllCards * collection, Player * op
|
||||
}
|
||||
}
|
||||
if (!nbdecks) return NULL;
|
||||
deckid = 1 + rand() % (nbdecks);
|
||||
deckid = 1 + WRand() % (nbdecks);
|
||||
}
|
||||
sprintf(deckFile, RESPATH"/ai/baka/deck%i.txt",deckid);
|
||||
sprintf(avatarFile, "avatar%i.jpg",deckid);
|
||||
@@ -628,7 +639,7 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty
|
||||
shouldPlayPercentage = shouldPlayPercentage - ((shouldPlayPercentage * 1.9) / (1 + xDiff));
|
||||
}
|
||||
|
||||
if (rand() % 100 > shouldPlayPercentage) continue;
|
||||
if (WRand() % 100 > shouldPlayPercentage) continue;
|
||||
nextCardToPlay = card;
|
||||
maxCost = currentCost;
|
||||
if(hasX) maxCost = pMana->getConvertedCost();
|
||||
|
||||
@@ -38,7 +38,7 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app){
|
||||
p1 = _p1;
|
||||
p2 = _p2;
|
||||
app = _app;
|
||||
showMsg = (rand() % 5);
|
||||
showMsg = (WRand() % 5);
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
if (!g->turn) return;
|
||||
if (!p1->isAI() && p2->isAI() && p1!= g->gameOver){
|
||||
@@ -238,7 +238,7 @@ int Credits::isRandomDeckUnlocked(){
|
||||
}
|
||||
|
||||
int Credits::unlockRandomSet(){
|
||||
int setId = rand() % MtgSets::SetsList->nb_items;
|
||||
int setId = WRand() % MtgSets::SetsList->nb_items;
|
||||
|
||||
if (1 == options[Options::optionSet(setId)].number)
|
||||
return 0;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <JGE.h>
|
||||
#include <JRenderer.h>
|
||||
#if defined (WIN32) || defined (LINUX)
|
||||
#include <time.h>
|
||||
#else
|
||||
#include <pspfpu.h>
|
||||
#endif
|
||||
@@ -65,6 +66,7 @@ GameApp::~GameApp()
|
||||
|
||||
void GameApp::Create()
|
||||
{
|
||||
srand(time(0)); // initialize random
|
||||
#if defined (WIN32)
|
||||
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
|
||||
#elif not defined (LINUX)
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
#include "../include/TestSuiteAI.h"
|
||||
#endif
|
||||
|
||||
#if defined (WIN32) || defined (LINUX)
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
enum ENUM_DUEL_STATE
|
||||
{
|
||||
DUEL_STATE_START,
|
||||
@@ -103,8 +107,8 @@ void GameStateDuel::Start()
|
||||
}
|
||||
|
||||
void GameStateDuel::loadPlayerRandom(int playerId, int isAI, int mode){
|
||||
int color1 = 1 + rand() % 5;
|
||||
int color2 = 1 + rand() % 5;
|
||||
int color1 = 1 + WRand() % 5;
|
||||
int color2 = 1 + WRand() % 5;
|
||||
int color0 = Constants::MTG_COLOR_ARTIFACT;
|
||||
if (mode == GAME_TYPE_RANDOM1) color2 = color1;
|
||||
int colors[]={color1,color2,color0};
|
||||
@@ -178,9 +182,15 @@ void GameStateDuel::loadPlayer(int playerId, int decknb, int isAI){
|
||||
}
|
||||
}
|
||||
|
||||
void GameStateDuel::initRand(unsigned int seed){
|
||||
if (!seed) seed = time(0);
|
||||
srand(seed);
|
||||
}
|
||||
|
||||
#ifdef TESTSUITE
|
||||
void GameStateDuel::loadTestSuitePlayers(){
|
||||
if (!testSuite) return;
|
||||
initRand(testSuite->seed);
|
||||
for (int i = 0; i < 2; i++){
|
||||
SAFE_DELETE(mPlayers[i]);
|
||||
SAFE_DELETE(deck[i]);
|
||||
@@ -407,8 +417,15 @@ void GameStateDuel::Render()
|
||||
}else{
|
||||
sprintf(buf, "%i tests out of %i FAILED!", nbFailed, nbTests);
|
||||
}
|
||||
|
||||
mFont->DrawString(buf,0,SCREEN_HEIGHT/2);
|
||||
nbFailed = testSuite->nbAIFailed;
|
||||
nbTests = testSuite->nbAITests;
|
||||
if (!nbFailed){
|
||||
sprintf(buf, "AI Tests: All %i tests successful!", nbTests);
|
||||
}else{
|
||||
sprintf(buf, "AI Tests: %i tests out of %i FAILED!", nbFailed, nbTests);
|
||||
}
|
||||
mFont->DrawString(buf,0,SCREEN_HEIGHT/2+20);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -290,7 +290,7 @@ void GameStateMenu::loadLangMenu(){
|
||||
mDip = opendir("Res/lang");
|
||||
}
|
||||
|
||||
while (mDit = readdir(mDip)){
|
||||
while ((mDit = readdir(mDip))){
|
||||
string filename = "Res/lang/";
|
||||
filename += mDit->d_name;
|
||||
std::ifstream file(filename.c_str());
|
||||
|
||||
@@ -187,7 +187,6 @@ void MTGAllCards::init(){
|
||||
tempCard = NULL;
|
||||
total_cards = 0;
|
||||
initCounters();
|
||||
srand(time(0)); // initialize random
|
||||
#if defined (_DEBUG)
|
||||
committed = true;
|
||||
#endif
|
||||
|
||||
@@ -160,7 +160,7 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone
|
||||
void MTGPlayerCards::discardRandom(MTGGameZone * from){
|
||||
if (!from->nb_cards)
|
||||
return;
|
||||
int r = rand() % (from->nb_cards);
|
||||
int r = WRand() % (from->nb_cards);
|
||||
putInZone(from->cards[r],from, graveyard);
|
||||
}
|
||||
|
||||
@@ -263,10 +263,9 @@ void MTGGameZone::cleanupPhase(){
|
||||
void MTGGameZone::shuffle(){
|
||||
int i;
|
||||
for (i=0; i<(nb_cards); i++) {
|
||||
int r = i + (rand() % (nb_cards-i)); // Random remaining position.
|
||||
int r = i + (WRand() % (nb_cards-i)); // Random remaining position.
|
||||
MTGCardInstance * temp = cards[i]; cards[i] = cards[r]; cards[r] = temp;
|
||||
}
|
||||
//srand(time(0)); // initialize seed "randomly" TODO :improve
|
||||
}
|
||||
|
||||
|
||||
@@ -365,7 +364,7 @@ void MTGLibrary::shuffleTopToBottom(int nbcards){
|
||||
if (nbcards>nb_cards) nbcards = nb_cards;
|
||||
MTGCardInstance * _cards[MTG_MAX_PLAYER_CARDS];
|
||||
for (int i= nb_cards-nbcards; i<(nb_cards); i++) {
|
||||
int r = i + (rand() % (nbcards-i)); // Random remaining position.
|
||||
int r = i + (WRand() % (nbcards-i)); // Random remaining position.
|
||||
MTGCardInstance * temp = cards[i]; cards[i] = cards[r]; cards[r] = temp;
|
||||
}
|
||||
for (int i= 0; i < nbcards; i++){
|
||||
|
||||
@@ -304,7 +304,7 @@ int MTGMomirRule::genRandomCreatureId(int convertedCost){
|
||||
i--;
|
||||
}
|
||||
if (!total_cards) return 0;
|
||||
int start = (rand() % total_cards);
|
||||
int start = (WRand() % total_cards);
|
||||
return pool[convertedCost][start];
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,11 @@ int TestSuiteAI::displayStack(){
|
||||
int TestSuiteAI::Act(float dt){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
g->gameOver = NULL; // Prevent draw rule from losing the game
|
||||
if (playMode == MODE_AI) return AIPlayerBaka::Act(dt);
|
||||
if (playMode == MODE_AI && suite->aiMaxCalls) {
|
||||
suite->aiMaxCalls--;
|
||||
suite->timerLimit = 40; //TODO Remove this limitation when AI is not using a stupid timer anymore...
|
||||
AIPlayerBaka::Act(dt);
|
||||
}
|
||||
if (playMode == MODE_HUMAN){
|
||||
g->mLayers->CheckUserInput(0);
|
||||
return 1;
|
||||
@@ -95,7 +99,7 @@ int TestSuiteAI::Act(float dt){
|
||||
}
|
||||
}
|
||||
|
||||
if (action == ""){
|
||||
if (action == ""){
|
||||
//end of game
|
||||
suite->assertGame();
|
||||
g->gameOver = g->players[0];
|
||||
@@ -284,7 +288,8 @@ void TestSuite::initGame(){
|
||||
g->phaseRing->goToPhase(initState.phase, g->players[0]);
|
||||
g->currentGamePhase = initState.phase;
|
||||
for (int i = 0; i < 2; i++){
|
||||
Player * p = g->players[i];
|
||||
AIPlayer * p = (AIPlayer *) (g->players[i]);
|
||||
p->forceBestAbilityUse = forceAbility;
|
||||
p->life = initState.playerData[i].life;
|
||||
p->getManaPool()->copy(initState.playerData[i].manapool);
|
||||
MTGGameZone * playerZones[] = {p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay};
|
||||
@@ -335,6 +340,8 @@ int TestSuite::assertGame(){
|
||||
Log(result);
|
||||
|
||||
int error = 0;
|
||||
bool wasAI = false;
|
||||
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
if (g->currentGamePhase != endState.phase){
|
||||
sprintf(result, "<span class=\"error\">==phase problem. Expected %i, got %i==</span><br />",endState.phase, g->currentGamePhase);
|
||||
@@ -342,7 +349,9 @@ int TestSuite::assertGame(){
|
||||
error++;
|
||||
}
|
||||
for (int i = 0; i < 2; i++){
|
||||
Player * p = g->players[i];
|
||||
TestSuiteAI * p = (TestSuiteAI *)(g->players[i]);
|
||||
if (p->playMode == MODE_AI) wasAI = true;
|
||||
|
||||
if (p->life != endState.playerData[i].life){
|
||||
sprintf(result, "<span class=\"error\">==life problem for player %i. Expected %i, got %i==</span><br />",i,endState.playerData[i].life, p->life);
|
||||
Log(result);
|
||||
@@ -380,10 +389,18 @@ int TestSuite::assertGame(){
|
||||
}
|
||||
}
|
||||
}
|
||||
nbTests++;
|
||||
if (error) {
|
||||
nbFailed++;
|
||||
return 0;
|
||||
if (wasAI) {
|
||||
nbAITests++;
|
||||
if (error) {
|
||||
nbAIFailed++;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
nbTests++;
|
||||
if (error) {
|
||||
nbFailed++;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Log("<span class=\"success\">==Test Succesful !==</span>");
|
||||
return 1;
|
||||
@@ -398,7 +415,12 @@ TestSuite::TestSuite(const char * filename,MTGAllCards* _collection){
|
||||
currentfile = 0;
|
||||
nbFailed = 0;
|
||||
nbTests = 0;
|
||||
nbAIFailed = 0;
|
||||
nbAITests = 0;
|
||||
int comment = 0;
|
||||
seed = 0;
|
||||
forceAbility = false;
|
||||
aiMaxCalls = -1;
|
||||
if(file){
|
||||
while(std::getline(file,s)){
|
||||
if (!s.size()) continue;
|
||||
@@ -430,6 +452,8 @@ TestSuite::TestSuite(const char * filename,MTGAllCards* _collection){
|
||||
|
||||
int TestSuite::loadNext(){
|
||||
summoningSickness = 0;
|
||||
seed = 0;
|
||||
aiMaxCalls = -1;
|
||||
if (!nbfiles) return 0;
|
||||
if (currentfile >= nbfiles) return 0;
|
||||
currentfile++;
|
||||
@@ -489,15 +513,18 @@ void TestSuite::cleanup(){
|
||||
initState.cleanup();
|
||||
endState.cleanup();
|
||||
actions.cleanup();
|
||||
loadRandValues("");
|
||||
}
|
||||
|
||||
int TestSuite::load(const char * _filename){
|
||||
summoningSickness = 0;
|
||||
forceAbility = false;
|
||||
gameType = GAME_TYPE_CLASSIC;
|
||||
char filename[4096];
|
||||
sprintf(filename, RESPATH"/test/%s", _filename);
|
||||
std::ifstream file(filename);
|
||||
std::string s;
|
||||
loadRandValues("");
|
||||
|
||||
int state = -1;
|
||||
|
||||
@@ -513,6 +540,22 @@ int TestSuite::load(const char * _filename){
|
||||
summoningSickness = 1;
|
||||
continue;
|
||||
}
|
||||
if (s.compare("forceability") == 0) {
|
||||
forceAbility = true;
|
||||
continue;
|
||||
}
|
||||
if (s.find("seed ") == 0) {
|
||||
seed = atoi(s.substr(5).c_str());
|
||||
continue;
|
||||
}
|
||||
if (s.find("rvalues:") == 0) {
|
||||
loadRandValues(s.substr(8).c_str());
|
||||
continue;
|
||||
}
|
||||
if (s.find("aicalls ") == 0) {
|
||||
aiMaxCalls = atoi(s.substr(8).c_str());
|
||||
continue;
|
||||
}
|
||||
if (s.compare("momir") == 0) {
|
||||
gameType = GAME_TYPE_MOMIR;
|
||||
continue;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "../include/TextScroller.h"
|
||||
|
||||
#include "../include/utils.h"
|
||||
#include <JLBFont.h>
|
||||
|
||||
TextScroller::TextScroller(JLBFont * font, float x, float y, float width, float speed):JGuiObject(0){
|
||||
|
||||
@@ -1,9 +1,37 @@
|
||||
#include "../include/config.h"
|
||||
#include "../include/utils.h"
|
||||
#include <vector>
|
||||
using std::vector;
|
||||
|
||||
int randValuesCursor = -1;
|
||||
vector<int>randValues;
|
||||
|
||||
int loadRandValues(string s){
|
||||
randValues.clear();
|
||||
randValuesCursor = -1;
|
||||
while (s.size()){
|
||||
unsigned int value;
|
||||
size_t limiter = s.find(",");
|
||||
if (limiter != string::npos){
|
||||
value = atoi(s.substr(0,limiter).c_str());
|
||||
s = s.substr(limiter+1);
|
||||
}else{
|
||||
value = atoi(s.c_str());
|
||||
s = "";
|
||||
}
|
||||
if (value) randValues.push_back(value);
|
||||
}
|
||||
if (randValues.size()) randValuesCursor = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int WRand(){
|
||||
if (randValuesCursor == -1) return rand();
|
||||
int result = randValues[randValuesCursor];
|
||||
randValuesCursor++;
|
||||
if ((size_t)randValuesCursor >= randValues.size()) randValuesCursor = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int filesize(const char * filename){
|
||||
int file_size = 0;
|
||||
@@ -60,92 +88,92 @@ void dumpStack()
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* RAM simple check functions source */
|
||||
|
||||
|
||||
// *** FUNCTIONS ***
|
||||
|
||||
u32 ramAvailableLineareMax (void)
|
||||
{
|
||||
u32 size, sizeblock;
|
||||
u8 *ram;
|
||||
|
||||
|
||||
// Init variables
|
||||
size = 0;
|
||||
sizeblock = RAM_BLOCK;
|
||||
|
||||
// Check loop
|
||||
while (sizeblock)
|
||||
{
|
||||
// Increment size
|
||||
size += sizeblock;
|
||||
|
||||
// Allocate ram
|
||||
ram = (u8 *) malloc(size);
|
||||
|
||||
// Check allocate
|
||||
if (!(ram))
|
||||
{
|
||||
// Restore old size
|
||||
size -= sizeblock;
|
||||
|
||||
// Size block / 2
|
||||
sizeblock >>= 1;
|
||||
}
|
||||
else
|
||||
free(ram);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
u32 ramAvailable (void)
|
||||
{
|
||||
u8 **ram, **temp;
|
||||
u32 size, count, x;
|
||||
|
||||
|
||||
// Init variables
|
||||
ram = NULL;
|
||||
size = 0;
|
||||
count = 0;
|
||||
|
||||
// Check loop
|
||||
for (;;)
|
||||
{
|
||||
// Check size entries
|
||||
if (!(count % 10))
|
||||
{
|
||||
// Allocate more entries if needed
|
||||
temp = (u8**) realloc(ram,sizeof(u8 *) * (count + 10));
|
||||
if (!(temp)) break;
|
||||
|
||||
// Update entries and size (size contains also size of entries)
|
||||
ram = temp;
|
||||
size += (sizeof(u8 *) * 10);
|
||||
}
|
||||
|
||||
// Find max lineare size available
|
||||
x = ramAvailableLineareMax();
|
||||
if (!(x)) break;
|
||||
|
||||
// Allocate ram
|
||||
ram[count] = (u8 *) malloc(x);
|
||||
if (!(ram[count])) break;
|
||||
|
||||
// Update variables
|
||||
size += x;
|
||||
count++;
|
||||
}
|
||||
|
||||
// Free ram
|
||||
if (ram)
|
||||
{
|
||||
for (x=0;x<count;x++) free(ram[x]);
|
||||
free(ram);
|
||||
}
|
||||
|
||||
return size;
|
||||
|
||||
/* RAM simple check functions source */
|
||||
|
||||
|
||||
// *** FUNCTIONS ***
|
||||
|
||||
u32 ramAvailableLineareMax (void)
|
||||
{
|
||||
u32 size, sizeblock;
|
||||
u8 *ram;
|
||||
|
||||
|
||||
// Init variables
|
||||
size = 0;
|
||||
sizeblock = RAM_BLOCK;
|
||||
|
||||
// Check loop
|
||||
while (sizeblock)
|
||||
{
|
||||
// Increment size
|
||||
size += sizeblock;
|
||||
|
||||
// Allocate ram
|
||||
ram = (u8 *) malloc(size);
|
||||
|
||||
// Check allocate
|
||||
if (!(ram))
|
||||
{
|
||||
// Restore old size
|
||||
size -= sizeblock;
|
||||
|
||||
// Size block / 2
|
||||
sizeblock >>= 1;
|
||||
}
|
||||
else
|
||||
free(ram);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
u32 ramAvailable (void)
|
||||
{
|
||||
u8 **ram, **temp;
|
||||
u32 size, count, x;
|
||||
|
||||
|
||||
// Init variables
|
||||
ram = NULL;
|
||||
size = 0;
|
||||
count = 0;
|
||||
|
||||
// Check loop
|
||||
for (;;)
|
||||
{
|
||||
// Check size entries
|
||||
if (!(count % 10))
|
||||
{
|
||||
// Allocate more entries if needed
|
||||
temp = (u8**) realloc(ram,sizeof(u8 *) * (count + 10));
|
||||
if (!(temp)) break;
|
||||
|
||||
// Update entries and size (size contains also size of entries)
|
||||
ram = temp;
|
||||
size += (sizeof(u8 *) * 10);
|
||||
}
|
||||
|
||||
// Find max lineare size available
|
||||
x = ramAvailableLineareMax();
|
||||
if (!(x)) break;
|
||||
|
||||
// Allocate ram
|
||||
ram[count] = (u8 *) malloc(x);
|
||||
if (!(ram[count])) break;
|
||||
|
||||
// Update variables
|
||||
size += x;
|
||||
count++;
|
||||
}
|
||||
|
||||
// Free ram
|
||||
if (ram)
|
||||
{
|
||||
for (x=0;x<count;x++) free(ram[x]);
|
||||
free(ram);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user