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