summaryrefslogtreecommitdiffstats
path: root/pacman-c++/common/util.cpp
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2011-05-05 00:57:07 +0200
committermanuel <manuel@mausz.at>2011-05-05 00:57:07 +0200
commitce48af53646cd9e7ec762fc1ac176b3aa620b11d (patch)
treef8fbf2cae8c7d0cbac2696a8f4cf94410bfb4928 /pacman-c++/common/util.cpp
parente54ccad07e256ba877bd41d70bd358bd0085bd1e (diff)
downloadfoop-ce48af53646cd9e7ec762fc1ac176b3aa620b11d.tar.gz
foop-ce48af53646cd9e7ec762fc1ac176b3aa620b11d.tar.bz2
foop-ce48af53646cd9e7ec762fc1ac176b3aa620b11d.zip
- refactorized the whole project and made a few subprojects
- replaced tcp with enet - added connect dialog - some smaller bugfixes
Diffstat (limited to 'pacman-c++/common/util.cpp')
-rw-r--r--pacman-c++/common/util.cpp342
1 files changed, 342 insertions, 0 deletions
diff --git a/pacman-c++/common/util.cpp b/pacman-c++/common/util.cpp
new file mode 100644
index 0000000..a3426b6
--- /dev/null
+++ b/pacman-c++/common/util.cpp
@@ -0,0 +1,342 @@
1#include "util.h"
2
3namespace Util
4{
5 Transmission::map_t createUninitialisedMap()
6 {
7 Transmission::map_t map;
8 map = new Transmission::field_t*[Constants::map_size.width];
9 for (unsigned int i = 0; i < Constants::map_size.width; ++i)
10 map[i] = new Transmission::field_t[Constants::map_size.height];
11 return map;
12 }
13
14 Transmission::map_t createEmptyMap()
15 {
16 Transmission::map_t map = createUninitialisedMap();
17 for (unsigned int x = 0; x < Constants::map_size.width; ++x)
18 {
19 for (unsigned int y = 0; y < Constants::map_size.height; ++y)
20 {
21 Transmission::field_t &cur = map[x][y];
22 cur = Transmission::none;
23 }
24 }
25 return map;
26 }
27
28 void deleteMap(Transmission::map_t map)
29 {
30 for (unsigned int x = 0; x < Constants::map_size.width; ++x)
31 delete[] map[x];
32 delete[] map;
33 }
34
35 Transmission::map_t createDemoMap()
36 {
37 Transmission::map_t map = createEmptyMap();
38
39 const char *tmpl[] = {
40 " # # ",
41 " #### ###### # #### # # ###### ### ",
42 " # # ",
43 " # ##### # # # # # ### # # # ",
44 " # # # # # # # # # # ## # # ",
45 " # # # # # # # # ### # # # # ",
46 " # # # # # # # # # # # # ## # ",
47 " # # ### ##### # ### # # # ",
48 " ### # ",
49 " # # ### #### #### #### ##### ",
50 " #### # #..# #..# #..# # # ",
51 " # # ### #..# #..# #### # # # # ",
52 " # # # #..# #..# # # ",
53 " # #### # #### #### # # ##### # ",
54 " # # ",
55 " #### ###### # ##### # ####### ### ",
56 " # # "
57 };
58
59 for (unsigned int x = 0; x < Constants::map_size.width; ++x)
60 {
61 for (unsigned int y = 0; y < Constants::map_size.height; ++y)
62 {
63 Transmission::field_t &cur = map[x][y];
64 cur = Transmission::none;
65 if (tmpl[y][x] == '#')
66 cur |= Color::none | Transmission::block;
67 /* this is a simple hack to create areas where no
68 * autoplaced points/actors will be placed (see makePoints)
69 */
70 else if (tmpl[y][x] == '.')
71 cur |= Transmission::point;
72 }
73 }
74 return map;
75 }
76
77 void placeActors(Transmission::map_t map, unsigned int players, const Color::Color *colors)
78 {
79#if 0
80 for(unsigned int i = 0; i < players; ++i)
81 map[i][0] = colors[i] | Transmission::pacman;
82 return;
83#endif
84
85 int mindistance = Constants::Game::player_minimum_distance;
86 /* this outer loop is used if there are no more valid places left
87 * so we can change mindistance
88 */
89 QList<QPoint> actors;
90 for(unsigned int i = 0; i < players; ++i)
91 {
92 /* first remove formerly placed actors from map */
93 foreach(QPoint pos, actors)
94 map[pos.x()][pos.y()] = Transmission::none;
95 actors.clear();
96
97 /* get list of valid positions */
98 QList<QPoint> validpos;
99 for (unsigned int x = 0; x < Constants::map_size.width; ++x)
100 {
101 for (unsigned int y = 0; y < Constants::map_size.height; ++y)
102 {
103 Transmission::field_t &cur = map[x][y];
104 if (cur == Transmission::none)
105 validpos.append(QPoint(x, y));
106 }
107 }
108
109 /* place actors at map */
110 for(i = 0; i < players; ++i)
111 {
112 int rand = (int) (validpos.size() * (qrand() / (RAND_MAX + 1.0)));
113 QPoint newpos = validpos.at(rand);
114 map[newpos.x()][newpos.y()] = colors[i] | Transmission::pacman;
115 qDebug() << "[Place] Actor" << i << "at" << newpos;
116 actors.append(newpos);
117 validpos.removeAt(rand);
118
119 QMutableListIterator<QPoint> j(validpos);
120 while(j.hasNext())
121 {
122 j.next();
123 QPoint tmp = j.value() - newpos;
124 if (tmp.manhattanLength() < mindistance)
125 j.remove();
126 }
127
128 if (validpos.empty())
129 {
130 qWarning() << "There are no more valid positions for actors left on the map";
131 mindistance -= Constants::Game::player_distance_decr;
132 break;
133 }
134 }
135 }
136 }
137
138 void fillPoints(Transmission::map_t map, Transmission::field_t type)
139 {
140 /* auto place normal points*/
141 for (unsigned int x = 0; x < Constants::map_size.width; ++x)
142 {
143 for (unsigned int y = 0; y < Constants::map_size.height; ++y)
144 {
145 Transmission::field_t &cur = map[x][y];
146 if (cur == Transmission::none)
147 {
148#if 0
149 /* use for endround testing */
150 if (x > 0)
151 continue;
152#endif
153 cur = type;
154 }
155 else if (cur == Transmission::point)
156 cur = Transmission::none;
157 }
158 }
159 }
160
161 Transmission::field_t actorMovementToTransmission(Actor::Movement mov, Transmission::field_t def)
162 {
163 switch (mov)
164 {
165 case Actor::None:
166 return Transmission::direction_none;
167 break;
168 case Actor::Left:
169 return Transmission::direction_left;
170 break;
171 case Actor::Right:
172 return Transmission::direction_right;
173 break;
174 case Actor::Up:
175 return Transmission::direction_up;
176 break;
177 case Actor::Down:
178 return Transmission::direction_down;
179 break;
180 default:
181 return def;
182 break;
183 }
184 return def;
185 }
186
187 Actor::Movement transmissionMovementToActor(Transmission::field_t field, Actor::Movement def)
188 {
189 switch (field)
190 {
191 case Transmission::direction_none:
192 return Actor::None;
193 break;
194 case Transmission::direction_left:
195 return Actor::Left;
196 break;
197 case Transmission::direction_right:
198 return Actor::Right;
199 break;
200 case Transmission::direction_up:
201 return Actor::Up;
202 break;
203 case Transmission::direction_down:
204 return Actor::Down;
205 break;
206 default:
207 return def;
208 break;
209 }
210 return def;
211 }
212
213 const QString colorToString(Color::Color color)
214 {
215 switch(color)
216 {
217 case Color::none:
218 return "none";
219 break;
220 case Color::red:
221 return "red";
222 break;
223 case Color::blue:
224 return "blue";
225 break;
226 case Color::green:
227 return "green";
228 break;
229 case Color::yellow:
230 return "yellow";
231 break;
232 default:
233 return "unknown";
234 break;
235 }
236 }
237
238 QSharedPointer<QByteArray> createPacket(const ::google::protobuf::MessageLite& packet)
239 {
240 qint64 packetlen = packet.ByteSize();
241 QSharedPointer<QByteArray> data = QSharedPointer<QByteArray>(new QByteArray);
242 data->resize(packetlen);
243
244 /* use protobuf.SerializeWithCachedSizesToArray() to avoid calling protobuf.ByteSize() again */
245 ::google::protobuf::uint8 *dataptr = reinterpret_cast<google::protobuf::uint8 *>(data->data());
246 packet.SerializeWithCachedSizesToArray(dataptr);
247 return data;
248 }
249
250 bool sendPacket(QByteArray *data, ENetPeer *peer, ENetHost *host)
251 {
252 ENetPacket *packet = enet_packet_create(data->data(), data->length(), ENET_PACKET_FLAG_RELIABLE);
253 if (enet_peer_send(peer, 0, packet) < 0)
254 {
255 qDebug() << "[sendPacket] Error while sending packet";
256 return false;
257 }
258 enet_host_flush(host);
259 return true;
260 }
261
262 bool sendPacket(const ::google::protobuf::MessageLite& packet, ENetPeer *peer, ENetHost *host)
263 {
264 return sendPacket(createPacket(packet).data(), peer, host);
265 }
266
267 QSharedPointer<QByteArray> receivePacket(ENetPacket *packet)
268 {
269 const char *pdata = reinterpret_cast<const char *>(packet->data);
270 QSharedPointer<QByteArray> data = QSharedPointer<QByteArray>(new QByteArray(pdata, packet->dataLength));
271 return data;
272 }
273
274 int floorLog2(unsigned int n)
275 {
276 if (n == 0)
277 return -1;
278
279 int pos = 0;
280 if (n >= 1<<16) { n >>= 16; pos += 16; }
281 if (n >= 1<< 8) { n >>= 8; pos += 8; }
282 if (n >= 1<< 4) { n >>= 4; pos += 4; }
283 if (n >= 1<< 2) { n >>= 2; pos += 2; }
284 if (n >= 1<< 1) { pos += 1; }
285 return pos;
286 }
287
288#if 0
289 void hexdump(void *pAddressIn, long lSize)
290 {
291 char szBuf[100];
292 long lIndent = 1;
293 long lOutLen, lIndex, lIndex2, lOutLen2;
294 long lRelPos;
295 struct { char *pData; unsigned long lSize; } buf;
296 unsigned char *pTmp,ucTmp;
297 unsigned char *pAddress = (unsigned char *)pAddressIn;
298
299 buf.pData = (char *)pAddress;
300 buf.lSize = lSize;
301
302 while (buf.lSize > 0)
303 {
304 pTmp = (unsigned char *)buf.pData;
305 lOutLen = (int)buf.lSize;
306 if (lOutLen > 16)
307 lOutLen = 16;
308
309 // create a 64-character formatted output line:
310 sprintf(szBuf, " > "
311 " "
312 " %08lX", pTmp-pAddress);
313 lOutLen2 = lOutLen;
314
315 for(lIndex = 1+lIndent, lIndex2 = 53-15+lIndent, lRelPos = 0;
316 lOutLen2;
317 lOutLen2--, lIndex += 2, lIndex2++
318 )
319 {
320 ucTmp = *pTmp++;
321
322 sprintf(szBuf + lIndex, "%02X ", (unsigned short)ucTmp);
323 if(!isprint(ucTmp)) ucTmp = '.'; // nonprintable char
324 szBuf[lIndex2] = ucTmp;
325
326 if (!(++lRelPos & 3)) // extra blank after 4 bytes
327 { lIndex++; szBuf[lIndex+2] = ' '; }
328 }
329
330 if (!(lRelPos & 3)) lIndex--;
331
332 szBuf[lIndex ] = '<';
333 szBuf[lIndex+1] = ' ';
334
335 printf("%s\n", szBuf);
336
337 buf.pData += lOutLen;
338 buf.lSize -= lOutLen;
339 }
340 }
341#endif
342}