Dependencies: XBeeLib mbed HvZAlphaNumLib HvZServerLib
Diff: lib/iHvZ.hpp
- Revision:
- 0:9cdba0589ba2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/iHvZ.hpp Sun Dec 12 19:35:00 2010 +0000 @@ -0,0 +1,281 @@ +#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 \ No newline at end of file