Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <conio.h>
- #include <time.h>
- #include <windows.h>
- void setCursorXY(int x, int y) {
- COORD point = {x, y};
- SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), point);
- }
- class Map {
- char ** data;
- int width, height;
- static char ** createMap(int w, int h) {
- char ** m = new char *[h];
- for(int y = 0; y < h; ++y)
- m[y] = new char [w];
- return m;
- }
- static void releaseMap(char ** m, const int width, const int height) {
- for(int y = 0; y < height; ++y)
- delete [] m[y];
- delete [] m;
- }
- public:
- const bool loadFile(const char * const filename) {
- std::ifstream file;
- file.open(filename);
- if(!file.is_open())
- return false;
- file >> width >> height;
- data = createMap(width, height);
- int c, row = 0, col = 0;
- do {
- c = file.get();
- if(c != EOF && c != '\n' && c != '\r') {
- data[row][col] = c;
- col++;
- if(col >= width) {
- col = 0;
- row++;
- if(row >= height)
- break;
- }
- }
- }while(c != EOF);
- file.close();
- return true;
- }
- void print() const {
- for(int y = 0; y < height; ++y) {
- for(int x = 0; x < width; ++x) {
- std::cout << data[y][x];
- }
- std::cout << std::endl;
- }
- }
- /**
- * @param x, y the coordinate of the upper left character
- * @param transparent a character that will not be printed
- */
- void draw(int x, int y, char transparent) const {
- for(int row = 0; row < height; ++row)
- {
- for(int col = 0; col < width; ++col)
- {
- setCursorXY(x+col, y+row);
- if(data[row][col] != transparent)
- std::cout << data[row][col];
- }
- }
- }
- /** @param x, y the coordinate of the upper left character */
- void draw(int x, int y) const {
- draw(x,y,' '); // borders on the edge of YAGNI
- }
- Map():data(0),height(-1),width(-1){}
- ~Map() {
- for(int y = 0; y < height; ++y)
- delete [] data[y];
- delete [] data;
- }
- char get(int x, int y) const { return data[y][x]; }
- char & getRef(int x, int y) { return data[y][x]; }
- void set(int x, int y, char c) { data[y][x] = c; }
- void drawFlippedH(int x, int y) const {
- for(int row = 0; row < height; ++row) {
- for(int col = 0; col < width; ++col) {
- setCursorXY(x+col, y+row);
- std::cout << data[row][width-1-col];
- }
- }
- }
- void drawFlippedV(int x, int y) const {
- for(int row = 0; row < height; ++row) {
- for(int col = 0; col < width; ++col) {
- setCursorXY(x+col, y+row);
- std::cout << data[height-1-row][col];
- }
- }
- }
- void drawFlippedXY(int x, int y) const {
- for(int row = 0; row < width; ++row) {
- for(int col = 0; col < height; ++col) {
- setCursorXY(x+col, y+row);
- std::cout << data[col][row];
- }
- }
- }
- void drawRotatedCW(int x, int y) const {
- for(int row = 0; row < width; ++row) {
- for(int col = 0; col < height; ++col) {
- setCursorXY(x+col, y+row);
- std::cout << data[height-1-col][row];
- }
- }
- }
- void drawRotatedCCW(int x, int y) const {
- for(int row = 0; row < width; ++row) {
- for(int col = 0; col < height; ++col) {
- setCursorXY(x+col, y+row);
- std::cout << data[col][width-1-row];
- }
- }
- }
- void flipH(){
- char ** m = createMap(width, height);
- for(int row = 0; row < height; ++row) {
- for(int col = 0; col < width; ++col) {
- m[row][col] = data[row][width-1-col];
- }
- }
- releaseMap(data, width, height);
- data = m;
- }
- void flipV(){
- char ** m = createMap(width, height);
- for(int row = 0; row < height; ++row) {
- for(int col = 0; col < width; ++col) {
- m[row][col] = data[height-1-row][col];
- }
- }
- releaseMap(data, width, height);
- data = m;
- }
- void flipXY(){
- char ** m = createMap(height, width);
- for(int row = 0; row < width; ++row) {
- for(int col = 0; col < height; ++col) {
- m[row][col] = data[col][row];
- }
- }
- releaseMap(data, width, height);
- int temp = width; width = height; height = temp;
- data = m;
- }
- void rotateCW(){ flipXY(); flipH(); }
- void rotateCCW(){ flipXY(); flipV(); }
- int getWidth() const {return width;}
- int getHeight() const {return height;}
- };
- class Vector2D {
- public:
- int x, y;
- Vector2D():x(0),y(0){}
- Vector2D(int x, int y):x(x),y(y){}
- };
- class Rect {
- public:
- Vector2D pmin, pmax;
- Rect(Vector2D a_min, Vector2D a_max):pmin(a_min),pmax(a_max){}
- bool isWithin(Rect const & larger) const {
- return pmin.x >= larger.pmin.x
- && pmin.y >= larger.pmin.y
- && pmax.x <= larger.pmax.x
- && pmax.y <= larger.pmax.y;
- }
- };
- struct Piece
- {
- public:
- Map m;
- Vector2D loc;
- Piece(char * filename) {
- m.loadFile(filename);
- }
- /** calls the Map draw using the loc argument for it's location */
- void draw() {m.draw(loc.x,loc.y);}
- int getWidth(){return m.getWidth();}
- int getHeight(){return m.getHeight();}
- /**
- * does not take into account:
- * - p might be bigger than this
- * - this might be in a non-(0,0) location.
- * @param p which piece is colliding with this (must be smaller)
- * @param myCollidingChar, hisCollidingChar what counts as a collision?
- * example: board.isCollidingWith(p, 'a', '*');
- */
- bool isCollidingWith(Piece & p, char myCollidingChar, char hisCollidingChar)
- {
- for(int row = 0; row < p.m.getHeight(); ++row)
- {
- for(int col = 0; col < p.m.getWidth(); ++col)
- {
- if(m.get(col+p.loc.x, row+p.loc.y) == myCollidingChar
- && p.m.get(col, row) == hisCollidingChar)
- {
- return true;
- }
- }
- }
- return false;
- }
- };
- struct Game
- {
- Piece a, b;
- bool running;
- int input;
- char transparent;
- Game():a("a.txt"),b("b.txt"),running(true)
- {
- // a.Piece::Piece("a.txt");
- // b.Piece::Piece("b.txt");
- // running = true;
- transparent = ' ';
- }
- void drawingCode() {
- a.draw(); b.draw();
- }
- void imprint()
- {
- for(int row = 0; row < b.getHeight(); ++row)
- {
- for(int col = 0; col < b.getWidth(); ++col)
- {
- if(b.m.get(col,row) != transparent)
- {
- a.m.set(b.loc.x+col, b.loc.y+row, b.m.get(col, row));
- }
- }
- }
- }
- void update() {
- Vector2D old = b.loc;
- const int NONE = 0, MOVE = 1, ROT_CW = 2, ROT_CCW = 3;
- int moveType = NONE;
- switch(input) {
- case 'w': b.loc.y--; moveType = MOVE; break;
- case 'a': b.loc.x--; moveType = MOVE; break;
- case 's': b.loc.y++; moveType = MOVE; break;
- case 'd': b.loc.x++; moveType = MOVE; break;
- case 'q': b.m.rotateCCW(); moveType = ROT_CCW; break;
- case 'e': b.m.rotateCW(); moveType = ROT_CW; break;
- case 27: running = false; break;
- case ' ':
- if(!a.isCollidingWith(b, '*', '*'))
- imprint();
- break;
- }
- Rect board(a.loc, Vector2D(a.loc.x+a.getWidth(), a.loc.y+a.getHeight()));
- Rect movingPiece(b.loc, Vector2D(b.loc.x+b.getWidth(), b.loc.y+b.getHeight()));
- setCursorXY(0, 20);
- if(!movingPiece.isWithin(board)
- || a.isCollidingWith(b, 'a', '*')) {
- std::cout << "OUTSIDE" << std::endl;
- switch(moveType){
- case MOVE: b.loc = old; break;
- case ROT_CW: b.m.rotateCCW(); break;
- case ROT_CCW: b.m.rotateCW(); break;
- }
- } else
- std::cout << " " << std::endl;
- }
- void getInput()
- {
- // throttle code, stalls the program to a
- // 1/10th second frame rate, or till a key is pressed
- long now = clock(), soon = now + 100;
- while(clock() < soon && !_kbhit())
- {
- Sleep(1);
- }
- // only gets input if there is keyboard input to get
- if(_kbhit())
- input = _getch();
- else
- input = 0;
- }
- };
- int main(int argc, char * argv[]) {
- Game g;
- while(g.running) {
- g.drawingCode(); // render
- g.getInput(); // input
- g.update(); // update
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement