Ver Fonte

technically you can play snake

tarfeef101 há 6 anos atrás
pai
commit
16c4ac070e
2 ficheiros alterados com 183 adições e 117 exclusões
  1. BIN
      assignments/a1/snake
  2. 183 117
      assignments/a1/snake.cc

BIN
assignments/a1/snake


+ 183 - 117
assignments/a1/snake.cc

@@ -13,6 +13,7 @@ Note: the -L option and -lstdc++ may not be needed on some machines.
 
 #include <iostream>
 #include <list>
+#include <vector>
 #include <cstdlib>
 #include <sys/time.h>
 #include <math.h>
@@ -32,9 +33,10 @@ using namespace std;
  */
 const int Border = 1;
 const int BufferSize = 10;
-const int FPS = 60;
-const int width = 600;
+const int FPS = 30;
+const int width = 800;
 const int height = 600;
+const int blockSize = 25;
 
 /*
  * Information to draw on the window.
@@ -69,7 +71,35 @@ class Displayable
 		virtual void paint(XInfo & xinfo) = 0;
 };
 
-class Snake : public Displayable
+class Fruit : public Displayable
+{
+	public:
+		virtual void paint(XInfo & xinfo)
+    {
+			XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], x, y, 25, 25);
+    }
+
+    Fruit()
+    {
+      newspot();
+    }
+
+    void newspot()
+    {
+      x = (rand() % 800);
+      y = (rand() % 600);
+    }
+        // ** ADD YOUR LOGIC **
+        /*
+         * The fruit needs to be re-generated at new location every time a snake eats it. See the assignment webpage for more details.
+         */
+
+    private:
+        int x;
+        int y;
+};
+
+class Section: public Displayable
 {
 	public:
 		virtual void paint(XInfo & xinfo)
@@ -77,174 +107,210 @@ class Snake : public Displayable
       switch(direction)
       {
         case 1:
-          XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], x, y, blockSize, 25);
+          XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], x, y, blockSize, len * blockSize);
           break;
 
         case 2:
-          XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], x, y, 25, blockSize);
+          XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], (x - len * blockSize), y, len * blockSize, blockSize);
           break;
 
         case 3:
-          XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], x, y, blockSize, 25);
+          XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], x, (y - len * blockSize), blockSize, len * blockSize);
           break;
 
         case 4:
-          XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], x, y, 25, blockSize);
+          XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], x, y, len * blockSize, blockSize);
           break;
       }
 		}
 
-		void move(XInfo &xinfo)
+    void increment(int x)
+    {
+      len += x;
+    }
+
+    void decrement()
+    {
+      --len;
+    }
+
+		bool empty()
+    {
+      return (!len);
+    }
+
+    void grow()
     {
       switch(direction)
       {
         case 1:
-          y -= speed;
+          y -= blockSize;
           break;
 
         case 2:
-          x += speed;
+          x += blockSize;
           break;
 
         case 3:
-          y += speed;
+          y += blockSize;
           break;
 
         case 4:
-          x -= speed;
+          x -= blockSize;
           break;
       }
 
-      if (x > width || y < 0)
+      ++len;
+    }
+
+    int getx()
+    {
+      return x;
+    }
+
+    int gety()
+    {
+      return y;
+    }
+
+		Section(int x, int y, int dir, int len = 1): x(x), y(y), direction(dir), len(len)
+    {
+      blockSize = 25;
+		}
+
+	private:
+		int x;
+    int y;
+    int len;
+		int blockSize;
+		int direction;
+};
+
+class Snake : public Displayable
+{
+	public:
+		virtual void paint(XInfo & xinfo)
+    {
+      for (Section * each: sections)
+      {
+        each->paint(xinfo);
+      }
+		}
+
+		void move(XInfo & xinfo)
+    {
+      // turn if a turn happens
+      if (direction)
+      {
+        Section * newsec = new Section(sections.front()->getx(), sections.front()->gety(), direction, 0);
+        direction = 0;
+        sections.insert(sections.begin(), newsec);
+      }
+
+      // move 1 block forwards
+      sections.front()->grow();
+
+      // see if fruit was eaten
+      if (sections.front()->getx() == 50 || sections.front()->gety() == 50)
+      {
+        fruit = 1;
+      }
+
+      // add fruit, remove 1 from end, delete if empty
+      sections.back()->increment(fruit);
+      if (fruit) fruity->newspot();
+      fruit = 0;
+      sections.back()->decrement();
+      if (sections.back()->empty())
       {
-        direction += 2;
+        delete sections.back();
+        sections.pop_back();
       }
 
-      if (x < 0 || y > height)
+      if (sections.front()->getx() > width || sections.front()->gety() < 0)
       {
-        direction -= 2;
+        printf("you're shit\n");
+        delete this;
+        exit(0);
       }
 
+      if (sections.front()->getx() < 0 || sections.front()->gety() > height)
+      {
+        printf("you're shit\n");
+        delete this;
+        exit(0);
+      }
             // ** ADD YOUR LOGIC **
             // Here, you will be performing collision detection between the snake,
             // the fruit, and the obstacles depending on what the snake lands on.
 		}
 
-		int getX()
+    /*
+     * ** ADD YOUR LOGIC **
+     * Use these placeholder methods as guidance for implementing the snake behaviour.
+     * You do not have to use these methods, feel free to implement your own.
+     */
+    void didEatFruit()
     {
-			return x;
-		}
 
-		int getY()
+    }
+
+    void didHitObstacle()
     {
-			return y;
-		}
 
