Pārlūkot izejas kodu

testing to see if i can even merge. semi working though

tarfeef101 6 gadi atpakaļ
vecāks
revīzija
138391c8fd
2 mainītis faili ar 200 papildinājumiem un 72 dzēšanām
  1. BIN
      assignments/a1/snake
  2. 200 72
      assignments/a1/snake.cc

BIN
assignments/a1/snake


+ 200 - 72
assignments/a1/snake.cc

@@ -28,15 +28,26 @@ Note: the -L option and -lstdc++ may not be needed on some machines.
 
 using namespace std;
 
+// Globals for xlib
+Colormap colours;
+XColor xcolour;
+char black[] = "rgb:00/00/00";
+char white[] = "rgb:ff/ff/ff";
+char lblue[] = "rgb:00/ff/ff";
+char orange[] = "rgb:FF/45/00";
+
 /*
  * Global game state variables
  */
 const int Border = 1;
 const int BufferSize = 10;
-const int FPS = 30;
+int FPS = 30;
 const int width = 800;
 const int height = 600;
 const int blockSize = 25;
+int velocity = 5;
+bool paused = true;
+bool starting = true;
 
 /*
  * Information to draw on the window.
@@ -49,9 +60,18 @@ typedef struct XInfo
 	GC gc[3];
 	int width;		// size of window
 	int height;
+  Pixmap buffer;
 } Xinfo;
 
 
+// get microseconds
+unsigned long now()
+{
+	timeval tv;
+	gettimeofday(&tv, NULL);
+	return tv.tv_sec * 1000000 + tv.tv_usec;
+}
+
 /*
  * Function to put out a message on error exits.
  */
@@ -61,6 +81,14 @@ void error(string str)
   exit(0);
 }
 
+// change the drawing coloursvoid changecolour(char colour[])
+void changecolour(XInfo & xinfo, char colour[])
+{
+  XParseColor(xinfo.display, colours, colour, &xcolour);
+  XAllocColor(xinfo.display, colours, &xcolour);
+  XSetForeground(xinfo.display, xinfo.gc[0], xcolour.pixel);
+  XFreeColormap(xinfo.display, colours);
+}
 
 /*
  * An abstract class representing displayable things.
@@ -76,7 +104,8 @@ class Fruit : public Displayable
 	public:
 		virtual void paint(XInfo & xinfo)
     {
-			XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], x, y, 25, 25);
+      changecolour(xinfo, orange);
+			XFillArc(xinfo.display, xinfo.buffer, xinfo.gc[0], x, y, 25, 25, 0, 360 * 64);
     }
 
     Fruit()
@@ -84,6 +113,16 @@ class Fruit : public Displayable
       newspot();
     }
 
+    int getx()
+    {
+      return x;
+    }
+
+    int gety()
+    {
+      return y;
+    }
+
     void newspot()
     {
       x = (rand() % 32) * 25;
@@ -104,22 +143,23 @@ class Section: public Displayable
 	public:
 		virtual void paint(XInfo & xinfo)
     {
+      changecolour(xinfo, black);
       switch(direction)
       {
         case 1:
-          XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], x, y, blockSize, len * blockSize);
+          XFillRectangle(xinfo.display, xinfo.buffer, xinfo.gc[0], x, y, blockSize, (len + 1) * blockSize);
           break;
 
         case 2:
-          XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], (x - len * blockSize), y, len * blockSize, blockSize);
+          XFillRectangle(xinfo.display, xinfo.buffer, xinfo.gc[0], (x - len * blockSize), y, (1 + len) * blockSize, blockSize);
           break;
 
         case 3:
-          XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], x, (y - len * blockSize), blockSize, len * blockSize);
+          XFillRectangle(xinfo.display, xinfo.buffer, xinfo.gc[0], x, (y - len * blockSize), blockSize, ((1 + len) * blockSize));
           break;
 
         case 4:
-          XFillRectangle(xinfo.display, xinfo.window, xinfo.gc[0], x, y, len * blockSize, blockSize);
+          XFillRectangle(xinfo.display, xinfo.buffer, xinfo.gc[0], x, y, (len + 1) * blockSize, blockSize);
           break;
       }
 		}
@@ -173,6 +213,16 @@ class Section: public Displayable
       return y;
     }
 
+    int getdir()
+    {
+      return direction;
+    }
+
+    int getlen()
+    {
+      return len;
+    }
+
 		Section(int x, int y, int dir, int len = 1): x(x), y(y), direction(dir), len(len)
     {
       blockSize = 25;
@@ -195,10 +245,15 @@ class Snake : public Displayable
       {
         each->paint(xinfo);
       }
+
 		}
 
 		void move(XInfo & xinfo)
     {
+      if ((now() - lastmove < speed) || paused)
+      {
+        return;
+      }
       // turn if a turn happens
       if (direction)
       {
@@ -211,7 +266,7 @@ class Snake : public Displayable
       sections.front()->grow();
 
       // see if fruit was eaten
-      if (sections.front()->getx() == 50 || sections.front()->gety() == 50)
+      if (sections.front()->getx() == fruity->getx() && sections.front()->gety() == fruity->gety())
       {
         fruit = 1;
       }
@@ -240,25 +295,60 @@ class Snake : public Displayable
         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.
-		}
-
-    /*
-     * ** 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()
-    {
+      if (sections.size() <= 3) goto SKIP;
+      for (auto each = sections.begin() + 1; each != sections.end(); ++each)
+      {
+        int tempdir = (*each)->getdir();
+        int frontx = sections.front()->getx();
+        int fronty = sections.front()->gety();
+        int eachx = (*each)->getx();
+        int eachy = (*each)->gety();
+        int eachlen = (*each)->getlen();
+
+        switch(tempdir)
+        {
+          case 1:
+            if (frontx == eachx && (fronty >= eachy && fronty <= (eachy + blockSize * eachlen)))
+            {
+              printf("you're shit\n");
+              delete this;
+              exit(0);
+            }
+            break;
+
+          case 2:
+            if ((frontx >= (eachx - eachlen * blockSize) && frontx <= eachx) && fronty == eachy)
+            {
+              printf("you're shit\n");
+              delete this;
+              exit(0);
+            }
+            break;
+
+          case 3:
+            if (frontx == eachx && (fronty <= eachy && fronty >= (eachy - blockSize * eachlen)))
+            {
+              printf("you're shit\n");
+              delete this;
+              exit(0);
+            }
+            break;
+
+          case 4:
+            if ((frontx <= (eachx - eachlen * blockSize) && frontx >= eachx) && fronty == eachy)
+            {
+              printf("you're shit\n");
+              delete this;
+              exit(0);
+            }
+            break;
+        }
+      }
 
-    }
+      SKIP:
+      lastmove = now();
+		}
 
     void moveup()
     {
@@ -280,20 +370,47 @@ class Snake : public Displayable
       if (direction == 1 || direction == 3 || direction == 0) direction = 4;
     }
 
-		Snake(int x, int y, Fruit * fruity): x(x), y(y), fruity(fruity)
+    void changespeed(unsigned long x)
     {
+      speed = 250000 / x;
+    }
+
+    void reset(int fast)
+    {
+      int size = sections.size();
+
+      for (int i = 0; i < size; i++)
+      {
+        delete sections.at(i);
+        sections.erase(sections.begin() + i);
+      }
+
       Section * newsec = new Section(x, y, 2, 2);
       sections.insert(sections.begin(), newsec);
       direction = 0;
       blockSize = 25;
-      speed = 1;
+      speed = 250000 / fast;
+      lastmove = 0;
+    }
+
+		Snake(int x, int y, Fruit * fruity, unsigned long fast): x(x), y(y), fruity(fruity)
+    {
+      Section * newsec = new Section(x, y, 2, 2);
+      sections.insert(sections.begin(), newsec);
+      direction = 0;
+      blockSize = 25;
+      speed = 250000 / fast;
+      lastmove = 0;
 		}
 
     ~Snake()
     {
-      for (auto each = sections.begin(); each != sections.end(); ++each)
+      int size = sections.size();
+
+      for (int i = 0; i < size; i++)
       {
-        delete *(sections.erase(each));
+        delete sections.at(i);
+        sections.erase(sections.begin() + i);
       }
     }
 
@@ -303,14 +420,15 @@ class Snake : public Displayable
     vector<Section *> sections;
 		int blockSize;
 		int direction;
-    int speed;
+    unsigned long speed;
     int fruit;
     Fruit * fruity;
+    unsigned long lastmove;
 };
 
 list<Displayable *> dList;           // list of Displayables
 Fruit fruity;
-Snake snake(100, 450, &fruity);
+Snake snake(100, 450, &fruity, velocity);
 
 /*
  * Initialize X and create a window
@@ -335,6 +453,7 @@ void initX(int argc, char * argv[], XInfo & xInfo)
 	*/
 	xInfo.screen = DefaultScreen(xInfo.display);
 
+  colours = DefaultColormap(xInfo.display, xInfo.screen);
 	white = XWhitePixel(xInfo.display, xInfo.screen);
 	black = XBlackPixel(xInfo.display, xInfo.screen);
 
@@ -366,11 +485,14 @@ void initX(int argc, char * argv[], XInfo & xInfo)
 		&hints
   );			// size hints for the window
 
+  int depth = DefaultDepth(xInfo.display, DefaultScreen(xInfo.display));
+  xInfo.buffer = XCreatePixmap(xInfo.display, xInfo.window, hints.width, hints.height, depth);
 	/*
 	 * Create Graphics Contexts
 	 */
 	int i = 0;
 	xInfo.gc[i] = XCreateGC(xInfo.display, xInfo.window, 0, 0);
+  XSetBackground(xInfo.display, xInfo.gc[0], WhitePixel(xInfo.display, xInfo.screen));
 	XSetFillStyle(xInfo.display, xInfo.gc[i], FillSolid);
 	XSetLineAttributes(xInfo.display, xInfo.gc[i],
 	                     1, LineSolid, CapButt, JoinRound);
@@ -387,6 +509,20 @@ void initX(int argc, char * argv[], XInfo & xInfo)
 	XFlush(xInfo.display);
 }
 
+void splash(XInfo & xinfo)
+{
+  //char * title = {'S', 'n', 'a', 'k', 'e', '\0'};
+  changecolour(xinfo, white);
+  XFillRectangle(xinfo.display, xinfo.buffer, xinfo.gc[0], 100, 100, 600, 400);
+  changecolour(xinfo, black);
+  XFontStruct * font = XLoadQueryFont(xinfo.display, "12x24");
+  XSetFont(xinfo.display, xinfo.gc[0], font->fid);
+  XDrawString(xinfo.display, xinfo.buffer, xinfo.gc[0], 350, 200, "Snake", 5);
+  XDrawString(xinfo.display, xinfo.buffer, xinfo.gc[0], 340, 240, "tsdedhar", 8);
+  XDrawString(xinfo.display, xinfo.buffer, xinfo.gc[0], 340, 280, "20621325", 8);
+  XDrawString(xinfo.display, xinfo.buffer, xinfo.gc[0], 265, 320, "Use arrow keys to turn", 22);
+  XDrawString(xinfo.display, xinfo.buffer, xinfo.gc[0], 200, 360, "Collect fruit to grow your snake", 32);
+}
 /*
  * Function to repaint a display list
  */
@@ -396,10 +532,13 @@ void repaint(XInfo & xinfo)
 	list<Displayable *>::const_iterator end = dList.end();
 
 	// get height and width of window (might have changed since last repaint)
-	XWindowAttributes windowInfo;
+  XWindowAttributes windowInfo;
 	XGetWindowAttributes(xinfo.display, xinfo.window, &windowInfo);
-	unsigned int height = windowInfo.height;
+  unsigned int height = windowInfo.height;
 	unsigned int width = windowInfo.width;
+  changecolour(xinfo, lblue);
+  XFillRectangle(xinfo.display, xinfo.buffer, xinfo.gc[0], 0, 0, width, height);
+  changecolour(xinfo, black);
 
 	// draw display list
 	while (begin != end)
