1 | /*************************************************************************** |
2 | * KBlocks, a falling blocks game for KDE * |
3 | * Copyright (C) 2010 Zhongjie Cai <squall.leonhart.cai@gmail.com> * |
4 | * * |
5 | * This program is free software; you can redistribute it and/or modify * |
6 | * it under the terms of the GNU General Public License as published by * |
7 | * the Free Software Foundation; either version 2 of the License, or * |
8 | * (at your option) any later version. * |
9 | ***************************************************************************/ |
10 | #include "KBlocksLayout.h" |
11 | |
12 | KBlocksLayout::KBlocksLayout(FieldInterface * pF, PieceInterface * pA, PieceInterface * pN) |
13 | { |
14 | mpGameField = pF; |
15 | mpActivePiece = pA; |
16 | mpNextPiece = pN; |
17 | |
18 | mPieceCellCount = mpActivePiece->getCellCount(); |
19 | mpLastPiecePos = new QPoint*[mPieceCellCount]; |
20 | for(int i = 0; i < mPieceCellCount; i++) |
21 | { |
22 | mpLastPiecePos[i] = new QPoint(0, 0); |
23 | } |
24 | |
25 | mWidth = mpGameField->getWidth(); |
26 | mHeight = mpGameField->getHeight(); |
27 | boardInfo = new int*[mHeight]; |
28 | for(int i = 0; i < mHeight; i++) |
29 | { |
30 | boardInfo[i] = new int[mWidth]; |
31 | for(int j = 0; j < mWidth; j++) |
32 | { |
33 | boardInfo[i][j] = -1; |
34 | } |
35 | } |
36 | |
37 | prepareInfo = new int*[PREPARE_AREA_WIDTH]; |
38 | for(int i = 0; i < PREPARE_AREA_WIDTH; i++) |
39 | { |
40 | prepareInfo[i] = new int[PREPARE_AREA_WIDTH]; |
41 | for(int j = 0; j < PREPARE_AREA_WIDTH; j++) |
42 | { |
43 | prepareInfo[i][j] = -1; |
44 | } |
45 | } |
46 | } |
47 | |
48 | KBlocksLayout::~KBlocksLayout() |
49 | { |
50 | for(int i = 0; i < mHeight; i++) |
51 | { |
52 | delete [] boardInfo[i]; |
53 | } |
54 | delete [] boardInfo; |
55 | |
56 | for(int i = 0; i < PREPARE_AREA_WIDTH; i++) |
57 | { |
58 | delete [] prepareInfo[i]; |
59 | } |
60 | delete [] prepareInfo; |
61 | |
62 | for(int i = 0; i < mPieceCellCount; i++) |
63 | { |
64 | delete mpLastPiecePos[i]; |
65 | } |
66 | delete [] mpLastPiecePos; |
67 | } |
68 | |
69 | void KBlocksLayout::beginUpdate(QList<int> * list) |
70 | { |
71 | int px = 0; |
72 | int py = 0; |
73 | list->clear(); |
74 | for(int i = 0; i < mPieceCellCount; i++) |
75 | { |
76 | px = mpLastPiecePos[i]->x(); |
77 | py = mpLastPiecePos[i]->y(); |
78 | list->append(px); |
79 | list->append(py); |
80 | if ((px >= 0) && (px < mWidth) |
81 | && (py >= 0) && (py < mHeight)) |
82 | { |
83 | boardInfo[py][px] = -1; |
84 | } |
85 | } |
86 | } |
87 | |
88 | void KBlocksLayout::updateLayout(int type, const QList<int> & dataList) |
89 | { |
90 | switch(type) |
91 | { |
92 | case KBlocksLayout_Update_FreezePiece: |
93 | updateFreezePiece(dataList); |
94 | break; |
95 | case KBlocksLayout_Update_RemoveLine: |
96 | updateRemoveLine(dataList); |
97 | break; |
98 | case KBlocksLayout_Update_PunishLine: |
99 | updatePunishLine(dataList); |
100 | break; |
101 | } |
102 | } |
103 | |
104 | void KBlocksLayout::endUpdate() |
105 | { |
106 | int px = 0; |
107 | int py = 0; |
108 | int activePieceColor = mpActivePiece->getType(); |
109 | for(int i = 0; i < mPieceCellCount; i++) |
110 | { |
111 | px = mpActivePiece->getCellPosX(i); |
112 | py = mpActivePiece->getCellPosY(i); |
113 | mpLastPiecePos[i]->setX(px); |
114 | mpLastPiecePos[i]->setY(py); |
115 | if ((px >= 0) && (px < mWidth) |
116 | && (py >= 0) && (py < mHeight)) |
117 | { |
118 | boardInfo[py][px] = activePieceColor; |
119 | } |
120 | } |
121 | |
122 | updatePrepareArea(); |
123 | } |
124 | |
125 | void KBlocksLayout::updateSnapshot() |
126 | { |
127 | for(int y = 0; y < mHeight; y++) |
128 | { |
129 | for(int x = 0; x < mWidth; x++) |
130 | { |
131 | if (mpGameField->getCell(x, y)) |
132 | { |
133 | boardInfo[y][x] = 0; // TODO : what color is better here? |
134 | } |
135 | else |
136 | { |
137 | boardInfo[y][x] = -1; |
138 | } |
139 | } |
140 | } |
141 | |
142 | endUpdate(); |
143 | } |
144 | |
145 | int KBlocksLayout::getFieldColor(int posX, int posY) |
146 | { |
147 | if ((posX < 0) || (posX >= mWidth) || (posY < 0) || (posY >= mHeight)) |
148 | { |
149 | return -1; |
150 | } |
151 | |
152 | return boardInfo[posY][posX]; |
153 | } |
154 | |
155 | int KBlocksLayout::getPrepareColor(int posX, int posY) |
156 | { |
157 | if ((posX < 0) || (posX >= PREPARE_AREA_WIDTH) || (posY < 0) || (posY >= PREPARE_AREA_WIDTH)) |
158 | { |
159 | return -1; |
160 | } |
161 | |
162 | return prepareInfo[posY][posX]; |
163 | } |
164 | |
165 | void KBlocksLayout::updatePrepareArea() |
166 | { |
167 | for(int i = 0; i < PREPARE_AREA_WIDTH; i++) |
168 | { |
169 | for(int j = 0; j < PREPARE_AREA_WIDTH; j++) |
170 | { |
171 | prepareInfo[i][j] = -1; |
172 | } |
173 | } |
174 | |
175 | int nextPieceColor = mpNextPiece->getType(); |
176 | for(int i = 0; i < 4; i++) |
177 | { |
178 | int posX = mpNextPiece->getCellPosX(i); |
179 | int posY = mpNextPiece->getCellPosY(i); |
180 | prepareInfo[posY][posX] = nextPieceColor; |
181 | } |
182 | } |
183 | |
184 | void KBlocksLayout::updateFreezePiece(const QList<int> & dataList) |
185 | { |
186 | QList<int> tmpList = dataList; |
187 | int freezeColor = tmpList.takeFirst(); |
188 | int loopCount = tmpList.size() / 2; |
189 | for(int i = 0; i < loopCount; i++) |
190 | { |
191 | int posX = tmpList[i * 2]; |
192 | int posY = tmpList[i * 2 + 1]; |
193 | if ((posX >= 0) && (posX < mWidth) |
194 | && (posY >= 0) && (posY < mHeight)) |
195 | { |
196 | boardInfo[posY][posX] = freezeColor; |
197 | } |
198 | } |
199 | } |
200 | |
201 | void KBlocksLayout::updateRemoveLine(const QList<int> & dataList) |
202 | { |
203 | int lineCount = dataList.size(); |
204 | for(int k = 0; k < lineCount; k++) |
205 | { |
206 | for(int i = dataList[k]; i > 0; i--) |
207 | { |
208 | for(int j = 0; j < mWidth; j++) |
209 | { |
210 | boardInfo[i][j] = boardInfo[i - 1][j]; |
211 | } |
212 | } |
213 | for(int j = 0; j < mWidth; j++) |
214 | { |
215 | boardInfo[0][j] = -1; |
216 | } |
217 | } |
218 | } |
219 | |
220 | void KBlocksLayout::updatePunishLine(const QList<int> & dataList) |
221 | { |
222 | int punishColor = mpNextPiece->getType(); // TODO : this color or new color? |
223 | int lineCount = dataList.size(); |
224 | for(int k = 0; k < lineCount; k++) |
225 | { |
226 | for(int i = 0; i < mHeight - dataList[k]; i++) |
227 | { |
228 | for(int j = 0; j < mWidth; j++) |
229 | { |
230 | boardInfo[i][j] = boardInfo[i + dataList[k]][j]; |
231 | } |
232 | } |
233 | for(int i = mHeight - dataList[k]; i < mHeight; i++) |
234 | { |
235 | for(int j = 0; j < mWidth; j++) |
236 | { |
237 | if (mpGameField->getCell(j, i)) |
238 | { |
239 | boardInfo[i][j] = punishColor; |
240 | } |
241 | else |
242 | { |
243 | boardInfo[i][j] = -1; |
244 | } |
245 | } |
246 | } |
247 | } |
248 | } |
249 | |