-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBoard.cpp
More file actions
148 lines (138 loc) · 3.98 KB
/
Board.cpp
File metadata and controls
148 lines (138 loc) · 3.98 KB
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
146
147
148
#include "Board.h"
#include <exception>
#include <random>
Board::Board(int _stepsPerTick = 8) : timestepsPerTick_(_stepsPerTick) {
timeToNextTick_ = timestepsPerTick_;
for (int i = 0; i < Board::HEIGHT; ++i) {
for (int j = 0; j < Board::WIDTH; ++j) {
board_.set(i, j, ' ');
}
}
Piece oPiece('o', &board_);
Piece lPiece('l', &board_);
Piece sPiece('s', &board_);
Piece zPiece('z', &board_);
Piece jPiece('j', &board_);
Piece sevenPiece('7', &board_);
Piece tPiece('t', &board_);
pieces_[0] = oPiece;
pieces_[1] = lPiece;
pieces_[2] = sPiece;
pieces_[3] = zPiece;
pieces_[4] = jPiece;
pieces_[5] = sevenPiece;
pieces_[6] = tPiece;
this->generateNextPiece();
this->bringNextPieceUp();
this->generateNextPiece();
}
bool Board::timestep(int _command) {
++timesteps_;
/* Logic of commands:
Case 5: speeding up descent, simply make the next tick happen immediately,
by setting the time to next tick to 1.
Case 6: pushing current piece to bottom immediately requires some calculation to
figure out how far the current piece should go, then make the next tick happen,
in order to lock the piece in place
The tick() function will check if current piece is "flush" against either the floor or
an already-laid piece
*/
if (this->gameLost_) {
std::cout << "Board::timestep found that game has been lost.\n";
return false;
}
if (this->periodBetweenPieces_) {
--timeToNextTick_;
if (!timeToNextTick_) {
timeToNextTick_ = timestepsPerTick_;
bringNextPieceUp();
generateNextPiece();
this->periodBetweenPieces_ = false;
}
return true;
}
switch(_command) {
case 1: currentPiece_->shiftLeft();
break;
case 2: currentPiece_->shiftRight();
break;
case 3: currentPiece_->rotateAnti();
break;
case 4: currentPiece_->rotateClock();
break;
case 5: timeToNextTick_ = 1;
break;
case 6: currentPiece_->dropToBottom(); timeToNextTick_ = 1;
break;
default:
break;
}
--timeToNextTick_;
if (!timeToNextTick_) {
timeToNextTick_ = timestepsPerTick_;
this->tick();
}
return true;
}
void Board::tick() {
if (currentPiece_->checkCollideBelow()) {
layCurrentPiece();
} else {
currentPiece_->tickDown();
}
}
void Board::layCurrentPiece() {
int pieceRowPos = currentPiece_->getRowPos();
int pieceColPos = currentPiece_->getColPos();
int width = currentPiece_->rotateFrameWidth();
int thisRow, thisCol;
for (int i = 0; i < width; ++i) {
thisRow = pieceRowPos + i;
for (int j = 0; j < width; ++j) {
thisCol = pieceColPos + j;
if (currentPiece_->checkIfRowColOccupied(thisRow, thisCol)) {
board_.set(thisRow, thisCol, currentPiece_->type());
}
}
}
for (int i = pieceRowPos; i < pieceRowPos + width; ++i) {
if (i >= Board::HEIGHT || i < 0) continue;
score_ += tryCollapseRow(i);
}
this->periodBetweenPieces_ = true;
}
int Board::tryCollapseRow(int _row) {
// First, check if the collapse fails: if so, return
for (int j = 0; j < Board::WIDTH; ++j) {
if (board_.get(_row, j) == ' ') {
return 0;
}
}
// This annoying nested loop moves all the squares downwards
int upperRow;
for (int j = 0; j < Board::WIDTH; ++j) {
for (int i = _row; i > 0; --i) {
upperRow = i - 1;
board_.set(i, j, board_.get(upperRow, j));
}
}
// Make sure top row is now empty.
for (int j = 0; j < Board::WIDTH; ++j) board_.set(0, j, ' ');
return 1;
}
long Board::getFinalScore() const { return score_; }
// Private member functions
void Board::bringNextPieceUp() {
currentPiece_ = nextPiece_;
if (!currentPiece_->resetPiece()) {
std::cout << "Board::bringNextPieceUp found that game is lost.\n";
this->gameLost_ = true;
}
}
void Board::generateNextPiece() {
std::random_device randomDevice;
std::mt19937 generator(randomDevice());
std::uniform_int_distribution<int> distribution(0, Board::NTYPES - 1);
int randomInt = distribution(generator);
nextPiece_ = pieces_ + randomInt;
}