Advertisement
Guest User

VP TicTacToe bot

a guest
May 14th, 2016
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.10 KB | None | 0 0
  1. #include "VP.h"
  2.  
  3. #include <iostream>
  4. #include <list>
  5. #include <map>
  6. #include <string>
  7.  
  8. using namespace std;
  9.  
  10. const char* UNIVERSE_HOST = "universe.virtualparadise.org";
  11. int UNIVERSE_PORT = 57000;
  12.  
  13. struct Object {
  14.   Object() {}
  15.  
  16.   Object(int objectId, int userId,
  17.       float objectX, float objectY, float objectZ,
  18.       float objectRotationX, float objectRotationY, float objectRotationZ,
  19.       float objectRotationAngle,
  20.       int objectType,
  21.       string objectModel, string objectDescription, string objectAction) :
  22.           mObjectId(objectId), mUserId(userId),
  23.           mX(objectX), mY(objectY), mZ(objectZ),
  24.           mRotationX(objectRotationX),
  25.           mRotationY(objectRotationY),
  26.           mRotationZ(objectRotationZ),
  27.           mRotationAngle(objectRotationAngle),
  28.           mType(objectType),
  29.           mModel(objectModel),
  30.           mDescription(objectDescription),
  31.           mAction(objectAction) {
  32.   }
  33.  
  34.   int mObjectId;
  35.   int mUserId;
  36.   float mX, mY, mZ;
  37.   float mRotationX, mRotationY, mRotationZ, mRotationAngle;
  38.   int mType;
  39.   string mModel, mDescription, mAction;
  40. };
  41.  
  42. void buildObject(VPInstance instance, const Object& o) {
  43.   vp_int_set(instance, VP_OBJECT_TYPE, o.mType);
  44.   vp_float_set(instance, VP_OBJECT_X, o.mX);
  45.   vp_float_set(instance, VP_OBJECT_Y, o.mY);
  46.   vp_float_set(instance, VP_OBJECT_Z, o.mZ);
  47.   vp_float_set(instance, VP_OBJECT_ROTATION_X, o.mRotationX);
  48.   vp_float_set(instance, VP_OBJECT_ROTATION_Y, o.mRotationY);
  49.   vp_float_set(instance, VP_OBJECT_ROTATION_Z, o.mRotationZ);
  50.   vp_float_set(instance, VP_OBJECT_ROTATION_ANGLE, o.mRotationAngle);
  51.   vp_string_set(instance, VP_OBJECT_MODEL, o.mModel.c_str());
  52.   vp_string_set(instance, VP_OBJECT_DESCRIPTION, o.mDescription.c_str());
  53.   vp_string_set(instance, VP_OBJECT_ACTION, o.mAction.c_str());
  54.   vp_object_add(instance);
  55. }
  56.  
  57. class TicTacToeBot {
  58.   public:
  59.     TicTacToeBot(VPInstance instance, const string& ownerName) :
  60.         mInstance(instance), mOwnerName(ownerName), mPhase(WAITING_FOR_OWNER) {
  61.     }
  62.  
  63.     void onAvatarAdd(const string& name, int session, int userId,
  64.         float x, float y, float z) {
  65.       mUserNamesBySession[session] = name;
  66.       if (mPhase == WAITING_FOR_OWNER && name == mOwnerName) {
  67.         mOwnerSession = session;
  68.         mOwnerId = userId;
  69.         joinOwner(x, y, z);
  70.       }
  71.     }
  72.  
  73.     void onObjectClick(int avatarSession, int objectId, float hitX, float hitY,
  74.         float hitZ) {
  75.       if (avatarSession == mOwnerSession && mPhase == PROMPTING_FOR_GRID) {
  76.         mCellObjects[mWaitingForCell] = mObjectsById[objectId];
  77.         if (mWaitingForCell < 8) {
  78.           promptForGrid(mWaitingForCell + 1);
  79.         } else {
  80.           promptBuildXs();
  81.         }
  82.       }
  83.       if (avatarSession == mOwnerSession && mPhase == MATCHING_XS) {
  84.         mXPieces[mWaitingForCell] = mObjectsById[objectId];
  85.         mPieceObjectIds.push_back(objectId);
  86.         if (mWaitingForCell < 8) {
  87.           promptMatchX(mWaitingForCell + 1);
  88.         } else {
  89.           deletePieces();
  90.           promptBuildOs();
  91.         }
  92.       }
  93.       if (avatarSession == mOwnerSession && mPhase == MATCHING_OS) {
  94.         mOPieces[mWaitingForCell] = mObjectsById[objectId];
  95.         mPieceObjectIds.push_back(objectId);
  96.         if (mWaitingForCell < 8) {
  97.           promptMatchO(mWaitingForCell + 1);
  98.         }
  99.         else {
  100.           deletePieces();
  101.           resetGame();
  102.           announceReady();
  103.         }
  104.       }
  105.       int cell = cellForObject(objectId);
  106.       if (cell != -1) {
  107.         if (mPhase == READY_PLAYER_ONE) {
  108.           mPlayer1Session = avatarSession;
  109.           buildGamePiece(cell, true);
  110.           mGameBoard[cell] = 1;
  111.           mPhase = READY_PLAYER_TWO;
  112.         } else if (mPhase == READY_PLAYER_TWO &&
  113.             avatarSession != mPlayer1Session &&
  114.             mGameBoard[cell] == 0) {
  115.           mPlayer2Session = avatarSession;
  116.           buildGamePiece(cell, false);
  117.           mGameBoard[cell] = -1;
  118.           mPhase = ONGOING_GAME;
  119.         } else if (mPhase == ONGOING_GAME &&
  120.             avatarSession == mPlayer1Session &&
  121.             mPlayer1sTurn &&
  122.             mGameBoard[cell] == 0) {
  123.           mPlayer1sTurn = false;
  124.           buildGamePieceAndBlock(cell, true);
  125.           mGameBoard[cell] = 1;
  126.         } else if (mPhase == ONGOING_GAME &&
  127.             avatarSession == mPlayer2Session &&
  128.             !mPlayer1sTurn &&
  129.             mGameBoard[cell] == 0) {
  130.           mPlayer1sTurn = true;
  131.           buildGamePieceAndBlock(cell, false);
  132.           mGameBoard[cell] = -1;
  133.         }
  134.       }
  135.     }
  136.  
  137.     void onObject(const Object& object) {
  138.       if (isSetupBuildingPhase(mPhase) && object.mUserId == mOwnerId) {
  139.         mObjectsById[object.mObjectId] = object;
  140.       }
  141.     }
  142.  
  143.     void onObjectChange(const Object& object) {
  144.       // No need to treat scanning differently from subscribing.
  145.       onObject(object);
  146.     }
  147.  
  148.     void onCellEnd() {
  149.       if (++mScanCell < 100) {
  150.         int nextX = mScanStartX + (mScanCell / 10);
  151.         int nextZ = mScanStartZ + (mScanCell % 10);
  152.         vp_query_cell(mInstance, nextX, nextZ);
  153.       } else {
  154.         mPhase = WATCHING_DELETES;
  155.         cout << "Found " << mObjectsById.size() << " of your objects." << endl;
  156.         whisperOwner("Now I'm going to scan how to rebuild your board design.");
  157.         whisperOwner("I need you to delete each object one at a time --");
  158.         whisperOwner("but don't worry, they'll come right back when you");
  159.         whisperOwner("say 'done'");
  160.       }
  161.     }
  162.  
  163.     void onObjectDelete(int avatarSession, int objectId) {
  164.       if (mPhase != WATCHING_DELETES) {
  165.         return;
  166.       }
  167.       if (mObjectsById.find(objectId) != mObjectsById.end()) {
  168.         Object object = mObjectsById[objectId];
  169.         mBoardObjects.push_back(object);
  170.         whisperOwner(string("Got it: you deleted a ") + object.mModel);
  171.       }
  172.     }
  173.  
  174.     void onAvatarDelete(int session) {
  175.       if (session == mPlayer1Session || session == mPlayer2Session) {
  176.         resetGame();
  177.       }
  178.     }
  179.  
  180.     void onChat(int session, string name, string message) {
  181.       if (session == mOwnerSession) {
  182.         if (mPhase == WATCHING_DELETES && message == "done") {
  183.           cout << "Got " << mBoardObjects.size() << " board objects" << endl;
  184.           rebuildBoard();
  185.         }
  186.         if (mPhase == WAITING_FOR_XS && message == "ready") {
  187.           promptMatchX(0);
  188.         }
  189.         if (mPhase == WAITING_FOR_OS && message == "ready") {
  190.           promptMatchO(0);
  191.         }
  192.       }
  193.     }
  194.  
  195.     void postObjectAdded(int objectId) {
  196.       if (objectsBuiltInPhaseAreGamePieces(mPhase)) {
  197.         mPieceObjectIds.push_back(objectId);
  198.       }
  199.     }
  200.  
  201.     const list<Object> getBlockingBuildQueue() {
  202.       return mBlockingBuildQueue;
  203.     }
  204.  
  205.     void postBuiltQueue(list<Object> builtObjects) {
  206.       mBlockingBuildQueue.clear();
  207.       if (objectsBuiltInPhaseAreGamePieces(mPhase)) {
  208.         for (list<Object>::iterator i = builtObjects.begin();
  209.             i != builtObjects.end(); ++i) {
  210.           mPieceObjectIds.push_back(i->mObjectId);
  211.         }
  212.       }
  213.       if (mPhase == BLOCKED_FOR_REBUILD) {
  214.         for (list<Object>::iterator i = builtObjects.begin();
  215.             i != builtObjects.end(); ++i) {
  216.           mObjectsById[i->mObjectId] = *i;
  217.         }
  218.         mPhase = PROMPTING_FOR_GRID;
  219.         promptForGrid(0);
  220.       }
  221.       if (mPhase == ONGOING_GAME) {
  222.         int winner = evaluateBoard();
  223.         if (winner != 0) {
  224.           gameOver(winner, false);
  225.         }
  226.         if (mPieceObjectIds.size() == 9) {
  227.           gameOver(0, true);
  228.         }
  229.       }
  230.     }
  231.   private:
  232.     VPInstance mInstance;
  233.  
  234.     string mOwnerName;
  235.     int mOwnerSession;
  236.     int mOwnerId;
  237.  
  238.     enum Phase {  
  239.       WAITING_FOR_OWNER,
  240.       SCANNING_OBJECTS,
  241.       WATCHING_DELETES,
  242.       BLOCKED_FOR_REBUILD,
  243.       PROMPTING_FOR_GRID,
  244.       WAITING_FOR_XS,
  245.       MATCHING_XS,
  246.       WAITING_FOR_OS,
  247.       MATCHING_OS,
  248.       READY_PLAYER_ONE,
  249.       READY_PLAYER_TWO,
  250.       ONGOING_GAME
  251.     };
  252.     Phase mPhase;
  253.  
  254.     int mScanStartX, mScanStartZ;
  255.     int mScanCell;
  256.  
  257.     map<int, Object> mObjectsById;
  258.     map<int, string> mUserNamesBySession;
  259.     list<Object> mBoardObjects;
  260.     int mWaitingForCell;
  261.     Object mCellObjects[9];
  262.     Object mXPieces[9];
  263.     Object mOPieces[9];
  264.     list<int> mPieceObjectIds;
  265.     list<Object> mBlockingBuildQueue;
  266.  
  267.     int mPlayer1Session;
  268.     int mPlayer2Session;
  269.     bool mPlayer1sTurn;
  270.     int mGameBoard[9];
  271.  
  272.     void whisperOwner(string msg) {
  273.       vp_console_message(mInstance, mOwnerSession, "", msg.c_str(), 0, 0, 0, 0);
  274.     }
  275.  
  276.     void joinOwner(float x, float y, float z) {
  277.       vp_float_set(mInstance, VP_MY_X, x);
  278.       vp_float_set(mInstance, VP_MY_Y, y);
  279.       vp_float_set(mInstance, VP_MY_Z, z);
  280.       vp_state_change(mInstance);
  281.       mPhase = SCANNING_OBJECTS;
  282.  
  283.       whisperOwner("Hi! One sec, scanning.");
  284.       startScan(x, y, z);
  285.     }
  286.  
  287.     void startScan(float x, float y, float z) {
  288.       mPhase = SCANNING_OBJECTS;
  289.       mScanCell = 0;
  290.       mScanStartX = x - 5;
  291.       mScanStartZ = z - 5;
  292.       vp_query_cell(mInstance, mScanStartX, mScanStartZ);
  293.     }
  294.  
  295.     void rebuildBoard() {
  296.       whisperOwner("Rebuilding...");
  297.       for (list<Object>::iterator i = mBoardObjects.begin();
  298.         i != mBoardObjects.end(); ++i) {
  299.         mBlockingBuildQueue.push_back(*i);
  300.       }
  301.       mPhase = BLOCKED_FOR_REBUILD;
  302.     }
  303.  
  304.     void promptForGrid(int cell) {
  305.       whisperOwner("Please click on the " + nameCell(cell) + " grid cell");
  306.       mWaitingForCell = cell;
  307.     }
  308.  
  309.     string nameCell(int cell) {
  310.       if (cell == 4) {
  311.         return "center";
  312.       }
  313.       string row;
  314.       if (cell < 3) {
  315.         row = "top";
  316.       } else if (cell > 5) {
  317.         row = "bottom";
  318.       } else {
  319.         row = "middle";
  320.       }
  321.       string column;
  322.       if (cell % 3 == 0) {
  323.         column = "left";
  324.       } else if (cell % 3 == 1) {
  325.         column = "middle";
  326.       } else {
  327.         column = "right";
  328.       }
  329.       return row + " " + column;
  330.     }
  331.  
  332.     void promptBuildXs() {
  333.       whisperOwner("Now build X's in each grid cell, then say 'ready'");
  334.       mPhase = WAITING_FOR_XS;
  335.     }
  336.  
  337.     void promptMatchX(int cell) {
  338.       mPhase = MATCHING_XS;
  339.       whisperOwner("Please click on the " + nameCell(cell) + " 'X' piece");
  340.       mWaitingForCell = cell;
  341.     }
  342.  
  343.     bool isSetupBuildingPhase(Phase phase) {
  344.       // We need to watch builds in these phases in case they're part of the
  345.       // initial construction.
  346.       return mPhase == SCANNING_OBJECTS || mPhase == WAITING_FOR_XS ||
  347.           mPhase == WAITING_FOR_OS;
  348.     }
  349.  
  350.     bool objectsBuiltInPhaseAreGamePieces(Phase phase) {
  351.       return phase != WATCHING_DELETES &&
  352.         phase != BLOCKED_FOR_REBUILD; // Don't count rebuilding the board.
  353.     }
  354.  
  355.     void deletePieces() {
  356.       for (list<int>::iterator i = mPieceObjectIds.begin();
  357.           i != mPieceObjectIds.end(); ++i) {
  358.         vp_object_delete(mInstance, *i);
  359.       }
  360.       mPieceObjectIds.clear();
  361.     }
  362.  
  363.     void promptBuildOs() {
  364.       whisperOwner("Now build O's in each grid cell, then say 'ready'");
  365.       mPhase = WAITING_FOR_OS;
  366.     }
  367.  
  368.     void promptMatchO(int cell) {
  369.       mPhase = MATCHING_OS;
  370.       whisperOwner("Please click on the " + nameCell(cell) + " 'O' piece");
  371.       mWaitingForCell = cell;
  372.     }
  373.  
  374.     void resetGame() {
  375.       mPhase = READY_PLAYER_ONE;
  376.       mPlayer1Session = -1;
  377.       mPlayer2Session = -1;
  378.       mPlayer1sTurn = true;
  379.       for (int i = 0; i < 9; ++i) {
  380.         mGameBoard[i] = 0;
  381.       }
  382.       deletePieces();
  383.     }
  384.  
  385.     void announceReady() {
  386.       whisperOwner("Ready"); // a little premature to realllly announce
  387.     }
  388.  
  389.     void buildGamePiece(int cell, bool asX) {
  390.       Object& originalObject = asX ? mXPieces[cell] : mOPieces[cell];
  391.       buildObject(mInstance, originalObject);
  392.     }
  393.  
  394.     void buildGamePieceAndBlock(int cell, bool asX) {
  395.       Object& originalObject = asX ? mXPieces[cell] : mOPieces[cell];
  396.       mBlockingBuildQueue.push_back(originalObject);
  397.     }
  398.  
  399.     int cellForObject(int objectId) {
  400.       for (int i = 0; i < 9; ++i) {
  401.         if (mCellObjects[i].mObjectId == objectId) {
  402.           return i;
  403.         }
  404.       }
  405.       return -1;
  406.     }
  407.  
  408.     void gameOver(int winner, bool tie) {
  409.       if (tie) {
  410.         resetGame();
  411.         return;
  412.      }
  413.       vp_say(mInstance, "Winner:");
  414.       string winnerName = (winner > 0) ? mUserNamesBySession[mPlayer1Session] :
  415.           mUserNamesBySession[mPlayer2Session];
  416.       vp_say(mInstance, winnerName.c_str());
  417.       resetGame();
  418.     }
  419.  
  420.     int evaluateBoard() {
  421.       if (playerWins(1)) {
  422.         return 1;
  423.       }
  424.       if (playerWins(-1)) {
  425.         return -1;
  426.       }
  427.       return 0;
  428.     }
  429.  
  430.     bool playerWins(int player) {
  431.       for (int row = 0; row < 3; ++row) {
  432.         bool winsOnRow = true;
  433.         for (int col = 0; col < 3; ++col) {
  434.           if (mGameBoard[row * 3 + col] != player) {
  435.             winsOnRow = false;
  436.             break;
  437.           }
  438.         }
  439.         if (winsOnRow) {
  440.           return true;
  441.         }
  442.       }
  443.       for (int col = 0; col < 3; ++col) {
  444.         bool winsOnCol = true;
  445.         for (int row = 0; row < 3; ++row) {
  446.           if (mGameBoard[row * 3 + col] != player) {
  447.             winsOnCol = false;
  448.             break;
  449.           }
  450.         }
  451.         if (winsOnCol) {
  452.           return true;
  453.         }
  454.       }
  455.       return (mGameBoard[0] == player && mGameBoard[4] == player && mGameBoard[8] == player) ||
  456.           (mGameBoard[2] == player && mGameBoard[4] == player && mGameBoard[6] == player);
  457.     }
  458. };
  459.  
  460. TicTacToeBot *BOT;
  461.  
  462. void event_avatar_add(VPInstance instance) {
  463.   string avatarName(vp_string(instance, VP_AVATAR_NAME));
  464.   int avatarSession = vp_int(instance, VP_AVATAR_SESSION);
  465.   int userId = vp_int(instance, VP_USER_ID);
  466.   float avatarX = vp_float(instance, VP_AVATAR_X);
  467.   float avatarY = vp_float(instance, VP_AVATAR_Y);
  468.   float avatarZ = vp_float(instance, VP_AVATAR_Z);
  469.   BOT->onAvatarAdd(avatarName, avatarSession, userId,
  470.       avatarX, avatarY, avatarZ);
  471. }
  472.  
  473. void event_object_click(VPInstance instance) {
  474.   int avatarSession = vp_int(instance, VP_AVATAR_SESSION);
  475.   int objectId = vp_int(instance, VP_OBJECT_ID);
  476.   float clickHitX = vp_float(instance, VP_CLICK_HIT_X);
  477.   float clickHitY = vp_float(instance, VP_CLICK_HIT_Y);
  478.   float clickHitZ = vp_float(instance, VP_CLICK_HIT_Z);
  479.   BOT->onObjectClick(avatarSession, objectId, clickHitX, clickHitY, clickHitZ);
  480. }
  481.  
  482. void event_object(VPInstance instance) {
  483.   int objectId = vp_int(instance, VP_OBJECT_ID);
  484.   int userId = vp_int(instance, VP_OBJECT_USER_ID);
  485.   float objectX = vp_float(instance, VP_OBJECT_X);
  486.   float objectY = vp_float(instance, VP_OBJECT_Y);
  487.   float objectZ = vp_float(instance, VP_OBJECT_Z);
  488.   float objectRotationX = vp_float(instance, VP_OBJECT_ROTATION_X);
  489.   float objectRotationY = vp_float(instance, VP_OBJECT_ROTATION_Y);
  490.   float objectRotationZ = vp_float(instance, VP_OBJECT_ROTATION_Z);
  491.   float objectRotationAngle = vp_float(instance, VP_OBJECT_ROTATION_ANGLE);
  492.   int objectType = vp_int(instance, VP_OBJECT_TYPE);
  493.   string objectModel =
  494.       string(vp_string(instance, VP_OBJECT_MODEL));
  495.   string objectDescription =
  496.       string(vp_string(instance, VP_OBJECT_DESCRIPTION));
  497.   string objectAction =
  498.       string(vp_string(instance, VP_OBJECT_ACTION));
  499.   Object object(objectId, userId, objectX, objectY, objectZ, objectRotationX,
  500.       objectRotationY, objectRotationZ, objectRotationAngle, objectType,
  501.       objectModel, objectDescription, objectAction);
  502.   BOT->onObject(object);
  503. }
  504.  
  505. void event_cell_end(VPInstance instance) {
  506.   BOT->onCellEnd();
  507. }
  508.  
  509. void event_object_delete(VPInstance instance) {
  510.   int session = vp_int(instance, VP_AVATAR_SESSION);
  511.   int objectId = vp_int(instance, VP_OBJECT_ID);
  512.   BOT->onObjectDelete(session, objectId);
  513. }
  514.  
  515. void event_chat(VPInstance instance) {
  516.   int session = vp_int(instance, VP_AVATAR_SESSION);
  517.   string name = vp_string(instance, VP_AVATAR_NAME);
  518.   string message = vp_string(instance, VP_CHAT_MESSAGE);
  519.   BOT->onChat(session, name, message);
  520. }
  521.  
  522. void event_object_change(VPInstance instance) {
  523.   int objectId = vp_int(instance, VP_OBJECT_ID);
  524.   int userId = vp_int(instance, VP_OBJECT_USER_ID);
  525.   int time = vp_int(instance, VP_OBJECT_TIME);
  526.   float objectX = vp_float(instance, VP_OBJECT_X);
  527.   float objectY = vp_float(instance, VP_OBJECT_Y);
  528.   float objectZ = vp_float(instance, VP_OBJECT_Z);
  529.   float objectRotationX = vp_float(instance, VP_OBJECT_ROTATION_X);
  530.   float objectRotationY = vp_float(instance, VP_OBJECT_ROTATION_Y);
  531.   float objectRotationZ = vp_float(instance, VP_OBJECT_ROTATION_Z);
  532.   float objectRotationAngle = vp_float(instance, VP_OBJECT_ROTATION_ANGLE);
  533.   int objectType = vp_int(instance, VP_OBJECT_TYPE);
  534.   string objectModel =
  535.     string(vp_string(instance, VP_OBJECT_MODEL));
  536.   string objectDescription =
  537.     string(vp_string(instance, VP_OBJECT_DESCRIPTION));
  538.   string objectAction =
  539.     string(vp_string(instance, VP_OBJECT_ACTION));
  540.   Object object(objectId, userId, objectX, objectY, objectZ, objectRotationX,
  541.     objectRotationY, objectRotationZ, objectRotationAngle, objectType,
  542.     objectModel, objectDescription, objectAction);
  543.   BOT->onObjectChange(object);
  544. }
  545.  
  546. void event_avatar_delete(VPInstance instance) {
  547.   int session = vp_int(instance, VP_AVATAR_SESSION);
  548.   BOT->onAvatarDelete(session);
  549. }
  550.  
  551. bool blockedAtTopLevel;
  552. int lastBlockResult;
  553. void callback_object_add(VPInstance instance, int cbType, int data) {
  554.   int objectId = vp_int(instance, VP_OBJECT_ID);
  555.  
  556.   if (blockedAtTopLevel) {
  557.     blockedAtTopLevel = false;
  558.     lastBlockResult = objectId;
  559.   } else {
  560.     BOT->postObjectAdded(objectId);
  561.   }
  562. }
  563.  
  564. int main(int argc, const char* argv[]) {
  565.   int rc;
  566.   if (rc = vp_init()) {
  567.     cout << "Unable to initialize API: " << rc << endl;
  568.     return -1;
  569.   }
  570.  
  571.   VPInstance instance = vp_create();
  572.  
  573.   if (rc = vp_connect_universe(instance, UNIVERSE_HOST, UNIVERSE_PORT)) {
  574.     cout << "Couldn't connect to universe: " << rc << endl;
  575.     return -1;
  576.   }
  577.  
  578.   cout << "Before you begin, you'll need to build an empty board." << endl;
  579.   cout << "Any design will do as long as there's a 3x3 grid." << endl;
  580.   cout << "When you're ready, stand next to it -- the bot will join when it gets"
  581.     << " started up, and it'll need to find your build." << endl << endl;
  582.  
  583.   // Sorry guys, old-school.
  584.   string username, password, world;
  585.   cout << "Username: ";
  586.   cin >> username;
  587.   cout << "Password: ";
  588.   cin >> password;
  589.   cout << "World: ";
  590.   cin >> world;
  591.   if (rc = vp_login(instance, username.c_str(), password.c_str(), "Crowbot")) {
  592.     cout << "Couldn't login: " << rc << endl;
  593.     return -1;
  594.   }
  595.  
  596.   if (rc = vp_enter(instance, world.c_str())) {
  597.     cout << "Couldn't enter world: " << rc << endl;
  598.     return -1;
  599.   }
  600.  
  601.   vp_event_set(instance, VP_EVENT_AVATAR_ADD, event_avatar_add);
  602.   vp_event_set(instance, VP_EVENT_OBJECT_CLICK, event_object_click);
  603.   vp_event_set(instance, VP_EVENT_OBJECT, event_object);
  604.   vp_event_set(instance, VP_EVENT_CELL_END, event_cell_end);
  605.   vp_event_set(instance, VP_EVENT_OBJECT_DELETE, event_object_delete);
  606.   vp_event_set(instance, VP_EVENT_CHAT, event_chat);
  607.   vp_event_set(instance, VP_EVENT_OBJECT_CHANGE, event_object_change);
  608.   vp_event_set(instance, VP_EVENT_AVATAR_DELETE, event_avatar_delete);
  609.   vp_callback_set(instance, VP_CALLBACK_OBJECT_ADD, callback_object_add);
  610.  
  611.   vp_state_change(instance);
  612.  
  613.   BOT = new TicTacToeBot(instance, username);
  614.  
  615.   list<Object> blockingBuildResults;
  616.   while (!vp_wait(instance, 0)) {
  617.     list<Object> blockingBuildQueue = BOT->getBlockingBuildQueue();
  618.     if (!blockingBuildQueue.empty()) {
  619.       while (!blockingBuildQueue.empty()) {
  620.         Object o = blockingBuildQueue.front();
  621.         blockingBuildQueue.pop_front();
  622.         blockedAtTopLevel = true;
  623.         buildObject(instance, o);
  624.         while (blockedAtTopLevel) {
  625.           vp_wait(instance, 0);
  626.         }
  627.         o.mObjectId = lastBlockResult;
  628.         blockingBuildResults.push_back(o);
  629.       }
  630.       BOT->postBuiltQueue(blockingBuildResults);
  631.       blockingBuildResults.clear();
  632.     }
  633.   }
  634. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement