diff options
| author | manuel <manuel@mausz.at> | 2011-04-18 19:47:34 +0200 |
|---|---|---|
| committer | manuel <manuel@mausz.at> | 2011-04-18 19:47:34 +0200 |
| commit | 85b09864f6d489e8c998e9f172d25079d572c602 (patch) | |
| tree | a6e38da5dc828810b21045d0ac1e4babcf198825 | |
| parent | e373442901064d07791c9739daa380acb1dfbb8c (diff) | |
| download | foop-85b09864f6d489e8c998e9f172d25079d572c602.tar.gz foop-85b09864f6d489e8c998e9f172d25079d572c602.tar.bz2 foop-85b09864f6d489e8c998e9f172d25079d572c602.zip | |
- add actor.canEat(other) to check if actor can eat other (note: that doesn't mean that other can eat actor!!)
- server now generated and sends the colorlist to the server in the first map update packet
- add a better AI
| -rw-r--r-- | pacman-c++/actor.cpp | 9 | ||||
| -rw-r--r-- | pacman-c++/actor.h | 1 | ||||
| -rw-r--r-- | pacman-c++/constants.h | 11 | ||||
| -rw-r--r-- | pacman-c++/mainwidget.cpp | 12 | ||||
| -rw-r--r-- | pacman-c++/pacman.proto | 5 | ||||
| -rw-r--r-- | pacman-c++/sceneholder.cpp | 10 | ||||
| -rw-r--r-- | pacman-c++/sceneholder.h | 9 | ||||
| -rw-r--r-- | pacman-c++/server.cpp | 145 | ||||
| -rw-r--r-- | pacman-c++/server.h | 2 |
9 files changed, 170 insertions, 34 deletions
diff --git a/pacman-c++/actor.cpp b/pacman-c++/actor.cpp index 9ff51f3..cf3fc13 100644 --- a/pacman-c++/actor.cpp +++ b/pacman-c++/actor.cpp | |||
| @@ -193,6 +193,15 @@ bool Actor::isMoving() | |||
| 193 | return (m_moving->state() == QAbstractAnimation::Running); | 193 | return (m_moving->state() == QAbstractAnimation::Running); |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | bool Actor::canEat(Actor *other, const QList<Color::Color> &order) | ||
| 197 | { | ||
| 198 | if (other == NULL || order.empty() || m_color == other->color()) | ||
| 199 | return false; | ||
| 200 | |||
| 201 | int idx = order.indexOf(m_color); | ||
| 202 | return (order.at(idx + 1) == other->color()); | ||
| 203 | } | ||
| 204 | |||
| 196 | void Actor::die() | 205 | void Actor::die() |
| 197 | { | 206 | { |
| 198 | if (!m_local) | 207 | if (!m_local) |
diff --git a/pacman-c++/actor.h b/pacman-c++/actor.h index 902951b..41ad232 100644 --- a/pacman-c++/actor.h +++ b/pacman-c++/actor.h | |||
| @@ -42,6 +42,7 @@ public: | |||
| 42 | void eatingPacman(); | 42 | void eatingPacman(); |
| 43 | void startEating(); | 43 | void startEating(); |
| 44 | void stopEating(); | 44 | void stopEating(); |
| 45 | bool canEat(Actor *other, const QList<Color::Color> &order); | ||
| 45 | 46 | ||
| 46 | unsigned int getRoundPoints(); | 47 | unsigned int getRoundPoints(); |
| 47 | unsigned int getGamePoints(); | 48 | unsigned int getGamePoints(); |
diff --git a/pacman-c++/constants.h b/pacman-c++/constants.h index dc72611..20a0e15 100644 --- a/pacman-c++/constants.h +++ b/pacman-c++/constants.h | |||
| @@ -41,6 +41,17 @@ namespace Constants { | |||
| 41 | const unsigned int colorize_block_tickcount_min = 50; | 41 | const unsigned int colorize_block_tickcount_min = 50; |
| 42 | const unsigned int colorize_block_tickcount_max = 100; | 42 | const unsigned int colorize_block_tickcount_max = 100; |
| 43 | } | 43 | } |
| 44 | |||
| 45 | namespace AI | ||
| 46 | { | ||
| 47 | /* bots minimum manhatten distance before other players will be recognized */ | ||
| 48 | const unsigned int player_minimum_distance = 4; | ||
| 49 | /* weight values used to determine new direction of bot */ | ||
| 50 | const unsigned int weight_afraid = 50; | ||
| 51 | const unsigned int weight_hunt = 10; | ||
| 52 | const unsigned int weight_bonus_point = 3; | ||
| 53 | const unsigned int weight_point = 1; | ||
| 54 | } | ||
| 44 | } | 55 | } |
| 45 | 56 | ||
| 46 | namespace Color | 57 | namespace Color |
diff --git a/pacman-c++/mainwidget.cpp b/pacman-c++/mainwidget.cpp index c674c55..42abd01 100644 --- a/pacman-c++/mainwidget.cpp +++ b/pacman-c++/mainwidget.cpp | |||
| @@ -6,7 +6,8 @@ | |||
| 6 | #include "pacman.pb.h" | 6 | #include "pacman.pb.h" |
| 7 | 7 | ||
| 8 | MainWidget::MainWidget(QWidget *parent) | 8 | MainWidget::MainWidget(QWidget *parent) |
| 9 | : QWidget(parent), m_currentKey(Transmission::none), m_running(false), m_maxplayers(0) | 9 | : QWidget(parent), m_currentKey(Transmission::none), m_running(false), m_scene(NULL), |
| 10 | m_maxplayers(0) | ||
| 10 | { | 11 | { |
| 11 | /* create audio player */ | 12 | /* create audio player */ |
| 12 | m_ambientPlayer = new GaplessAudioPlayer(Sound::Ambient, 100, this); | 13 | m_ambientPlayer = new GaplessAudioPlayer(Sound::Ambient, 100, this); |
| @@ -146,6 +147,15 @@ void MainWidget::tick() | |||
| 146 | bool worked = m_updatepacket.ParseFromArray(data->data(), data->size()); | 147 | bool worked = m_updatepacket.ParseFromArray(data->data(), data->size()); |
| 147 | Q_ASSERT(worked); | 148 | Q_ASSERT(worked); |
| 148 | Q_UNUSED(worked); | 149 | Q_UNUSED(worked); |
| 150 | |||
| 151 | if (m_updatepacket.eating_order_size() > 0) | ||
| 152 | { | ||
| 153 | Q_ASSERT(m_scene != NULL); | ||
| 154 | QList<Color::Color> order; | ||
| 155 | for(int i = 0; i < m_updatepacket.eating_order_size(); ++i) | ||
| 156 | order.append(static_cast<Color::Color>(m_updatepacket.eating_order(i) & Transmission::color_mask)); | ||
| 157 | } | ||
| 158 | |||
| 149 | Transmission::map_t map = Util::createUninitialisedMap(); | 159 | Transmission::map_t map = Util::createUninitialisedMap(); |
| 150 | Q_ASSERT(m_updatepacket.field_size() == (int) (Constants::map_size.width * Constants::map_size.height)); | 160 | Q_ASSERT(m_updatepacket.field_size() == (int) (Constants::map_size.width * Constants::map_size.height)); |
| 151 | int i = 0; | 161 | int i = 0; |
diff --git a/pacman-c++/pacman.proto b/pacman-c++/pacman.proto index 51bb239..8e088e8 100644 --- a/pacman-c++/pacman.proto +++ b/pacman-c++/pacman.proto | |||
| @@ -9,13 +9,10 @@ message Init { | |||
| 9 | required uint32 maxplayers = 2; | 9 | required uint32 maxplayers = 2; |
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | message MapInit { | ||
| 13 | repeated uint32 field = 1 [packed=true]; | ||
| 14 | } | ||
| 15 | |||
| 16 | message MapUpdate { | 12 | message MapUpdate { |
| 17 | repeated uint32 field = 1 [packed=true]; | 13 | repeated uint32 field = 1 [packed=true]; |
| 18 | repeated uint32 round_points = 2; | 14 | repeated uint32 round_points = 2; |
| 19 | repeated uint32 game_points = 3; | 15 | repeated uint32 game_points = 3; |
| 16 | repeated uint32 eating_order = 4; | ||
| 20 | } | 17 | } |
| 21 | 18 | ||
diff --git a/pacman-c++/sceneholder.cpp b/pacman-c++/sceneholder.cpp index 578b0df..dace711 100644 --- a/pacman-c++/sceneholder.cpp +++ b/pacman-c++/sceneholder.cpp | |||
| @@ -197,6 +197,16 @@ void SceneHolder::decrementPoints() | |||
| 197 | --m_pointsLeft; | 197 | --m_pointsLeft; |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | void SceneHolder::setEatingOrder(QList<Color::Color> &order) | ||
| 201 | { | ||
| 202 | m_eatingorder = order; | ||
| 203 | } | ||
| 204 | |||
| 205 | QList<Color::Color> &SceneHolder::eatingOrder() | ||
| 206 | { | ||
| 207 | return m_eatingorder; | ||
| 208 | } | ||
| 209 | |||
| 200 | QPoint SceneHolder::mapPositionToCoord(unsigned int x, unsigned int y) | 210 | QPoint SceneHolder::mapPositionToCoord(unsigned int x, unsigned int y) |
| 201 | { | 211 | { |
| 202 | return QPoint(x * Constants::field_size.width, y * Constants::field_size.height); | 212 | return QPoint(x * Constants::field_size.width, y * Constants::field_size.height); |
diff --git a/pacman-c++/sceneholder.h b/pacman-c++/sceneholder.h index 418f16b..69ee598 100644 --- a/pacman-c++/sceneholder.h +++ b/pacman-c++/sceneholder.h | |||
| @@ -21,6 +21,8 @@ public: | |||
| 21 | void updateMap(const Transmission::map_t& map, const unsigned int x, const unsigned int y); | 21 | void updateMap(const Transmission::map_t& map, const unsigned int x, const unsigned int y); |
| 22 | void setColor(Color::Color color = Color::none); | 22 | void setColor(Color::Color color = Color::none); |
| 23 | Color::Color color(); | 23 | Color::Color color(); |
| 24 | void setEatingOrder(QList<Color::Color> &order); | ||
| 25 | QList<Color::Color> &eatingOrder(); | ||
| 24 | 26 | ||
| 25 | private slots: | 27 | private slots: |
| 26 | void decrementPoints(); | 28 | void decrementPoints(); |
| @@ -46,6 +48,13 @@ protected: | |||
| 46 | /* my local color */ | 48 | /* my local color */ |
| 47 | Color::Color m_color; | 49 | Color::Color m_color; |
| 48 | 50 | ||
| 51 | /* a actor can only eat his upper neighbour | ||
| 52 | * the order of the neighbours is determined by the colors order (sent from server) | ||
| 53 | * please note that !pl1.canEat(pl2, ...) doesn't necessarily mean that pl2 can eat pl1 | ||
| 54 | * order MUST be in this format: [col1, [col2, ..., colN], col1] | ||
| 55 | */ | ||
| 56 | QList<Color::Color> m_eatingorder; | ||
| 57 | |||
| 49 | /* points left before round ends */ | 58 | /* points left before round ends */ |
| 50 | unsigned int m_pointsLeft; | 59 | unsigned int m_pointsLeft; |
| 51 | }; | 60 | }; |
diff --git a/pacman-c++/server.cpp b/pacman-c++/server.cpp index 65a8f8b..4219a43 100644 --- a/pacman-c++/server.cpp +++ b/pacman-c++/server.cpp | |||
| @@ -19,6 +19,11 @@ Server::Server(QWidget *parent) | |||
| 19 | 19 | ||
| 20 | bool Server::run() | 20 | bool Server::run() |
| 21 | { | 21 | { |
| 22 | /* create eating order list first - this can also be created dynamically per round (theoretically) */ | ||
| 23 | for(unsigned i = 0; i < m_maxplayers; ++i) | ||
| 24 | m_eatingorder.append(Color::order[i]); | ||
| 25 | m_eatingorder.append(Color::order[0]); | ||
| 26 | |||
| 22 | qDebug() << "[Server] Running server..."; | 27 | qDebug() << "[Server] Running server..."; |
| 23 | qDebug() << "[Server] Max players:" << m_maxplayers; | 28 | qDebug() << "[Server] Max players:" << m_maxplayers; |
| 24 | qDebug() << "[Server] Number of bots:" << m_numbots; | 29 | qDebug() << "[Server] Number of bots:" << m_numbots; |
| @@ -42,7 +47,7 @@ bool Server::run() | |||
| 42 | } | 47 | } |
| 43 | 48 | ||
| 44 | updateMap(map); | 49 | updateMap(map); |
| 45 | sendUpdate(map); | 50 | sendUpdate(map, true); |
| 46 | Util::deleteMap(map); | 51 | Util::deleteMap(map); |
| 47 | map = NULL; | 52 | map = NULL; |
| 48 | 53 | ||
| @@ -55,7 +60,7 @@ bool Server::run() | |||
| 55 | void Server::tick() | 60 | void Server::tick() |
| 56 | { | 61 | { |
| 57 | //qDebug() << "[Tick] Doing server update"; | 62 | //qDebug() << "[Tick] Doing server update"; |
| 58 | foreach(Color::Color color, m_bots) | 63 | foreach (Color::Color color, m_bots) |
| 59 | botCalculate(m_actors[color]); | 64 | botCalculate(m_actors[color]); |
| 60 | Transmission::map_t map = calculateUpdates(); | 65 | Transmission::map_t map = calculateUpdates(); |
| 61 | updateMap(map); | 66 | updateMap(map); |
| @@ -218,7 +223,7 @@ void Server::colorizeBlocks(Transmission::map_t map) | |||
| 218 | { | 223 | { |
| 219 | /* check for actor collision */ | 224 | /* check for actor collision */ |
| 220 | bool skip = false; | 225 | bool skip = false; |
| 221 | foreach(Actor *actor, m_actors) | 226 | foreach (Actor *actor, m_actors) |
| 222 | { | 227 | { |
| 223 | if (CoordToMapPosition(actor->pos().toPoint()) == i.key()) | 228 | if (CoordToMapPosition(actor->pos().toPoint()) == i.key()) |
| 224 | skip = true; | 229 | skip = true; |
| @@ -272,6 +277,7 @@ bool Server::waitForClientConnections() | |||
| 272 | 277 | ||
| 273 | qDebug() << "[Server] Waiting for clients"; | 278 | qDebug() << "[Server] Waiting for clients"; |
| 274 | ProtoBuf::Init packet; | 279 | ProtoBuf::Init packet; |
| 280 | packet.set_maxplayers(m_maxplayers); | ||
| 275 | for (unsigned int i = 0; i < (m_maxplayers - m_numbots); ++i) | 281 | for (unsigned int i = 0; i < (m_maxplayers - m_numbots); ++i) |
| 276 | { | 282 | { |
| 277 | bool connectionAvailable = tcpSrv->waitForNewConnection(-1); | 283 | bool connectionAvailable = tcpSrv->waitForNewConnection(-1); |
| @@ -284,7 +290,6 @@ bool Server::waitForClientConnections() | |||
| 284 | Color::Color color = Color::order[i]; | 290 | Color::Color color = Color::order[i]; |
| 285 | m_clientConnections[color] = socket; | 291 | m_clientConnections[color] = socket; |
| 286 | packet.set_color(color); | 292 | packet.set_color(color); |
| 287 | packet.set_maxplayers(m_maxplayers); | ||
| 288 | Util::sendPacket(packet, socket); | 293 | Util::sendPacket(packet, socket); |
| 289 | qDebug() << "[Connect] New Player: color=" << color; | 294 | qDebug() << "[Connect] New Player: color=" << color; |
| 290 | } | 295 | } |
| @@ -299,7 +304,7 @@ bool Server::waitForClientConnections() | |||
| 299 | return true; | 304 | return true; |
| 300 | } | 305 | } |
| 301 | 306 | ||
| 302 | void Server::sendUpdate(Transmission::map_t map) | 307 | void Server::sendUpdate(Transmission::map_t map, bool firstPacket) |
| 303 | { | 308 | { |
| 304 | m_updatepacket.Clear(); | 309 | m_updatepacket.Clear(); |
| 305 | 310 | ||
| @@ -315,6 +320,13 @@ void Server::sendUpdate(Transmission::map_t map) | |||
| 315 | m_updatepacket.add_game_points(m_actors.value(Color::order[i])->getGamePoints()); | 320 | m_updatepacket.add_game_points(m_actors.value(Color::order[i])->getGamePoints()); |
| 316 | } | 321 | } |
| 317 | 322 | ||
| 323 | /* we send the eating_order inside the first packet */ | ||
| 324 | if (firstPacket) | ||
| 325 | { | ||
| 326 | foreach(Color::Color color, m_eatingorder) | ||
| 327 | m_updatepacket.add_eating_order(color); | ||
| 328 | } | ||
| 329 | |||
| 318 | QSharedPointer<QByteArray> data = Util::createPacket(m_updatepacket); | 330 | QSharedPointer<QByteArray> data = Util::createPacket(m_updatepacket); |
| 319 | QMutableMapIterator<Color::Color, QTcpSocket *> i(m_clientConnections); | 331 | QMutableMapIterator<Color::Color, QTcpSocket *> i(m_clientConnections); |
| 320 | while(i.hasNext()) | 332 | while(i.hasNext()) |
| @@ -349,53 +361,125 @@ void Server::botCalculate(Actor *actor) | |||
| 349 | QPoint actorpos = CoordToMapPosition(actor->pos().toPoint()); | 361 | QPoint actorpos = CoordToMapPosition(actor->pos().toPoint()); |
| 350 | 362 | ||
| 351 | /* first make list of possible directions based on current actor position */ | 363 | /* first make list of possible directions based on current actor position */ |
| 352 | QList<Actor::Movement> directions; | 364 | QHash<Actor::Movement, unsigned int> directions; |
| 353 | if (actorpos.x() > 0) | 365 | if (actorpos.x() > 0) |
| 354 | directions.append(Actor::Left); | 366 | directions.insert(Actor::Left, 0); |
| 355 | if (actorpos.x() < visualMap.size() - 1) | 367 | if (actorpos.x() < visualMap.size() - 1) |
| 356 | directions.append(Actor::Right); | 368 | directions.insert(Actor::Right, 0); |
| 357 | if (actorpos.y() > 0) | 369 | if (actorpos.y() > 0) |
| 358 | directions.append(Actor::Up); | 370 | directions.insert(Actor::Up, 0); |
| 359 | if (actorpos.y() < visualMap[actorpos.x()].size() - 1) | 371 | if (actorpos.y() < visualMap[actorpos.x()].size() - 1) |
| 360 | directions.append(Actor::Down); | 372 | directions.insert(Actor::Down, 0); |
| 361 | 373 | ||
| 362 | /* copy of directions: used if there's no good direction based on rules */ | 374 | /* check neighbours for blocks first */ |
| 363 | QList<Actor::Movement> directions2(directions); | 375 | QMutableHashIterator<Actor::Movement, unsigned int> i(directions); |
| 364 | |||
| 365 | QMutableListIterator<Actor::Movement> i(directions); | ||
| 366 | while(i.hasNext()) | 376 | while(i.hasNext()) |
| 367 | { | 377 | { |
| 368 | i.next(); | 378 | i.next(); |
| 369 | Actor::Movement direction = i.value(); | 379 | QPoint newpos = actorpos + Actor::movementToPoint(i.key()); |
| 370 | QPoint pos = actorpos + Actor::movementToPoint(direction); | 380 | if (newpos.x() < 0 || newpos.x() >= visualMap.size()) |
| 371 | if (pos.x() < 0 || pos.x() >= visualMap.size()) | ||
| 372 | continue; | 381 | continue; |
| 373 | if (pos.y() < 0 || pos.y() >= visualMap[pos.x()].size()) | 382 | if (newpos.y() < 0 || newpos.y() >= visualMap[newpos.x()].size()) |
| 374 | continue; | 383 | continue; |
| 375 | GameEntity *item = visualMap[pos.x()][pos.y()]; | 384 | GameEntity *item = visualMap[newpos.x()][newpos.y()]; |
| 376 | 385 | ||
| 377 | /* check if neighbour is a block */ | 386 | /* check if neighbour is a block */ |
| 378 | Block *block = qgraphicsitem_cast<Block *>(item); | 387 | Block *block = qgraphicsitem_cast<Block *>(item); |
| 379 | if (block != NULL && block->color() != actor->color()) | 388 | if (block != NULL && block->color() != actor->color()) |
| 380 | { | 389 | { |
| 381 | i.remove(); | 390 | i.remove(); |
| 382 | directions2.removeAll(direction); | ||
| 383 | continue; | 391 | continue; |
| 384 | } | 392 | } |
| 393 | } | ||
| 394 | |||
| 395 | /* we're enclosed by blocks */ | ||
| 396 | if (directions.empty()) | ||
| 397 | return; | ||
| 398 | |||
| 399 | /* determine if other actors are in range to afraid/hunt*/ | ||
| 400 | int mindistance = Constants::AI::player_minimum_distance; | ||
| 401 | QList<QPoint> pos_afraid; | ||
| 402 | QList<QPoint> pos_hunt; | ||
| 403 | foreach (Actor *other, m_actors) | ||
| 404 | { | ||
| 405 | if (actor == other) | ||
| 406 | continue; | ||
| 407 | |||
| 408 | QList<QPoint> *ptr = NULL; | ||
| 409 | if (other->canEat(actor, m_eatingorder)) | ||
| 410 | ptr = &pos_afraid; | ||
| 411 | else if (actor->canEat(other, m_eatingorder)) | ||
| 412 | ptr = &pos_hunt; | ||
| 413 | if (ptr == NULL) | ||
| 414 | continue; | ||
| 415 | |||
| 416 | QPoint otherpos = CoordToMapPosition(other->pos().toPoint()); | ||
| 417 | QPoint distance = actorpos - otherpos; | ||
| 418 | if (distance.manhattanLength() < mindistance) | ||
| 419 | ptr->append(otherpos); | ||
| 420 | } | ||
| 385 | 421 | ||
| 386 | /* if neighbour is not a point */ | 422 | /* check new directions and change direction-weight */ |
| 423 | i = directions; | ||
| 424 | while(i.hasNext()) | ||
| 425 | { | ||
| 426 | i.next(); | ||
| 427 | QPoint newpos = actorpos + Actor::movementToPoint(i.key()); | ||
| 428 | |||
| 429 | /* check for new positions in afraid list */ | ||
| 430 | foreach(QPoint otherpos, pos_afraid) | ||
| 431 | { | ||
| 432 | int olddistance = (actorpos - otherpos).manhattanLength(); | ||
| 433 | int newdistance = (newpos - otherpos).manhattanLength(); | ||
| 434 | if (newdistance >= olddistance) | ||
| 435 | i.setValue(i.value() += Constants::AI::weight_afraid); | ||
| 436 | } | ||
| 437 | |||
| 438 | /* check for new positions in hunt list */ | ||
| 439 | foreach(QPoint otherpos, pos_hunt) | ||
| 440 | { | ||
| 441 | int olddistance = (actorpos - otherpos).manhattanLength(); | ||
| 442 | |||
| 443 | int newdistance = (newpos - otherpos).manhattanLength(); | ||
| 444 | if (newdistance <= olddistance) | ||
| 445 | i.setValue(i.value() += Constants::AI::weight_hunt); | ||
| 446 | } | ||
| 447 | |||
| 448 | /* check for bonuspoint */ | ||
| 449 | GameEntity *item = visualMap[newpos.x()][newpos.y()]; | ||
| 387 | BonusPoint *bpoint = qgraphicsitem_cast<BonusPoint *>(item); | 450 | BonusPoint *bpoint = qgraphicsitem_cast<BonusPoint *>(item); |
| 451 | if (bpoint != NULL) | ||
| 452 | i.setValue(i.value() + Constants::AI::weight_bonus_point); | ||
| 453 | |||
| 454 | /* check for normal point */ | ||
| 388 | Point *point = qgraphicsitem_cast<Point *>(item); | 455 | Point *point = qgraphicsitem_cast<Point *>(item); |
| 389 | if (bpoint == NULL && point == NULL) | 456 | if (point != NULL) |
| 390 | { | 457 | i.setValue(i.value() + Constants::AI::weight_point); |
| 458 | } | ||
| 459 | |||
| 460 | /* sort directions */ | ||
| 461 | QList<unsigned int> weightlist = directions.values(); | ||
| 462 | qSort(weightlist.begin(), weightlist.end(), qGreater<unsigned int>()); | ||
| 463 | |||
| 464 | /* remove directions with lesser weight */ | ||
| 465 | unsigned int max = weightlist.at(0); | ||
| 466 | i = directions; | ||
| 467 | while(i.hasNext()) | ||
| 468 | { | ||
| 469 | i.next(); | ||
| 470 | if (i.value() < max) | ||
| 391 | i.remove(); | 471 | i.remove(); |
| 392 | continue; | ||
| 393 | } | ||
| 394 | } | 472 | } |
| 395 | 473 | ||
| 396 | QList<Actor::Movement> *ptr = (!directions.empty()) ? &directions : &directions2; | 474 | QList<Actor::Movement> list = directions.keys(); |
| 397 | int rand = (int) (ptr->size() * (qrand() / (RAND_MAX + 1.0))); | 475 | |
| 398 | m_actorMovements[actor->color()] = ptr->at(rand); | 476 | /* default is no direction change */ |
| 477 | if (list.contains(actor->direction())) | ||
| 478 | return; | ||
| 479 | |||
| 480 | /* random direction */ | ||
| 481 | int rand = (int) (list.size() * (qrand() / (RAND_MAX + 1.0))); | ||
| 482 | m_actorMovements[actor->color()] = list.at(rand); | ||
| 399 | } | 483 | } |
| 400 | 484 | ||
| 401 | void Server::keyPressUpdate() | 485 | void Server::keyPressUpdate() |
| @@ -504,6 +588,11 @@ bool Server::parseCommandline() | |||
| 504 | return false; | 588 | return false; |
| 505 | } | 589 | } |
| 506 | m_maxplayers = maxplayers; | 590 | m_maxplayers = maxplayers; |
| 591 | if (m_maxplayers == 2) | ||
| 592 | { | ||
| 593 | qCritical() << "2 player game is not supported (who wins if a player gets eaten?)"; | ||
| 594 | return false; | ||
| 595 | } | ||
| 507 | } | 596 | } |
| 508 | 597 | ||
| 509 | if (opt.getValue("bots") != NULL) | 598 | if (opt.getValue("bots") != NULL) |
diff --git a/pacman-c++/server.h b/pacman-c++/server.h index 8d40f27..826c701 100644 --- a/pacman-c++/server.h +++ b/pacman-c++/server.h | |||
| @@ -32,7 +32,7 @@ protected: | |||
| 32 | Transmission::map_t calculateUpdates(); | 32 | Transmission::map_t calculateUpdates(); |
| 33 | 33 | ||
| 34 | /* update client maps */ | 34 | /* update client maps */ |
| 35 | void sendUpdate(Transmission::map_t map); | 35 | void sendUpdate(Transmission::map_t map, bool firstPacket = false); |
| 36 | 36 | ||
| 37 | QPoint addRandomPoint(Transmission::map_t map, Transmission::field_t type = Transmission::bonuspoint); | 37 | QPoint addRandomPoint(Transmission::map_t map, Transmission::field_t type = Transmission::bonuspoint); |
| 38 | void colorizeBlocks(Transmission::map_t map); | 38 | void colorizeBlocks(Transmission::map_t map); |
