Dependencies:   XBeeLib mbed HvZAlphaNumLib HvZServerLib

lib/iHvZ.hpp

Committer:
etherealflaim
Date:
2010-12-12
Revision:
1:d1b5cd8b2c18
Parent:
0:9cdba0589ba2

File content as of revision 1:d1b5cd8b2c18:

#ifndef _iHvZ
#define _iHvZ

#include "mbed.h"


#include <map>
#include <string>
#include <sstream>
#include <fstream>
class iHvZ;

#define STUN_STATUS_LED LED4
#define STUN_DEFAULT_DURATION (15)
#define STUN_INCUBATION_TIME (30)
#include "Stun.hpp"

#define _XBEE_DEBUG 0
#define XBEE_PINS_DIN_DOUT_RST_ON p28,p27,p26,p20
#include "XBee.hpp"

#define TAG_TIMEOUT_TIME 5
#define TAG_INPUT p23
#include "Tag.hpp"

#define ALPHA_NUM_DISPLAY_PINS p13, p10, p8, p11, p9, p15, p6, p14, p5, p12, p7
#include "AlphaNumDisplay.hpp"

#define ETH_PIN p21
#include "udp.hpp"

typedef enum
{
  STATUS_HUMAN = 0,
  STATUS_ZOMBIE
} Status;

class iHvZ {
private: 
    // Device configuration
    string   m_id;              //< The ID (8-byte DeviceID or 16-bit MAC Address) of this iHvZ device
    Stun     m_stun;            //< The stun status class
    XBee     m_xb;              //< The XBee device
    Tag      m_tag;             //< The device-to-device tagging
    AlphaNumDisplay m_alphanum;  //< The alphanumeric display 
    UDP      m_server;          //< The UDP server class
    
    // Game configuration
    unsigned m_stun_duration;   //< The current stun duration time
    unsigned m_incubation_time; //< The zombie incubation time
    
    // Tag IDs
    vector<string> m_tagids;   //< The list of IDs (8-byte TagIDs) given out when stunned or tagged (antidotes, etc can add to this list)
        
    // List of TagIDs of victims
    vector<string> m_victimids;
    
public:
    /// Start an iHvZ game with the given ID (should start out as the MAC address)
    inline iHvZ(string id)
    : m_id(id),
      m_stun(STUN_STATUS_LED),
      m_xb(id, XBEE_PINS_DIN_DOUT_RST_ON),
      m_tag(this, TAG_INPUT),
      m_server(this, ETH_PIN),
      m_alphanum(ALPHA_NUM_DISPLAY_PINS),
      m_stun_duration(STUN_DEFAULT_DURATION),
      m_incubation_time(STUN_INCUBATION_TIME)
    {
        srand(time(NULL));
    }
    
    inline string itoa(int i)
    {
        static char buf[12];
        sprintf(buf, "%d", i);
        return string(buf);
    }
    
    inline int atoi(string s)
    {
        int i;
        sscanf(s.c_str(), "%d", &i);
        return i;
    }
    
    /* Filesystem save and load */
    /** Save the iHvZ state to iHvZ.cfg on the filesystem */
    inline bool save()
    {
        LocalFileSystem lfs("usb");
        Serial usb(USBTX,USBRX);
        ofstream statefile("/usb/iHvZ.cfg");
        map<string,string> params;
        int writecount = 0;
        
        // Make sure the file opened
        if (!statefile) return false;
        
        // Set the parameters
        //params["mode"] = (m_status==STATUS_HUMAN)?"HUMAN":"ZOMBIE";
        params["deviceid"] = m_id;
        params["stundur"] = itoa(m_stun_duration);
        params["inctime"] = itoa(m_incubation_time);
        params["tagcount"] = itoa(m_tagids.size());
        for (int i = 0; i < m_tagids.size(); ++i)
        {
            params["tagid[" + itoa(i) + "]"] = m_tagids[i];
        }
        params["victimcount"] = itoa(m_victimids.size());
        for (int i = 0; i < m_victimids.size(); ++i)
        {
            params["victim[" + itoa(i) + "]"] = m_victimids[i];
        }
        
        
        // Write to file
        for (map<string,string>::iterator iter = params.begin(); iter != params.end(); ++iter)
        {
            statefile << iter->first << "=" << iter->second << endl;
            ++writecount;
        }
        
        // Write status to USB
        usb.printf("Successfully wrote %d parameters to iHvZ.cfg\r\n", writecount);
        
        // Update the display (in case stuff changed)
        m_alphanum.display(m_tagids.size()==0?'Z':'H');
        
        // Success
        return true;
    }
    
