diff --git a/Tetris.cbp b/Tetris.cbp new file mode 100644 index 0000000..1f1f50b --- /dev/null +++ b/Tetris.cbp @@ -0,0 +1,56 @@ + + + + + + diff --git a/Tetris.depend b/Tetris.depend new file mode 100644 index 0000000..7835609 --- /dev/null +++ b/Tetris.depend @@ -0,0 +1,36 @@ +# depslib dependency file v1.0 +1409361558 source:f:\dropbox\documents\source code\tetris\main.cpp + "piece.h" + "board.h" + "graphics.h" + + + + + + +1384017582 f:\dropbox\documents\source code\tetris\piece.h + +1384017615 f:\dropbox\documents\source code\tetris\board.h + "piece.h" + +1409360597 f:\dropbox\documents\source code\tetris\graphics.h + + + + +1409360954 source:f:\dropbox\documents\source code\tetris\piece.cpp + "graphics.h" + + + + "piece.h" + +1410040619 source:f:\dropbox\documents\source code\tetris\board.cpp + "graphics.h" + + + + + "board.h" + diff --git a/bin/Debug/Tetris.exe b/bin/Debug/Tetris.exe new file mode 100644 index 0000000..42f6207 Binary files /dev/null and b/bin/Debug/Tetris.exe differ diff --git a/board.cpp b/board.cpp new file mode 100644 index 0000000..7bcecf9 --- /dev/null +++ b/board.cpp @@ -0,0 +1,155 @@ +#include "graphics.h" +#include +#include +#include +#include +#include "board.h" + +using namespace std; + +Board::Board() { + int i, j; + for (i = 0; i < 24; i++) { + widths[i] = 0; + for (j = 0; j < 10; j++) { + grid[i][j] = 0; + } + } + for (i = 0; i < 10; i++) { + heights[i] = 0; + } + score = 0; + offset = Point ( (getmaxx() - 10 * Piece::side) / 2, + (getmaxy() - 24 * Piece::side) / 2); + backup(); +} + +void Board::backup() { + int i, j; + for (i = 0; i < 24; i++) + for (j = 0; j < 10; j++) { + xgrid[i][j] = grid[i][j]; + } + for (i = 0; i < 10; i++) { + xheights[i] = heights[i]; + } + for (j = 0; j < 24; j++) { + xwidths[j] = widths[j]; + } +} + +void Board::undo() { + int i, j; + for (i = 0; i < 24; i++) + for (j = 0; j < 10; j++) { + grid[i][j] = xgrid[i][j]; + } + for (i = 0; i < 10; i++) { + heights[i] = xheights[i]; + } + for (j = 0; j < 24; j++) { + widths[j] = xwidths[j]; + } +} + +int Board::drop (Piece p, Point pos) { + while (place (p, pos) != PLACE_BAD) { + undo(); + pos.y--; + } + undo(); + return pos.y + 1; +} + +int Board::place (Piece p, Point loc) { + Point pos; + int i, j; + if (loc.x < 0 || loc.x + p.getWidth() > 10) { + return PLACE_OUT_BOUNDS; + } + if (loc.y < 0) { + return PLACE_BAD; + } + for (i = 0; i < 4; i++) { + pos = p.getBody (i); + pos.x += loc.x; + pos.y += loc.y; + if (grid[pos.y][pos.x]) { + return PLACE_BAD; + } else { + grid[pos.y][pos.x] = p.getColor(); + } + } + for (i = 0; i < 4; i++) { + widths[loc.y + p.getBody (i).y]++; + } + for (i = loc.y; i < loc.y + p.getHeight(); i++) + if (widths[i] == 10) { + return PLACE_ROW_FILLED; + } + for (i = 0; i < 4; i++) + if (heights[loc.x + p.getBody (i).x] < loc.y + p.getBody (i).y + 1) { + heights[loc.x + p.getBody (i).x] = loc.y + p.getBody (i).y + 1; + } + for (i = 0; i < 4; i++) + if (heights[p.getBody (i).x + loc.x] >= 19) { + return PLACE_FULL; + } + return PLACE_OK; +} + +void Board::clearRows() { + int i, j, k; + for (i = 0; i < 23; i++) { + if (widths[i] == 10) { + for (j = i; j < 23 && widths[j]; j++) { + for (k = 0; k < 10; k++) { + grid[j][k] = grid[j + 1][k]; + } + widths[j] = widths[j + 1]; + } + i--; + } + } + for (i = 0; i < 10; i++) { + for (j = 23; j >= 0 && !grid[j][i]; j--); + heights[i] = j + 1; + } +} + +void Board::display() { + int i, j, maxy = getmaxy(); + char sc[10]; + //itoa (score, sc, 10); + settextstyle (TRIPLEX_FONT, HORIZ_DIR, 3); + setfillstyle (SOLID_FILL, BLACK); + bar (10, 10, 5 * textwidth (sc), 1.8 * textheight (sc) ); + outtextxy (10, 10, sc); + for (i = 0; i < 11; i++) + line ( offset.x + Piece::side * ( (float) (i) - 0.5), + maxy - offset.y - Piece::side * ( (float) (24) - 0.5), + offset.x + Piece::side * ( (float) (i) - 0.5), + maxy - offset.y + Piece::side * (0.5) ); + for (j = 0; j < 25; j++) + line ( offset.x + Piece::side * (-0.5), + maxy - offset.y - Piece::side * ( (float) (j) - 0.5), + offset.x + Piece::side * ( (float) (10) - 0.5), + maxy - offset.y - Piece::side * ( (float) (j) - 0.5) ); + for (j = 0; j < 24; j++) { + for (i = 0; i < 10; i++) { + if (grid[j][i]) { + setfillstyle (SOLID_FILL, grid[j][i]); + floodfill (offset.x + Piece::side * i, maxy - offset.y - Piece::side * j, + WHITE); + } else if (j == xheights[i]) { + setfillstyle (SLASH_FILL, DARKGRAY); + floodfill (offset.x + Piece::side * i, maxy - offset.y - Piece::side * j, + WHITE); + } else { + setfillstyle (SOLID_FILL, BLACK); + floodfill (offset.x + Piece::side * i, maxy - offset.y - Piece::side * j, + WHITE); + } + } + } +} diff --git a/board.h b/board.h new file mode 100644 index 0000000..8a9d931 --- /dev/null +++ b/board.h @@ -0,0 +1,28 @@ +#ifndef BOARD_H +#define BOARD_H +#include "piece.h" + +enum {PLACE_OK=0, PLACE_OUT_BOUNDS, PLACE_ROW_FILLED, PLACE_OVERLAP, PLACE_FULL, PLACE_BAD}; + +class Board{ +private: + int grid[24][10]; + int xgrid[24][10]; + int widths[24]; + int xwidths[24]; + int heights[10]; + int xheights[10]; + int score; + Point offset; +public: + Board(); + int place(Piece p, Point loc); + int drop(Piece p, Point pos); + void display(); + void backup(); + void undo(); + void clearRows(); + void scored() {score+=100;} +}; + +#endif \ No newline at end of file diff --git a/graphics.h b/graphics.h new file mode 100644 index 0000000..bbccd4a --- /dev/null +++ b/graphics.h @@ -0,0 +1,366 @@ +// The winbgim library, Version 6.0, August 9, 2004 +// Written by: +// Grant Macklem (Grant.Macklem@colorado.edu) +// Gregory Schmelter (Gregory.Schmelter@colorado.edu) +// Alan Schmidt (Alan.Schmidt@colorado.edu) +// Ivan Stashak (Ivan.Stashak@colorado.edu) +// Michael Main (Michael.Main@colorado.edu) +// CSCI 4830/7818: API Programming +// University of Colorado at Boulder, Spring 2003 + + +// --------------------------------------------------------------------------- +// Notes +// --------------------------------------------------------------------------- +// * This library is still under development. +// * Please see http://www.cs.colorado.edu/~main/bgi for information on +// * using this library with the mingw32 g++ compiler. +// * This library only works with Windows API level 4.0 and higher (Windows 95, NT 4.0 and newer) +// * This library may not be compatible with 64-bit versions of Windows +// --------------------------------------------------------------------------- + + +// --------------------------------------------------------------------------- +// Macro Guard and Include Directives +// --------------------------------------------------------------------------- +#ifndef WINBGI_H +#define WINBGI_H +#include // Provides the mouse message types +#include // Provides INT_MAX +#include // Provides std::ostringstream +// --------------------------------------------------------------------------- + + + +// --------------------------------------------------------------------------- +// Definitions +// --------------------------------------------------------------------------- +// Definitions for the key pad extended keys are added here. When one +// of these keys are pressed, getch will return a zero followed by one +// of these values. This is the same way that it works in conio for +// dos applications. +#define KEY_HOME 71 +#define KEY_UP 72 +#define KEY_PGUP 73 +#define KEY_LEFT 75 +#define KEY_CENTER 76 +#define KEY_RIGHT 77 +#define KEY_END 79 +#define KEY_DOWN 80 +#define KEY_PGDN 81 +#define KEY_INSERT 82 +#define KEY_DELETE 83 +#define KEY_F1 59 +#define KEY_F2 60 +#define KEY_F3 61 +#define KEY_F4 62 +#define KEY_F5 63 +#define KEY_F6 64 +#define KEY_F7 65 +#define KEY_F8 66 +#define KEY_F9 67 + +// Line thickness settings +#define NORM_WIDTH 1 +#define THICK_WIDTH 3 + +// Character Size and Direction +#define USER_CHAR_SIZE 0 +#define HORIZ_DIR 0 +#define VERT_DIR 1 + + +// Constants for closegraph +#define CURRENT_WINDOW -1 +#define ALL_WINDOWS -2 +#define NO_CURRENT_WINDOW -3 + +// The standard Borland 16 colors +#define MAXCOLORS 15 +enum colors { BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHTGRAY, DARKGRAY, + LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE + }; + +// The standard line styles +enum line_styles { SOLID_LINE, DOTTED_LINE, CENTER_LINE, DASHED_LINE, USERBIT_LINE }; + +// The standard fill styles +enum fill_styles { EMPTY_FILL, SOLID_FILL, LINE_FILL, LTSLASH_FILL, SLASH_FILL, + BKSLASH_FILL, LTBKSLASH_FILL, HATCH_FILL, XHATCH_FILL, INTERLEAVE_FILL, + WIDE_DOT_FILL, CLOSE_DOT_FILL, USER_FILL + }; + +// The various graphics drivers +enum graphics_drivers { DETECT, CGA, MCGA, EGA, EGA64, EGAMONO, IBM8514, HERCMONO, + ATT400, VGA, PC3270 + }; + +// Various modes for each graphics driver +enum graphics_modes { CGAC0, CGAC1, CGAC2, CGAC3, CGAHI, + MCGAC0 = 0, MCGAC1, MCGAC2, MCGAC3, MCGAMED, MCGAHI, + EGALO = 0, EGAHI, + EGA64LO = 0, EGA64HI, + EGAMONOHI = 3, + HERCMONOHI = 0, + ATT400C0 = 0, ATT400C1, ATT400C2, ATT400C3, ATT400MED, ATT400HI, + VGALO = 0, VGAMED, VGAHI, + PC3270HI = 0, + IBM8514LO = 0, IBM8514HI + }; + +// Borland error messages for the graphics window. +#define NO_CLICK -1 // No mouse event of the current type in getmouseclick +enum graph_errors { grInvalidVersion = -18, grInvalidDeviceNum = -15, grInvalidFontNum, + grInvalidFont, grIOerror, grError, grInvalidMode, grNoFontMem, + grFontNotFound, grNoFloodMem, grNoScanMem, grNoLoadMem, + grInvalidDriver, grFileNotFound, grNotDetected, grNoInitGraph, + grOk + }; + +// Write modes +enum putimage_ops { COPY_PUT, XOR_PUT, OR_PUT, AND_PUT, NOT_PUT }; + +// Text Modes +enum horiz { LEFT_TEXT, CENTER_TEXT, RIGHT_TEXT }; +enum vertical { BOTTOM_TEXT, VCENTER_TEXT, TOP_TEXT }; // middle not needed other than as seperator +enum font_names { DEFAULT_FONT, TRIPLEX_FONT, SMALL_FONT, SANS_SERIF_FONT, + GOTHIC_FONT, SCRIPT_FONT, SIMPLEX_FONT, TRIPLEX_SCR_FONT, + COMPLEX_FONT, EUROPEAN_FONT, BOLD_FONT + }; +// --------------------------------------------------------------------------- + + + +// --------------------------------------------------------------------------- +// Structures +// --------------------------------------------------------------------------- +// This structure records information about the last call to arc. It is used +// by getarccoords to get the location of the endpoints of the arc. +struct arccoordstype { + int x, y; // Center point of the arc + int xstart, ystart; // The starting position of the arc + int xend, yend; // The ending position of the arc. +}; + + +// This structure defines the fill style for the current window. Pattern is +// one of the system patterns such as SOLID_FILL. Color is the color to +// fill with +struct fillsettingstype { + int pattern; // Current fill pattern + int color; // Current fill color +}; + + +// This structure records information about the current line style. +// linestyle is one of the line styles such as SOLID_LINE, upattern is a +// 16-bit pattern for user defined lines, and thickness is the width of the +// line in pixels. +struct linesettingstype { + int linestyle; // Current line style + unsigned upattern; // 16-bit user line pattern + int thickness; // Width of the line in pixels +}; + + +// This structure records information about the text settings. +struct textsettingstype { + int font; // The font in use + int direction; // Text direction + int charsize; // Character size + int horiz; // Horizontal text justification + int vert; // Vertical text justification +}; + + +// This structure records information about the viewport +struct viewporttype { + int left, top, // Viewport bounding box + right, bottom; + int clip; // Whether to clip image to viewport +}; + + +// This structure records information about the palette. +struct palettetype { + unsigned char size; + signed char colors[MAXCOLORS + 1]; +}; +// --------------------------------------------------------------------------- + + + +// --------------------------------------------------------------------------- +// API Entries +// --------------------------------------------------------------------------- +#ifdef __cplusplus +extern "C" { +#endif + +// Drawing Functions +void arc ( int x, int y, int stangle, int endangle, int radius ); +void bar ( int left, int top, int right, int bottom ); +void bar3d ( int left, int top, int right, int bottom, int depth, int topflag ); +void circle ( int x, int y, int radius ); +void cleardevice( ); +void clearviewport( ); +void drawpoly (int n_points, int *points); +void ellipse ( int x, int y, int stangle, int endangle, int xradius, + int yradius ); +void fillellipse ( int x, int y, int xradius, int yradius ); +void fillpoly (int n_points, int *points); +void floodfill ( int x, int y, int border ); +void line ( int x1, int y1, int x2, int y2 ); +void linerel ( int dx, int dy ); +void lineto ( int x, int y ); +void pieslice ( int x, int y, int stangle, int endangle, int radius ); +void putpixel ( int x, int y, int color ); +void rectangle ( int left, int top, int right, int bottom ); +void sector ( int x, int y, int stangle, int endangle, int xradius, + int yradius ); + +// Miscellaneous Functions +int getdisplaycolor ( int color ); +int converttorgb ( int color ); +void delay ( int msec ); +void getarccoords ( arccoordstype *arccoords ); +int getbkcolor( ); +int getcolor( ); +void getfillpattern ( char *pattern ); +void getfillsettings ( fillsettingstype *fillinfo ); +void getlinesettings ( linesettingstype *lineinfo ); +int getmaxcolor( ); +int getmaxheight( ); +int getmaxwidth( ); +int getmaxx( ); +int getmaxy( ); +bool getrefreshingbgi( ); +int getwindowheight( ); +int getwindowwidth( ); +int getpixel ( int x, int y ); +void getviewsettings ( viewporttype *viewport ); +int getx( ); +int gety( ); +void moverel ( int dx, int dy ); +void moveto ( int x, int y ); +void refreshbgi (int left, int top, int right, int bottom); +void refreshallbgi( ); +void setbkcolor ( int color ); +void setcolor ( int color ); +void setfillpattern ( char *upattern, int color ); +void setfillstyle ( int pattern, int color ); +void setlinestyle ( int linestyle, unsigned upattern, int thickness ); +void setrefreshingbgi (bool value); +void setviewport ( int left, int top, int right, int bottom, int clip ); +void setwritemode ( int mode ); + +// Window Creation / Graphics Manipulation +void closegraph ( int wid = ALL_WINDOWS ); +void detectgraph ( int *graphdriver, int *graphmode ); +void getaspectratio ( int *xasp, int *yasp ); +char *getdrivername( ); +int getgraphmode( ); +int getmaxmode( ); +char *getmodename ( int mode_number ); +void getmoderange ( int graphdriver, int *lomode, int *himode ); +void graphdefaults( ); +char *grapherrormsg ( int errorcode ); +int graphresult( ); +void initgraph ( int *graphdriver, int *graphmode, char *pathtodriver ); +int initwindow +( int width, int height, const char *title = "Windows BGI", int left = 0, + int top = 0, bool dbflag = false, bool closeflag = true ); +int installuserdriver ( char *name, int *fp ); // Not available in WinBGI +int installuserfont ( char *name ); // Not available in WinBGI +int registerbgidriver ( void *driver ); // Not available in WinBGI +int registerbgifont ( void *font ); // Not available in WinBGI +void restorecrtmode( ); +void setaspectratio ( int xasp, int yasp ); +unsigned setgraphbufsize ( unsigned bufsize ); // Not available in WinBGI +void setgraphmode ( int mode ); +void showerrorbox ( const char *msg = NULL ); + +// User Interaction +int getch( ); +int kbhit( ); + +// User-Controlled Window Functions (winbgi.cpp) +int getcurrentwindow( ); +void setcurrentwindow ( int window ); + +// Double buffering support (winbgi.cpp) +int getactivepage( ); +int getvisualpage( ); +void setactivepage ( int page ); +void setvisualpage ( int page ); +void swapbuffers( ); + +// Image Functions (drawing.cpp) +unsigned imagesize ( int left, int top, int right, int bottom ); +void getimage ( int left, int top, int right, int bottom, void *bitmap ); +void putimage ( int left, int top, void *bitmap, int op ); +void printimage ( + const char *title = NULL, + double width_inches = 7, double border_left_inches = 0.75, + double border_top_inches = 0.75, + int left = 0, int top = 0, int right = INT_MAX, int bottom = INT_MAX, + bool active = true, HWND hwnd = NULL +); +void readimagefile ( + const char *filename = NULL, + int left = 0, int top = 0, int right = INT_MAX, int bottom = INT_MAX +); +void writeimagefile ( + const char *filename = NULL, + int left = 0, int top = 0, int right = INT_MAX, int bottom = INT_MAX, + bool active = true, HWND hwnd = NULL +); + +// Text Functions (text.cpp) +void gettextsettings (struct textsettingstype *texttypeinfo); +void outtext (char *textstring); +void outtextxy (int x, int y, char *textstring); +void settextjustify (int horiz, int vert); +void settextstyle (int font, int direction, int charsize); +void setusercharsize (int multx, int divx, int multy, int divy); +int textheight (char *textstring); +int textwidth (char *textstring); +extern std::ostringstream bgiout; +void outstream (std::ostringstream &out = bgiout); +void outstreamxy (int x, int y, std::ostringstream &out = bgiout); + +// Mouse Functions (mouse.cpp) +void clearmouseclick ( int kind ); +void clearresizeevent( ); +void getmouseclick ( int kind, int &x, int &y ); +bool ismouseclick ( int kind ); +bool isresizeevent( ); +int mousex( ); +int mousey( ); +void registermousehandler ( int kind, void h ( int, int ) ); +void setmousequeuestatus ( int kind, bool status = true ); + +// Palette Functions +palettetype *getdefaultpalette( ); +void getpalette ( palettetype *palette ); +int getpalettesize( ); +void setallpalette ( palettetype *palette ); +void setpalette ( int colornum, int color ); +void setrgbpalette ( int colornum, int red, int green, int blue ); + +// Color Macros +#define IS_BGI_COLOR(v) ( ((v) >= 0) && ((v) < 16) ) +#define IS_RGB_COLOR(v) ( (v) & 0x03000000 ) +#define RED_VALUE(v) int(GetRValue( converttorgb(v) )) +#define GREEN_VALUE(v) int(GetGValue( converttorgb(v) )) +#define BLUE_VALUE(v) int(GetBValue( converttorgb(v) )) +#undef COLOR +int COLOR (int r, int g, int b); // No longer a macro + +#ifdef __cplusplus +} +#endif +// --------------------------------------------------------------------------- + +#endif // WINBGI_H + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..c14f2a8 --- /dev/null +++ b/main.cpp @@ -0,0 +1,170 @@ +#include "piece.h" +#include "board.h" +#include "graphics.h" +#include +#include +#include +#include +#include + +using namespace std; + +const int d = 100; + +int drop (Board &b, Piece &piece, Point &pos); +void save (Board &b); +void load (Board &b); +void welcome(); +int random (int); + +int main() { + int gd = DETECT, gm, i, placed; + initwindow ( 800 , 640 , "Tetris" ); +INIT: + char c; + Point pos; + Piece *pieces = Piece::getPieces(); + Piece *piece; + Board b; + srand (time (NULL) ); + clearviewport(); + welcome(); + if (getch() == 'l') { + load (b); + } + clearviewport(); + do { +START: + piece = pieces + random (7); + for (i = 0; i < random (10); i++) { + piece = piece -> getRotation(); + } + pos = Point (4, 19); + do { + while (!kbhit() ) { + pos.y -= 1; + delay (d); + if (b.place (*piece, pos) == PLACE_BAD) { + b.undo(); + if (drop (b, *piece, pos) ) { + goto START; + } else { + goto INIT; + } + } + b.display(); + b.undo(); + } + c = getch(); + switch (c) { + case 'd': pos.x++; break; + case 'a': pos.x--; break; + case 'w': piece = piece -> getRotation(); break; + case 's': if (drop (b, *piece, pos) ) { + goto START; + } else { + goto INIT; + } + case 'e': exit (0); + case 'q': save (b); break; + default: break; + } + placed = b.place (*piece, pos); + if (placed == PLACE_OUT_BOUNDS) { + if (pos.x < 0) { + pos.x = 0; + } else { + pos.x = 10 - piece->getWidth(); + } + } + b.undo(); + while (b.place (*piece, pos) == PLACE_BAD) { + b.undo(); + if (c == 'a') { + pos.x++; + } else if (c == 'd') { + pos.x--; + } + } + b.undo(); + } while (1); + } while (1); +} + +int drop (Board &b, Piece &piece, Point &pos) { + pos.y = b.drop (piece, pos); + int placed = b.place (piece, pos); + char go[] = "GAME OVER!"; + char ex[] = "Press `Esc' to exit, anything else to continue"; + char c; + if (placed == PLACE_ROW_FILLED) { + b.scored(); + b.clearRows(); + } else if (placed == PLACE_FULL) { + b.display(); + clearviewport(); + settextstyle (TRIPLEX_FONT, HORIZ_DIR, 8); + outtextxy ( (getmaxx() - textwidth (go) ) / 2, + (getmaxy() - 2 * textheight (go) ) / 2, + go); + settextstyle (GOTHIC_FONT, HORIZ_DIR, 2); + outtextxy ( (getmaxx() - textwidth (ex) ) / 2, + (getmaxy() + textheight (go) ) / 2 + 5, + ex); + c = getch(); + if (c == 27) { + exit (0); + } else { + return 0; + } + } + b.backup(); + b.display(); + return 1; +} \ + +void welcome() { + char tet[] = "TETRIS"; + char ins[14][50] = {"Welcome to tetris. The objective of the game is", + "to clear the board of pieces.", + "A row is cleared when it is completely filled.", + "Pieces appear at random at the", + "top of the board. The controls are: ", + "a - Move piece left ", + "d - Move piece right ", + "s - Drop piece ", + "w - Change rotation ", + "q - Quicksave (overwrites previous saves)", + "e - Exit (you will lose all progress)", + "Press 'l' if you would like to load a previously", + "saved game. Press any other ", + "key to start a new game." + }; + int i; + settextstyle (TRIPLEX_FONT, HORIZ_DIR, 10); + outtextxy ( (getmaxx() - textwidth (tet) ) / 2, + 5, + tet); + settextstyle (SANS_SERIF_FONT, HORIZ_DIR, 1); + for (i = 0; i < 14; i++) + outtextxy ( (getmaxx() - textwidth (ins[i]) ) / 2, + (10 * textheight (tet) + i * textheight (ins[0]) + 5), + ins[i]); +} + +void save (Board &b) { + fstream f; + f.open ("saves.dat", ios::out | ios::binary | ios::trunc); + f.write ( (char *) (&b), sizeof (b) ); + outtextxy (10, 40, "Saved"); +} + +void load (Board &b) { + fstream f; + f.open ("saves.dat", ios::in | ios::binary); + f.read ( (char *) (&b), sizeof (b) ); +} + +int random (int a) { + return rand() % a; +} diff --git a/makefile b/makefile new file mode 100644 index 0000000..d980afb --- /dev/null +++ b/makefile @@ -0,0 +1,16 @@ +all: tetris.exe + +tetris.exe: main.o board.o piece.o + g++ main.o board.o piece.o -o tetris.exe -lbgi -lgdi32 -lcomdlg32 -luuid -loleaut32 -lole32 + +main.o: main.cpp + g++ -c main.cpp -w + +board.o: board.cpp + g++ -c board.cpp -w + +piece.o: piece.cpp + g++ -c piece.cpp -w + +clean: + rm -rf *o tetris.exe diff --git a/obj/Debug/board.o b/obj/Debug/board.o new file mode 100644 index 0000000..e2bccec Binary files /dev/null and b/obj/Debug/board.o differ diff --git a/obj/Debug/main.o b/obj/Debug/main.o new file mode 100644 index 0000000..e6a7053 Binary files /dev/null and b/obj/Debug/main.o differ diff --git a/obj/Debug/piece.o b/obj/Debug/piece.o new file mode 100644 index 0000000..2bf9ddf Binary files /dev/null and b/obj/Debug/piece.o differ diff --git a/piece.cpp b/piece.cpp new file mode 100644 index 0000000..2d51a3a --- /dev/null +++ b/piece.cpp @@ -0,0 +1,142 @@ +#include "graphics.h" +#include +#include +#include +#include "piece.h" + +using namespace std; + +Piece *Piece::pieces = NULL; +int Piece::side = 18; +int Piece::space = 1; + +void Piece::testDraw() { + Piece *pieces = Piece::getPieces(), *temp; + int i, gd = DETECT, gm; + Point cur (10, 4 * side + space); + initgraph (&gd, &gm, "C:\\TurboC3\\BGI"); + for (i = 0; i < 4; i++) { + temp = pieces + i; + do { + temp->draw (cur); + cur.x += (5 * side) + (6 * space); + temp = temp->getRotation(); + } while (temp != pieces + i); + cur.x = 0; + cur.y += (5 * side) + (6 * space); + } + clearviewport(); + cur.y = 4 * side + space; + for (i = 4; i < 7; i++) { + temp = pieces + i; + do { + temp->draw (cur); + cur.x += (5 * side) + (6 * space); + temp = temp->getRotation(); + } while (temp != pieces + i); + cur.x = 0; + cur.y += (5 * side) + (6 * space); + } +} + +void Piece::draw (Point cur) { + int i; + char sk[5]; + for (i = 0; i < 4; i++) { + rectangle (cur.x + body[i].x * side + space, + cur.y - body[i].y * side - space, + cur.x + (body[i].x + 1) *side - space, + cur.y - (body[i].y + 1) *side + space); + } + for (i = 0; i < width; i++) { + sk[i] = (char) ( (int) (skirt[i]) + (int) ('0') ); + } + sk[i] = '\0'; + outtextxy (cur.x + width * side / 2, cur.y + 5 * space, sk); +} + +Piece::Piece (char pointlist[9], int c) { + int i, j; + height = width = 0; + next = NULL; + color = c; + for (i = 0; i < 8; i += 2) { + body[i / 2] = Point (ctoi (pointlist[i]), ctoi (pointlist[i + 1]) ); + } + for (i = 0; i < 4; i++) { + if (body[i].y > height) { + height = body[i].y; + } + if (body[i].x > width) { + width = body[i].x; + } + } + height++; + width++; + skirt = new int[width]; + for (i = 0; i < width; i++) { + skirt[i] = 10; + for (j = 0; j < 4; j++) + if (body[i].x == i && body[j].y < skirt[i]) { + skirt[i] = body[j].y; + } + } +} + +Piece *Piece::getPieces() { + int i; + Piece *p; + p = new Piece[7]; + p[0] = Piece ("00010203", LIGHTGREEN); + p[1] = Piece ("00010210", LIGHTRED); + p[2] = Piece ("00101112", YELLOW); + p[3] = Piece ("00101121", LIGHTCYAN); + p[4] = Piece ("01111020", LIGHTMAGENTA); + p[5] = Piece ("00011011", BROWN); + p[6] = Piece ("00101120", LIGHTGRAY); + for (i = 0; i < 7; i++) { + p[i].linkRotations(); + } + pieces = p; + return p; +} + +void Piece::linkRotations() { + Piece *temp = this; + char newpointslist[9]; + int i; + do { + for (i = 0; i < 8; i += 2) { + newpointslist[i] = (char) ('0' + temp->height - 1 - temp->body[i / 2].y); + newpointslist[i + 1] = (char) ('0' + temp->body[i / 2].x); + } + newpointslist[8] = '\0'; + temp->next = new Piece (newpointslist, color); + if (equals (temp->next) ) { + delete temp->next; + temp->next = this; + } else if (temp->next == NULL) { + cout << "Low memory" << endl; + getch(); + exit (0); + } else { + temp = temp->next; + } + } while (temp->next != this); +} + +int Piece::equals (Piece *p) { + int i, j, pointmatch = 1; + for (i = 0; i < 4 && pointmatch; i++) { + pointmatch = 0; + for (j = 0; j < 4; j++) + if (body[i] == p->body[j]) { + pointmatch = 1; + } + } + return pointmatch; +} + +int ctoi (char c) { + return (int) (c - '0'); +} \ No newline at end of file diff --git a/piece.h b/piece.h new file mode 100644 index 0000000..02a6d21 --- /dev/null +++ b/piece.h @@ -0,0 +1,47 @@ +#ifndef PIECE_H +#define PIECE_H +class Point{ +public: + int x,y; + Point(int a=0,int b=0): x(a),y(b) {}; + + inline int operator==(const Point &rhs) + { return ((x == rhs.x) && (y == rhs.y))?(1):(0); } +}; + +class Piece{ +private: + Point body[4]; + int color; + int width; + int height; + int* skirt; + Piece* next; + + void linkRotations(); + int equals(Piece *p); + + static Piece *pieces; +public: + Piece(char pointlist[9],int c); + Piece() {}; + static Piece* getPieces(); + int getWidth() {return width;} + int getHeight() {return height;} + int getSkirt(int i) {return skirt[i];} + int getColor() {return color;} + Point getBody(int i) {return body[i];} + Piece* getRotation() {return next;} + void draw(Point cur); + static void testDraw(); + + static int side; + static int space; +}; + +inline int ctoi(char c); +#endif + +//Changes +//Point cur to Point loc in void draw +//Made all static members private. Affect functionality? \ No newline at end of file diff --git a/saves.dat b/saves.dat new file mode 100644 index 0000000..4225100 Binary files /dev/null and b/saves.dat differ