@@ -408,6 +547,8 @@ void repaint(XInfo & xinfo)
 		d->paint(xinfo);
 		begin++;
 	}
+
+  if (starting) splash(xinfo);
 }
 
 void handleKeyPress(XInfo & xinfo, XEvent & event)
@@ -432,6 +573,17 @@ void handleKeyPress(XInfo & xinfo, XEvent & event)
       case 'q':
         error("Terminating normally.");
         break;
+
+      case ' ':
+        paused = !paused;
+        starting = false;
+        break;
+
+      case 'r':
+        snake.reset(velocity);
+        paused = true;
+        starting = true;
+        break;
     }
 	}
 
@@ -458,21 +610,9 @@ void handleKeyPress(XInfo & xinfo, XEvent & event)
 
 void handleAnimation(XInfo & xinfo, int inside)
 {
-    /*
-     * ADD YOUR OWN LOGIC
-     * This method handles animation for different objects on the screen and readies the next frame before the screen is re-painted.
-     */
 	snake.move(xinfo);
 }
 
-// get microseconds
-unsigned long now()
-{
-	timeval tv;
-	gettimeofday(&tv, NULL);
-	return tv.tv_sec * 1000000 + tv.tv_usec;
-}
-
 void eventLoop(XInfo & xinfo)
 {
 	// Add stuff to paint to the display list
@@ -483,10 +623,6 @@ void eventLoop(XInfo & xinfo)
   int inside = 0;
   XWindowAttributes w;
   XGetWindowAttributes(xinfo.display, xinfo.window, &w);
-  int depth = DefaultDepth(xinfo.display, DefaultScreen(xinfo.display));
-  // represents thing to draw
-  Pixmap buffer = XCreatePixmap(xinfo.display, xinfo.window, w.width, w.height, depth);
-  bool usebuffer = 1;
 
   while(1)
   {
@@ -506,37 +642,15 @@ void eventLoop(XInfo & xinfo)
           inside = 0;
           break;
       }
-      usebuffer = !usebuffer;
     }
 
     unsigned long end = now();
 
     if (end - lastRepaint > 1000000 / FPS)
     {
-      Pixmap pixmap; // represents thing in buffer
-
-      if (usebuffer)
-      {
-        pixmap = buffer;
-        XSetForeground(xinfo.display, xinfo.gc[0], BlackPixel(xinfo.display, xinfo.screen));
-        XSetBackground(xinfo.display, xinfo.gc[0], WhitePixel(xinfo.display, xinfo.screen));
-        XFillRectangle(xinfo.display, pixmap, xinfo.gc[0], 0, 0, w.width, w.height);
-      }
-      else
-      {
-        pixmap = xinfo.window; // set this to the windowInfo
-        XClearWindow(xinfo.display, pixmap);
-      }
-
-      XSetForeground(xinfo.display, xinfo.gc[0], BlackPixel(xinfo.display, xinfo.screen));
-      XSetBackground(xinfo.display, xinfo.gc[0], WhitePixel(xinfo.display, xinfo.screen));
       handleAnimation(xinfo, inside);
       repaint(xinfo);
-      if (usebuffer)
-      {
-        XCopyArea(xinfo.display, pixmap, xinfo.window, xinfo.gc[0], 0, 0 , w.width, w.height, 0, 0);
-      }
-
+      XCopyArea(xinfo.display, xinfo.buffer, xinfo.window, xinfo.gc[0], 0, 0 , w.width, w.height, 0, 0);
       XFlush(xinfo.display);
       lastRepaint = now();
     }
@@ -557,8 +671,22 @@ void eventLoop(XInfo & xinfo)
  */
 int main (int argc, char * argv[])
 {
-	XInfo xInfo;
+  if (argc == 1)
+  {
+  }
+  else if (argc == 3)
+  {
+    FPS = atoi(argv[1]);
+    velocity = atoi(argv[2]);
+  }
+  else
+  {
+    printf("you're shit\n");
+    exit(0);
+  }
 
+  snake.changespeed(velocity);
+	XInfo xInfo;
 	initX(argc, argv, xInfo);
 	eventLoop(xInfo);
 	XCloseDisplay(xInfo.display);