-        /*
-         * ** ADD YOUR LOGIC **
-         * Use these placeholder methods as guidance for implementing the snake behaviour.
-         * You do not have to use these methods, feel free to implement your own.
-         */
-        void didEatFruit()
-        {
-
-        }
-
-        void didHitObstacle()
-        {
-
-        }
-
-        void moveup()
-        {
-          if (direction == 4 || direction == 2) direction = 1;
-        }
-
-        void moveright()
-        {
-          if (direction == 1 || direction == 3) direction = 2;
-        }
-
-        void movedown()
-        {
-          if (direction == 4 || direction == 2) direction = 3;
-        }
-
-        void moveleft()
-        {
-          if (direction == 1 || direction == 3) direction = 4;
-        }
-
-        void turnLeft()
-        {
-          if (direction != 1)
-          {
-            --direction;
-          }
-          else
-          {
-            direction = 4;
-          }
-        }
-
-        void turnRight()
-        {
-          if (direction != 4)
-          {
-            ++direction;
-          }
-          else
-          {
-            direction = 1;
-          }
-        }
-
-		Snake(int x, int y): x(x), y(y)
+    }
+
+    void moveup()
+    {
+      if (direction == 4 || direction == 2 || direction == 0) direction = 1;
+    }
+
+    void moveright()
+    {
+      if (direction == 1 || direction == 3 || direction == 0) direction = 2;
+    }
+
+    void movedown()
+    {
+      if (direction == 4 || direction == 2 || direction == 0) direction = 3;
+    }
+
+    void moveleft()
     {
-			direction = 2;
-      blockSize = 10;
-      speed = 5;
+      if (direction == 1 || direction == 3 || direction == 0) direction = 4;
+    }
+
+		Snake(int x, int y, Fruit * fruity): x(x), y(y), fruity(fruity)
+    {
+      Section * newsec = new Section(x, y, 2, 2);
+      sections.insert(sections.begin(), newsec);
+      direction = 0;
+      blockSize = 25;
+      speed = 1;
 		}
 
+    ~Snake()
+    {
+      for (auto each = sections.begin(); each != sections.end(); ++each)
+      {
+        delete *(sections.erase(each));
+      }
+    }
+
 	private:
 		int x;
 		int y;
+    vector<Section *> sections;
 		int blockSize;
 		int direction;
     int speed;
+    int fruit;
+    Fruit * fruity;
 };
 
-class Fruit : public Displayable
-{
-	public:
-		virtual void paint(XInfo & xinfo)
-    {
-			XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], x, y, 10, 10);
-    }
-
-        Fruit()
-        {
-            // ** ADD YOUR LOGIC **
-            // generate the x and y value for the fruit
-            x = 50;
-            y = 50;
-        }
-
-        // ** ADD YOUR LOGIC **
-        /*
-         * The fruit needs to be re-generated at new location every time a snake eats it. See the assignment webpage for more details.
-         */
-
-    private:
-        int x;
-        int y;
-};
-
-
 list<Displayable *> dList;           // list of Displayables
-Snake snake(100, 450);
-Fruit fruit;
-
+Fruit fruity;
+Snake snake(100, 450, &fruity);
 
 /*
  * Initialize X and create a window
@@ -274,7 +340,7 @@ void initX(int argc, char * argv[], XInfo & xInfo)
 
 	hints.x = 100;
 	hints.y = 100;
-	hints.width = 600;
+	hints.width = 800;
 	hints.height = 600;
 	hints.flags = PPosition | PSize;
 
@@ -425,7 +491,7 @@ void eventLoop(XInfo & xinfo)
 {
 	// Add stuff to paint to the display list
 	dList.push_front(&snake);
-  dList.push_front(&fruit);
+  dList.push_front(&fruity);
 
 	XEvent event;
 	unsigned long lastRepaint = 0;