From 2ed1b1915c0f06097675df7b581023bc45f9b9e6 Mon Sep 17 00:00:00 2001 From: lorien420 Date: Tue, 22 Mar 2005 03:59:59 +0000 Subject: [PATCH] AI --- src/ComputerPlayer.cxx | 174 +++++++++++++++++++++++++++++++++++++++++++++++ src/ComputerPlayer.h | 55 +++++++++++++++ src/ComputerPlayerAI.cxx | 155 +++++++++++++++++++++++++++++++++++++++++ src/ComputerPlayerAI.h | 69 +++++++++++++++++++ 4 files changed, 453 insertions(+) create mode 100644 src/ComputerPlayer.cxx create mode 100644 src/ComputerPlayer.h create mode 100644 src/ComputerPlayerAI.cxx create mode 100644 src/ComputerPlayerAI.h diff --git a/src/ComputerPlayer.cxx b/src/ComputerPlayer.cxx new file mode 100644 index 0000000..3181b3e --- /dev/null +++ b/src/ComputerPlayer.cxx @@ -0,0 +1,174 @@ +using namespace std; + +#include "ComputerPlayer.h" +#include "Score.h" +#include "Garbage.h" +#include "GarbageGenerator.h" +#include "GarbageManager.h" +#include "Clock.h" +#include "ComputerPlayerAI.h" + +//#define WAIT_TIME ( GC_STEPS_PER_SECOND * 10 ) + +bool ComputerPlayer::lost; +GarbageQueue *ComputerPlayer::queue; +ComputerPlayerAI *ComputerPlayer::ai; + +void ComputerPlayer::gameStart() +{ + queue = new GarbageQueue(); + + if ((MetaState::mode & CM_AI_EASY)) + ai = new EasyAI(); + if ((MetaState::mode & CM_AI_MEDIUM)) + ai = new MediumAI(); + if ((MetaState::mode & CM_AI_HARD)) + ai = new HardAI(); + if (ai) + ai->garbageQueue(queue); + + lost = false; +} + +void show_element (GarbageQueueElement *e) { + printf("Element: %p h %d w %d f %d\n", + e, + e->height, + e->width, + e->flavor); +} + +void show_element_foreach (gpointer e, gpointer unused) +{ + show_element((GarbageQueueElement *)e); +} + +void ComputerPlayer::determineLoss() +{ + int garbage_height = queue->height(); + if (garbage_height > GC_SAFE_HEIGHT) { + cerr << "Game over height: " << garbage_height << endl; + exit(0); + /* + lost = true; + Game::win(); + */ + } +} + +int ComputerPlayer::gameFinish() +{ + return lost ? GS_WON : GS_LOST; +} + +void ComputerPlayer::timeStep() +{ + MESSAGE("Computer timeStep"); + if (!ai) { + return; + } + ComputerPlayerAI &localAi = *ai; + if (Game::time_step >= localAi.alarm()) { + localAi.garbageQueue(queue); + GarbageQueue *tmp = localAi.garbageAmount();//garbage_queue); + tmp->sendToGenerator(); + cout << "init pop: " << GC_INITIAL_POP_DELAY << endl; + cout << "steps per second: " << GC_STEPS_PER_SECOND << endl; + cout << "Height: " << queue->height() << endl; + //delete tmp; + queue->reset(); + localAi.resetAlarm(); + } + if(localAi.determineLoss()) { + Game::aiPlayerLoss(); + } +} + +/* Garbage Queue */ +GarbageQueue::GarbageQueue () { + garbage_queue = NULL; + cached_height = -1; +} + +GarbageQueue::~GarbageQueue () { + reset(); +} + +void delete_elements ( gpointer e, gpointer unused ) +{ + delete (GarbageQueueElement *)e; +} + +void GarbageQueue::reset () { + if (garbage_queue != NULL) { + g_slist_foreach(garbage_queue, delete_elements, NULL); + g_slist_free(garbage_queue); + garbage_queue = NULL; + } + cached_height = -1; +} + +void GarbageQueue::add ( int height, int width, int flavor) +{ + GarbageQueueElement *e = new GarbageQueueElement(); + e->active = true; + e->height = height; + e->width = width; + e->flavor = flavor; + add(e); +} + +void GarbageQueue::add ( GarbageQueueElement *element ) +{ + element->active = true; + MESSAGE("Adding garbage " << element->active); + show_element(element); + assert(element->height <= GC_PLAY_HEIGHT); + assert(element->width <= GC_PLAY_WIDTH); + garbage_queue = g_slist_append(garbage_queue, element); + cached_height = -1; +} + +int GarbageQueue::height ( ) +{ + int garbage_height = 0; + GarbageQueueElement *e = NULL; + GSList *cur = NULL; + for (cur = garbage_queue; cur; cur = g_slist_next(cur)) { + e = (GarbageQueueElement *) (cur->data); + if (!e) + break; + garbage_height += e->height; + } + cached_height = garbage_height; + return garbage_height; +} + +GSList *GarbageQueue::garbage ( ) +{ + return garbage_queue; +} + +GSList *GarbageQueue::specialGarbage ( ) +{ + GarbageQueueElement *e = NULL; + GSList *iter = NULL, *ret = NULL; + for (iter = garbage_queue; iter; g_slist_next(iter)) { + e = (GarbageQueueElement *) (iter->data); + if (!e) + break; + if (GarbageManager::isSpecialFlavor(e->flavor)) { + ret = g_slist_append(ret, e); + } + } +} + +static void send_to_generator (gpointer e, gpointer unused) +{ + GarbageGenerator::addToQueue((GarbageQueueElement *)e); +} + +void GarbageQueue::sendToGenerator ( ) +{ + g_slist_foreach(garbage_queue, send_to_generator, NULL); +} diff --git a/src/ComputerPlayer.h b/src/ComputerPlayer.h new file mode 100644 index 0000000..2edf8f1 --- /dev/null +++ b/src/ComputerPlayer.h @@ -0,0 +1,55 @@ +#ifndef COMP_PLAY_H +#define COMP_PLAY_H + +using namespace std; + +#include + +#include "Score.h" +#include "GarbageGenerator.h" +#include "ComputerPlayerAI.h" + +class GarbageQueueElement; +class ComputerPlayerAI; + +class GarbageQueue { +public: + GarbageQueue(); + ~GarbageQueue(); + + void add ( int height, int width, int flavor ); + void add ( GarbageQueueElement *element ); + + int height ( ); + + GSList *garbage ( ); + GSList *specialGarbage ( ); + + void reset(); + + void sendToGenerator ( ); +private: + GSList *garbage_queue; + int cached_height; +}; + +/* static */ class ComputerPlayer { +private: + static bool lost; + static GarbageQueue *queue; + static ComputerPlayerAI *ai; + + static void determineLoss ( ); + +public: + static void gameStart ( ); + static void timeStep ( ); + static int gameFinish ( ); + + static void addGarbage ( int height, int width, int flavor ) { + if (queue) + queue->add(height, width, flavor); + } +}; + +#endif diff --git a/src/ComputerPlayerAI.cxx b/src/ComputerPlayerAI.cxx new file mode 100644 index 0000000..2afc2fd --- /dev/null +++ b/src/ComputerPlayerAI.cxx @@ -0,0 +1,155 @@ +#include "ComputerPlayerAI.h" +#include "Score.h" +#include "Garbage.h" +#include "GarbageGenerator.h" +#include "Game.h" + +/* Begin ComputerPlayerAI */ +int ComputerPlayerAI::baseSteps() +{ + return GC_STEPS_PER_SECOND; +} + +int ComputerPlayerAI::stateSteps() +{ + if (state == AI_WAITING) { + return 0; + } + if (state == AI_SHATTERING) { + return garbageShatterDelay(); + } +} + +void ComputerPlayerAI::resetAlarm() +{ + last_time = Game::time_step; +} + +int ComputerPlayerAI::alarm() +{ + //cout << "Comp AI" << endl; + return last_time + baseSteps() + stateSteps(); +} + +int ComputerPlayerAI::garbageShatterDelay() +{ + if (queue) { + cout << "Given height on shatter calc: " << queue->height() << endl; + return GC_INITIAL_POP_DELAY * 3 * queue->height(); + } else + return 0; +} + +void ComputerPlayerAI::garbageQueue ( GarbageQueue *q ) +{ + queue = q; +} + +GarbageQueue *ComputerPlayerAI::garbageQueue () +{ + return queue; +} + +void set_timestamp (gpointer element, gpointer time_stamp) +{ + BufferElement *e = (BufferElement *)element; + e->time_stamp = GPOINTER_TO_INT(time_stamp); +} + +GarbageQueue *ComputerPlayerAI::garbageAmount( ) +{ + GarbageQueue *q = new GarbageQueue(); + size_t const size = 20; + size_t i = 0; + BufferElement garbage; + if (Score::score > 500) { + for (i = 0; i < (2 % size); ++i) { + garbage.height = 3; + garbage.width = 6; + garbage.flavor = GF_NORMAL; + q->add(garbage.height, garbage.width, garbage.flavor); + } + for (i = 0; i < (3 % size); ++i) { + garbage.height = 1; + garbage.width = 3; + garbage.flavor = GF_GRAY; + q->add(garbage.height, garbage.width, garbage.flavor); + } + for (i = 0; i < (2 % size); ++i) { + garbage.height = 3; + garbage.width = 6; + garbage.flavor = GF_NORMAL; + q->add(garbage.height, garbage.width, garbage.flavor); + } + } else + if (Score::score > 300) { + for (i = 0; i < (2 % size); ++i) { + garbage.height = 2; + garbage.width = 6; + garbage.flavor = GF_NORMAL; + q->add(garbage.height, garbage.width, garbage.flavor); + } + for (i = 0; i < (3 % size); ++i) { + garbage.height = 1; + garbage.width = 3; + garbage.flavor = GF_GRAY; + q->add(garbage.height, garbage.width, garbage.flavor); + } + } else + if (Score::score > 100) { + for (i = 0; i < (3 % size); ++i) { + garbage.height = 1; + garbage.width = 6; + garbage.flavor = GF_NORMAL; + q->add(garbage.height, garbage.width, garbage.flavor); + } + garbage.flavor = GF_GRAY; + q->add(garbage.height, garbage.width, garbage.flavor); + } else + if (Score::score > 50) { + for (i = 0; i < (3 % size); ++i) { + garbage.height = 1; + garbage.width = 4; + garbage.flavor = GF_NORMAL; + q->add(garbage.height, garbage.width, garbage.flavor); + } + } else + for (i = 0; i < (3 % size); ++i) { + garbage.height = 1; + garbage.width = 3; + garbage.flavor = GF_NORMAL; + q->add(garbage.height, garbage.width, garbage.flavor); + } + return q; +} + +bool ComputerPlayerAI::determineLoss() +{ + const unsigned int target = 4; + MESSAGE("Begin AI check for loss"); + if (queue) { + MESSAGE("AI queue height " << queue->height() << " target " << target); + return queue->height() > target; + } else { + return true; + } +} + +/* End ComputerPlayerAI */ + +int EasyAI::baseSteps() +{ + //cout << "easy baseSteps" << endl; + int a = ComputerPlayerAI::baseSteps() * 20; + return a; +} + +int MediumAI::baseSteps() +{ + return ComputerPlayerAI::baseSteps() * 10; +} + +int HardAI::baseSteps() +{ + return ComputerPlayerAI::baseSteps() * 5; +} diff --git a/src/ComputerPlayerAI.h b/src/ComputerPlayerAI.h new file mode 100644 index 0000000..bae7f33 --- /dev/null +++ b/src/ComputerPlayerAI.h @@ -0,0 +1,69 @@ +#ifndef cpai_h_ +#define cpai_h_ + +#include + +using namespace std; + +#include "Game.h" +#include "ComputerPlayer.h" + +class GarbageQueue; + +class ComputerPlayerAI { +private: + int last_time; + +protected: + enum AI_STATE { AI_WAITING, AI_SHATTERING } state; + GarbageQueue *queue; + + virtual int baseSteps(); + virtual int stateSteps(); + +public: + + ComputerPlayerAI(){ + resetAlarm(); + state = AI_WAITING; + queue = NULL; + cout << "Creating a fucking generic" << endl; + } + + ~ComputerPlayerAI(){} + + int alarm ( ); + void resetAlarm ( ); + virtual int garbageShatterDelay ( ); + void garbageQueue ( GarbageQueue *queue ); + GarbageQueue *garbageQueue ( ); + virtual GarbageQueue *garbageAmount ( ); + virtual bool determineLoss ( ); +}; + +class EasyAI :public ComputerPlayerAI { +public: + EasyAI() { cout << "Creating a fucking easy" << endl;} + ~EasyAI(){} + +protected: + virtual int baseSteps(); +}; + +class MediumAI :public ComputerPlayerAI { +public: + MediumAI(){} + ~MediumAI(){} +protected: + virtual int baseSteps(); +}; + +class HardAI :public ComputerPlayerAI { +public: + HardAI(){} + ~HardAI(){} +protected: + virtual int baseSteps(); +}; + +#endif -- 2.11.4.GIT