summaryrefslogtreecommitdiffstats
path: root/pacman-c++
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2011-04-15 03:20:17 +0200
committermanuel <manuel@mausz.at>2011-04-15 03:20:17 +0200
commit536ddd91ae7f162045226d4b358ba95d678f6deb (patch)
tree7311153ba9e54bacd5d319e21bf419a3acdb7c4c /pacman-c++
parent9a1787acd9fcd5dc0cce80cc0d6d007fa47b8bbe (diff)
downloadfoop-536ddd91ae7f162045226d4b358ba95d678f6deb.tar.gz
foop-536ddd91ae7f162045226d4b358ba95d678f6deb.tar.bz2
foop-536ddd91ae7f162045226d4b358ba95d678f6deb.zip
add support for random bonus points
Diffstat (limited to 'pacman-c++')
-rw-r--r--pacman-c++/constants.h10
-rw-r--r--pacman-c++/sceneholder.cpp215
-rw-r--r--pacman-c++/sceneholder.h1
-rw-r--r--pacman-c++/server.cpp50
-rw-r--r--pacman-c++/server.h2
-rw-r--r--pacman-c++/util.cpp16
-rw-r--r--pacman-c++/util.h2
7 files changed, 185 insertions, 111 deletions
diff --git a/pacman-c++/constants.h b/pacman-c++/constants.h
index a14e623..06b6561 100644
--- a/pacman-c++/constants.h
+++ b/pacman-c++/constants.h
@@ -27,6 +27,16 @@ namespace Constants {
27 { 27 {
28 const unsigned int bonus_point_value = 100; 28 const unsigned int bonus_point_value = 100;
29 const unsigned int point_value = 10; 29 const unsigned int point_value = 10;
30 /* players will be placed with this minimum manhattan distance */
31 const unsigned int player_minimum_distance = 5;
32 /* if the distance above isn't possible, decrease the distance by this value */
33 const unsigned int player_distance_decr = 2;
34 }
35
36 namespace Random
37 {
38 /* there's a chance of 1:20 that a bonus point will be added */
39 const unsigned int bouns_point_chance = 20;
30 } 40 }
31} 41}
32 42
diff --git a/pacman-c++/sceneholder.cpp b/pacman-c++/sceneholder.cpp
index d9e07e5..11e0772 100644
--- a/pacman-c++/sceneholder.cpp
+++ b/pacman-c++/sceneholder.cpp
@@ -39,117 +39,130 @@ void SceneHolder::updateMap(const Transmission::map_t& map)
39 const Transmission::field_t &cur = map[x][y]; 39 const Transmission::field_t &cur = map[x][y];
40 if (cur == Transmission::none) 40 if (cur == Transmission::none)
41 continue; 41 continue;
42 updateMap(map, x, y);
43 }
44 }
45}
42 46
43 Color::Color color = static_cast<Color::Color>(cur & Transmission::color_mask); 47void SceneHolder::updateMap(const Transmission::map_t& map, const unsigned int x, unsigned int y)
44 GameEntity* item = NULL; 48{
49 const Transmission::field_t &cur = map[x][y];
50 if (cur == Transmission::none)
51 return;
45 52
46 if (cur & Transmission::empty) 53 Color::Color color = static_cast<Color::Color>(cur & Transmission::color_mask);
47 { 54 GameEntity* item = NULL;
48 GameEntity *oldItem = visualMap[x][y];
49 /* special handling for purging field
50 * remove elements (in case it's not an actor)
51 */
52 if (oldItem != NULL && dynamic_cast<Actor *>(oldItem) == NULL)
53 {
54 visualMap[x][y] = NULL;
55 Actor *actor = NULL;
56 foreach (Actor *tmp, m_actors)
57 {
58 if (cur & tmp->color())
59 {
60 actor = tmp;
61 break;
62 }
63 }
64
65 /* an item must be removed by an actor */
66 if (actor == NULL)
67 Q_ASSERT(false);
68 oldItem->onDie(actor);
69
70 /* register item for removal in next update */
71 m_oldItems.append(oldItem);
72 }
73 }
74 55
75 if (cur == Transmission::none) 56 if (cur & Transmission::empty)
76 { 57 {
77 // no update 58 GameEntity *oldItem = visualMap[x][y];
78 } 59 /* special handling for purging field
79 else if (cur & Transmission::block) 60 * remove elements (in case it's not an actor)
80 { 61 */
81 unsigned int neighbours = Block::None; 62 if (oldItem != NULL && dynamic_cast<Actor *>(oldItem) == NULL)
82 // check left side 63 {
83 if (x > 0 && map[x - 1][y] & Transmission::block) 64 visualMap[x][y] = NULL;
84 neighbours |= Block::Left; 65 Actor *actor = NULL;
85 // check right side 66 foreach (Actor *tmp, m_actors)
86 if (x < Constants::map_size.width && map[x + 1][y] & Transmission::block)
87 neighbours |= Block::Right;
88 // check upside
89 if (y > 0 && map[x][y - 1] & Transmission::block)
90 neighbours |= Block::Up;
91 // check down side
92 if (y < Constants::map_size.height && map[x][y + 1] & Transmission::block)
93 neighbours |= Block::Down;
94 item = new Block(color, neighbours);
95 }
96 else if (cur & Transmission::bonuspoint)
97 item = new BonusPoint();
98 else if (cur & Transmission::point)
99 {
100 item = new Point();
101 connect(item, SIGNAL(destroyed()), this, SLOT(decrementPoints()));
102 ++m_pointsLeft;
103 }
104 else if (cur & Transmission::pacman)
105 { 67 {
106 Actor *actor = m_actors.value(color, NULL); 68 if (cur & tmp->color())
107 if (actor == NULL)
108 { 69 {
109 actor = new Actor(color, (color == m_color)); 70 actor = tmp;
110 m_actors[color] = actor; 71 break;
111 addItem(actor);
112 actor->setPos(mapPositionToCoord(x, y));
113 }
114 else
115 {
116 Actor::Movement direction = Util::transmissionMovementToActor(
117 cur & Transmission::direction_mask);
118 actor->move(direction);
119 /* that's kind a hack but working right now
120 * I think that will fall on our's hat sooner or later
121 */
122 if (!(cur & Transmission::empty))
123 actor->stopEating();
124 qDebug() << "[SceneUpdate] actor moves: color=" << color
125 << "direction=" << direction << "newpos=" << QPoint(x, y);
126 } 72 }
127 } 73 }
128 else if (cur & Transmission::empty) 74
129 { 75 /* an item must be removed by an actor */
130 /* already handled */ 76 if (actor == NULL)
131 }
132 else
133 {
134 qWarning() << "Unknown data. value=" << cur;
135 Q_ASSERT(false); 77 Q_ASSERT(false);
136 } 78 oldItem->onDie(actor);
137 79
138 /* add new created item to scene 80 /* register item for removal in next update */
139 * remove old item on that location if there's one 81 m_oldItems.append(oldItem);
82 }
83 }
84
85 if (cur == Transmission::none)
86 {
87 // no update
88 }
89 else if (cur & Transmission::block)
90 {
91 unsigned int neighbours = Block::None;
92 // check left side
93 if (x > 0 && map[x - 1][y] & Transmission::block)
94 neighbours |= Block::Left;
95 // check right side
96 if (x < Constants::map_size.width && map[x + 1][y] & Transmission::block)
97 neighbours |= Block::Right;
98 // check upside
99 if (y > 0 && map[x][y - 1] & Transmission::block)
100 neighbours |= Block::Up;
101 // check down side
102 if (y < Constants::map_size.height && map[x][y + 1] & Transmission::block)
103 neighbours |= Block::Down;
104 item = new Block(color, neighbours);
105 }
106 else if (cur & Transmission::bonuspoint)
107 item = new BonusPoint();
108 else if (cur & Transmission::point)
109 {
110 item = new Point();
111 connect(item, SIGNAL(destroyed()), this, SLOT(decrementPoints()));
112 ++m_pointsLeft;
113 }
114 else if (cur & Transmission::pacman)
115 {
116 Actor *actor = m_actors.value(color, NULL);
117 if (actor == NULL)
118 {
119 actor = new Actor(color, (color == m_color));
120 m_actors[color] = actor;
121 addItem(actor);
122 actor->setPos(mapPositionToCoord(x, y));
123 }
124 else
125 {
126 Actor::Movement direction = Util::transmissionMovementToActor(
127 cur & Transmission::direction_mask);
128 /* WARNING: do NOT add actor to visualMap as visualMap-items may
129 * get deleted during update and actors are referenced in_mactors too
130 * if you REALLY need that you need to changed updateMap so that all actors
131 * will be moved before any new items get allocated (totally untested)
140 */ 132 */
141 if (item != NULL) 133 actor->move(direction);
142 { 134 /* that's kind a hack but working right now
143 addItem(item); 135 * I think that will fall on our's hat sooner or later
144 item->setPos(mapPositionToCoord(x, y)); 136 */
145 GameEntity *oldItem = visualMap[x][y]; 137 if (!(cur & Transmission::empty))
146 visualMap[x][y] = item; 138 actor->stopEating();
147 if (oldItem != NULL) 139 qDebug() << "[SceneUpdate] actor moves: color=" << color
148 { 140 << "direction=" << direction << "newpos=" << QPoint(x, y);
149 removeItem(item); 141 }
150 delete oldItem; 142 }
151 } 143 else if (cur & Transmission::empty)
152 } 144 {
145 /* already handled */
146 }
147 else
148 {
149 qWarning() << "Unknown data. value=" << cur;
150 Q_ASSERT(false);
151 }
152
153 /* add new created item to scene
154 * remove old item on that location if there's one
155 */
156 if (item != NULL)
157 {
158 addItem(item);
159 item->setPos(mapPositionToCoord(x, y));
160 GameEntity *oldItem = visualMap[x][y];
161 visualMap[x][y] = item;
162 if (oldItem != NULL)
163 {
164 removeItem(item);
165 delete oldItem;
153 } 166 }
154 } 167 }
155} 168}
diff --git a/pacman-c++/sceneholder.h b/pacman-c++/sceneholder.h
index 5183f65..418f16b 100644
--- a/pacman-c++/sceneholder.h
+++ b/pacman-c++/sceneholder.h
@@ -18,6 +18,7 @@ public:
18 {}; 18 {};
19 unsigned int pointsLeft(); 19 unsigned int pointsLeft();
20 void updateMap(const Transmission::map_t& map); 20 void updateMap(const Transmission::map_t& map);
21 void updateMap(const Transmission::map_t& map, const unsigned int x, const unsigned int y);
21 void setColor(Color::Color color = Color::none); 22 void setColor(Color::Color color = Color::none);
22 Color::Color color(); 23 Color::Color color();
23 24
diff --git a/pacman-c++/server.cpp b/pacman-c++/server.cpp
index a045cad..01c74c4 100644
--- a/pacman-c++/server.cpp
+++ b/pacman-c++/server.cpp
@@ -3,6 +3,7 @@
3#include "pacman.pb.h" 3#include "pacman.pb.h"
4#include "block.h" 4#include "block.h"
5#include "anyoption.h" 5#include "anyoption.h"
6#include "bonuspoint.h"
6#include <QtNetwork/QTcpServer> 7#include <QtNetwork/QTcpServer>
7#include <QtNetwork/QTcpSocket> 8#include <QtNetwork/QTcpSocket>
8#include <QTextStream> 9#include <QTextStream>
@@ -26,7 +27,7 @@ bool Server::run()
26 qDebug() << "[Server] Creating map..."; 27 qDebug() << "[Server] Creating map...";
27 Transmission::map_t map = Util::createDemoMap(); 28 Transmission::map_t map = Util::createDemoMap();
28 Util::placeActors(map, m_maxplayers, Color::order); 29 Util::placeActors(map, m_maxplayers, Color::order);
29 Util::makePoints(map); 30 Util::fillPoints(map);
30 updateMap(map); 31 updateMap(map);
31 sendUpdate(map); 32 sendUpdate(map);
32 Util::deleteMap(map); 33 Util::deleteMap(map);
@@ -43,6 +44,12 @@ void Server::tick()
43 qDebug() << "[Tick] Doing server update"; 44 qDebug() << "[Tick] Doing server update";
44 Transmission::map_t map = calculateUpdates(); 45 Transmission::map_t map = calculateUpdates();
45 updateMap(map); 46 updateMap(map);
47
48 /* add a random bonus point */
49 QPoint pos = addRandomPoint(map, Transmission::bonuspoint);
50 if (!pos.isNull())
51 updateMap(map, pos.x(), pos.y());
52
46 sendUpdate(map); 53 sendUpdate(map);
47 Util::deleteMap(map); 54 Util::deleteMap(map);
48} 55}
@@ -161,6 +168,43 @@ invalid_direction:
161 return map; 168 return map;
162} 169}
163 170
171QPoint Server::addRandomPoint(Transmission::map_t map, Transmission::field_t type)
172{
173 int chance = Constants::Random::bouns_point_chance;
174 int rand = (int) (chance * (qrand() / (RAND_MAX + 1.0)));
175 if (rand != 0)
176 return QPoint();
177
178 /* get list of valid positions */
179 QList<QPoint> validpos;
180 for (unsigned int x = 0; x < Constants::map_size.width; ++x)
181 {
182 for (unsigned int y = 0; y < Constants::map_size.height; ++y)
183 {
184 if (visualMap[x][y] == NULL)
185 validpos.append(QPoint(x, y));
186 }
187 }
188
189 /* remove actors possitions from list
190 * performance would be better if actors would be listed in visualMap too
191 * but this isn't possible that easily. see comment in updateMap(map)
192 */
193 foreach (Actor *tmp, m_actors)
194 {
195 QPoint oldpos = CoordToMapPosition(tmp->pos().toPoint());
196 validpos.removeAll(oldpos);
197 }
198
199 if (validpos.empty())
200 return QPoint();
201
202 rand = (int) (validpos.size() * (qrand() / (RAND_MAX + 1.0)));
203 QPoint pos = validpos.at(rand);
204 map[pos.x()][pos.y()] = type;
205 return pos;
206}
207
164bool Server::waitForClientConnections() 208bool Server::waitForClientConnections()
165{ 209{
166 // server must stay alive as long as sockets (qt parent mem mechanism) 210 // server must stay alive as long as sockets (qt parent mem mechanism)
@@ -185,14 +229,12 @@ bool Server::waitForClientConnections()
185 QTcpSocket *socket = tcpSrv->nextPendingConnection(); 229 QTcpSocket *socket = tcpSrv->nextPendingConnection();
186 connect(socket, SIGNAL(readyRead()), this, SLOT(keyPressUpdate())); 230 connect(socket, SIGNAL(readyRead()), this, SLOT(keyPressUpdate()));
187 231
188 /* assign color */ 232 /* assign color and notify client */
189 Color::Color color = Color::order[i]; 233 Color::Color color = Color::order[i];
190 m_clientConnections[color] = socket; 234 m_clientConnections[color] = socket;
191 /* notify player of color */
192 packet.set_color(color); 235 packet.set_color(color);
193 packet.set_maxplayers(m_maxplayers); 236 packet.set_maxplayers(m_maxplayers);
194 Util::sendPacket(packet, socket); 237 Util::sendPacket(packet, socket);
195
196 qDebug() << "[Connect] New Player: color=" << color; 238 qDebug() << "[Connect] New Player: color=" << color;
197 } 239 }
198 240
diff --git a/pacman-c++/server.h b/pacman-c++/server.h
index dac5d1c..0f2879d 100644
--- a/pacman-c++/server.h
+++ b/pacman-c++/server.h
@@ -34,6 +34,8 @@ protected:
34 /* update client maps */ 34 /* update client maps */
35 void sendUpdate(Transmission::map_t map); 35 void sendUpdate(Transmission::map_t map);
36 36
37 QPoint addRandomPoint(Transmission::map_t map, Transmission::field_t type = Transmission::bonuspoint);
38
37protected: 39protected:
38 QMap<Color::Color, QTcpSocket *> m_clientConnections; 40 QMap<Color::Color, QTcpSocket *> m_clientConnections;
39 41
diff --git a/pacman-c++/util.cpp b/pacman-c++/util.cpp
index 2a3b78a..708d005 100644
--- a/pacman-c++/util.cpp
+++ b/pacman-c++/util.cpp
@@ -77,7 +77,13 @@ namespace Util
77 77
78 void placeActors(Transmission::map_t map, unsigned int players, const Color::Color *colors) 78 void placeActors(Transmission::map_t map, unsigned int players, const Color::Color *colors)
79 { 79 {
80 int mindistance = 5; 80#if 0
81 for(unsigned int i = 0; i < players; ++i)
82 map[i][0] = colors[i] | Transmission::pacman | Transmission::direction_none;
83 return;
84#endif
85
86 int mindistance = Constants::Game::player_minimum_distance;
81 /* this outer loop is used if there are no more valid places left 87 /* this outer loop is used if there are no more valid places left
82 * so we can change mindistance 88 * so we can change mindistance
83 */ 89 */
@@ -107,9 +113,9 @@ namespace Util
107 int rand = (int) (validpos.size() * (qrand() / (RAND_MAX + 1.0))); 113 int rand = (int) (validpos.size() * (qrand() / (RAND_MAX + 1.0)));
108 QPoint newpos = validpos.at(rand); 114 QPoint newpos = validpos.at(rand);
109 map[newpos.x()][newpos.y()] = colors[i] | Transmission::pacman | Transmission::direction_none; 115 map[newpos.x()][newpos.y()] = colors[i] | Transmission::pacman | Transmission::direction_none;
116 qDebug() << "Actor" << i << "at" << newpos;
110 actors.append(newpos); 117 actors.append(newpos);
111 validpos.removeAt(rand); 118 validpos.removeAt(rand);
112 qDebug() << "actor" << colors[i] << "at" << newpos;
113 119
114 QMutableListIterator<QPoint> j(validpos); 120 QMutableListIterator<QPoint> j(validpos);
115 while(j.hasNext()) 121 while(j.hasNext())
@@ -123,14 +129,14 @@ namespace Util
123 if (validpos.empty()) 129 if (validpos.empty())
124 { 130 {
125 qWarning() << "There are no more valid positions for actors left on the map"; 131 qWarning() << "There are no more valid positions for actors left on the map";
126 mindistance -= 2; 132 mindistance -= Constants::Game::player_distance_decr;
127 break; 133 break;
128 } 134 }
129 } 135 }
130 } 136 }
131 } 137 }
132 138
133 void makePoints(Transmission::map_t map) 139 void fillPoints(Transmission::map_t map, Transmission::field_t type)
134 { 140 {
135 /* auto place normal points*/ 141 /* auto place normal points*/
136 for (unsigned int x = 0; x < Constants::map_size.width; ++x) 142 for (unsigned int x = 0; x < Constants::map_size.width; ++x)
@@ -139,7 +145,7 @@ namespace Util
139 { 145 {
140 Transmission::field_t &cur = map[x][y]; 146 Transmission::field_t &cur = map[x][y];
141 if (cur == Transmission::none) 147 if (cur == Transmission::none)
142 cur |= Transmission::point; 148 cur = type;
143 else if (cur == Transmission::point) 149 else if (cur == Transmission::point)
144 cur = Transmission::none; 150 cur = Transmission::none;
145 } 151 }
diff --git a/pacman-c++/util.h b/pacman-c++/util.h
index a9ddbee..9812bc4 100644
--- a/pacman-c++/util.h
+++ b/pacman-c++/util.h
@@ -12,7 +12,7 @@ namespace Util
12 Transmission::map_t createUninitialisedMap(); 12 Transmission::map_t createUninitialisedMap();
13 Transmission::map_t createDemoMap(); 13 Transmission::map_t createDemoMap();
14 void placeActors(Transmission::map_t map, unsigned int players, const Color::Color *colors); 14 void placeActors(Transmission::map_t map, unsigned int players, const Color::Color *colors);
15 void makePoints(Transmission::map_t map); 15 void fillPoints(Transmission::map_t map, Transmission::field_t type = Transmission::point);
16 Transmission::map_t createEmptyMap(); 16 Transmission::map_t createEmptyMap();
17 void deleteMap(Transmission::map_t map); 17 void deleteMap(Transmission::map_t map);
18 18