    /* Load the iHvZ state from iHvZ.cfg on the filesystem */
    inline bool load()
    {
        LocalFileSystem lfs("usb");
        Serial usb(USBTX,USBRX);
        ifstream statefile("/usb/iHvZ.cfg");
        map<string,string> params;
        int readcount = 0;
        
        // Make sure the file opened
        if (statefile)
        {
            // Read in the lines of the file
            string line;
            while (getline(statefile, line))
            {
                int eqsign = line.find('=');
                if (eqsign == string::npos) continue;
                string param = line.substr(0,eqsign);
                string value = line.substr(eqsign+1);
                params[param] = value;
                ++readcount;
            }
            
            // Read static parameters
            m_id = params["deviceid"];
            m_stun_duration = atoi(params["stundur"]);
            m_incubation_time = atoi(params["inctime"]);
            
            // Read lives
            int tagcnt = atoi(params["tagcount"]);
            m_tagids.clear();
            m_tagids.reserve(tagcnt);
            for (int i = 0; i < tagcnt; ++i)
            {
                m_tagids.push_back( params["tagid[" + itoa(i) + "]"] );
            }
            
            // Read victims
            int victimcnt = atoi(params["victimcount"]);
            m_victimids.clear();
            m_victimids.reserve(victimcnt);
            for (int i = 0; i < victimcnt; ++i)
            {
                m_victimids.push_back( params["victim[" + itoa(i) + "]"] );
            }
        
            usb.printf("Successfully read %d parameters from /usb/iHvZ.cfg\r\n", readcount);
        }
        else
        {
            usb.printf("Unable to read /usb/iHvZ.cfg\r\n");
        }
        m_alphanum.display(m_tagids.size()==0?'Z':'H');
        
        // Success or failure
        return readcount > 0;
    }
    
    
    /* Getters */
    /// Get the status
    inline bool status() { return m_tagids.size() ? STATUS_HUMAN : STATUS_ZOMBIE; }
    /// Get the id
    inline string id() { return m_id; }
    /// Get the next tagid
    inline string life()
    {
        if (m_tagids.size() == 0) return m_id;
        return m_tagids.back();
    }
    /// Get the victims vector
    inline vector<string> &get_victims() { return m_victimids; }
    
    /// Get stun time
    inline unsigned stun_duration() { return m_stun_duration; }    
    /// Get incubation time
    inline unsigned incubation_time() { return m_incubation_time; }
    /// Get the stun tracker
    inline Stun &stun_tracker() { return m_stun; }
    /// Get the tag tracker
    inline Tag &tag_tracker() { return m_tag; }
    /// Get the xbee device
    inline XBee &xbee_device() { return m_xb; }
    /// Get the UDP device
    //inline UDP &udp_device() { return m_server; }
    /// Get the alphanum device
    inline AlphaNumDisplay &alphanumdisplay_device() { return m_alphanum; }
    
    
    /* Setters */
    /// Set the id
    inline void id(string newid) { m_id = newid; m_xb.uid(newid); }
    /// Add a tagid
    inline void life(string newtagid) { 
        m_tagids.push_back(newtagid); 
        
        m_alphanum.display('H');
    }
    /// Set stun time
    inline void stun_duration(unsigned stun) { m_stun_duration = stun; }    
    /// Set incubation time
    inline void incubation_time(unsigned incubation) { m_incubation_time = incubation; }

    /* Meta-actions */
    inline void tagged()
    {
        if (status() == STATUS_ZOMBIE) return;
        // Should we have an admin flag?
        
        // Use up the next player life or antidote
        if (m_tagids.size() > 0) m_tagids.pop_back();
        
        // If the player still has lives, they are fine
        if (m_tagids.size() > 0) return;
        
        // This player is now a zombie!
        m_stun.stun(m_incubation_time);

        // Save the stun to prevent power cycle cheating
        save();
        wait(1);
        m_alphanum.display('Z');
    }
    
    // Register the tagging of the given tagID by this device
    inline void register_tag(string tagid) { m_victimids.push_back(tagid); }
    
    // Clear the victim list
    inline void clear_victims() { m_victimids.clear(); }
    inline void clear_lives() { m_tagids.clear(); }
    
    inline void stunned()
    {
        if (status() == STATUS_HUMAN) return;
        
        // This zombie is now stunned
        m_stun.stun(m_stun_duration);
        
        // Save the stun to prevent power cycle cheating
        save();
    }
    
    inline void register_stun(string tagid) {}
};


#endif