-
Notifications
You must be signed in to change notification settings - Fork 0
/
manipulate.cc
124 lines (109 loc) · 3.23 KB
/
manipulate.cc
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
#include "manipulate.h"
int Manipulate::update(Gamedef &gamedef, Gamestate &gamestate) {
int limit = 1000;
int everFired = 0;
int fired = 0; // by default no template fired
do {
fired = vFour(gamestate) | hFour(gamestate) | vThree(gamestate) | hThree(gamestate);
if (fired) {
everFired = 1;
limit--;
}
scan_drop(gamedef, gamestate);
} while (fired && limit > 0);
return everFired;
}
void Manipulate::scan_drop(Gamedef &gamedef, Gamestate &gamestate) {
Board* extension = gamedef.extensioncolor;
int* offset = gamestate.extensionoffset;
Board* board = gamestate.boardcandies;
int index;
int* payload;
int value;
for (int j = 0; j < board->columns; j++) {
index = 0;
for (int i = 0; i < board->rows; i++) {
Get(board->data, i, j, (Payload*)&payload);
if (payload[0] != -1) {
if (index != i) Swap(board->data, i, j, index, j);
index++;
}
// if payload[0] == -1, don't update index
}
// drop here
for (int k = index; k < board->rows; k++) {
// get value from extension board
Get(extension->data, (offset[j] % extension->rows), j, (Payload*)&payload);
value = *payload;
// update offset[j]
offset[j]++;
// update value on the board
Get(board->data, k, j, (Payload*)&payload);
payload[0] = value;
}
}
}
int Manipulate::vertical(Gamestate &gamestate, int bound) {
int fired = 0; // by default no template fired
Board* board = gamestate.boardcandies;
int* payload;
int* curr;
int* next;
for (int i = 0; i < board->rows - (bound - 1); i++) {
for (int j = 0; j < board->columns; j++) {
Get(board->data, i, j, (Payload*)&curr);
for (int k = 1; k < bound; k++) {
Get(board->data, i + k, j, (Payload*)&next);
if (curr[0] != next[0] || curr[0] == -1) break;
if (k + 1 == bound) { // last iteration of the loop
fired = 1;
for (int l = 0; l < bound; l++) { // set the matched blocks to -1
Get(board->data, i + l, j, (Payload*)&payload);
payload[0] = -1;
// update the score
gamestate.currentscore++;
}
}
}
}
}
return fired; // if fired == 1, then at least 1 template fired
}
int Manipulate::horizontal(Gamestate &gamestate, int bound) {
int fired = 0; // by default no template fired
Board* board = gamestate.boardcandies;
int* payload;
int* curr;
int* next;
for (int i = 0; i < board->rows; i++) {
for (int j = 0; j < board->columns - (bound - 1); j++) {
Get(board->data, i, j, (Payload*)&curr);
for (int k = 1; k < bound; k++) {
Get(board->data, i, j + k, (Payload*)&next);
if (curr[0] != next[0] || curr[0] == -1) break;
if (k + 1 == bound) { // last iteration of the loop
fired = 1;
for (int l = 0; l < bound; l++) { // set the matched blocks to -1
Get(board->data, i, j + l, (Payload*)&payload);
payload[0] = -1;
// update the score
gamestate.currentscore++;
}
}
}
}
}
return fired; // if fired == 1, then at least 1 template fired
}
int Manipulate::vFour(Gamestate &gamestate) {
return vertical(gamestate, 4);
}
int Manipulate::vThree(Gamestate &gamestate) {
return vertical(gamestate, 3);
}
int Manipulate::hFour(Gamestate &gamestate) {
return horizontal(gamestate, 4);
}
int Manipulate::hThree(Gamestate &gamestate) {
return horizontal(gamestate, 3);
}