Last active
August 16, 2016 21:15
-
-
Save mimukit/2a1fd02cd3f865f2a54a50ef2fb2eac9 to your computer and use it in GitHub Desktop.
Missionaries and Cannibals river crossing puzzle game using OpenGL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdlib.h> | |
| #include <iostream> | |
| #include <math.h> | |
| #include <Windows.h> | |
| #include <GL/glut.h> | |
| using namespace std; | |
| bool isWin, isLost; | |
| int leftCannibals, leftMissionaries, rightCannibals, rightMissionaries, onBoatCannibals, onBoatMissionaries; | |
| GLfloat boatPosX, boatDeltaX; | |
| bool moveBoat, moveBoatReverse, boatCrossed, riverCrossedOnce; | |
| float moveClouds, cloudDeltaX; | |
| //Character Details | |
| int leftCharacterPosX, leftCharacterPosY, rightCharacterPosX, rightCharacterPosY, characterWidth, characterHeight; | |
| bool leftMissionaryVisibility[3], leftCannibalVisibility[3], rightMissionaryVisibility[3], rightCannibalVisibility[3], boatMissionaryVisibility[2], boatCannibalVisibility[2]; | |
| int boatCharacterLeftX, boatCharacterRightX, boatCharacterY; | |
| // 0 = none, 1 = cannibal, 2 = missionary | |
| int boatLeftCharacter, boatRightCharacter; | |
| void resetAll() | |
| { | |
| isWin = false; | |
| isLost = false; | |
| boatLeftCharacter = 0; | |
| boatRightCharacter = 0; | |
| boatPosX = 0.0; | |
| boatDeltaX = 2.0; | |
| moveBoat = false; | |
| moveBoatReverse = false; | |
| boatCrossed = false; | |
| riverCrossedOnce = false; | |
| moveClouds = 0.0; | |
| cloudDeltaX = 1.0; | |
| leftCharacterPosX = 5; | |
| leftCharacterPosY = 250; | |
| rightCharacterPosX = 700; | |
| rightCharacterPosY = 250; | |
| characterWidth = 45; | |
| characterHeight = 80; | |
| for (int i = 0; i < 3; i++) | |
| { | |
| leftMissionaryVisibility[i] = true; | |
| leftCannibalVisibility[i] = true; | |
| rightMissionaryVisibility[i] = false; | |
| rightCannibalVisibility[i] = false; | |
| } | |
| for (int i = 0; i < 2; i++) | |
| { | |
| boatMissionaryVisibility[i] = false; | |
| boatCannibalVisibility[i] = false; | |
| } | |
| boatCharacterLeftX = 285; | |
| boatCharacterRightX = 360; | |
| boatCharacterY = 165; | |
| system("cls"); | |
| } | |
| void checkGameStatus() | |
| { | |
| cout << "Checking game status..." << endl; | |
| leftCannibals = 0; | |
| leftMissionaries = 0; | |
| rightCannibals = 0; | |
| rightMissionaries = 0; | |
| onBoatCannibals = 0; | |
| onBoatMissionaries = 0; | |
| for (int i = 0; i < 3; i++) | |
| { | |
| if (leftCannibalVisibility[i]) | |
| { | |
| leftCannibals++; | |
| } | |
| if (leftMissionaryVisibility[i]) | |
| { | |
| leftMissionaries++; | |
| } | |
| if (rightCannibalVisibility[i]) | |
| { | |
| rightCannibals++; | |
| } | |
| if (rightMissionaryVisibility[i]) | |
| { | |
| rightMissionaries++; | |
| } | |
| } | |
| if (boatLeftCharacter == 1) | |
| { | |
| onBoatCannibals++; | |
| } | |
| if (boatRightCharacter == 1) | |
| { | |
| onBoatCannibals++; | |
| } | |
| if (boatLeftCharacter == 2) | |
| { | |
| onBoatMissionaries++; | |
| } | |
| if (boatRightCharacter == 2) | |
| { | |
| onBoatMissionaries++; | |
| } | |
| cout << "Left : cannibals = " << leftCannibals << ", missionaries = " << leftMissionaries << endl; | |
| cout << "Right : cannibals = " << rightCannibals << ", missionaries = " << rightMissionaries << endl; | |
| cout << "On Boat : cannibals = " << onBoatCannibals << ", missionaries = " << onBoatMissionaries << endl; | |
| if (!boatCrossed) | |
| { | |
| if ((leftCannibals + onBoatCannibals) > (leftMissionaries + onBoatMissionaries) && (leftMissionaries + onBoatMissionaries) > 0) | |
| { | |
| isLost = true; | |
| } | |
| if ((rightCannibals) > (rightMissionaries) && rightMissionaries > 0) | |
| { | |
| isLost = true; | |
| } | |
| } | |
| else if (boatCrossed) | |
| { | |
| if ((rightCannibals + onBoatCannibals) > (rightMissionaries + onBoatMissionaries) && (rightMissionaries + onBoatMissionaries) > 0) | |
| { | |
| isLost = true; | |
| } | |
| if ((leftCannibals) > (leftMissionaries) && leftMissionaries > 0) | |
| { | |
| isLost = true; | |
| } | |
| } | |
| if (boatCrossed && (rightCannibals + onBoatCannibals) == 3 && (rightMissionaries + onBoatMissionaries) == 3) | |
| { | |
| isWin = true; | |
| } | |
| if (isLost) | |
| { | |
| int msgRes = MessageBox(NULL, "You Lose...", "Retry", MB_RETRYCANCEL); | |
| if (msgRes == IDRETRY) | |
| { | |
| resetAll(); | |
| } | |
| else if (msgRes == IDCANCEL) | |
| { | |
| exit(1); | |
| } | |
| } | |
| if (isWin) | |
| { | |
| MessageBox(NULL, "Congratulation. You Win!!!", "Congratulation", MB_OK); | |
| int msgRes = MessageBox(NULL, "Do you want to play again?", "Restart?", MB_YESNO); | |
| if (msgRes == IDYES) | |
| { | |
| resetAll(); | |
| } | |
| else if (msgRes == IDNO) | |
| { | |
| exit(1); | |
| } | |
| } | |
| } | |
| int getCannibalBlankPosition() | |
| { | |
| if (!boatCrossed) | |
| { | |
| for (int i = 0; i < 3; i++) | |
| { | |
| if (leftCannibalVisibility[i] == false) | |
| { | |
| return i; | |
| } | |
| } | |
| return -1; | |
| } | |
| else if (boatCrossed) | |
| { | |
| for (int i = 0; i < 3; i++) | |
| { | |
| if (rightCannibalVisibility[i] == false) | |
| { | |
| return i; | |
| } | |
| } | |
| return -1; | |
| } | |
| } | |
| int getMissinaryBlankPosition() | |
| { | |
| if (!boatCrossed) | |
| { | |
| for (int i = 0; i < 3; i++) | |
| { | |
| if (leftMissionaryVisibility[i] == false) | |
| { | |
| return i; | |
| } | |
| } | |
| return -1; | |
| } | |
| else if (boatCrossed) | |
| { | |
| for (int i = 0; i < 3; i++) | |
| { | |
| if (rightMissionaryVisibility[i] == false) | |
| { | |
| return i; | |
| } | |
| } | |
| return -1; | |
| } | |
| } | |
| void drawPixel(GLint cx, GLint cy) | |
| { | |
| glBegin(GL_POINTS); | |
| glVertex2i(cx, cy); | |
| glEnd(); | |
| } | |
| void plotPixels(GLint h, GLint k, GLint x, GLint y) | |
| { | |
| drawPixel(x + h, y + k); | |
| drawPixel(-x + h, y + k); | |
| drawPixel(x + h, -y + k); | |
| drawPixel(-x + h, -y + k); | |
| drawPixel(y + h, x + k); | |
| drawPixel(-y + h, x + k); | |
| drawPixel(y + h, -x + k); | |
| drawPixel(-y + h, -x + k); | |
| } | |
| void drawCircle(GLint h, GLint k, GLint r) | |
| { | |
| GLint d = 1 - r, x = 0, y = r; | |
| while (y>x) | |
| { | |
| plotPixels(h, k, x, y); | |
| if (d<0) d += 2 * x + 3; | |
| else | |
| { | |
| d += 2 * (x - y) + 5; | |
| --y; | |
| } | |
| ++x; | |
| } | |
| plotPixels(h, k, x, y); | |
| } | |
| void drawBackground() | |
| { | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.58, 0.85, 1.0); | |
| glVertex2f(0, 0); | |
| glVertex2f(0, 700); | |
| glVertex2f(1000, 700); | |
| glVertex2f(1000, 0); | |
| glEnd(); | |
| } | |
| void drawRiverBank() | |
| { | |
| // Left Bank | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.52, 0.78, 0.22); | |
| glVertex2i(0, 0); | |
| glVertex2i(0, 400); | |
| glVertex2i(400, 400); | |
| glVertex2i(150, 0); | |
| glEnd(); | |
| // Right Bank | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.52, 0.78, 0.22); | |
| glVertex2i(1000, 0); | |
| glVertex2i(1000, 400); | |
| glVertex2i(600, 400); | |
| glVertex2i(850, 0); | |
| glEnd(); | |
| } | |
| void drawWater() | |
| { | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.06, 0.66, 0.75); | |
| glVertex2i(150, 0); | |
| glVertex2i(400, 400); | |
| glVertex2i(600, 400); | |
| glVertex2i(850, 0); | |
| glEnd(); | |
| } | |
| void drawHill(int sx, int sy, int w, int h) | |
| { | |
| glBegin(GL_TRIANGLES); | |
| glColor3f(0.13, 0.48, 0.49); | |
| glVertex2i(sx, sy); | |
| glVertex2i(sx + (w / 2), sy); | |
| glVertex2i(sx + (w / 2), sy + h); | |
| glEnd(); | |
| glBegin(GL_TRIANGLES); | |
| glColor3f(0.11, 0.55, 0.55); | |
| glVertex2i(sx + w, sy); | |
| glVertex2i(sx + (w / 2), sy); | |
| glVertex2i(sx + (w / 2), sy + h); | |
| glEnd(); | |
| glBegin(GL_TRIANGLES); | |
| glColor3f(0.77, 0.87, 0.98); | |
| glVertex2i(sx + (w / 2), sy + h); | |
| glVertex2i(sx + (w / 3), sy + (h / 1.5)); | |
| glVertex2i(sx + w - (w / 3), sy + (h / 1.5)); | |
| glEnd(); | |
| } | |
| void drawSun(GLfloat x, GLfloat y, GLfloat radius) { | |
| int i; | |
| double const PI = 3.1416; | |
| int triangleAmount = 500; //# of triangles used to draw circle | |
| //GLfloat radius = 0.8f; //radius | |
| GLfloat twicePi = 2.0f * PI; | |
| glBegin(GL_TRIANGLE_FAN); | |
| glColor3f(1.0, 0.93, 0.35); | |
| glVertex2f(x, y); // center of circle | |
| for (i = 0; i <= triangleAmount; i++) { | |
| glVertex2f( | |
| x + (radius * cos(i * twicePi / triangleAmount)), | |
| y + (radius * sin(i * twicePi / triangleAmount)) | |
| ); | |
| } | |
| glEnd(); | |
| radius = radius - 5; | |
| glBegin(GL_TRIANGLE_FAN); | |
| glColor3f(0.99, 0.85, 0.21); | |
| glVertex2f(x, y); // center of circle | |
| for (i = 0; i <= triangleAmount; i++) { | |
| glVertex2f( | |
| x + (radius * cos(i * twicePi / triangleAmount)), | |
| y + (radius * sin(i * twicePi / triangleAmount)) | |
| ); | |
| } | |
| glEnd(); | |
| radius = radius - 5; | |
| glBegin(GL_TRIANGLE_FAN); | |
| glColor3f(0.98, 0.75, 0.18); | |
| glVertex2f(x, y); // center of circle | |
| for (i = 0; i <= triangleAmount; i++) { | |
| glVertex2f( | |
| x + (radius * cos(i * twicePi / triangleAmount)), | |
| y + (radius * sin(i * twicePi / triangleAmount)) | |
| ); | |
| } | |
| glEnd(); | |
| } | |
| void drawClouds() | |
| { | |
| // cloud 1 | |
| for (int l = 0; l <= 20; l++) | |
| { | |
| glColor3f(1.0, 1.0, 1.0); | |
| drawCircle(190 + moveClouds, 580, l); | |
| } | |
| for (int l = 0; l <= 35; l++) | |
| { | |
| glColor3f(1.0, 1.0, 1.0); | |
| drawCircle(230 + moveClouds, 580, l); | |
| drawCircle(255 + moveClouds, 580, l); | |
| } | |
| for (int l = 0; l <= 20; l++) | |
| { | |
| glColor3f(1.0, 1.0, 1.0); | |
| drawCircle(295 + moveClouds, 580, l); | |
| } | |
| //cloud2 | |
| for (int l = 0; l <= 20; l++) | |
| { | |
| glColor3f(1.0, 1.0, 1.0); | |
| drawCircle(770 + moveClouds, 615, l); | |
| } | |
| for (int l = 0; l <= 35; l++) | |
| { | |
| glColor3f(1.0, 1.0, 1.0); | |
| drawCircle(810 + moveClouds, 615, l); | |
| drawCircle(835 + moveClouds, 615, l); | |
| drawCircle(870 + moveClouds, 615, l); | |
| } | |
| for (int l = 0; l <= 20; l++) | |
| { | |
| glColor3f(1.0, 1.0, 1.0); | |
| drawCircle(900 + moveClouds, 615, l); | |
| } | |
| } | |
| void drawBoat() | |
| { | |
| int px = 245, py = 200, w = 200, h = 50; | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.0, 0.0, 0.04); | |
| glVertex2i(px + boatPosX, py); | |
| glVertex2i(px + boatPosX + w, py); | |
| glVertex2i(px + boatPosX + w - (w / 4), py - h); | |
| glVertex2i(px + boatPosX + (w / 4), py - h); | |
| glEnd(); | |
| // Under water reflection | |
| glBegin(GL_POLYGON); | |
| glColor4f(0.06, 0.66, 0.75, .5); | |
| glVertex2i(px + boatPosX + (w / 8), py - (h / 2)); | |
| glVertex2i(px + boatPosX + w - (w / 8), py - (h / 2)); | |
| glVertex2i(px + boatPosX + w - (w / 5), py - h); | |
| glVertex2i(px + boatPosX + (w / 5), py - h); | |
| glEnd(); | |
| } | |
| void drawMissionary(int px, int py) | |
| { | |
| int w = characterWidth, h = characterHeight; | |
| // Hair | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.0, 0.0, 0.0); | |
| glVertex2i(px + 12, py + 66); | |
| glVertex2i(px + 34, py + 66); | |
| glVertex2i(px + 34, py + 76); | |
| glVertex2i(px + 12, py + 76); | |
| glEnd(); | |
| // Head | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.99, 0.87, 0.75); | |
| glVertex2i(px + 20, py + 58); | |
| glVertex2i(px + 25, py + 58); | |
| glVertex2i(px + 25, py + 62); | |
| glVertex2i(px + 20, py + 62); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.99, 0.87, 0.75); | |
| glVertex2i(px + 15, py + 62); | |
| glVertex2i(px + 30, py + 62); | |
| glVertex2i(px + 30, py + 72); | |
| glVertex2i(px + 15, py + 72); | |
| glEnd(); | |
| // Face | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.0, 0.0, 0.0); | |
| glVertex2i(px + 17, py + 67); | |
| glVertex2i(px + 21, py + 67); | |
| glVertex2i(px + 21, py + 69); | |
| glVertex2i(px + 17, py + 69); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.0, 0.0, 0.0); | |
| glVertex2i(px + 24, py + 67); | |
| glVertex2i(px + 28, py + 67); | |
| glVertex2i(px + 28, py + 69); | |
| glVertex2i(px + 24, py + 69); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.0, 0.0, 0.0); | |
| glVertex2i(px + 20, py + 64); | |
| glVertex2i(px + 25, py + 64); | |
| glVertex2i(px + 25, py + 65); | |
| glVertex2i(px + 20, py + 65); | |
| glEnd(); | |
| // Hand | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.99, 0.87, 0.75); | |
| glVertex2i(px + 10, py + 56); | |
| glVertex2i(px + 5, py + 56); | |
| glVertex2i(px + 5, py + 33); | |
| glVertex2i(px + 8, py + 33); | |
| glVertex2i(px + 8, py + 53); | |
| glVertex2i(px + 10, py + 53); | |
| glVertex2i(px + 10, py + 56); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.99, 0.87, 0.75); | |
| glVertex2i(px + 34, py + 56); | |
| glVertex2i(px + 39, py + 56); | |
| glVertex2i(px + 39, py + 33); | |
| glVertex2i(px + 36, py + 33); | |
| glVertex2i(px + 36, py + 53); | |
| glVertex2i(px + 34, py + 53); | |
| glVertex2i(px + 34, py + 56); | |
| glEnd(); | |
| // Body | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.68, 0.50, 0.77); | |
| glVertex2i(px + 10, py + 34); | |
| glVertex2i(px + 34, py + 34); | |
| glVertex2i(px + 34, py + 58); | |
| glVertex2i(px + 10, py + 58); | |
| glEnd(); | |
| // Pant | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.0, 0.33, 0.56); | |
| glVertex2i(px + 10, py + 8); | |
| glVertex2i(px + 17, py + 8); | |
| glVertex2i(px + 17, py + 34); | |
| glVertex2i(px + 10, py + 34); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.0, 0.33, 0.56); | |
| glVertex2i(px + 26, py + 8); | |
| glVertex2i(px + 34, py + 8); | |
| glVertex2i(px + 34, py + 34); | |
| glVertex2i(px + 26, py + 34); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.0, 0.33, 0.56); | |
| glVertex2i(px + 10, py + 34); | |
| glVertex2i(px + 34, py + 34); | |
| glVertex2i(px + 34, py + 20); | |
| glVertex2i(px + 10, py + 20); | |
| glEnd(); | |
| // Shoes | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.0, 0.0, 0.0); | |
| glVertex2i(px + 7, py + 3); | |
| glVertex2i(px + 19, py + 3); | |
| glVertex2i(px + 19, py + 8); | |
| glVertex2i(px + 7, py + 8); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.0, 0.0, 0.0); | |
| glVertex2i(px + 25, py + 3); | |
| glVertex2i(px + 38, py + 3); | |
| glVertex2i(px + 38, py + 8); | |
| glVertex2i(px + 25, py + 8); | |
| glEnd(); | |
| } | |
| void drawCannibal(int px, int py) | |
| { | |
| int w = characterWidth, h = characterHeight; | |
| // Hair | |
| glBegin(GL_POLYGON); | |
| glColor3f(1.0, 0.0, 0.0); | |
| glVertex2i(px + 17, py + 72); | |
| glVertex2i(px + 21, py + 72); | |
| glVertex2i(px + 21, py + 78); | |
| glVertex2i(px + 17, py + 78); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(1.0, 0.0, 0.0); | |
| glVertex2i(px + 24, py + 72); | |
| glVertex2i(px + 28, py + 72); | |
| glVertex2i(px + 28, py + 78); | |
| glVertex2i(px + 24, py + 78); | |
| glEnd(); | |
| // Head | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.90, 0.91, 0.08); | |
| glVertex2i(px + 20, py + 58); | |
| glVertex2i(px + 25, py + 58); | |
| glVertex2i(px + 25, py + 62); | |
| glVertex2i(px + 20, py + 62); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.90, 0.91, 0.08); | |
| glVertex2i(px + 15, py + 62); | |
| glVertex2i(px + 30, py + 62); | |
| glVertex2i(px + 30, py + 72); | |
| glVertex2i(px + 15, py + 72); | |
| glEnd(); | |
| // Face | |
| glBegin(GL_POLYGON); | |
| glColor3f(1.0, 0.0, 0.0); | |
| glVertex2i(px + 17, py + 67); | |
| glVertex2i(px + 21, py + 67); | |
| glVertex2i(px + 21, py + 69); | |
| glVertex2i(px + 17, py + 69); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(1.0, 0.0, 0.0); | |
| glVertex2i(px + 24, py + 67); | |
| glVertex2i(px + 28, py + 67); | |
| glVertex2i(px + 28, py + 69); | |
| glVertex2i(px + 24, py + 69); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.0, 0.0, 0.0); | |
| glVertex2i(px + 20, py + 64); | |
| glVertex2i(px + 25, py + 64); | |
| glVertex2i(px + 25, py + 65); | |
| glVertex2i(px + 20, py + 65); | |
| glEnd(); | |
| // Hand | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.90, 0.91, 0.08); | |
| glVertex2i(px + 10, py + 56); | |
| glVertex2i(px + 5, py + 56); | |
| glVertex2i(px + 5, py + 33); | |
| glVertex2i(px + 8, py + 33); | |
| glVertex2i(px + 8, py + 53); | |
| glVertex2i(px + 10, py + 53); | |
| glVertex2i(px + 10, py + 56); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.90, 0.91, 0.08); | |
| glVertex2i(px + 34, py + 56); | |
| glVertex2i(px + 39, py + 56); | |
| glVertex2i(px + 39, py + 33); | |
| glVertex2i(px + 36, py + 33); | |
| glVertex2i(px + 36, py + 53); | |
| glVertex2i(px + 34, py + 53); | |
| glVertex2i(px + 34, py + 56); | |
| glEnd(); | |
| // Body | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.77, 0.15, 0.10); | |
| glVertex2i(px + 10, py + 34); | |
| glVertex2i(px + 34, py + 34); | |
| glVertex2i(px + 34, py + 58); | |
| glVertex2i(px + 10, py + 58); | |
| glEnd(); | |
| // Pant | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.77, 0.15, 0.10); | |
| glVertex2i(px + 10, py + 8); | |
| glVertex2i(px + 17, py + 8); | |
| glVertex2i(px + 17, py + 34); | |
| glVertex2i(px + 10, py + 34); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.77, 0.15, 0.10); | |
| glVertex2i(px + 26, py + 8); | |
| glVertex2i(px + 34, py + 8); | |
| glVertex2i(px + 34, py + 34); | |
| glVertex2i(px + 26, py + 34); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(0.77, 0.15, 0.10); | |
| glVertex2i(px + 10, py + 34); | |
| glVertex2i(px + 34, py + 34); | |
| glVertex2i(px + 34, py + 20); | |
| glVertex2i(px + 10, py + 20); | |
| glEnd(); | |
| // Shoes | |
| glBegin(GL_POLYGON); | |
| glColor3f(1.0, 0.0, 0.0); | |
| glVertex2i(px + 7, py + 3); | |
| glVertex2i(px + 19, py + 3); | |
| glVertex2i(px + 19, py + 8); | |
| glVertex2i(px + 7, py + 8); | |
| glEnd(); | |
| glBegin(GL_POLYGON); | |
| glColor3f(1.0, 0.0, 0.0); | |
| glVertex2i(px + 25, py + 3); | |
| glVertex2i(px + 38, py + 3); | |
| glVertex2i(px + 38, py + 8); | |
| glVertex2i(px + 25, py + 8); | |
| glEnd(); | |
| } | |
| void drawMissionaryOnBoat() | |
| { | |
| int px = boatCharacterLeftX, py = boatCharacterY, w = characterWidth, h = characterHeight; | |
| if (boatMissionaryVisibility[0]) | |
| { | |
| drawMissionary(px, py); | |
| } | |
| px = boatCharacterRightX; | |
| if (boatMissionaryVisibility[1]) | |
| { | |
| drawMissionary(px, py); | |
| } | |
| } | |
| void drawCannibalOnBoat() | |
| { | |
| int px = boatCharacterLeftX, py = boatCharacterY, w = characterWidth, h = characterHeight; | |
| if (boatCannibalVisibility[0]) | |
| { | |
| drawCannibal(px, py); | |
| } | |
| px = boatCharacterRightX; | |
| if (boatCannibalVisibility[1]) | |
| { | |
| drawCannibal(px, py); | |
| } | |
| } | |
| void drawCharacters() | |
| { | |
| int px, py, w = characterWidth, h = characterHeight; | |
| px = leftCharacterPosX; | |
| py = leftCharacterPosY; | |
| if (leftCannibalVisibility[0]) | |
| { | |
| drawCannibal(px, py); | |
| } | |
| if (leftCannibalVisibility[1]) | |
| { | |
| drawCannibal(px + w + 5, py); | |
| } | |
| if (leftCannibalVisibility[2]) | |
| { | |
| drawCannibal(px + (2 * w) + (2 * 5), py); | |
| } | |
| if (leftMissionaryVisibility[0]) | |
| { | |
| drawMissionary(px + (3 * w) + (3 * 5), py); | |
| } | |
| if (leftMissionaryVisibility[1]) | |
| { | |
| drawMissionary(px + (4 * w) + (4 * 5), py); | |
| } | |
| if (leftMissionaryVisibility[2]) | |
| { | |
| drawMissionary(px + (5 * w) + (5 * 5), py); | |
| } | |
| px = rightCharacterPosX; | |
| py = rightCharacterPosY; | |
| if (rightMissionaryVisibility[0]) | |
| { | |
| drawMissionary(px, py); | |
| } | |
| if (rightMissionaryVisibility[1]) | |
| { | |
| drawMissionary(px + w + 5, py); | |
| } | |
| if (rightMissionaryVisibility[2]) | |
| { | |
| drawMissionary(px + (2 * w) + (2 * 5), py); | |
| } | |
| if (rightCannibalVisibility[0]) | |
| { | |
| drawCannibal(px + (3 * w) + (3 * 5), py); | |
| } | |
| if (rightCannibalVisibility[1]) | |
| { | |
| drawCannibal(px + (4 * w) + (4 * 5), py); | |
| } | |
| if (rightCannibalVisibility[2]) | |
| { | |
| drawCannibal(px + (5 * w) + (5 * 5), py); | |
| } | |
| } | |
| // Animation Functions | |
| void animateClouds() | |
| { | |
| moveClouds += cloudDeltaX; | |
| //cout << "Cloud Animation" << endl; | |
| if (moveClouds == 850) | |
| { | |
| moveClouds = -900; | |
| } | |
| } | |
| void animateBoat() | |
| { | |
| if (moveBoat == true) | |
| { | |
| //cout << "Boat animation" << endl; | |
| boatPosX += boatDeltaX; | |
| boatCharacterLeftX += boatDeltaX; | |
| boatCharacterRightX += boatDeltaX; | |
| if (boatPosX == 300.0) | |
| { | |
| boatCrossed = true; | |
| moveBoat = false; | |
| riverCrossedOnce = true; | |
| checkGameStatus(); | |
| } | |
| } | |
| if (moveBoatReverse == true) | |
| { | |
| boatPosX -= boatDeltaX; | |
| boatCharacterLeftX -= boatDeltaX; | |
| boatCharacterRightX -= boatDeltaX; | |
| if (boatPosX == 0.0) | |
| { | |
| boatCrossed = false; | |
| moveBoatReverse = false; | |
| checkGameStatus(); | |
| } | |
| } | |
| } | |
| void myDisplay(void) | |
| { | |
| glClear(GL_COLOR_BUFFER_BIT); | |
| // Drawings | |
| drawBackground(); | |
| drawWater(); | |
| drawRiverBank(); | |
| drawSun(650, 600, 50); | |
| drawHill(200, 400, 600, 300); | |
| drawHill(0, 400, 400, 200); | |
| drawHill(700, 400, 300, 150); | |
| drawClouds(); | |
| drawCharacters(); | |
| drawMissionaryOnBoat(); | |
| drawCannibalOnBoat(); | |
| drawBoat(); | |
| glFlush(); | |
| // Animations | |
| animateBoat(); | |
| animateClouds(); | |
| glutPostRedisplay(); | |
| } | |
| void keyboardFunc(unsigned char key, int x, int y) | |
| { | |
| //-------- Boat Move -------- | |
| if (key == 'g' || key == 'G') | |
| { | |
| //cout << "Keyboard event: G" << endl; | |
| if (boatPosX == 0.0 && (boatLeftCharacter != 0 || boatRightCharacter != 0)) | |
| { | |
| moveBoat = true; | |
| } | |
| glutPostRedisplay(); | |
| } | |
| else if (key == 'b' || key == 'B') | |
| { | |
| //cout << "Keyboard event: B" << endl; | |
| if (boatPosX == 300.0 && (boatLeftCharacter != 0 || boatRightCharacter != 0)) | |
| { | |
| moveBoatReverse = true; | |
| } | |
| glutPostRedisplay(); | |
| } | |
| else if (key == 'r' || key == 'R') | |
| { | |
| //cout << "Keyboard event: R" << endl; | |
| resetAll(); | |
| glutPostRedisplay(); | |
| } | |
| } | |
| void mouseFunc(int b, int s, int x, int y) { | |
| if (s == GLUT_DOWN && b == GLUT_LEFT_BUTTON) { | |
| int px, py, w = characterWidth, h = characterHeight; | |
| if (!boatCrossed) | |
| { | |
| px = leftCharacterPosX; | |
| py = leftCharacterPosY + 120; | |
| if (x >= px && x <= (px + w) && y >= py && y <= (py + h) && leftCannibalVisibility[0]) | |
| { | |
| cout << "Left: Cannibal 0" << endl; | |
| if (boatLeftCharacter == 0) | |
| { | |
| leftCannibalVisibility[0] = false; | |
| boatCannibalVisibility[0] = true; | |
| boatLeftCharacter = 1; | |
| } | |
| else if (boatRightCharacter == 0) | |
| { | |
| leftCannibalVisibility[0] = false; | |
| boatCannibalVisibility[1] = true; | |
| boatRightCharacter = 1; | |
| } | |
| //cout << px << ',' << px + w << ',' << py << ',' << py + h << endl; | |
| //cout << x << '\t' << y << endl; | |
| } | |
| else if (x >= (px + w + 5) && x <= (px + w + 5 + w) && y >= py && y <= (py + h) && leftCannibalVisibility[1]) | |
| { | |
| cout << "Left: Cannibal 1" << endl; | |
| if (boatLeftCharacter == 0) | |
| { | |
| leftCannibalVisibility[1] = false; | |
| boatCannibalVisibility[0] = true; | |
| boatLeftCharacter = 1; | |
| } | |
| else if (boatRightCharacter == 0) | |
| { | |
| leftCannibalVisibility[1] = false; | |
| boatCannibalVisibility[1] = true; | |
| boatRightCharacter = 1; | |
| } | |
| } | |
| else if (x >= (px + (2 * w) + (2 * 5)) && x <= (px + (2 * w) + (2 * 5) + w) && y >= py && y <= (py + h) && leftCannibalVisibility[2]) | |
| { | |
| cout << "Left: Cannibal 2" << endl; | |
| if (boatLeftCharacter == 0) | |
| { | |
| leftCannibalVisibility[2] = false; | |
| boatCannibalVisibility[0] = true; | |
| boatLeftCharacter = 1; | |
| } | |
| else if (boatRightCharacter == 0) | |
| { | |
| leftCannibalVisibility[2] = false; | |
| boatCannibalVisibility[1] = true; | |
| boatRightCharacter = 1; | |
| } | |
| } | |
| else if (x >= (px + (3 * w) + (3 * 5)) && x <= (px + (3 * w) + (3 * 5) + w) && y >= py && y <= (py + h) && leftMissionaryVisibility[0]) | |
| { | |
| cout << "Left: Missionary 0" << endl; | |
| if (boatLeftCharacter == 0) | |
| { | |
| leftMissionaryVisibility[0] = false; | |
| boatMissionaryVisibility[0] = true; | |
| boatLeftCharacter = 2; | |
| //leftMissionaries--; | |
| } | |
| else if (boatRightCharacter == 0) | |
| { | |
| leftMissionaryVisibility[0] = false; | |
| boatMissionaryVisibility[1] = true; | |
| boatRightCharacter = 2; | |
| } | |
| } | |
| else if (x >= (px + (4 * w) + (4 * 5)) && x <= (px + (4 * w) + (4 * 5) + w) && y >= py && y <= (py + h) && leftMissionaryVisibility[1]) | |
| { | |
| cout << "Left: Missionary 1" << endl; | |
| if (boatLeftCharacter == 0) | |
| { | |
| leftMissionaryVisibility[1] = false; | |
| boatMissionaryVisibility[0] = true; | |
| boatLeftCharacter = 2; | |
| } | |
| else if (boatRightCharacter == 0) | |
| { | |
| leftMissionaryVisibility[1] = false; | |
| boatMissionaryVisibility[1] = true; | |
| boatRightCharacter = 2; | |
| } | |
| } | |
| else if (x >= (px + (5 * w) + (5 * 5)) && x <= (px + (5 * w) + (5 * 5) + w) && y >= py && y <= (py + h) && leftMissionaryVisibility[2]) | |
| { | |
| cout << "Left: Missionary 2" << endl; | |
| if (boatLeftCharacter == 0) | |
| { | |
| leftMissionaryVisibility[2] = false; | |
| boatMissionaryVisibility[0] = true; | |
| boatLeftCharacter = 2; | |
| } | |
| else if (boatRightCharacter == 0) | |
| { | |
| leftMissionaryVisibility[2] = false; | |
| boatMissionaryVisibility[1] = true; | |
| boatRightCharacter = 2; | |
| } | |
| } | |
| if (boatLeftCharacter != 0 || boatRightCharacter != 0) | |
| { | |
| w = characterWidth, h = characterHeight; | |
| if (x >= boatCharacterLeftX && x <= (boatCharacterLeftX + w) && y >= (boatCharacterY + 260) && y <= ((boatCharacterY + 260) + h)) | |
| { | |
| /*cout << boatCharacterLeftX << ',' << boatCharacterLeftX + w << ',' << (boatCharacterY + 260) << ',' << (boatCharacterY + 260) + h << endl; | |
| cout << x << '\t' << y << endl;*/ | |
| cout << "Left: Left Character On boat" << endl; | |
| if (boatLeftCharacter == 1) | |
| { | |
| leftCannibalVisibility[getCannibalBlankPosition()] = true; | |
| boatCannibalVisibility[0] = false; | |
| boatLeftCharacter = 0; | |
| } | |
| else if (boatLeftCharacter == 2) | |
| { | |
| leftMissionaryVisibility[getMissinaryBlankPosition()] = true; | |
| boatMissionaryVisibility[0] = false; | |
| boatLeftCharacter = 0; | |
| } | |
| } | |
| else if (x >= boatCharacterRightX && x <= (boatCharacterRightX + w) && y >= (boatCharacterY + 260) && y <= ((boatCharacterY + 260) + h)) | |
| { | |
| cout << "Left: Right Character On boat" << endl; | |
| if (boatRightCharacter == 1) | |
| { | |
| leftCannibalVisibility[getCannibalBlankPosition()] = true; | |
| boatCannibalVisibility[1] = false; | |
| boatRightCharacter = 0; | |
| } | |
| else if (boatRightCharacter == 2) | |
| { | |
| leftMissionaryVisibility[getMissinaryBlankPosition()] = true; | |
| boatMissionaryVisibility[1] = false; | |
| boatRightCharacter = 0; | |
| } | |
| } | |
| } | |
| } | |
| else if (boatCrossed) | |
| { | |
| px = rightCharacterPosX; | |
| py = rightCharacterPosY + 120; | |
| if (x >= px && x <= (px + w) && y >= py && y <= (py + h) && rightMissionaryVisibility[0]) | |
| { | |
| //cout << px << ',' << px + w << ',' << py << ',' << py + h << endl; | |
| //cout << x << '\t' << y << endl; | |
| cout << "Right: Missionary 0" << endl; | |
| if (boatLeftCharacter == 0) | |
| { | |
| rightMissionaryVisibility[0] = false; | |
| boatMissionaryVisibility[0] = true; | |
| boatLeftCharacter = 2; | |
| } | |
| else if (boatRightCharacter == 0) | |
| { | |
| rightMissionaryVisibility[0] = false; | |
| boatMissionaryVisibility[1] = true; | |
| boatRightCharacter = 2; | |
| } | |
| } | |
| else if (x >= (px + w + 5) && x <= (px + w + 5 + w) && y >= py && y <= (py + h) && rightMissionaryVisibility[1]) | |
| { | |
| cout << "Right: Missionary 1" << endl; | |
| if (boatLeftCharacter == 0) | |
| { | |
| rightMissionaryVisibility[1] = false; | |
| boatMissionaryVisibility[0] = true; | |
| boatLeftCharacter = 2; | |
| } | |
| else if (boatRightCharacter == 0) | |
| { | |
| rightMissionaryVisibility[1] = false; | |
| boatMissionaryVisibility[1] = true; | |
| boatRightCharacter = 2; | |
| } | |
| } | |
| else if (x >= (px + (2 * w) + (2 * 5)) && x <= (px + (2 * w) + (2 * 5) + w) && y >= py && y <= (py + h) && rightMissionaryVisibility[2]) | |
| { | |
| cout << "Right: Missionary 2" << endl; | |
| if (boatLeftCharacter == 0) | |
| { | |
| rightMissionaryVisibility[2] = false; | |
| boatMissionaryVisibility[0] = true; | |
| boatLeftCharacter = 2; | |
| } | |
| else if (boatRightCharacter == 0) | |
| { | |
| rightMissionaryVisibility[2] = false; | |
| boatMissionaryVisibility[1] = true; | |
| boatRightCharacter = 2; | |
| } | |
| } | |
| else if (x >= (px + (3 * w) + (3 * 5)) && x <= (px + (3 * w) + (3 * 5) + w) && y >= py && y <= (py + h) && rightCannibalVisibility[0]) | |
| { | |
| cout << "Right: Cannibal 0" << endl; | |
| if (boatLeftCharacter == 0) | |
| { | |
| rightCannibalVisibility[0] = false; | |
| boatCannibalVisibility[0] = true; | |
| boatLeftCharacter = 1; | |
| } | |
| else if (boatRightCharacter == 0) | |
| { | |
| rightCannibalVisibility[0] = false; | |
| boatCannibalVisibility[1] = true; | |
| boatRightCharacter = 1; | |
| } | |
| } | |
| else if (x >= (px + (4 * w) + (4 * 5)) && x <= (px + (4 * w) + (4 * 5) + w) && y >= py && y <= (py + h) && rightCannibalVisibility[1]) | |
| { | |
| cout << "Right: Cannibal 1" << endl; | |
| if (boatLeftCharacter == 0) | |
| { | |
| rightCannibalVisibility[1] = false; | |
| boatCannibalVisibility[0] = true; | |
| boatLeftCharacter = 1; | |
| } | |
| else if (boatRightCharacter == 0) | |
| { | |
| rightCannibalVisibility[1] = false; | |
| boatCannibalVisibility[1] = true; | |
| boatRightCharacter = 1; | |
| } | |
| } | |
| else if (x >= (px + (5 * w) + (5 * 5)) && x <= (px + (5 * w) + (5 * 5) + w) && y >= py && y <= (py + h) && rightCannibalVisibility[2]) | |
| { | |
| cout << "Right: Cannibal 2" << endl; | |
| if (boatLeftCharacter == 0) | |
| { | |
| rightCannibalVisibility[2] = false; | |
| boatCannibalVisibility[0] = true; | |
| boatLeftCharacter = 1; | |
| } | |
| else if (boatRightCharacter == 0) | |
| { | |
| rightCannibalVisibility[2] = false; | |
| boatCannibalVisibility[1] = true; | |
| boatRightCharacter = 1; | |
| } | |
| } | |
| if (boatLeftCharacter != 0 || boatRightCharacter != 0) | |
| { | |
| w = characterWidth, h = characterHeight; | |
| if (x >= boatCharacterLeftX && x <= (boatCharacterLeftX + w) && y >= (boatCharacterY + 260) && y <= ((boatCharacterY + 260) + h)) | |
| { | |
| /*cout << boatCharacterLeftX << ',' << boatCharacterLeftX + w << ',' << (boatCharacterY + 260) << ',' << (boatCharacterY + 260) + h << endl; | |
| cout << x << '\t' << y << endl;*/ | |
| cout << "Right: Left Character On boat" << endl; | |
| if (boatLeftCharacter == 1) | |
| { | |
| rightCannibalVisibility[getCannibalBlankPosition()] = true; | |
| boatCannibalVisibility[0] = false; | |
| boatLeftCharacter = 0; | |
| } | |
| else if (boatLeftCharacter == 2) | |
| { | |
| rightMissionaryVisibility[getMissinaryBlankPosition()] = true; | |
| boatMissionaryVisibility[0] = false; | |
| boatLeftCharacter = 0; | |
| } | |
| } | |
| else if (x >= boatCharacterRightX && x <= (boatCharacterRightX + w) && y >= (boatCharacterY + 260) && y <= ((boatCharacterY + 260) + h)) | |
| { | |
| cout << "Right: Right Character On boat" << endl; | |
| if (boatRightCharacter == 1) | |
| { | |
| rightCannibalVisibility[getCannibalBlankPosition()] = true; | |
| boatCannibalVisibility[1] = false; | |
| boatRightCharacter = 0; | |
| } | |
| else if (boatRightCharacter == 2) | |
| { | |
| rightMissionaryVisibility[getMissinaryBlankPosition()] = true; | |
| boatMissionaryVisibility[1] = false; | |
| boatRightCharacter = 0; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| void myInit(void) | |
| { | |
| glClearColor(1.0, 1.0, 1.0, 0.0); | |
| glColor3f(0.0f, 0.0f, 0.0f); | |
| glPointSize(4.0); | |
| glEnable(GL_BLEND); | |
| glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
| glMatrixMode(GL_PROJECTION); | |
| glLoadIdentity(); | |
| gluOrtho2D(0.0, 1000.0, 0.0, 700.0); | |
| } | |
| void main(int argc, char** argv) | |
| { | |
| glutInit(&argc, argv); | |
| glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); | |
| glutInitWindowSize(1000, 700); | |
| glutInitWindowPosition((glutGet(GLUT_SCREEN_WIDTH) - 1000) / 2, (glutGet(GLUT_SCREEN_HEIGHT) - 700) / 2); | |
| glutCreateWindow("Missionaries and Cannibals"); | |
| glutDisplayFunc(myDisplay); | |
| glutKeyboardFunc(keyboardFunc); | |
| glutMouseFunc(mouseFunc); | |
| resetAll(); | |
| myInit(); | |
| glutMainLoop(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment