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 "KBlocksPiece.h"
11
12const int C_PieceRotationCount[PieceType_Max_Count] =
13{
14 2, 2, 2, 4, 1, 4, 4,
15};
16
17const PiecePoint C_PieceSize[PieceType_Detail_Max_Count] =
18{
19 //Four blocks, also stair-like (Z)
20 PiecePoint(2, 3), PiecePoint(3, 2), PiecePoint(2, 3), PiecePoint(3, 2),
21
22 //Four blocks, stair-like (S)
23 PiecePoint(2, 3), PiecePoint(3, 2), PiecePoint(2, 3), PiecePoint(3, 2),
24
25 //Four blocks, straight line (I)
26 PiecePoint(1, 4), PiecePoint(4, 1), PiecePoint(1, 4), PiecePoint(4, 1),
27
28 //Four blocks, resembling an airplane (T)
29 PiecePoint(2, 3), PiecePoint(3, 2), PiecePoint(2, 3), PiecePoint(3, 2),
30
31 //Four blocks, square (O)
32 PiecePoint(2, 2), PiecePoint(2, 2), PiecePoint(2, 2), PiecePoint(2, 2),
33
34 //Four blocks, L shape (L)
35 PiecePoint(2, 3), PiecePoint(3, 2), PiecePoint(2, 3), PiecePoint(3, 2),
36
37 //Four blocks, also (J)
38 PiecePoint(2, 3), PiecePoint(3, 2), PiecePoint(2, 3), PiecePoint(3, 2),
39};
40
41const PiecePoint C_PieceOffset[PieceType_Detail_Max_Count] =
42{
43 //Four blocks, also stair-like (Z)
44 PiecePoint(-1,-1), PiecePoint(-1, 0), PiecePoint(-1,-1), PiecePoint(-1, 0),
45
46 //Four blocks, stair-like (S)
47 PiecePoint(-1,-1), PiecePoint(-1, 0), PiecePoint(-1,-1), PiecePoint(-1, 0),
48
49 //Four blocks, straight line (I)
50 PiecePoint(0, -1), PiecePoint(-1, 0), PiecePoint(0, -1), PiecePoint(-1, 0),
51
52 //Four blocks, resembling an airplane (T)
53 PiecePoint( 0,-1), PiecePoint(-1,-1), PiecePoint(-1,-1), PiecePoint(-1, 0),
54
55 //Four blocks, square (O)
56 PiecePoint(-1,-1), PiecePoint(-1,-1), PiecePoint(-1,-1), PiecePoint(-1,-1),
57
58 //Four blocks, L shape (L)
59 PiecePoint(0, -1), PiecePoint(-1,-1), PiecePoint(-1,-1), PiecePoint(-1, 0),
60
61 //Four blocks, also (J)
62 PiecePoint(-1,-1), PiecePoint(-1, 0), PiecePoint( 0,-1), PiecePoint(-1,-1),
63};
64
65const PiecePoint C_PieceCell[PieceType_Detail_Max_Count][KBlocksPiece_CellCount] =
66{
67 //Four blocks, also stair-like (Z)
68 { PiecePoint(0, 1), PiecePoint(1, 0), PiecePoint(1, 1), PiecePoint(0, 2) },
69 { PiecePoint(0, 0), PiecePoint(1, 0), PiecePoint(1, 1), PiecePoint(2, 1) },
70 { PiecePoint(0, 1), PiecePoint(1, 0), PiecePoint(1, 1), PiecePoint(0, 2) },
71 { PiecePoint(0, 0), PiecePoint(1, 0), PiecePoint(1, 1), PiecePoint(2, 1) },
72
73 //Four blocks, stair-like (S)
74 { PiecePoint(0, 0), PiecePoint(0, 1), PiecePoint(1, 1), PiecePoint(1, 2) },
75 { PiecePoint(0, 1), PiecePoint(1, 1), PiecePoint(1, 0), PiecePoint(2, 0) },
76 { PiecePoint(0, 0), PiecePoint(0, 1), PiecePoint(1, 1), PiecePoint(1, 2) },
77 { PiecePoint(0, 1), PiecePoint(1, 1), PiecePoint(1, 0), PiecePoint(2, 0) },
78
79 //Four blocks, straight line (I)
80 { PiecePoint(0, 0), PiecePoint(0, 1), PiecePoint(0, 2), PiecePoint(0, 3) },
81 { PiecePoint(0, 0), PiecePoint(1, 0), PiecePoint(2, 0), PiecePoint(3, 0) },
82 { PiecePoint(0, 0), PiecePoint(0, 1), PiecePoint(0, 2), PiecePoint(0, 3) },
83 { PiecePoint(0, 0), PiecePoint(1, 0), PiecePoint(2, 0), PiecePoint(3, 0) },
84
85 //Four blocks, resembling an airplane (T)
86 { PiecePoint(0, 0), PiecePoint(0, 1), PiecePoint(0, 2), PiecePoint(1, 1) },
87 { PiecePoint(0, 1), PiecePoint(1, 1), PiecePoint(2, 1), PiecePoint(1, 0) },
88 { PiecePoint(1, 2), PiecePoint(0, 1), PiecePoint(1, 1), PiecePoint(1, 0) },
89 { PiecePoint(0, 0), PiecePoint(1, 0), PiecePoint(1, 1), PiecePoint(2, 0) },
90
91 //Four blocks, square (O)
92 { PiecePoint(0, 0), PiecePoint(1, 0), PiecePoint(0, 1), PiecePoint(1, 1) },
93 { PiecePoint(0, 0), PiecePoint(1, 0), PiecePoint(0, 1), PiecePoint(1, 1) },
94 { PiecePoint(0, 0), PiecePoint(1, 0), PiecePoint(0, 1), PiecePoint(1, 1) },
95 { PiecePoint(0, 0), PiecePoint(1, 0), PiecePoint(0, 1), PiecePoint(1, 1) },
96
97 //Four blocks, L shape (L)
98 { PiecePoint(0, 2), PiecePoint(1, 2), PiecePoint(1, 1), PiecePoint(1, 0) },
99 { PiecePoint(0, 0), PiecePoint(1, 0), PiecePoint(2, 0), PiecePoint(2, 1) },
100 { PiecePoint(0, 0), PiecePoint(0, 1), PiecePoint(0, 2), PiecePoint(1, 0) },
101 { PiecePoint(0, 0), PiecePoint(0, 1), PiecePoint(1, 1), PiecePoint(2, 1) },
102
103 //Four blocks, also (J)
104 { PiecePoint(0, 0), PiecePoint(0, 1), PiecePoint(0, 2), PiecePoint(1, 2) },
105 { PiecePoint(0, 1), PiecePoint(1, 1), PiecePoint(2, 1), PiecePoint(2, 0) },
106 { PiecePoint(0, 0), PiecePoint(1, 0), PiecePoint(1, 1), PiecePoint(1, 2) },
107 { PiecePoint(0, 0), PiecePoint(1, 0), PiecePoint(2, 0), PiecePoint(0, 1) },
108};
109
110//-----------------------------------------------------------------------------
111PiecePoint::PiecePoint(int x, int y)
112{
113 mPosX = x;
114 mPosY = y;
115}
116
117PiecePoint::~PiecePoint()
118{
119}
120
121int PiecePoint::x()
122{
123 return mPosX;
124}
125
126int PiecePoint::y()
127{
128 return mPosY;
129}
130//-----------------------------------------------------------------------------
131
132KBlocksPiece::KBlocksPiece()
133{
134 mType = 0;
135 mPosX = 0;
136 mPosY = 0;
137 mRotation = 0;
138}
139
140KBlocksPiece::KBlocksPiece(PieceInterface * p)
141{
142 copy(p);
143}
144
145KBlocksPiece::~KBlocksPiece()
146{
147}
148
149void KBlocksPiece::copy(PieceInterface * p)
150{
151 mType = p->getType();
152 mPosX = p->getPosX();
153 mPosY = p->getPosY();
154 mRotation = p->getRotation();
155}
156
157int KBlocksPiece::toValue()
158{
159 return (mType * PieceRotation_Max_Count + mRotation);
160}
161
162void KBlocksPiece::fromValue(int val)
163{
164 mType = val / PieceRotation_Max_Count;
165 mRotation = val % PieceRotation_Max_Count;
166}
167
168int KBlocksPiece::getType()
169{
170 return mType;
171}
172
173void KBlocksPiece::setType(int newType)
174{
175 mType = (newType + PieceType_Max_Count) % PieceType_Max_Count;
176}
177
178int KBlocksPiece::getRotation()
179{
180 return mRotation;
181}
182
183void KBlocksPiece::setRotation(int newRotation)
184{
185 mRotation = (newRotation + PieceRotation_Max_Count) % PieceRotation_Max_Count;
186}
187
188int KBlocksPiece::getPosX()
189{
190 return mPosX;
191}
192
193void KBlocksPiece::setPosX(int newPosX)
194{
195 mPosX = newPosX;
196}
197
198int KBlocksPiece::getPosY()
199{
200 return mPosY;
201}
202
203void KBlocksPiece::setPosY(int newPosY)
204{
205 mPosY = newPosY;
206}
207
208int KBlocksPiece::getCellCount()
209{
210 return KBlocksPiece_CellCount;
211}
212
213int KBlocksPiece::getCellPosX(int index)
214{
215 if ((index < 0) || (index >= KBlocksPiece_CellCount))
216 {
217 return -1;
218 }
219
220 PiecePoint tmpCell = C_PieceCell[mType * PieceRotation_Max_Count + mRotation][index];
221 PiecePoint tmpOffset = C_PieceOffset[mType * PieceRotation_Max_Count + mRotation];
222
223 return (mPosX + tmpCell.x() + tmpOffset.x());
224}
225
226int KBlocksPiece::getCellPosY(int index)
227{
228 if ((index < 0) || (index >= KBlocksPiece_CellCount))
229 {
230 return -1;
231 }
232
233 PiecePoint tmpCell = C_PieceCell[mType * PieceRotation_Max_Count + mRotation][index];
234 PiecePoint tmpOffset = C_PieceOffset[mType * PieceRotation_Max_Count + mRotation];
235
236 return (mPosY + tmpCell.y() + tmpOffset.y());
237}
238
239int KBlocksPiece::getWidth()
240{
241 PiecePoint tmpPoint = C_PieceSize[mType * PieceRotation_Max_Count + mRotation];
242 return tmpPoint.x();
243}
244
245int KBlocksPiece::getHeight()
246{
247 PiecePoint tmpPoint = C_PieceSize[mType * PieceRotation_Max_Count + mRotation];
248 return tmpPoint.y();
249}
250
251int KBlocksPiece::getRotationCount()
252{
253 return C_PieceRotationCount[mType];
254}
255
256int KBlocksPiece::getSignature(int * signature)
257{
258 for(int i = 0; i < KBlocksPiece_CellCount; i++)
259 {
260 signature[i] = -1;
261 }
262
263 for(int i = 0; i < KBlocksPiece_CellCount; i++)
264 {
265 PiecePoint tmpPoint = C_PieceCell[mType * PieceRotation_Max_Count + mRotation][i];
266 if (tmpPoint.y() > signature[tmpPoint.x()])
267 {
268 signature[tmpPoint.x()] = tmpPoint.y();
269 }
270 }
271
272 return getWidth();
273}
274
275void KBlocksPiece::encodeData(unsigned char * data)
276{
277 data[0] = mType;
278 data[1] = mPosX;
279 data[2] = mPosY;
280 data[3] = mRotation;
281}
282
283void KBlocksPiece::decodeData(unsigned char * data)
284{
285 mType = data[0];
286 mPosX = data[1];
287 mPosY = data[2];
288 mRotation = data[3];
289}
290