summaryrefslogtreecommitdiffstats
path: root/pacman-c++
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2011-04-20 02:19:08 +0200
committermanuel <manuel@mausz.at>2011-04-20 02:19:08 +0200
commitbbd2a69a962d15f74a4afcb7b66462eac9fa5008 (patch)
tree17527ce744a9f1c4beb85e953a60f832cdd09068 /pacman-c++
parent58ba349f19f98fe3af5332188f5d3dfe4d076807 (diff)
downloadfoop-bbd2a69a962d15f74a4afcb7b66462eac9fa5008.tar.gz
foop-bbd2a69a962d15f74a4afcb7b66462eac9fa5008.tar.bz2
foop-bbd2a69a962d15f74a4afcb7b66462eac9fa5008.zip
game rounds finally implemented:
- game rounds will be detected during the round AND - a new map will be send in the NEXT tick to the clients
Diffstat (limited to 'pacman-c++')
-rw-r--r--pacman-c++/actor.cpp11
-rw-r--r--pacman-c++/actor.h1
-rw-r--r--pacman-c++/constants.h1
-rw-r--r--pacman-c++/mainwidget.cpp4
-rw-r--r--pacman-c++/sceneholder.cpp37
-rw-r--r--pacman-c++/sceneholder.h3
-rw-r--r--pacman-c++/server.cpp100
-rw-r--r--pacman-c++/server.h10
8 files changed, 109 insertions, 58 deletions
diff --git a/pacman-c++/actor.cpp b/pacman-c++/actor.cpp
index cf3fc13..c8922f7 100644
--- a/pacman-c++/actor.cpp
+++ b/pacman-c++/actor.cpp
@@ -10,7 +10,7 @@ static QVariant myBooleanInterpolator(const bool &start, const bool &end, qreal
10} 10}
11 11
12Actor::Actor(Color::Color color, bool local, QGraphicsItem *parent) 12Actor::Actor(Color::Color color, bool local, QGraphicsItem *parent)
13 : GameEntity(color, parent),m_direction(Actor::None), m_local(local), 13 : GameEntity(color, parent), m_direction(Actor::None), m_local(local),
14 m_wakaPlayer(NULL), m_roundPoints(0), m_gamePoints(0) 14 m_wakaPlayer(NULL), m_roundPoints(0), m_gamePoints(0)
15{ 15{
16 m_type = Type; 16 m_type = Type;
@@ -112,6 +112,15 @@ bool Actor::isLocal()
112 return m_local; 112 return m_local;
113} 113}
114 114
115void Actor::resetDirection()
116{
117 /* hide all pictures */
118 for (int i = 0; i < m_images.size(); ++i)
119 m_images.at(i)->setVisible(false);
120 m_direction = Actor::None;
121 m_images[m_direction]->setVisible(true);
122}
123
115void Actor::move(Actor::Movement direction) 124void Actor::move(Actor::Movement direction)
116{ 125{
117 if (Constants::server) 126 if (Constants::server)
diff --git a/pacman-c++/actor.h b/pacman-c++/actor.h
index 41ad232..389d7c6 100644
--- a/pacman-c++/actor.h
+++ b/pacman-c++/actor.h
@@ -34,6 +34,7 @@ public:
34 34
35 PixmapItem &icon(); 35 PixmapItem &icon();
36 Movement direction(); 36 Movement direction();
37 void resetDirection();
37 bool isLocal(); 38 bool isLocal();
38 void move(Movement direction); 39 void move(Movement direction);
39 bool isMoving(); 40 bool isMoving();
diff --git a/pacman-c++/constants.h b/pacman-c++/constants.h
index 20a0e15..f9f40f9 100644
--- a/pacman-c++/constants.h
+++ b/pacman-c++/constants.h
@@ -51,6 +51,7 @@ namespace Constants {
51 const unsigned int weight_hunt = 10; 51 const unsigned int weight_hunt = 10;
52 const unsigned int weight_bonus_point = 3; 52 const unsigned int weight_bonus_point = 3;
53 const unsigned int weight_point = 1; 53 const unsigned int weight_point = 1;
54 const unsigned int weight_colorblock = 5;
54 } 55 }
55} 56}
56 57
diff --git a/pacman-c++/mainwidget.cpp b/pacman-c++/mainwidget.cpp
index 82099c4..eb032bd 100644
--- a/pacman-c++/mainwidget.cpp
+++ b/pacman-c++/mainwidget.cpp
@@ -149,7 +149,9 @@ void MainWidget::tick()
149 if (m_updatepacket.eating_order_size() > 0) 149 if (m_updatepacket.eating_order_size() > 0)
150 { 150 {
151 Q_ASSERT(m_scene != NULL); 151 Q_ASSERT(m_scene != NULL);
152 m_scene->removeActors(); 152 m_scene->reset();
153
154 /* fetch eating order */
153 QList<Color::Color> order; 155 QList<Color::Color> order;
154 for(int i = 0; i < m_updatepacket.eating_order_size(); ++i) 156 for(int i = 0; i < m_updatepacket.eating_order_size(); ++i)
155 order.append(static_cast<Color::Color>(m_updatepacket.eating_order(i) & Transmission::color_mask)); 157 order.append(static_cast<Color::Color>(m_updatepacket.eating_order(i) & Transmission::color_mask));
diff --git a/pacman-c++/sceneholder.cpp b/pacman-c++/sceneholder.cpp
index 1610b7e..56e0fff 100644
--- a/pacman-c++/sceneholder.cpp
+++ b/pacman-c++/sceneholder.cpp
@@ -18,6 +18,13 @@ SceneHolder::SceneHolder(QObject *parent)
18 visualMap[i].resize(Constants::map_size.height); 18 visualMap[i].resize(Constants::map_size.height);
19} 19}
20 20
21void SceneHolder::reset()
22{
23 /* reset actor directions */
24 foreach(Actor *actor, m_actors)
25 actor->resetDirection();
26}
27
21void SceneHolder::updateMap(const Transmission::map_t& map) 28void SceneHolder::updateMap(const Transmission::map_t& map)
22{ 29{
23 /* remove items that got marked for removal from scene */ 30 /* remove items that got marked for removal from scene */
@@ -42,6 +49,9 @@ void SceneHolder::updateMap(const Transmission::map_t& map)
42 updateMap(map, x, y); 49 updateMap(map, x, y);
43 } 50 }
44 } 51 }
52
53 if (m_pointsLeft == 0)
54 emit allPointsRemoved();
45} 55}
46 56
47void SceneHolder::updateMap(const Transmission::map_t& map, const unsigned int x, unsigned int y) 57void SceneHolder::updateMap(const Transmission::map_t& map, const unsigned int x, unsigned int y)
@@ -83,30 +93,30 @@ void SceneHolder::updateMap(const Transmission::map_t& map, const unsigned int x
83 93
84 if (cur == Transmission::none) 94 if (cur == Transmission::none)
85 { 95 {
86 // no update 96 /* no update */
87 } 97 }
88 else 98 else
89 { 99 {
90 if (cur & Transmission::block) 100 if (cur & Transmission::block)
91 { 101 {
92 unsigned int neighbours = Block::None; 102 unsigned int neighbours = Block::None;
93 // check for old block first 103 /* check for old block first */
94 if (visualMap[x][y] != NULL) 104 if (visualMap[x][y] != NULL)
95 { 105 {
96 Block *oldItem = qgraphicsitem_cast<Block *>(visualMap[x][y]); 106 Block *oldItem = qgraphicsitem_cast<Block *>(visualMap[x][y]);
97 if (oldItem != NULL) 107 if (oldItem != NULL)
98 neighbours = oldItem->neighbours(); 108 neighbours = oldItem->neighbours();
99 } 109 }
100 // check left side 110 /* check left side */
101 if (x > 0 && map[x - 1][y] & Transmission::block) 111 if (x > 0 && map[x - 1][y] & Transmission::block)
102 neighbours |= Block::Left; 112 neighbours |= Block::Left;
103 // check right side 113 /* check right side */
104 if (x < Constants::map_size.width && map[x + 1][y] & Transmission::block) 114 if (x < Constants::map_size.width && map[x + 1][y] & Transmission::block)
105 neighbours |= Block::Right; 115 neighbours |= Block::Right;
106 // check upside 116 /* check upside */
107 if (y > 0 && map[x][y - 1] & Transmission::block) 117 if (y > 0 && map[x][y - 1] & Transmission::block)
108 neighbours |= Block::Up; 118 neighbours |= Block::Up;
109 // check down side 119 /* check down side */
110 if (y < Constants::map_size.height && map[x][y + 1] & Transmission::block) 120 if (y < Constants::map_size.height && map[x][y + 1] & Transmission::block)
111 neighbours |= Block::Down; 121 neighbours |= Block::Down;
112 item = new Block(color, neighbours); 122 item = new Block(color, neighbours);
@@ -124,6 +134,11 @@ void SceneHolder::updateMap(const Transmission::map_t& map, const unsigned int x
124 134
125 if (cur & Transmission::pacman) 135 if (cur & Transmission::pacman)
126 { 136 {
137 /* WARNING: do NOT add actor to visualMap as visualMap-items may
138 * get deleted during update and actors are referenced in_mactors too
139 * if you REALLY need that you need to changed updateMap so that all actors
140 * will be moved before any new items get allocated (totally untested)
141 */
127 Actor *actor = m_actors.value(color, NULL); 142 Actor *actor = m_actors.value(color, NULL);
128 if (actor == NULL) 143 if (actor == NULL)
129 { 144 {
@@ -136,11 +151,11 @@ void SceneHolder::updateMap(const Transmission::map_t& map, const unsigned int x
136 { 151 {
137 Actor::Movement direction = Util::transmissionMovementToActor( 152 Actor::Movement direction = Util::transmissionMovementToActor(
138 cur & Transmission::direction_mask); 153 cur & Transmission::direction_mask);
139 /* WARNING: do NOT add actor to visualMap as visualMap-items may 154 /* direction Actor::None is used on round change (i.e. new actor positions)
140 * get deleted during update and actors are referenced in_mactors too 155 * it is animation-safe to use it for this direction only
141 * if you REALLY need that you need to changed updateMap so that all actors
142 * will be moved before any new items get allocated (totally untested)
143 */ 156 */
157 if (direction == Actor::None)
158 actor->setPos(mapPositionToCoord(x, y));
144 actor->move(direction); 159 actor->move(direction);
145 /* that's kind a hack but working right now 160 /* that's kind a hack but working right now
146 * I think that will fall on our's hat sooner or later 161 * I think that will fall on our's hat sooner or later
@@ -194,8 +209,6 @@ unsigned int SceneHolder::pointsLeft()
194void SceneHolder::decrementPoints() 209void SceneHolder::decrementPoints()
195{ 210{
196 --m_pointsLeft; 211 --m_pointsLeft;
197 if (m_pointsLeft == 0)
198 emit allPointsRemoved();
199} 212}
200 213
201void SceneHolder::setEatingOrder(QList<Color::Color> &order) 214void SceneHolder::setEatingOrder(QList<Color::Color> &order)
diff --git a/pacman-c++/sceneholder.h b/pacman-c++/sceneholder.h
index c61de58..9340850 100644
--- a/pacman-c++/sceneholder.h
+++ b/pacman-c++/sceneholder.h
@@ -16,6 +16,7 @@ public:
16 SceneHolder(QObject *parent = 0); 16 SceneHolder(QObject *parent = 0);
17 virtual ~SceneHolder() 17 virtual ~SceneHolder()
18 {}; 18 {};
19 void reset();
19 unsigned int pointsLeft(); 20 unsigned int pointsLeft();
20 void updateMap(const Transmission::map_t& map); 21 void updateMap(const Transmission::map_t& map);
21 void updateMap(const Transmission::map_t& map, const unsigned int x, const unsigned int y); 22 void updateMap(const Transmission::map_t& map, const unsigned int x, const unsigned int y);
@@ -56,7 +57,7 @@ protected:
56 /* a actor can only eat his upper neighbour 57 /* a actor can only eat his upper neighbour
57 * the order of the neighbours is determined by the colors order (sent from server) 58 * the order of the neighbours is determined by the colors order (sent from server)
58 * please note that !pl1.canEat(pl2, ...) doesn't necessarily mean that pl2 can eat pl1 59 * please note that !pl1.canEat(pl2, ...) doesn't necessarily mean that pl2 can eat pl1
59 * order MUST be in this format: [col1, [col2, ..., colN], col1] 60 * order MUST be in this format: [col1, [col2 ... colN], col1]
60 */ 61 */
61 QList<Color::Color> m_eatingorder; 62 QList<Color::Color> m_eatingorder;
62 63
diff --git a/pacman-c++/server.cpp b/pacman-c++/server.cpp
index 72ee995..be45a66 100644
--- a/pacman-c++/server.cpp
+++ b/pacman-c++/server.cpp
@@ -11,7 +11,8 @@
11 11
12Server::Server(QWidget *parent) 12Server::Server(QWidget *parent)
13 : SceneHolder(parent), m_bindaddress(QHostAddress::Any), 13 : SceneHolder(parent), m_bindaddress(QHostAddress::Any),
14 m_port(Constants::Networking::port), m_rounds(3), m_numbots(0), m_curRound(0) 14 m_port(Constants::Networking::port), m_numbots(0),
15 m_rounds(3), m_curRound(0), m_roundFinished(false)
15{ 16{
16 /* determine max players by using order array */ 17 /* determine max players by using order array */
17 for(m_maxplayers = 0; Color::order[m_maxplayers] != Color::none; ++m_maxplayers); 18 for(m_maxplayers = 0; Color::order[m_maxplayers] != Color::none; ++m_maxplayers);
@@ -24,41 +25,65 @@ bool Server::run()
24 m_eatingorder.append(Color::order[i]); 25 m_eatingorder.append(Color::order[i]);
25 m_eatingorder.append(Color::order[0]); 26 m_eatingorder.append(Color::order[0]);
26 27
28 m_tickTimer = new QTimer(this);
29 m_tickTimer->setInterval(Constants::tick);
30 connect(m_tickTimer, SIGNAL(timeout()), this, SLOT(tick()));
31
27 qDebug() << "[Server] Running server..."; 32 qDebug() << "[Server] Running server...";
28 qDebug() << "[Server] Max players:" << m_maxplayers; 33 qDebug() << "[Server] Max players:" << m_maxplayers;
29 qDebug() << "[Server] Number of rounds:" << m_rounds;
30 qDebug() << "[Server] Number of bots:" << m_numbots; 34 qDebug() << "[Server] Number of bots:" << m_numbots;
35 qDebug() << "[Server] Number of rounds:" << m_rounds;
31 if (!waitForClientConnections()) 36 if (!waitForClientConnections())
32 return false; 37 return false;
33 38
39 connect(this, SIGNAL(allPointsRemoved()), this, SLOT(setRoundFinished()));
34 initRoundMap(); 40 initRoundMap();
35
36 m_tickTimer = new QTimer(this);
37 connect(m_tickTimer, SIGNAL(timeout()), this, SLOT(tick()));
38 m_tickTimer->start(Constants::tick);
39
40 return true; 41 return true;
41} 42}
42 43
43void Server::tick() 44void Server::tick()
44{ 45{
45 //qDebug() << "[Tick] Doing server update"; 46 //qDebug() << "[Tick] Doing server update";
46 foreach (Color::Color color, m_bots) 47 if (m_roundFinished)
47 botCalculate(m_actors[color]); 48 {
48 Transmission::map_t map = calculateUpdates(); 49 // TODO: call this when a pacman get's eaten
49 updateMap(map); 50 /* first finish previous round */
51 foreach(Actor *actor, m_actors)
52 actor->finishRound();
53
54 ++m_curRound;
55 if(m_curRound < m_rounds)
56 initRoundMap();
57 else
58 {
59 /* end of game */
60 qDebug() << "All round finished. Exiting...";
61 m_tickTimer->stop();
62 qApp->quit();
63 }
64 }
65 else
66 {
67 /* let the bots move */
68 foreach (Color::Color color, m_bots)
69 botCalculate(m_actors[color]);
50 70
51 /* add a random bonus point */ 71 /* move on the virtual map */
52 QPoint pos = addRandomPoint(map, Transmission::bonuspoint); 72 Transmission::map_t map = calculateUpdates();
53 if (!pos.isNull()) 73 updateMap(map);
54 updateMap(map, pos.x(), pos.y());
55 74
56 /* add/remove random colorized block */ 75 /* add a random bonus point */
57 if (this->property("coloredblocks").toBool()) 76 QPoint pos = addRandomPoint(map, Transmission::bonuspoint);
58 colorizeBlocks(map); 77 if (!pos.isNull())
78 updateMap(map, pos.x(), pos.y());
59 79
60 sendUpdate(map); 80 /* add/remove random colorized block */
61 Util::deleteMap(map); 81 if (this->property("coloredblocks").toBool())
82 colorizeBlocks(map);
83
84 sendUpdate(map);
85 Util::deleteMap(map);
86 }
62} 87}
63 88
64Transmission::map_t Server::calculateUpdates() 89Transmission::map_t Server::calculateUpdates()
@@ -364,10 +389,7 @@ void Server::botCalculate(Actor *actor)
364 /* check if neighbour is a block */ 389 /* check if neighbour is a block */
365 Block *block = qgraphicsitem_cast<Block *>(item); 390 Block *block = qgraphicsitem_cast<Block *>(item);
366 if (block != NULL && block->color() != actor->color()) 391 if (block != NULL && block->color() != actor->color())
367 {
368 i.remove(); 392 i.remove();
369 continue;
370 }
371 } 393 }
372 394
373 /* we're enclosed by blocks */ 395 /* we're enclosed by blocks */
@@ -410,7 +432,13 @@ void Server::botCalculate(Actor *actor)
410 int olddistance = (actorpos - otherpos).manhattanLength(); 432 int olddistance = (actorpos - otherpos).manhattanLength();
411 int newdistance = (newpos - otherpos).manhattanLength(); 433 int newdistance = (newpos - otherpos).manhattanLength();
412 if (newdistance >= olddistance) 434 if (newdistance >= olddistance)
413 i.setValue(i.value() += Constants::AI::weight_afraid); 435 i.setValue(i.value() + Constants::AI::weight_afraid);
436
437 /* check for blocks of own color: other pacman can't follow their */
438 GameEntity *item = visualMap[newpos.x()][newpos.y()];
439 Block *block = qgraphicsitem_cast<Block *>(item);
440 if (block != NULL && block->color() == actor->color())
441 i.setValue(i.value() + Constants::AI::weight_colorblock);
414 } 442 }
415 443
416 /* check for new positions in hunt list */ 444 /* check for new positions in hunt list */
@@ -419,7 +447,7 @@ void Server::botCalculate(Actor *actor)
419 int olddistance = (actorpos - otherpos).manhattanLength(); 447 int olddistance = (actorpos - otherpos).manhattanLength();
420 int newdistance = (newpos - otherpos).manhattanLength(); 448 int newdistance = (newpos - otherpos).manhattanLength();
421 if (newdistance <= olddistance) 449 if (newdistance <= olddistance)
422 i.setValue(i.value() += Constants::AI::weight_hunt); 450 i.setValue(i.value() + Constants::AI::weight_hunt);
423 } 451 }
424 452
425 /* check for bonuspoint */ 453 /* check for bonuspoint */
@@ -482,24 +510,15 @@ void Server::keyPressUpdate()
482 } 510 }
483} 511}
484 512
485void Server::onRoundFinished() 513void Server::setRoundFinished(bool value)
486{ 514{
487 // TODO: call this when a pacman get's eaten 515 m_roundFinished = value;
488 foreach(Actor *actor, m_actors)
489 actor->finishRound();
490
491 initRoundMap();
492 ++m_curRound;
493
494 /* end of game */
495 if(m_curRound >= m_rounds)
496 m_tickTimer->stop();
497} 516}
498 517
499void Server::initRoundMap() 518void Server::initRoundMap()
500{ 519{
501 /* delete actors first */ 520 qDebug() << "[initRoundMap] New round starts...";
502 removeActors(); 521 m_tickTimer->stop();
503 522
504 /* create new map */ 523 /* create new map */
505 Transmission::map_t map = Util::createDemoMap(); 524 Transmission::map_t map = Util::createDemoMap();
@@ -523,7 +542,9 @@ void Server::initRoundMap()
523 Util::deleteMap(map); 542 Util::deleteMap(map);
524 map = NULL; 543 map = NULL;
525 544
526 connect(this, SIGNAL(allPointsRemoved()), this, SLOT(onRoundFinished()), Qt::UniqueConnection); 545 m_roundFinished = false;
546 m_actorMovements.clear();
547 m_tickTimer->start();
527} 548}
528 549
529bool Server::parseCommandline() 550bool Server::parseCommandline()
@@ -564,6 +585,7 @@ bool Server::parseCommandline()
564 opt.setOption("rounds", 'r'); 585 opt.setOption("rounds", 'r');
565 out << " -r, --rounds [1..n]" << endl 586 out << " -r, --rounds [1..n]" << endl
566 << " Number of rounds to play" << endl 587 << " Number of rounds to play" << endl
588 << " Default: " << m_rounds << endl
567 << endl; 589 << endl;
568 opt.setFlag("nocolorblocks"); 590 opt.setFlag("nocolorblocks");
569 out << " -h, --help" << endl 591 out << " -h, --help" << endl
diff --git a/pacman-c++/server.h b/pacman-c++/server.h
index 6dd138b..a5afbfe 100644
--- a/pacman-c++/server.h
+++ b/pacman-c++/server.h
@@ -41,7 +41,7 @@ protected:
41 41
42protected slots: 42protected slots:
43 /* called when a round is finished */ 43 /* called when a round is finished */
44 void onRoundFinished(); 44 void setRoundFinished(bool value = true);
45 45
46protected: 46protected:
47 QMap<Color::Color, QTcpSocket *> m_clientConnections; 47 QMap<Color::Color, QTcpSocket *> m_clientConnections;
@@ -61,10 +61,12 @@ protected:
61 QHostAddress m_bindaddress; 61 QHostAddress m_bindaddress;
62 unsigned int m_port; 62 unsigned int m_port;
63 unsigned int m_maxplayers; 63 unsigned int m_maxplayers;
64 unsigned int m_rounds; // number of rounds (>= 1)
65 unsigned int m_numbots; 64 unsigned int m_numbots;
66 65 /* number of rounds (>= 1) */
67 unsigned int m_curRound; // current round starting with 0 66 unsigned int m_rounds;
67 /* current round, starting at 0 */
68 unsigned int m_curRound;
69 bool m_roundFinished;
68 70
69 QTimer *m_tickTimer; 71 QTimer *m_tickTimer;
70 72