cvazquez_tetris9_03032017.cpp
cvazquez_tetris9_03032017.cpp
#include
<
iostream
>
#include
<
conio
.
h
>
#include
<
vector
>
#include
<
string
>
#include
<
windows
.
h
>
#include
<
tchar
.
h
>
#include
<
cstdlib
>
#include
<
ctime
>
using
namespace
std
;
/* tetris program constants */
const
static
int
SCREEN_WIDTH
=
365
,
SCREEN_HEIGHT
=
435
;
// setting console size
const
static
int
COLUMNS
=
41
,
ROWS
=
30
,
MID_COLUMN
=
COLUMNS
-
20
;
// mapping the memory
const
static
int
NEXT_TETRIS_ROW
=
9
;
// positioning the next block
const
static
int
NEXT_TETRIS_COLUMN
=
COLUMNS
-
12
;
// positioning the next block
const
static
int
CURRENT_TETRIS_ROW
=
5
;
// positioning the current piece
const
static
int
CURRENT_TETRIS_COLUMN
=
(
COLUMNS
-
20
)
/
2
;
// positioning the current piece
const
static
int
CURRENT
=
0
,
NEXT
=
1
;
//vector index
const
static
int
NUM_SHAPES
=
7
;
//Tetris subclasses
const
static
int
LEVEL_1_SPEED
=
300
;
// setting game speed
const
static
int
SPEED_MULTIPLIER
=
20
;
// incrementing speed between different levels
const
static
int
ROWS_2_NEXT_LEVEL
=
10
;
// next level rows
//defining gotoxy()
void
gotoXY
(
short
x
,
short
y
){
COORD pos
=
{
x
,
y
};
SetConsoleCursorPosition
(
GetStdHandle
(
STD_OUTPUT_HANDLE
),
pos
);
}
class
Bucket
{
protected
:
char
bucket
[
ROWS
][
COLUMNS
];
public
:
friend
void
gotoXY
(
int
row
,
int
column
);
void
setBucket
(
int
row
,
int
column
,
char
character
)
{
bucket
[
row
][
column
]
=
character
;
}
char
getBucket
(
int
row
,
int
column
)
{
return
bucket
[
row
][
column
];
}
void
initializeBucket
();
void
drawBucket
();
int
testForFullRows
();
};
/* initializes a Bucket memory map with borders */
void
Bucket
::
initializeBucket
(){
for
(
int
i
=
0
;
i
<
ROWS
;
i
++
)
{
for
(
int
j
=
0
;
j
<
COLUMNS
;
j
++
){
/** create borders and initialize a game Bucket array **/
if
((
i
==
0
)
||
(
j
==
0
)
||
(
i
==
ROWS
-
1
)
||
(
j
==
COLUMNS
-
1
)
||
(
j
==
MID_COLUMN
))
{
bucket
[
i
][
j
]
=
(
char
)
219
;
gotoXY
(
i
,
j
);
cout
<<
bucket
[
i
][
j
];
}
else
bucket
[
i
][
j
]
=
' '
;
}
}
}
/* draws a current state of the game bucket. */
void
Bucket
::
drawBucket
(){
for
(
int
i
=
0
;
i
<
ROWS
;
i
++
)
{
for
(
int
j
=
0
;
j
<
COLUMNS
;
j
++
){
gotoXY
(
i
,
j
);
cout
<<
bucket
[
i
][
j
];
}
}
}
/* removes full rows and returns an int value equal to number rows removed */
int
Bucket
::
testForFullRows
()
{
bool
fullRow
=
false
;
int
rows
=
0
;
// test each row for full row.
for
(
int
i
=
ROWS
-
2
;
i
>
4
;
i
--
)
{
for
(
int
j
=
MID_COLUMN
-
1
;
j
>
0
;
j
--
){
if
(
bucket
[
i
][
j
]
!=
' '
)
fullRow
=
true
;
else
fullRow
=
false
;
// skip to next row if there is a space
if
(
!
fullRow
)
break
;
}
// move rows down if full row
if
(
fullRow
){
rows
++
;
for
(
int
k
=
i
;
k
>
4
;
k
--
)
{
for
(
int
l
=
MID_COLUMN
-
1
;
l
>
0
;
l
--
)
{
bucket
[
k
][
l
]
=
bucket
[
k
-
1
][
l
];
}
}
i
++
;
// check same row index with new contents.
}
}
return
rows
;
}
/* Abstract class for various tetris shapes */
class
Tetris
{
protected
:
int
rowPosition
,
columnPosition
;
int
rotation
;
char
graphic
;
public
:
Tetris
(){
rotation
=
0
;
rowPosition
=
NEXT_TETRIS_ROW
;
columnPosition
=
NEXT_TETRIS_COLUMN
;
}
friend
void
gotoXY
(
int
row
,
int
column
);
/* Display, erase, and manipulate memory map*/
/* bool erase == true removes characters from screen and memory map*/
virtual
void
tetrisDisplay
(
Bucket
&
,
bool
)
=
0
;
/* return true for tetris landing on a surface*/
virtual
bool
testForStop
(
Bucket
,
int
)
=
0
;
void
incrementRotation
(){
rotation
++
;
}
void
incrementRowPosition
(){
rowPosition
++
;
}
void
decrementRowPosition
(){
rowPosition
--
;
}
void
incrementColumnPosition
(){
columnPosition
++
;
}
void
decrementColumnPosition
(){
columnPosition
--
;
}
int
getColumnPosition
(){
return
columnPosition
;
}
int
getRowPosition
(){
return
rowPosition
;
}
void
setPosition
(
int
row
,
int
col
)
{
rowPosition
=
row
;
columnPosition
=
col
;
}
};
/* Square class inherits Tetris */
class
Square
:
public
Tetris
{
public
:
Square
()
:
Tetris
(){
graphic
=
char
(
219
);
};
/* simulates tetris motion by erasing at old positions and drawing at new ones */
/* also modifies Bucket array */
void
tetrisDisplay
(
Bucket
&
bucket
,
bool
erase
);
bool
testForStop
(
Bucket
bucket
,
int
horizChange
);
};
/* Square class virtual function definition */
void
Square
::
tetrisDisplay
(
Bucket
&
bucket
,
bool
erase
){
char
symbol
;
if
(
erase
==
true
)
symbol
=
' '
;
else
symbol
=
graphic
;
bucket
.
setBucket
(
rowPosition
,
columnPosition
,
symbol
);
gotoXY
(
rowPosition
,
columnPosition
);
cout
<<
symbol
;
bucket
.
setBucket
(
rowPosition
,
columnPosition
+
1
,
symbol
);
gotoXY
(
rowPosition
,
columnPosition
+
1
);
cout
<<
symbol
;
bucket
.
setBucket
(
rowPosition
-
1
,
columnPosition
,
symbol
);
gotoXY
(
rowPosition
-
1
,
columnPosition
);
cout
<<
symbol
;
bucket
.
setBucket
(
rowPosition
-
1
,
columnPosition
+
1
,
symbol
);
gotoXY
(
rowPosition
-
1
,
columnPosition
+
1
);
cout
<<
symbol
;
gotoXY
(
0
,
0
);
//moves cursor to corner of screen
};
/* Square class virtual function definition */
bool
Square
::
testForStop
(
Bucket
bucket
,
int
horizChange
){
if
(
bucket
.
getBucket
(
rowPosition
+
1
,
columnPosition
+
horizChange
)
!=
' '
||
bucket
.
getBucket
(
rowPosition
+
1
,
columnPosition
+
1
+
horizChange
)
!=
' '
)
return
true
;
else
return
false
;
}
/* Line Class inherits Tetris */
class
Line
:
public
Tetris
{
public
:
Line
()
:
Tetris
(){
graphic
=
char
(
177
);
};
/* simulates tetris motion by erasing at old positions and drawing at new ones */
/* also modifies Bucket array */
void
tetrisDisplay
(
Bucket
&
bucket
,
bool
erase
);
bool
testForStop
(
Bucket
bucket
,
int
horizChange
);
};
/* Line Class virtual function definition */
void
Line
::
tetrisDisplay
(
Bucket
&
bucket
,
bool
erase
)
{
char
symbol
;
if
(
erase
==
true
)
symbol
=
' '
;
else
symbol
=
graphic
;
// vertical position
if
(
rotation
%
2
==
0
){
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
bucket
.
setBucket
(
rowPosition
-
i
,
columnPosition
,
symbol
);
gotoXY
(
rowPosition
-
i
,
columnPosition
);
cout
<<
symbol
;
}
}
// horizontal position
else
if
(
rotation
%
2
==
1
)
{
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
bucket
.
setBucket
(
rowPosition
,
columnPosition
+
i
,
symbol
);
gotoXY
(
rowPosition
,
columnPosition
+
i
);
cout
<<
symbol
;
}
}
gotoXY
(
0
,
0
);
//moves cursor to corner of screen
}
/* Line Class virtual function definition */
bool
Line
::
testForStop
(
Bucket
bucket
,
int
horizChange
)
{
// test vertical position
if
(
rotation
%
2
==
0
)
{
if
(
bucket
.
getBucket
(
rowPosition
+
1
,
columnPosition
+
horizChange
)
!=
' '
)
return
true
;
}
// test horizontal position
else
if
(
rotation
%
2
==
1
)
{
if
(
bucket
.
getBucket
(
rowPosition
+
1
,
columnPosition
+
horizChange
)
!=
' '
||
bucket
.
getBucket
(
rowPosition
+
1
,
columnPosition
+
1
+
horizChange
)
!=
' '
||
bucket
.
getBucket
(
rowPosition
+
1
,
columnPosition
+
2
+
horizChange
)
!=
' '
||
bucket
.
getBucket
(
rowPosition
+
1
,
columnPosition
+
3
+
horizChange
)
!=
' '
)
return
true
;
}
// else piece is still falling
return
false
;
}
/* Z Class inherits Tetris */
class
Z
:
public
Tetris
{
public
:
Z
()
:
Tetris
(){
graphic
=
char
(
176
);
};
/* simulates tetris motion by erasing at old positions and drawing at new ones */
/* also modifies Bucket array */
void
tetrisDisplay
(
Bucket
&
bucket
,
bool
erase
);
bool
testForStop
(
Bucket
bucket
,
int
horizChange
);
};
/* Z Class virtual function definition */
void
Z
::
tetrisDisplay
(
Bucket
&
bucket
,
bool
erase
)
{
char
symbol
;
if
(
erase
==
true
)
symbol
=
' '
;
else
symbol
=
graphic
;
// horizontal position
if
(
rotation
%
2
==
0
){
bucket
.
setBucket
(
rowPosition
,
columnPosition
,
symbol
);