daily pastebin goal
24%
SHARE
TWEET

GSP420 block puzzle primer

mvaganov Sep 11th, 2013 140 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <fstream>
  3. #include <conio.h>
  4. #include <time.h>
  5. #include <windows.h>
  6. void setCursorXY(int x, int y) {
  7.         COORD point = {x, y};
  8.         SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), point);
  9. }
  10.  
  11. class Map {
  12.         char ** data;
  13.         int width, height;
  14.         static char ** createMap(int w, int h) {
  15.                 char ** m = new char *[h];
  16.                 for(int y = 0; y < h; ++y)
  17.                         m[y] = new char [w];
  18.                 return m;
  19.         }
  20.         static void releaseMap(char ** m, const int width, const int height) {
  21.                 for(int y = 0; y < height; ++y)
  22.                         delete [] m[y];
  23.                 delete [] m;
  24.         }
  25. public:
  26.         const bool loadFile(const char * const filename) {
  27.                 std::ifstream file;
  28.                 file.open(filename);
  29.                 if(!file.is_open())
  30.                         return false;
  31.                 file >> width >> height;
  32.                 data = createMap(width, height);
  33.                 int c, row = 0, col = 0;
  34.                 do {
  35.                         c = file.get();
  36.                         if(c != EOF && c != '\n' && c != '\r') {
  37.                                 data[row][col] = c;
  38.                                 col++;
  39.                                 if(col >= width) {
  40.                                         col = 0;
  41.                                         row++;
  42.                                         if(row >= height)
  43.                                                 break;
  44.                                 }
  45.                         }
  46.                 }while(c != EOF);
  47.                 file.close();
  48.                 return true;
  49.         }
  50.         void print() const {
  51.                 for(int y = 0; y < height; ++y) {
  52.                         for(int x = 0; x < width; ++x) {
  53.                                 std::cout << data[y][x];
  54.                         }
  55.                         std::cout << std::endl;
  56.                 }
  57.         }
  58.         /**
  59.          * @param x, y the coordinate of the upper left character
  60.          * @param transparent a character that will not be printed
  61.          */
  62.         void draw(int x, int y, char transparent) const {
  63.                 for(int row = 0; row < height; ++row)
  64.                 {
  65.                         for(int col = 0; col < width; ++col)
  66.                         {
  67.                                 setCursorXY(x+col, y+row);
  68.                                 if(data[row][col] != transparent)
  69.                                         std::cout << data[row][col];
  70.                         }
  71.                 }
  72.         }
  73.         /** @param x, y the coordinate of the upper left character */
  74.         void draw(int x, int y) const {
  75.                 draw(x,y,' ');  // borders on the edge of YAGNI
  76.         }
  77.         Map():data(0),height(-1),width(-1){}
  78.         ~Map() {
  79.                 for(int y = 0; y < height; ++y)
  80.                         delete [] data[y];
  81.                 delete [] data;
  82.         }
  83.         char get(int x, int y) const { return data[y][x]; }
  84.         char & getRef(int x, int y) { return data[y][x]; }
  85.         void set(int x, int y, char c) { data[y][x] = c; }
  86.         void drawFlippedH(int x, int y) const {
  87.                 for(int row = 0; row < height; ++row) {
  88.                         for(int col = 0; col < width; ++col) {
  89.                                 setCursorXY(x+col, y+row);
  90.                                 std::cout << data[row][width-1-col];
  91.                         }
  92.                 }
  93.         }
  94.         void drawFlippedV(int x, int y) const {
  95.                 for(int row = 0; row < height; ++row) {
  96.                         for(int col = 0; col < width; ++col) {
  97.                                 setCursorXY(x+col, y+row);
  98.                                 std::cout << data[height-1-row][col];
  99.                         }
  100.                 }
  101.         }
  102.         void drawFlippedXY(int x, int y) const {
  103.                 for(int row = 0; row < width; ++row) {
  104.                         for(int col = 0; col < height; ++col) {
  105.                                 setCursorXY(x+col, y+row);
  106.                                 std::cout << data[col][row];
  107.                         }
  108.                 }
  109.         }
  110.         void drawRotatedCW(int x, int y) const {
  111.                 for(int row = 0; row < width; ++row) {
  112.                         for(int col = 0; col < height; ++col) {
  113.                                 setCursorXY(x+col, y+row);
  114.                                 std::cout << data[height-1-col][row];
  115.                         }
  116.                 }
  117.         }
  118.         void drawRotatedCCW(int x, int y) const {
  119.                 for(int row = 0; row < width; ++row) {
  120.                         for(int col = 0; col < height; ++col) {
  121.                                 setCursorXY(x+col, y+row);
  122.                                 std::cout << data[col][width-1-row];
  123.                         }
  124.                 }
  125.         }
  126.         void flipH(){
  127.                 char ** m = createMap(width, height);
  128.                 for(int row = 0; row < height; ++row) {
  129.                         for(int col = 0; col < width; ++col) {
  130.                                 m[row][col] = data[row][width-1-col];
  131.                         }
  132.                 }
  133.                 releaseMap(data, width, height);
  134.                 data = m;
  135.         }
  136.         void flipV(){
  137.                 char ** m = createMap(width, height);
  138.                 for(int row = 0; row < height; ++row) {
  139.                         for(int col = 0; col < width; ++col) {
  140.                                 m[row][col] = data[height-1-row][col];
  141.                         }
  142.                 }
  143.                 releaseMap(data, width, height);
  144.                 data = m;
  145.         }
  146.         void flipXY(){
  147.                 char ** m = createMap(height, width);
  148.                 for(int row = 0; row < width; ++row) {
  149.                         for(int col = 0; col < height; ++col) {
  150.                                 m[row][col] = data[col][row];
  151.                         }
  152.                 }
  153.                 releaseMap(data, width, height);
  154.                 int temp = width;       width = height; height = temp;
  155.                 data = m;
  156.         }
  157.         void rotateCW(){        flipXY();       flipH();        }
  158.         void rotateCCW(){       flipXY();       flipV();        }
  159.         int getWidth() const {return width;}
  160.         int getHeight() const {return height;}
  161. };
  162. class Vector2D {
  163. public:
  164.         int x, y;
  165.         Vector2D():x(0),y(0){}
  166.         Vector2D(int x, int y):x(x),y(y){}
  167. };
  168. class Rect {
  169. public:
  170.         Vector2D pmin, pmax;
  171.         Rect(Vector2D a_min, Vector2D a_max):pmin(a_min),pmax(a_max){}
  172.         bool isWithin(Rect const & larger) const {
  173.                 return pmin.x >= larger.pmin.x
  174.                         && pmin.y >= larger.pmin.y
  175.                         && pmax.x <= larger.pmax.x
  176.                         && pmax.y <= larger.pmax.y;
  177.         }
  178. };
  179. struct Piece
  180. {
  181. public:
  182.         Map m;
  183.         Vector2D loc;
  184.         Piece(char * filename) {
  185.                 m.loadFile(filename);
  186.         }
  187.         /** calls the Map draw using the loc argument for it's location */
  188.         void draw() {m.draw(loc.x,loc.y);}
  189.         int getWidth(){return m.getWidth();}
  190.         int getHeight(){return m.getHeight();}
  191.         /**
  192.          * does not take into account:
  193.          * - p might be bigger than this
  194.          * - this might be in a non-(0,0) location.
  195.          * @param p which piece is colliding with this (must be smaller)
  196.          * @param myCollidingChar, hisCollidingChar what counts as a collision?
  197.          * example: board.isCollidingWith(p, 'a', '*');
  198.          */
  199.         bool isCollidingWith(Piece & p, char myCollidingChar, char hisCollidingChar)
  200.         {
  201.                 for(int row = 0; row < p.m.getHeight(); ++row)
  202.                 {
  203.                         for(int col = 0; col < p.m.getWidth(); ++col)
  204.                         {
  205.                                 if(m.get(col+p.loc.x, row+p.loc.y) == myCollidingChar
  206.                                 && p.m.get(col, row) == hisCollidingChar)
  207.                                 {
  208.                                         return true;
  209.                                 }
  210.                         }
  211.                 }
  212.                 return false;
  213.         }
  214. };
  215. struct Game
  216. {
  217.         Piece a, b;
  218.         bool running;
  219.         int input;
  220.         char transparent;
  221.         Game():a("a.txt"),b("b.txt"),running(true)
  222.         {
  223. //              a.Piece::Piece("a.txt");
  224. //              b.Piece::Piece("b.txt");
  225. //              running = true;
  226.                 transparent = ' ';
  227.         }
  228.         void drawingCode() {
  229.                 a.draw();       b.draw();
  230.         }
  231.         void imprint()
  232.         {
  233.                 for(int row = 0; row < b.getHeight(); ++row)
  234.                 {
  235.                         for(int col = 0; col < b.getWidth(); ++col)
  236.                         {
  237.                                 if(b.m.get(col,row) != transparent)
  238.                                 {
  239.                                         a.m.set(b.loc.x+col, b.loc.y+row, b.m.get(col, row));
  240.                                 }
  241.                         }
  242.                 }
  243.         }
  244.         void update() {
  245.                 Vector2D old = b.loc;
  246.                 const int NONE = 0, MOVE = 1, ROT_CW = 2, ROT_CCW = 3;
  247.                 int moveType = NONE;
  248.                 switch(input) {
  249.                 case 'w':       b.loc.y--;                      moveType = MOVE;        break;
  250.                 case 'a':       b.loc.x--;                      moveType = MOVE;        break;
  251.                 case 's':       b.loc.y++;                      moveType = MOVE;        break;
  252.                 case 'd':       b.loc.x++;                      moveType = MOVE;        break;
  253.                 case 'q':       b.m.rotateCCW();        moveType = ROT_CCW;     break;
  254.                 case 'e':       b.m.rotateCW();         moveType = ROT_CW;      break;
  255.                 case 27:        running = false;        break;
  256.                 case ' ':      
  257.                         if(!a.isCollidingWith(b, '*', '*'))
  258.                                 imprint();
  259.                         break;
  260.                 }
  261.                 Rect board(a.loc, Vector2D(a.loc.x+a.getWidth(), a.loc.y+a.getHeight()));
  262.                 Rect movingPiece(b.loc, Vector2D(b.loc.x+b.getWidth(), b.loc.y+b.getHeight()));
  263.                 setCursorXY(0, 20);
  264.                 if(!movingPiece.isWithin(board)
  265.                 || a.isCollidingWith(b, 'a', '*')) {
  266.                         std::cout << "OUTSIDE" << std::endl;
  267.                         switch(moveType){
  268.                         case MOVE:              b.loc = old;            break;
  269.                         case ROT_CW:    b.m.rotateCCW();        break;
  270.                         case ROT_CCW:   b.m.rotateCW();         break;
  271.                         }
  272.                 } else
  273.                         std::cout << "       " << std::endl;
  274.         }
  275.         void getInput()
  276.         {
  277.                 // throttle code, stalls the program to a
  278.                 // 1/10th second frame rate, or till a key is pressed
  279.                 long now = clock(), soon = now + 100;
  280.                 while(clock() < soon && !_kbhit())
  281.                 {
  282.                         Sleep(1);
  283.                 }
  284.                 // only gets input if there is keyboard input to get
  285.                 if(_kbhit())
  286.                         input = _getch();
  287.                 else
  288.                         input = 0;
  289.         }
  290. };
  291.  
  292. int main(int argc, char * argv[]) {
  293.         Game g;
  294.         while(g.running) {
  295.                 g.drawingCode();        // render
  296.                 g.getInput();           // input
  297.                 g.update();                     // update
  298.         }
  299.         return 0;
  300. }
RAW Paste Data
Top