/mona/src/muzz/muzzWorld.cpp
C++ | 4145 lines | 3534 code | 367 blank | 244 comment | 731 complexity | 3454fa1b80c6c635759610d79a53c870 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- // For conditions of distribution and use, see copyright notice in muzz.hpp
- /*
- *
- * The Muzz World.
- *
- * Muzz creatures interact with a block world.
- * Each muzz has a mona neural network for a brain.
- *
- */
- #ifdef WIN32
- #include <windows.h>
- #include <io.h>
- #endif
- #include <stdlib.h>
- #include <stdio.h>
- #include <assert.h>
- #include "../gui/TimeUtils.h"
- #include "../gui/EasyGL.h"
- #include "muzzWorld.hpp"
- // Version.
- const char *MuzzWorldVersion = MUZZ_WORLD_VERSION;
- // Print version.
- void
- printVersion(FILE *out)
- {
- fprintf(out, "%s\n", &MuzzWorldVersion[4]);
- }
- #ifndef MUZZ_WORLD_DRIVER
- char *Usage[] =
- {
- (char *)"Usage: muzz_world\n",
- (char *)" [-cycles <number of cycles>]\n",
- (char *)" [-initHunger (initial hunger)]\n",
- (char *)" [-initThirst (initial thirst)]\n",
- (char *)" [-numMuzzes <number of muzzes>]\n",
- (char *)" [-numMushrooms <number of mushrooms>]\n",
- (char *)" [-numPools <number of pools>]\n",
- (char *)" [-load <load file name>]\n",
- (char *)" [-save <save file name>]\n",
- (char *)" [-randomSeed <random seed>]\n",
- (char *)" [-objectSeed <object placement seed>]\n",
- (char *)" [-TmazeTerrain (create T-maze terrain)]\n",
- (char *)" [-terrainSeed <terrain generation seed>]\n",
- (char *)" [-terrainDimension <terrain size = dimension x dimension> (minimum=2)]\n",
- (char *)" [-noGraphics (turn off graphics)]\n",
- (char *)" [-pause (graphics only)]\n",
- (char *)" [-numTrainingTrials <number of training trials>]\n",
- (char *)" (Pauses when training trials are completed)\n",
- (char *)" [-forcedResponseTrain (train correct responses by forcibly overriding them)]\n",
- #ifdef WIN32
- (char *)" [-attachConsole (attach to console)]\n",
- #endif
- (char *)" [-version (print version)]\n",
- NULL
- };
- void printUsage()
- {
- for (int i = 0; Usage[i] != NULL; i++)
- {
- fprintf(stderr, (char *)"%s", Usage[i]);
- }
- }
- #endif
- // Run cycles.
- int Cycles = -1;
- int CycleCounter = 0;
- // Show graphics.
- bool Graphics = true;
- // Smooth movements.
- bool SmoothMove = true;
- // Random numbers.
- RANDOM RandomSeed = INVALID_RANDOM;
- Random *Randomizer = NULL;
- RANDOM ObjectSeed = INVALID_RANDOM;
- RANDOM TerrainSeed = INVALID_RANDOM;
- // Files.
- char *SaveFile = NULL;
- char *LoadFile = NULL;
- // Graphics window dimensions.
- #define WINDOW_WIDTH 850
- #define WINDOW_HEIGHT 690
- int WindowWidth = WINDOW_WIDTH;
- int WindowHeight = WINDOW_HEIGHT;
- int GUIheight = WINDOW_HEIGHT / 8;
- int MainWindow;
- // Viewports.
- #define TERRAIN_VIEWPORT 0
- #define MUZZ_VIEWPORT 1
- #define CONTROLS_VIEWPORT 2
- #define MUZZ_STATUS_VIEWPORT 3
- #define TERRAIN_HELP_VIEWPORT 4
- #define MUZZ_HELP_VIEWPORT 5
- #define NUM_VIEWPORTS 6
- typedef enum
- {
- MUZZ_VIEW_ONLY = 0, TERRAIN_VIEW_ONLY = 1, VIEW_BOTH = 2
- }
- VIEW_SELECTION;
- VIEW_SELECTION ViewSelection = VIEW_BOTH;
- VIEW_SELECTION PendingViewSelection = (VIEW_SELECTION)(-1);
- struct ViewportDimension
- {
- GLint x, y;
- GLint width, height;
- GLfloat aspect;
- }
- Viewports[NUM_VIEWPORTS];
- // Picking.
- #define BUFSIZE 1024
- GLuint selectBuf[BUFSIZE];
- GLint pickHits;
- GLenum renderMode = GL_RENDER;
- int cursorX, cursorY;
- void startPicking();
- void processHits(GLint hits, GLuint buffer[], int sw);
- void stopPicking();
- // Muzzes.
- int NUM_MUZZES = DEFAULT_NUM_MUZZES;
- vector<Muzz *> Muzzes;
- // Muzz states.
- #define MUZZ_FRUSTUM_ANGLE 60.0f
- #define MUZZ_FRUSTUM_NEAR 0.01f
- #define MUZZ_FRUSTUM_FAR 10.0f
- #define MUZZ_TURN_DELTA 5.0f
- #define MUZZ_MOVEMENT_DELTA 0.002f
- int CurrentMuzz;
- struct MuzzState
- {
- int sensors[Muzz::NUM_SENSORS];
- int response;
- int x, z;
- int dir;
- BlockTerrain::Block::DIRECTION forward;
- BlockTerrain::Block::DIRECTION backward;
- int lookAtX, lookAtZ;
- int moveType;
- GLfloat moveAmount;
- };
- vector<struct MuzzState> MuzzStates;
- // Move a muzz.
- bool moveMuzz(int muzzIndex);
- // Sense muzz world.
- void senseMuzz(int muzzIndex);
- void senseMuzzDir(int muzzIndex, int direction, GLfloat view[3],
- int &senseX, int &senseZ, int &terrain, int &object);
- // Run a muzz.
- #define INVALID_RESPONSE (-100)
- void runMuzz(int muzzIndex, int forcedResponse = INVALID_RESPONSE);
- // Place muzz in world without changing initial placement.
- void placeMuzz(int muzzIndex, int placeX, int placeY,
- BlockTerrain::Block::DIRECTION placeDir);
- // Terrain.
- // See blockTerrain.hpp for terrain generation parameters.
- typedef enum
- {
- STANDARD_TERRAIN = 0, TMAZE_TERRAIN = 1
- }
- TERRAIN_TYPE;
- TERRAIN_TYPE TerrainType = STANDARD_TERRAIN;
- int TerrainDimension = DEFAULT_TERRAIN_DIMENSION;
- BlockTerrain *Terrain = NULL;
- TmazeTerrain *MazeTerrain = NULL;
- // Terrain view/movement.
- #define TERRAIN_FRUSTUM_ANGLE 60.0f
- #define TERRAIN_FRUSTUM_NEAR 0.01f
- #define TERRAIN_FRUSTUM_FAR 10.0f
- #define TERRAIN_MOVEMENT_DELTA 0.01f
- #define TERRAIN_INITIAL_VIEW_HEIGHT 0.5f
- GLfloat TerrainViewPosition[3];
- // Mushrooms.
- int NUM_MUSHROOMS = DEFAULT_NUM_MUSHROOMS;
- vector<Mushroom *> Mushrooms;
- GLfloat MushroomColor[3] = { 1.0f, 1.0f, 0.0f };
- // Water pools.
- int NUM_POOLS = DEFAULT_NUM_POOLS;
- vector<Pool *> Pools;
- GLfloat PoolColor[3] = { 0.0f, 0.0f, 1.0f };
- // Training.
- int NumTrainingTrials = -1;
- int CurrentTrial = 0;
- int CurrentTrialStep = 0;
- int TrialResetDelay = -1;
- int TrainingTrialResume = -1;
- // Return runMuzzWorld when all muzzes have gotten food and water.
- bool RunMuzzWorldUntilGoalsGotten = false;
- // Forced response training.
- bool ForcedResponseTrain = false;
- vector<struct SensoryResponse> ForcedResponseSequence;
- enum
- {
- INIT_INDEX=(-1), ERROR_INDEX=(-2)
- };
- int ResponseIdx = INIT_INDEX;
- // Get response sequence to obtain food and water.
- struct SensoryResponse
- {
- vector<int> sensors;
- int response;
- int x, y, dir;
- };
- typedef enum
- {
- BREADTH_SEARCH = 0, DEPTH_SEARCH = 1
- }
- SEARCH_TYPE;
- bool getResponseSequenceToGoals(int muzzIndex,
- vector<struct SensoryResponse> &responseSequence,
- SEARCH_TYPE, int maxSearchDepth = (-1));
- // Camera.
- Camera camera;
- // Frame rate management.
- #define TARGET_FRAME_RATE 100.0f
- FrameRate frameRate(TARGET_FRAME_RATE);
- /*
- * Available fonts:
- * GLUT_BITMAP_8_BY_13
- * GLUT_BITMAP_9_BY_15
- * GLUT_BITMAP_TIMES_ROMAN_10
- * GLUT_BITMAP_TIMES_ROMAN_24
- * GLUT_BITMAP_HELVETICA_10
- * GLUT_BITMAP_HELVETICA_12
- * GLUT_BITMAP_HELVETICA_18
- */
- #define FONT GLUT_BITMAP_9_BY_15
- #define LINE_SPACE 15
- // Modes.
- typedef enum
- {
- MANUAL_MODE = 0, TERRAIN_MODE = 1, HELP_MODE = 2
- }
- MODE;
- MODE Mode = TERRAIN_MODE;
- bool TerrainMode = true;
- bool WireView = false;
- bool Pause = false;
- bool Step = false;
- int ManualResponse = INVALID_RESPONSE;
- // 2D functions.
- void helpInfo(int viewport), drawPartitions();
- void enter2Dmode(), exit2Dmode();
- void draw2Dstring(GLfloat x, GLfloat y, void *font, char *string);
- void enter2DMode(int width, int height), exit2DMode();
- // Save muzz world to file.
- bool saveMuzzWorld(char *saveFile);
- // Muzz control help.
- char *MuzzControlHelp[] =
- {
- (char *)"Checks:",
- (char *)" Manual : \"Drive\" selected muzz",
- (char *)" Pause : Pause world",
- (char *)"",
- (char *)"Buttons:",
- (char *)" Reset : Reset world to initial state",
- (char *)" Step : Single-step world",
- (char *)" Help : Show help",
- (char *)" Quit : Terminate",
- (char *)"",
- (char *)"Keys:",
- (char *)" Up arrow : Move forward",
- (char *)" Left arrow : Turn left",
- (char *)" Right arrow : Turn right",
- (char *)" e : Eat",
- (char *)" d : Drink",
- (char *)" p : Print selected muzz brain",
- (char *)" s : Save world to file",
- (char *)" \"muzz.world\"",
- (char *)" f : Full screen",
- NULL
- };
- // Terrain view control help.
- char *TerrainViewControlHelp[] =
- {
- (char *)" Up arrow : Scroll camera up",
- (char *)" Down arrow : Scroll camera down",
- (char *)" Left arrow : Scroll camera left",
- (char *)" Right arrow : Scroll camera right",
- (char *)" PgUp arrow : Zoom camera out",
- (char *)"PgDown arrow : Zoom camera in",
- (char *)" Left mouse : Select/deselect muzz",
- (char *)" and select view pane",
- NULL
- };
- // GUI components.
- class EventsHandler : public GUIEventListener
- {
- public:
- virtual void actionPerformed(GUIEvent& evt);
- };
- EventsHandler handler;
- FPSCounter counter;
- GUICheckBox *manualCheck;
- GUICheckBox *pauseCheck;
- GUIFrame *guiFrame = NULL;
- // Annotate graph?
- bool AnnotateGraph = true;
- // Run muzzes.
- void runMuzzes()
- {
- int i;
- bool moveDone, gotGoals, foundGoals;
- // Complete movements for previous responses before proceeding.
- moveDone = true;
- for (i = 0; i < NUM_MUZZES; i++)
- {
- if (!moveMuzz(i))
- {
- moveDone = false;
- }
- }
- if (!moveDone)
- {
- return;
- }
- // Determine sensory input for muzzes.
- for (i = 0; i < NUM_MUZZES; i++)
- {
- senseMuzz(i);
- }
- // Manual mode?
- if (Mode == MANUAL_MODE)
- {
- // Only current muzz can run.
- if (CurrentMuzz != -1)
- {
- // Manual response provided?
- if (ManualResponse != INVALID_RESPONSE)
- {
- // Override muzz with manual response.
- Muzzes[CurrentMuzz]->brain->responseOverride = ManualResponse;
- runMuzz(CurrentMuzz);
- Muzzes[CurrentMuzz]->brain->responseOverride = Mona::NULL_RESPONSE;
- // Wait for next manual response.
- ManualResponse = INVALID_RESPONSE;
- }
- // Reset training when leaving manual mode.
- if (CurrentTrial < NumTrainingTrials)
- {
- TrainingTrialResume = CurrentTrial;
- }
- }
- return;
- }
- // Resume training?
- if (TrainingTrialResume != -1)
- {
- i = TrainingTrialResume;
- resetTraining();
- resetMuzzWorld();
- CurrentTrial = i;
- TrainingTrialResume = -1;
- if (CurrentTrial > NumTrainingTrials)
- {
- CurrentTrial = NumTrainingTrials;
- }
- }
- // One-time search for forced response training? Much faster.
- if (ForcedResponseTrain && (ResponseIdx == INIT_INDEX) &&
- (CurrentTrial < NumTrainingTrials))
- {
- if (getResponseSequenceToGoals(0, ForcedResponseSequence, DEPTH_SEARCH))
- {
- ResponseIdx = 0;
- }
- else
- {
- ResponseIdx = ERROR_INDEX;
- }
- }
- // Muzzes already have goals?
- gotGoals = true;
- for (i = 0; i < NUM_MUZZES; i++)
- {
- if (!Muzzes[i]->gotFood || !Muzzes[i]->gotWater)
- {
- gotGoals = false;
- }
- }
- // Run the muzzes.
- if (gotGoals)
- {
- foundGoals = false;
- }
- else
- {
- foundGoals = true;
- }
- gotGoals = true;
- for (i = 0; i < NUM_MUZZES; i++)
- {
- // For forced response training, get response to obtain food and water.
- if (ForcedResponseTrain && (CurrentTrial < NumTrainingTrials))
- {
- if ((ResponseIdx >= 0) && (ResponseIdx <
- (int)ForcedResponseSequence.size()))
- {
- Muzzes[i]->brain->responseOverride =
- ForcedResponseSequence[ResponseIdx].response;
- ResponseIdx++;
- }
- else
- {
- Muzzes[i]->brain->responseOverride = Mona::NULL_RESPONSE;
- }
- }
- // Run the muzz.
- runMuzz(i);
- // Goals not gotten?
- if (!Muzzes[i]->gotFood || !Muzzes[i]->gotWater)
- {
- gotGoals = foundGoals = false;
- }
- }
- // Increment training trial.
- if (CurrentTrial < NumTrainingTrials)
- {
- // Increment trial step.
- CurrentTrialStep++;
- // Trial complete?
- if (gotGoals)
- {
- if (TrialResetDelay == -1)
- {
- TrialResetDelay = 1;
- }
- else
- {
- TrialResetDelay--;
- }
- }
- if (TrialResetDelay == 0)
- {
- // Reset for next trial.
- TrialResetDelay = -1;
- CurrentTrial++;
- CurrentTrialStep = 0;
- if (ForcedResponseTrain && (ResponseIdx >= 0))
- {
- ResponseIdx = 0;
- }
- resetMuzzWorld();
- }
- }
- }
- // Idle muzzes.
- void idleMuzzes()
- {
- // Complete movements for previous responses.
- for (int i = 0; i < NUM_MUZZES; i++)
- {
- moveMuzz(i);
- }
- }
- // Reset muzz world.
- void resetMuzzWorld()
- {
- int i;
- for (i = 0; i < NUM_MUZZES; i++)
- {
- Muzzes[i]->brain->responseOverride = Mona::NULL_RESPONSE;
- Muzzes[i]->reset();
- if (NUM_MUSHROOMS == 0)
- {
- Muzzes[i]->clearNeed(Muzz::FOOD);
- }
- if (NUM_POOLS == 0)
- {
- Muzzes[i]->clearNeed(Muzz::WATER);
- }
- MuzzStates[i].response = Muzz::WAIT;
- MuzzStates[i].moveType = Muzz::FORWARD;
- MuzzStates[i].moveAmount = 0.0f;
- }
- for (i = 0; i < NUM_MUSHROOMS; i++)
- {
- Mushrooms[i]->setAlive(true);
- }
- }
- // Move muzz.
- // Returns true when movement is complete.
- bool moveMuzz(int i)
- {
- int j, x, z, x2, z2, x3, z3;
- GLfloat a, p[3], p2[3], f[3], u[3];
- bool move;
- // Continue queued movement.
- if (MuzzStates[i].moveAmount > 0.0)
- {
- move = true;
- }
- else
- {
- move = false;
- }
- Muzzes[i]->getPosition(p);
- x = (int)(p[0] / Terrain->BLOCK_SIZE);
- z = (int)(p[2] / Terrain->BLOCK_SIZE);
- if (move)
- {
- switch (MuzzStates[i].moveType)
- {
- case Muzz::FORWARD:
- if (SmoothMove)
- {
- a = MUZZ_MOVEMENT_DELTA * frameRate.speedFactor;
- if (a > MuzzStates[i].moveAmount)
- {
- a = MuzzStates[i].moveAmount;
- }
- }
- else
- {
- a = MuzzStates[i].moveAmount;
- }
- MuzzStates[i].moveAmount -= a;
- Muzzes[i]->forward(a);
- // Check for collision.
- Muzzes[i]->getPosition(p);
- x2 = (int)(p[0] / Terrain->BLOCK_SIZE);
- z2 = (int)(p[2] / Terrain->BLOCK_SIZE);
- if ((x != x2) || (z != z2))
- {
- for (j = 0; j < NUM_MUZZES; j++)
- {
- if (j == i)
- {
- continue;
- }
- Muzzes[j]->getPosition(p2);
- x3 = (int)(p2[0] / Terrain->BLOCK_SIZE);
- z3 = (int)(p2[2] / Terrain->BLOCK_SIZE);
- if ((x2 == x3) && (z2 == z3))
- {
- Muzzes[i]->backward(a);
- MuzzStates[i].moveAmount = 0.0f;
- break;
- }
- }
- }
- break;
- case Muzz::RIGHT:
- if (SmoothMove)
- {
- a = MUZZ_TURN_DELTA * frameRate.speedFactor;
- if (a > MuzzStates[i].moveAmount)
- {
- a = MuzzStates[i].moveAmount;
- }
- }
- else
- {
- a = MuzzStates[i].moveAmount;
- }
- MuzzStates[i].moveAmount -= a;
- Muzzes[i]->right(a);
- break;
- case Muzz::LEFT:
- if (SmoothMove)
- {
- a = MUZZ_TURN_DELTA * frameRate.speedFactor;
- if (a > MuzzStates[i].moveAmount)
- {
- a = MuzzStates[i].moveAmount;
- }
- }
- else
- {
- a = MuzzStates[i].moveAmount;
- }
- MuzzStates[i].moveAmount -= a;
- Muzzes[i]->left(a);
- break;
- }
- }
- // Continue movement?
- if (MuzzStates[i].moveAmount > 0.0f)
- {
- return(false);
- }
- MuzzStates[i].moveAmount = 0.0f;
- // Center muzz on block, orient orthogonally and
- // store position and direction.
- Muzzes[i]->getPosition(p);
- x = (int)(p[0] / Terrain->BLOCK_SIZE);
- z = (int)(p[2] / Terrain->BLOCK_SIZE);
- if (move)
- {
- p2[0] = ((GLfloat)x + 0.5f) * Terrain->BLOCK_SIZE;
- p2[1] = p[1];
- p2[2] = ((GLfloat)z + 0.5f) * Terrain->BLOCK_SIZE;
- for (j = 0; j < 3; j++)
- {
- p2[j] = p[j] + ((p2[j] - p[j]) * 0.1f);
- }
- Muzzes[i]->setPosition(p2);
- }
- Muzzes[i]->getForward(f);
- f[1] = 0.0f;
- cSpacial::normalize(f);
- u[0] = 0.0f;
- u[1] = 1.0f;
- u[2] = 0.0f;
- if (fabs(f[0]) > fabs(f[2]))
- {
- if (f[0] < 0.0f)
- {
- MuzzStates[i].dir = 3;
- MuzzStates[i].forward = BlockTerrain::Block::WEST;
- MuzzStates[i].backward = BlockTerrain::Block::EAST;
- if (move)
- {
- Muzzes[i]->loadRotation(90.0f, u);
- Muzzes[i]->forward(0.0f);
- }
- }
- else
- {
- MuzzStates[i].dir = 1;
- MuzzStates[i].forward = BlockTerrain::Block::EAST;
- MuzzStates[i].backward = BlockTerrain::Block::WEST;
- if (move)
- {
- Muzzes[i]->loadRotation(270.0f, u);
- Muzzes[i]->forward(0.0f);
- }
- }
- }
- else
- {
- if (f[2] < 0.0f)
- {
- MuzzStates[i].dir = 0;
- MuzzStates[i].forward = BlockTerrain::Block::NORTH;
- MuzzStates[i].backward = BlockTerrain::Block::SOUTH;
- if (move)
- {
- Muzzes[i]->loadRotation(180.0f, u);
- Muzzes[i]->forward(0.0f);
- }
- }
- else
- {
- MuzzStates[i].dir = 2;
- MuzzStates[i].forward = BlockTerrain::Block::SOUTH;
- MuzzStates[i].backward = BlockTerrain::Block::NORTH;
- if (move)
- {
- Muzzes[i]->loadRotation(0.0f, u);
- Muzzes[i]->forward(0.0f);
- }
- }
- }
- Muzzes[i]->getPosition(p);
- MuzzStates[i].x = (int)(p[0] / Terrain->BLOCK_SIZE);
- MuzzStates[i].z = (int)(p[2] / Terrain->BLOCK_SIZE);
- return(true);
- }
- // Sense muzz world.
- void senseMuzz(int i)
- {
- int terrain, object, lookx, lookz;
- GLfloat view[3];
- // Determine sensory input.
- Muzzes[i]->getRight(view);
- for (int j = 0; j < 3; j++)
- {
- view[j] = -view[j];
- }
- senseMuzzDir(i, (MuzzStates[i].dir + 1) % 4, view, lookx, lookz, terrain, object);
- if ((terrain == Muzz::WALL) || (terrain == Muzz::DROP) ||
- ((object == Muzz::MUSHROOM) && Muzzes[i]->gotFood) ||
- (object == Muzz::MUZZ))
- {
- MuzzStates[i].sensors[Muzz::RIGHT_SENSOR] = Muzz::CLOSED;
- }
- else
- {
- MuzzStates[i].sensors[Muzz::RIGHT_SENSOR] = Muzz::OPEN;
- }
- Muzzes[i]->getRight(view);
- senseMuzzDir(i, (MuzzStates[i].dir + 3) % 4, view, lookx, lookz, terrain, object);
- if ((terrain == Muzz::WALL) || (terrain == Muzz::DROP) ||
- ((object == Muzz::MUSHROOM) && Muzzes[i]->gotFood) ||
- (object == Muzz::MUZZ))
- {
- MuzzStates[i].sensors[Muzz::LEFT_SENSOR] = Muzz::CLOSED;
- }
- else
- {
- MuzzStates[i].sensors[Muzz::LEFT_SENSOR] = Muzz::OPEN;
- }
- Muzzes[i]->getForward(view);
- senseMuzzDir(i, MuzzStates[i].dir, view, lookx, lookz, terrain, object);
- MuzzStates[i].sensors[Muzz::TERRAIN_SENSOR] = terrain;
- MuzzStates[i].sensors[Muzz::OBJECT_SENSOR] = object;
- if ((terrain == Muzz::WALL) || (terrain == Muzz::DROP) ||
- ((object == Muzz::MUSHROOM) && Muzzes[i]->gotFood) ||
- (object == Muzz::MUZZ))
- {
- MuzzStates[i].sensors[Muzz::FORWARD_SENSOR] = Muzz::CLOSED;
- }
- else
- {
- MuzzStates[i].sensors[Muzz::FORWARD_SENSOR] = Muzz::OPEN;
- }
- MuzzStates[i].lookAtX = lookx;
- MuzzStates[i].lookAtZ = lookz;
- }
- // Sense muzz world in a given direction and view vector.
- void senseMuzzDir(int muzzIndex, int direction, GLfloat view[3],
- int& senseX, int& senseZ, int& terrain, int& object)
- {
- int i, h, x, z, x2, z2, x3, z3;
- GLfloat p[3], p2[3], v[3];
- BlockTerrain::Block::DIRECTION forward, backward;
- Muzzes[muzzIndex]->getPosition(p);
- x = (int)(p[0] / Terrain->BLOCK_SIZE);
- z = (int)(p[2] / Terrain->BLOCK_SIZE);
- switch (direction)
- {
- case 0: // North.
- if (z == 0)
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- return;
- }
- else
- {
- senseX = x2 = x;
- senseZ = z2 = z - 1;
- }
- forward = BlockTerrain::Block::NORTH;
- backward = BlockTerrain::Block::SOUTH;
- break;
- case 1: // East.
- if (x == Terrain->WIDTH - 1)
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- return;
- }
- else
- {
- senseX = x2 = x + 1;
- senseZ = z2 = z;
- }
- forward = BlockTerrain::Block::EAST;
- backward = BlockTerrain::Block::WEST;
- break;
- case 2: // South.
- if (z == Terrain->HEIGHT - 1)
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- return;
- }
- else
- {
- senseX = x2 = x;
- senseZ = z2 = z + 1;
- }
- forward = BlockTerrain::Block::SOUTH;
- backward = BlockTerrain::Block::NORTH;
- break;
- case 3: // West.
- if (x == 0)
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- return;
- }
- else
- {
- senseX = x2 = x - 1;
- senseZ = z2 = z;
- }
- forward = BlockTerrain::Block::WEST;
- backward = BlockTerrain::Block::EAST;
- break;
- }
- // Object in view?
- // Cannot see objects when crosswise on ramp.
- if ((Terrain->blocks[x][z].type != BlockTerrain::Block::RAMP) ||
- ((Terrain->blocks[x][z].type == BlockTerrain::Block::RAMP) &&
- ((Terrain->blocks[x][z].rampDir == forward) ||
- (Terrain->blocks[x][z].rampDir == backward))))
- {
- // Determine point in view.
- x3 = (int)(p[0] / Terrain->BLOCK_SIZE);
- p2[0] = ((GLfloat)x3 + 0.5f) * Terrain->BLOCK_SIZE;
- p2[1] = p[1];
- z3 = (int)(p[2] / Terrain->BLOCK_SIZE);
- p2[2] = ((GLfloat)z3 + 0.5f) * Terrain->BLOCK_SIZE;
- for (i = 0; i < 3; i++)
- {
- v[i] = view[i];
- }
- cSpacial::normalize(v);
- for (i = 0; i < 3; i++)
- {
- p[i] = p2[i] + (v[i] * Terrain->BLOCK_SIZE);
- }
- for (i = 0; i < NUM_MUZZES; i++)
- {
- if (i == muzzIndex)
- {
- continue;
- }
- Muzzes[i]->getPosition(p2);
- if (fabs(cSpacial::pointDistance(p, p2)) < (Terrain->BLOCK_SIZE * 0.4f))
- {
- x3 = (int)(p2[0] / Terrain->BLOCK_SIZE);
- z3 = (int)(p2[2] / Terrain->BLOCK_SIZE);
- if (Terrain->blocks[x3][z3].type != BlockTerrain::Block::RAMP)
- {
- terrain = Muzz::PLATFORM;
- }
- else
- {
- if (Terrain->blocks[x3][z3].rampDir == forward)
- {
- terrain = Muzz::RAMP_UP;
- }
- else
- {
- terrain = Muzz::RAMP_DOWN;
- }
- }
- object = Muzz::MUZZ;
- return;
- }
- }
- for (i = 0; i < NUM_MUSHROOMS; i++)
- {
- if (!Mushrooms[i]->isAlive())
- {
- continue;
- }
- Mushrooms[i]->getPosition(p2);
- if (fabs(cSpacial::pointDistance(p, p2)) < (Terrain->BLOCK_SIZE * 0.4f))
- {
- terrain = Muzz::PLATFORM;
- object = Muzz::MUSHROOM;
- return;
- }
- }
- for (i = 0; i < NUM_POOLS; i++)
- {
- Pools[i]->getPosition(p2);
- if (fabs(cSpacial::pointDistance(p, p2)) < (Terrain->BLOCK_SIZE * 0.4f))
- {
- terrain = Muzz::PLATFORM;
- object = Muzz::POOL;
- return;
- }
- }
- }
- // View terrain.
- h = Terrain->blocks[x2][z2].elevation - Terrain->blocks[x][z].elevation;
- switch (Terrain->blocks[x][z].type)
- {
- case BlockTerrain::Block::PLATFORM:
- switch (Terrain->blocks[x2][z2].type)
- {
- case BlockTerrain::Block::PLATFORM:
- case BlockTerrain::Block::LANDING:
- if (h < 0)
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- }
- else if (h > 0)
- {
- terrain = Muzz::WALL;
- #if (SENSE_BLOCK_ID == 1)
- object = (Terrain->blocks[x2][z2].id << 8) |
- (unsigned char )((int)'A' + Terrain->blocks[x2][z2].textureIndexes[Terrain->blocks[x][z].elevation + 1]);
- #else
- object = (int)'A' + Terrain->blocks[x2][z2].textureIndexes[Terrain->blocks[x][z].elevation + 1];
- #endif
- }
- else
- {
- terrain = Muzz::PLATFORM;
- #if (SENSE_BLOCK_ID == 1)
- object = (Terrain->blocks[x2][z2].id << 8) |
- (unsigned char )((int)'A' + Terrain->blocks[x2][z2].textureIndexes[Terrain->blocks[x][z].elevation]);
- #else
- object = (int)'A' + Terrain->blocks[x2][z2].textureIndexes[Terrain->blocks[x][z].elevation];
- #endif
- }
- break;
- case BlockTerrain::Block::RAMP:
- if (h < 0)
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- }
- else if (h > 0)
- {
- terrain = Muzz::WALL;
- object = Muzz::EMPTY;
- }
- else
- {
- if (Terrain->isUpperRamp(x2, z2))
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- }
- else
- {
- terrain = Muzz::WALL;
- object = Muzz::EMPTY;
- }
- }
- break;
- }
- break;
- case BlockTerrain::Block::LANDING:
- switch (Terrain->blocks[x2][z2].type)
- {
- case BlockTerrain::Block::PLATFORM:
- case BlockTerrain::Block::LANDING:
- if (h < 0)
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- }
- else if (h > 0)
- {
- terrain = Muzz::WALL;
- #if (SENSE_BLOCK_ID == 1)
- object = (Terrain->blocks[x2][z2].id << 8) |
- (unsigned char )((int)'A' + Terrain->blocks[x2][z2].textureIndexes[Terrain->blocks[x][z].elevation + 1]);
- #else
- object = (int)'A' + Terrain->blocks[x2][z2].textureIndexes[Terrain->blocks[x][z].elevation + 1];
- #endif
- }
- else
- {
- terrain = Muzz::PLATFORM;
- #if (SENSE_BLOCK_ID == 1)
- object = (Terrain->blocks[x2][z2].id << 8) |
- (unsigned char )((int)'A' + Terrain->blocks[x2][z2].textureIndexes[Terrain->blocks[x][z].elevation]);
- #else
- object = (int)'A' + Terrain->blocks[x2][z2].textureIndexes[Terrain->blocks[x][z].elevation];
- #endif
- }
- break;
- case BlockTerrain::Block::RAMP:
- if (Terrain->blocks[x2][z2].rampDir == forward)
- {
- terrain = Muzz::RAMP_UP;
- object = Muzz::EMPTY;
- }
- else if (Terrain->blocks[x2][z2].rampDir == backward)
- {
- terrain = Muzz::RAMP_DOWN;
- object = Muzz::EMPTY;
- }
- else if (h < 0)
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- }
- else if (h > 0)
- {
- terrain = Muzz::WALL;
- object = Muzz::EMPTY;
- }
- else
- {
- if (Terrain->isUpperRamp(x2, z2))
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- }
- else
- {
- terrain = Muzz::WALL;
- object = Muzz::EMPTY;
- }
- }
- break;
- }
- break;
- case BlockTerrain::Block::RAMP:
- switch (Terrain->blocks[x2][z2].type)
- {
- case BlockTerrain::Block::PLATFORM:
- if (h < 0)
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- }
- else if (h > 0)
- {
- terrain = Muzz::WALL;
- object = Muzz::EMPTY;
- }
- else
- {
- if (Terrain->isUpperRamp(x, z))
- {
- terrain = Muzz::WALL;
- object = Muzz::EMPTY;
- }
- else
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- }
- }
- break;
- case BlockTerrain::Block::LANDING:
- if ((Terrain->blocks[x][z].rampDir == forward) ||
- (Terrain->blocks[x][z].rampDir == backward))
- {
- terrain = Muzz::PLATFORM;
- #if (SENSE_BLOCK_ID == 1)
- object = (Terrain->blocks[x2][z2].id << 8) |
- (unsigned char )((int)'A' + Terrain->blocks[x2][z2].textureIndexes[Terrain->blocks[x][z].elevation]);
- #else
- object = (int)'A' + Terrain->blocks[x2][z2].textureIndexes[Terrain->blocks[x][z].elevation];
- #endif
- }
- else if (h < 0)
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- }
- else if (h > 0)
- {
- terrain = Muzz::WALL;
- object = Muzz::EMPTY;
- }
- else
- {
- if (Terrain->isUpperRamp(x, z))
- {
- terrain = Muzz::WALL;
- object = Muzz::EMPTY;
- }
- else
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- }
- }
- break;
- case BlockTerrain::Block::RAMP:
- if ((Terrain->blocks[x][z].rampDir == forward) &&
- (Terrain->blocks[x2][z2].rampDir == forward))
- {
- terrain = Muzz::RAMP_UP;
- object = Muzz::EMPTY;
- }
- else if ((Terrain->blocks[x][z].rampDir == backward) &&
- (Terrain->blocks[x2][z2].rampDir == backward))
- {
- terrain = Muzz::RAMP_DOWN;
- object = Muzz::EMPTY;
- }
- else if (h < 0)
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- }
- else if (h > 0)
- {
- terrain = Muzz::WALL;
- object = Muzz::EMPTY;
- }
- else
- {
- if (Terrain->isUpperRamp(x, z))
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- }
- else if (Terrain->isUpperRamp(x2, z2))
- {
- terrain = Muzz::WALL;
- object = Muzz::EMPTY;
- }
- else
- {
- terrain = Muzz::DROP;
- object = Muzz::EMPTY;
- }
- }
- break;
- }
- break;
- }
- }
- // Run muzz.
- void runMuzz(int i, int forcedResponse)
- {
- int j, dir, x, z, x2, z2, x3, z3;
- bool hadFood;
- GLfloat p[3], p2[3], f[3];
- BlockTerrain::Block::DIRECTION forward;
- BlockTerrain::Block::DIRECTION backward;
- // Get muzz response.
- hadFood = Muzzes[i]->gotFood;
- if (forcedResponse == INVALID_RESPONSE)
- {
- // Let brain decide.
- MuzzStates[i].response = Muzzes[i]->cycle(MuzzStates[i].sensors);
- }
- else
- {
- // Force response.
- MuzzStates[i].response = forcedResponse;
- if ((MuzzStates[i].sensors[Muzz::OBJECT_SENSOR] == Muzz::MUSHROOM) &&
- (MuzzStates[i].response == Muzz::EAT))
- {
- Muzzes[i]->gotFood = true;
- }
- if ((MuzzStates[i].sensors[Muzz::OBJECT_SENSOR] == Muzz::POOL) &&
- (MuzzStates[i].response == Muzz::DRINK))
- {
- Muzzes[i]->gotWater = true;
- }
- }
- // Process response.
- x = MuzzStates[i].x;
- z = MuzzStates[i].z;
- dir = MuzzStates[i].dir;
- forward = MuzzStates[i].forward;
- backward = MuzzStates[i].backward;
- switch (MuzzStates[i].response)
- {
- case Muzz::WAIT:
- break;
- case Muzz::FORWARD:
- MuzzStates[i].moveType = Muzz::FORWARD;
- MuzzStates[i].moveAmount = Terrain->BLOCK_SIZE;
- if ((MuzzStates[i].sensors[Muzz::OBJECT_SENSOR] == Muzz::MUSHROOM) ||
- (MuzzStates[i].sensors[Muzz::OBJECT_SENSOR] == Muzz::MUZZ))
- {
- MuzzStates[i].moveAmount = 0.0f;
- break;
- }
- switch (dir)
- {
- case 0: // North.
- if (z == 0)
- {
- MuzzStates[i].moveAmount = 0.0f;
- return;
- }
- x2 = x;
- z2 = z - 1;
- break;
- case 1: // East.
- if (x == Terrain->WIDTH - 1)
- {
- MuzzStates[i].moveAmount = 0.0f;
- return;
- }
- x2 = x + 1;
- z2 = z;
- break;
- case 2: // South.
- if (z == Terrain->HEIGHT - 1)
- {
- MuzzStates[i].moveAmount = 0.0f;
- return;
- }
- x2 = x;
- z2 = z + 1;
- break;
- case 3: // West.
- if (x == 0)
- {
- MuzzStates[i].moveAmount = 0.0f;
- return;
- }
- x2 = x - 1;
- z2 = z;
- break;
- }
- if (Terrain->blocks[x][z].type == BlockTerrain::Block::RAMP)
- {
- if ((Terrain->blocks[x][z].rampDir != forward) &&
- (Terrain->blocks[x][z].rampDir != backward))
- {
- MuzzStates[i].moveAmount = 0.0f;
- return;
- }
- }
- if (((Terrain->blocks[x][z].type != BlockTerrain::Block::RAMP) ||
- (Terrain->blocks[x2][z2].type != BlockTerrain::Block::RAMP)) &&
- (Terrain->blocks[x][z].elevation != Terrain->blocks[x2][z2].elevation))
- {
- MuzzStates[i].moveAmount = 0.0f;
- }
- else if ((Terrain->blocks[x][z].type != BlockTerrain::Block::RAMP) &&
- (Terrain->blocks[x2][z2].type == BlockTerrain::Block::RAMP) &&
- (Terrain->blocks[x2][z2].rampDir != forward) &&
- (Terrain->blocks[x2][z2].rampDir != backward))
- {
- MuzzStates[i].moveAmount = 0.0f;
- }
- else
- {
- switch (Terrain->blocks[x][z].type)
- {
- case BlockTerrain::Block::LANDING:
- if (Terrain->blocks[x2][z2].type == BlockTerrain::Block::RAMP)
- {
- MuzzStates[i].moveAmount = (Terrain->BLOCK_SIZE * 0.5f) +
- (Terrain->BLOCK_SIZE * (2.236f / 4.0f));
- }
- break;
- case BlockTerrain::Block::RAMP:
- if (Terrain->blocks[x2][z2].type == BlockTerrain::Block::RAMP)
- {
- MuzzStates[i].moveAmount = Terrain->BLOCK_SIZE * (2.236f / 2.0f);
- }
- else if (Terrain->blocks[x2][z2].type == BlockTerrain::Block::LANDING)
- {
- MuzzStates[i].moveAmount = (Terrain->BLOCK_SIZE * 0.5f) +
- (Terrain->BLOCK_SIZE * (2.236f / 4.0f));
- }
- break;
- }
- }
- break;
- case Muzz::RIGHT:
- MuzzStates[i].moveType = Muzz::RIGHT;
- MuzzStates[i].moveAmount = 90.0f;
- break;
- case Muzz::LEFT:
- MuzzStates[i].moveType = Muzz::LEFT;
- MuzzStates[i].moveAmount = 90.0f;
- break;
- case Muzz::EAT:
- if (!hadFood && Muzzes[i]->gotFood &&
- (MuzzStates[i].sensors[Muzz::OBJECT_SENSOR] == Muzz::MUSHROOM))
- {
- Muzzes[i]->getPosition(p);
- x3 = (int)(p[0] / Terrain->BLOCK_SIZE);
- p2[0] = ((GLfloat)x3 + 0.5f) * Terrain->BLOCK_SIZE;
- p2[1] = p[1];
- z3 = (int)(p[2] / Terrain->BLOCK_SIZE);
- p2[2] = ((GLfloat)z3 + 0.5f) * Terrain->BLOCK_SIZE;
- Muzzes[i]->getForward(f);
- cSpacial::normalize(f);
- for (j = 0; j < 3; j++)
- {
- p[j] = p2[j] + (f[j] * Terrain->BLOCK_SIZE);
- }
- for (j = 0; j < NUM_MUSHROOMS; j++)
- {
- if (!Mushrooms[j]->isAlive())
- {
- continue;
- }
- Mushrooms[j]->getPosition(p2);
- if (fabs(cSpacial::pointDistance(p, p2)) < (Terrain->BLOCK_SIZE * 0.4f))
- {
- Mushrooms[j]->setAlive(false);
- }
- }
- }
- break;
- case Muzz::DRINK:
- break;
- }
- }
- // Place muzz in world without changing its initial stored placement.
- void placeMuzz(int muzzIndex, int placeX, int placeZ, BlockTerrain::Block::DIRECTION placeDir)
- {
- GLfloat p[3];
- Vector n;
- // Clear pending movement.
- MuzzStates[muzzIndex].moveType = Muzz::FORWARD;
- MuzzStates[muzzIndex].moveAmount = 0.0f;
- Muzzes[muzzIndex]->clearSpacial();
- p[0] = ((GLfloat)placeX * Terrain->BLOCK_SIZE) + (Terrain->BLOCK_SIZE * 0.5f);
- p[2] = ((GLfloat)placeZ * Terrain->BLOCK_SIZE) + (Terrain->BLOCK_SIZE * 0.5f);
- Terrain->getGeometry(p[0], p[2], p[1], n);
- Muzzes[muzzIndex]->setPosition(p);
- switch (placeDir)
- {
- case BlockTerrain::Block::NORTH:
- Muzzes[muzzIndex]->setYaw(0.0f);
- break;
- case BlockTerrain::Block::EAST:
- Muzzes[muzzIndex]->setYaw(90.0f);
- break;
- case BlockTerrain::Block::SOUTH:
- Muzzes[muzzIndex]->setYaw(180.0f);
- break;
- case BlockTerrain::Block::WEST:
- Muzzes[muzzIndex]->setYaw(270.0f);
- break;
- }
- Muzzes[muzzIndex]->forward(0.0f);
- }
- // Reset training.
- void resetTraining()
- {
- CurrentTrial = 0;
- CurrentTrialStep = 0;
- TrialResetDelay = -1;
- TrainingTrialResume = -1;
- if (ResponseIdx > 0)
- {
- ResponseIdx = 0;
- }
- }
- // Draw world.
- void drawWorld(int skipMuzz)
- {
- int i;
- glColor3f(1.0f, 1.0f, 1.0f);
- if (WireView)
- {
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- }
- else
- {
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
- glPushMatrix();
- // Draw the terrain.
- Terrain->draw();
- // Draw muzzes.
- for (i = 0; i < NUM_MUZZES; i++)
- {
- if (i != skipMuzz)
- {
- // Name the muzz for selection purposes.
- glPushMatrix();
- glPushName(i + 1);
- Muzzes[i]->draw();
- glPopName();
- glPopMatrix();
- }
- }
- // Draw mushrooms.
- for (i = 0; i < NUM_MUSHROOMS; i++)
- {
- if (Mushrooms[i]->isAlive())
- {
- Mushrooms[i]->draw();
- }
- }
- // Draw water pools.
- for (i = 0; i < NUM_POOLS; i++)
- {
- Pools[i]->draw();
- }
- glPopMatrix();
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
- // Display muzz view.
- void displayMuzzView(void)
- {
- if (ViewSelection == TERRAIN_VIEW_ONLY)
- {
- return;
- }
- // Clear transform matrix.
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- // Place camera at current muzz view point.
- if (CurrentMuzz != -1)
- {
- // Camera follows muzz.
- Muzzes[CurrentMuzz]->aimCamera(camera);
- // Set viewport and frustum.
- glViewport(Viewports[MUZZ_VIEWPORT].x, Viewports[MUZZ_VIEWPORT].y,
- Viewports[MUZZ_VIEWPORT].width, Viewports[MUZZ_VIEWPORT].height);
- camera.setFrustum(MUZZ_FRUSTUM_ANGLE, Viewports[MUZZ_VIEWPORT].aspect,
- MUZZ_FRUSTUM_NEAR, MUZZ_FRUSTUM_FAR);
- // Draw the world.
- drawWorld(CurrentMuzz);
- }
- else
- {
- // Set viewport.
- glViewport(Viewports[MUZZ_VIEWPORT].x, Viewports[MUZZ_VIEWPORT].y,
- Viewports[MUZZ_VIEWPORT].width, Viewports[MUZZ_VIEWPORT].height);
- }
- // Label view.
- glLineWidth(2.0);
- enter2Dmode();
- draw2Dstring(5, 12, FONT, (char *)"Muzz");
- exit2Dmode();
- }
- // Display the terrain view.
- void displayTerrainView(void)
- {
- if (ViewSelection == MUZZ_VIEW_ONLY)
- {
- return;
- }
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- // Set viewport and frustum.
- glViewport(Viewports[TERRAIN_VIEWPORT].x, Viewports[TERRAIN_VIEWPORT].y,
- Viewports[TERRAIN_VIEWPORT].width, Viewports[TERRAIN_VIEWPORT].height);
- camera.setFrustum(TERRAIN_FRUSTUM_ANGLE, Viewports[TERRAIN_VIEWPORT].aspect,
- MUZZ_FRUSTUM_NEAR, MUZZ_FRUSTUM_FAR);
- // Position camera.
- camera.clearSpacial();
- camera.setPosition(TerrainViewPosition);
- camera.setPitch(-90.0f);
- camera.setRoll(180.0f);
- camera.place();
- // Rendering to select a muzz?
- if (renderMode == GL_SELECT)
- {
- startPicking();
- }
- // Draw the world with a small perspective angle.
- glPushMatrix();
- glRotatef(20.0f, 1.0f, 0.0f, 1.0f);
- drawWorld(-1);
- if (renderMode == GL_SELECT)
- {
- stopPicking();
- }
- else
- {
- // Highlight current muzz.
- if (CurrentMuzz != -1)
- {
- Muzzes[CurrentMuzz]->highlight();
- }
- }
- glPopMatrix();
- // Label view.
- glLineWidth(2.0);
- enter2Dmode();
- draw2Dstring(5, 12, FONT, (char *)"Terrain");
- exit2Dmode();
- }
- // Display the controls view.
- void displayControls(void)
- {
- int vw, vh;
- GLint viewport[4];
- char buf[100];
- // Set viewport.
- glViewport(Viewports[CONTROLS_VIEWPORT].x, Viewports[CONTROLS_VIEWPORT].y,
- Viewports[CONTROLS_VIEWPORT].width, Viewports[CONTROLS_VIEWPORT].height);
- glGetIntegerv(GL_VIEWPORT, viewport);
- vw = viewport[2];
- vh = viewport[3];
- // Render the GUI.
- counter.markFrameStart();
- enter2DMode(guiFrame->getWidth(), guiFrame->getHeight());
- guiFrame->render(counter.getFrameInterval());
- counter.markFrameEnd();
- // Show frame rate.
- sprintf(buf, "FPS: %.2f", frameRate.FPS);
- draw2Dstring(5, 15, FONT, buf);
- // Show cycle?
- if (Cycles >= 0)
- {
- // Show training trial also?
- if ((NumTrainingTrials >= 0) && (CurrentTrial >= 0) &&
- (CurrentTrial <= NumTrainingTrials))
- {
- sprintf(buf, "Cycle=%d/%d Training trial=%d/%d",
- CycleCounter, Cycles, CurrentTrial, NumTrainingTrials);
- draw2Dstring(5, vh - 10, FONT, buf);
- }
- else
- {
- sprintf(buf, "Cycle=%d/%d", CycleCounter, Cycles);
- draw2Dstring(5, vh - 10, FONT, buf);
- }
- }
- else
- {
- // Show training trial?
- if ((NumTrainingTrials >= 0) && (CurrentTrial >= 0) &&
- (CurrentTrial <= NumTrainingTrials))
- {
- sprintf(buf, "Training trial=%d/%d",
- CurrentTrial, NumTrainingTrials);
- draw2Dstring(5, vh - 10, FONT, buf);
- }
- }
- exit2DMode();
- }
- // Display the muzz status panel.
- void displayMuzzStatus(void)
- {
- int vw, vh, xoff, yoff;
- GLint viewport[4];
- char buf[50];
- // Set viewport.
- glViewport(Viewports[MUZZ_STATUS_VIEWPORT].x, Viewports[MUZZ_STATUS_VIEWPORT].y,
- Viewports[MUZZ_STATUS_VIEWPORT].width, Viewports[MUZZ_STATUS_VIEWPORT].height);
- enter2Dmode();
- if (CurrentMuzz != -1)
- {
- sprintf(buf, "Muzz %d status", Muzzes[CurrentMuzz]->id);
- draw2Dstring(5, 12, FONT, buf);
- }
- else
- {
- draw2Dstring(5, 12, FONT, (char *)"Muzz status");
- }
- glGetIntegerv(GL_VIEWPORT, viewport);
- vw = viewport[2];
- vh = viewport[3];
- // Show sensors.
- xoff = 5;
- yoff = vh / 3;
- draw2Dstring(xoff, yoff, FONT, (char *)"Sensors:");
- xoff += 5;
- yoff += 15;
- if (CurrentMuzz != -1)
- {
- if (MuzzStates[CurrentMuzz].sensors[Muzz::RIGHT_SENSOR] != Muzz::CLOSED)
- {
- if (MuzzStates[CurrentMuzz].sensors[Muzz::LEFT_SENSOR] != Muzz::CLOSED)
- {
- if (MuzzStates[CurrentMuzz].sensors[Muzz::FORWARD_SENSOR] != Muzz::CLOSED)
- {
- draw2Dstring(xoff, yoff, FONT, (char *)" open<-open->open");
- }
- else
- {
- draw2Dstring(xoff, yoff, FONT, (char *)" open<-closed->open");
- }
- }
- else
- {
- if (MuzzStates[CurrentMuzz].sensors[Muzz::FORWARD_SENSOR] != Muzz::CLOSED)
- {
- draw2Dstring(xoff, yoff, FONT, (char *)" closed<-open->open");
- }
- else
- {
- draw2Dstring(xoff, yoff, FONT, (char *)" closed<-closed->open");
- }
- }
- }
- else
- {
- if (MuzzStates[CurrentMuzz].sensors[Muzz::LEFT_SENSOR] != Muzz::CLOSED)
- {
- if (MuzzStates[CurrentMuzz].sensors[Muzz::FORWARD_SENSOR] != Muzz::CLOSED)
- {
- draw2Dstring(xoff, yoff, FONT, (char *)" open<-open->closed");
- }
- else
- {
- draw2Dstring(xoff, yoff, FONT, (char *)" open<-closed->closed");
- }
- }
- else
- {
- if (MuzzStates[CurrentMuzz].sensors[Muzz::FORWARD_SENSOR] != Muzz::CLOSED)
- {
- draw2Dstring(xoff, yoff, FONT, (char *)" closed<-open->closed");
- }
- else
- {
- draw2Dstring(xoff, yoff, FONT, (char *)" closed<-closed->closed");
- }
- }
- }
- yoff += 15;
- switch (MuzzStates[CurrentMuzz].sensors[Muzz::TERRAIN_SENSOR])
- {
- case Muzz::PLATFORM:
- draw2Dstring(xoff, yoff, FONT, (char *)" Terrain=platform");
- break;
- case Muzz::WALL:
- draw2Dstring(xoff, yoff, FONT, (char *)" Terrain=wall");
- break;
- case Muzz::DROP:
- draw2Dstring(xoff, yoff, FONT, (char *)" Terrain=drop off");
- break;
- case Muzz::RAMP_UP:
- draw2Dstring(xoff, yoff, FONT, (char *)" Terrain=ramp up");
- break;
- case Muzz::RAMP_DOWN:
- draw2Dstring(xoff, yoff, FONT, (char *)" Terrain=ramp down");
- break;
- }
- yoff += 15;
- switch (MuzzStates[CurrentMuzz].sensors[Muzz::OBJECT_SENSOR])
- {
- case Muzz::MUSHROOM:
- draw2Dstring(xoff, yoff, FONT, (char *)" Object=mushroom");
- break;
- case Muzz::POOL:
- draw2Dstring(xoff, yoff, FONT, (char *)" Object=pool");
- break;
- case Muzz::MUZZ:
- draw2Dstring(xoff, yoff, FONT, (char *)" Object=muzz");
- break;
- case Muzz::EMPTY:
- draw2Dstring(xoff, yoff, FONT, (char *)" Object=empty");
- break;
- default:
- #if (SENSE_BLOCK_ID == 1)
- if ((char)(MuzzStates[CurrentMuzz].sensors[Muzz::OBJECT_SENSOR] & 0xff) == '[')
- {
- sprintf(buf, " Object=blank(%d)", MuzzStates[CurrentMuzz].sensors[Muzz::OBJECT_SENSOR]);
- }
- else
- {
- sprintf(buf, " Object=%c(%d)", (char)(MuzzStates[CurrentMuzz].sensors[Muzz::OBJECT_SENSOR] & 0xff),
- MuzzStates[CurrentMuzz].sensors[Muzz::OBJECT_SENSOR]);
- }
- #else
- if ((char)MuzzStates[CurrentMuzz].sensors[Muzz::OBJECT_SENSOR] == '[')
- {
- sprintf(buf, " Object=blank");
- }
- else
- {
- sprintf(buf, " Object=%c", MuzzStates[CurrentMuzz].sensors[Muzz::OBJECT_SENSOR]);
- }
- #endif
- draw2Dstring(xoff, yoff, FONT, buf);
- break;
- }
- }
- else
- {
- draw2Dstring(xoff, yoff, FONT, (char *)" NA<-NA->NA");
- yoff += 15;
- draw2Dstring(xoff, yoff, FONT, (char *)" Terrain=NA");
- yoff += 15;
- draw2Dstring(xoff, yoff, FONT, (char *)" Object=NA");
- }
- // Show response.
- xoff = (vw / 2) + 15;
- yoff = vh / 4;
- if (CurrentMuzz != -1)
- {
- switch (MuzzStates[CurrentMuzz].response)
- {
- case Muzz::WAIT:
- draw2Dstring(xoff, yoff, FONT, (char *)"Response=wait");
- break;
- case Muzz::FORWARD:
- draw2Dstring(xoff, yoff, FONT, (char *)"Response=forward");
- break;
- case Muzz::RIGHT:
- draw2Dstring(xoff, yoff, FONT, (char *)"Response=right");
- break;
- case Muzz::LEFT:
- draw2Dstring(xoff, yoff, FONT, (char *)"Response=left");
- break;
- case Muzz::EAT:
- draw2Dstring(xoff, yoff, FONT, (char *)"Response=eat");
- break;
- case Muzz::DRINK:
- draw2Dstring(xoff, yoff, FONT, (char *)"Response=drink");
- break;
- }
- }
- else
- {
- draw2Dstring(xoff, yoff, FONT, (char *)"Response=NA");
- }
- // Show needs.
- yoff += 15;
- draw2Dstring(xoff, yoff, FONT, (char *)"Needs:");
- xoff += 5;
- yoff += 15;
- if (CurrentMuzz != -1)
- {
- sprintf(buf, " Water=%.2f", Muzzes[CurrentMuzz]->getNeed(Muzz::WATER));
- draw2Dstring(xoff, yoff, FONT, buf);
- yoff += 15;
- sprintf(buf, " Food=%.2f", Muzzes[CurrentMuzz]->getNeed(Muzz::FOOD));
- draw2Dstring(xoff, yoff, FONT, buf);
- }
- else
- {
- draw2Dstring(xoff, yoff, FONT, (char *)" Water=NA");
- yoff += 15;
- draw2Dstring(xoff, yoff, FONT, (char *)" Food=NA");
- }
- exit2Dmode();
- }
- // Display muzz help view.
- void displayMuzzHelpView(void)
- {
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glViewport(Viewports[MUZZ_HELP_VIEWPORT].x, Viewports[MUZZ_HELP_VIEWPORT].y,
- Viewports[MUZZ_HELP_VIEWPORT].width, Viewports[MUZZ_HELP_VIEWPORT].height);
- glLineWidth(2.0);
- enter2Dmode();
- helpInfo(MUZZ_HELP_VIEWPORT);
- draw2Dstring(5, 12, FONT, (char *)"Muzz");
- exit2Dmode();
- }
- // Display the terrain help view.
- void displayTerrainHelpView(void)
- {
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glViewport(Viewports[TERRAIN_HELP_VIEWPORT].x, Viewports[TERRAIN_HELP_VIEWPORT].y,
- Viewports[TERRAIN_HELP_VIEWPORT].width, Viewports[TERRAIN_HELP_VIEWPORT].height);
- glLineWidth(2.0);
- enter2Dmode();
- helpInfo(TERRAIN_HELP_VIEWPORT);
- draw2Dstring(5, 12, FONT, (char *)"Terrain");
- exit2Dmode();
- }
- // Display function.
- void display(void)
- {
- // Clear display.
- glutSetWindow(MainWindow);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- // Normal rendering?
- if (renderMode == GL_RENDER)
- {
- // Display viewports.
- if (Mod…
Large files files are truncated, but you can click here to view the full file