-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBoard.cpp
145 lines (128 loc) · 2.77 KB
/
Board.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Board.cpp
#include <stdlib.h>
#include "Config.h"
#include "Window.h"
#include "Board.h"
// Default constructor for active playfield
Board::Board()
{
boardData = new int*[F_HEIGHT];
for (int i = 0; i < F_HEIGHT; i++)
boardData[i] = new int[F_WIDTH]();
}
// Overloaded constructor for each board type
Board::Board(int type)
{
switch (type) {
case 0: // Active playfield
{
maxY = F_HEIGHT;
maxX = F_WIDTH;
boardData = new int*[F_HEIGHT];
for (int i = 0; i < F_HEIGHT; i++)
boardData[i] = new int[F_WIDTH]();
break;
}
case 1: // Current piece
{
maxY = F_HEIGHT+2;
maxX = F_WIDTH;
boardData = new int*[F_HEIGHT+2];
for (int i = 0; i < F_HEIGHT+2; i++)
boardData[i] = new int[F_WIDTH]();
break;
}
}
}
// boardData Getter
int Board::Get(int yPos, int xPos)
{
// Prevent out of bounds access
if (!(yPos >= maxY || yPos < 0 || xPos >= F_WIDTH || xPos < 0))
return boardData[yPos][xPos];
}
// boardData Setter
void Board::Set(int yPos, int xPos, int val)
{
// Prevent out of bounds access
if (!(yPos >= maxY || yPos < 0 || xPos >= F_WIDTH || xPos < 0))
boardData[yPos][xPos] = val;
}
// Randomly generates next 7-bag piece sequence
int* Board::GenerateBag()
{
// Dynamically initialise bag array
int* bag = new int[7];
// Default bag to invalid value
for (int bagID = 0; bagID < 7; bagID++) {
bag[bagID] = 7;
}
// Declare function variables
int i = 0;
int newID;
// Get number sequence
while (i != 7)
{
// Assume newID as valid
bool isValidID = true;
// Get new random ID [0-6]
newID = rand() % 7;
// Reject newID if already in bag
for (int bagID = 0; bagID < 7; bagID++) {
if (bag[bagID] == newID) {
isValidID = false;
break;
}
}
// Set newID as next ID
if (isValidID) {
bag[i] = newID;
i++;
}
}
return bag;
}
// Checks for clearable lines and deletes them, returns lines cleared
int Board::ClearLine(Board* field, bool pc)
{
int linesCleared = 0;
// Loop over all lines
for (int yPos = 0; yPos < F_HEIGHT; yPos++) {
// Assume line as clearable
bool isClearable = true;
// Loop over line elements
for (int xPos = 0; xPos < F_WIDTH; xPos++) {
// Set line as unclearable if empty space found
if (field->Get(yPos,xPos) == 0) {
isClearable = false;
break;
}
}
// Clear line
if (isClearable) {
linesCleared++;
for (int line = 0; line < yPos; line++) {
for (int xPos = 0; xPos < F_WIDTH; xPos++) {
field->Set(yPos-line,xPos,field->Get(yPos-line-1,xPos));
}
}
}
}
// Perfect clear
for (int yPos = 0; yPos < F_HEIGHT; yPos++) {
for (int xPos = 0; xPos < F_WIDTH; xPos++) {
if (field->Get(yPos,xPos) != 0)
return linesCleared;
}
}
if (pc) {
return 8;
} else {
return linesCleared;
}
}
// Destructor
Board::~Board()
{
delete boardData;
}