Line data Source code
1 : #include <client.hpp>
2 : #include <iostream>
3 : #include <sstream>
4 : #include <sys/stat.h>
5 : #include <thread>
6 :
7 : #define REFRESH_ELEMENT 1
8 :
9 : #define WINDOW_LENGTH 1600
10 : #define WINDOW_WIDTH 900
11 :
12 : #define MENU 1
13 : #define GAME 2
14 :
15 : #ifndef RESOURCES_PATH
16 : #define RESOURCES_PATH "../resources"
17 : #endif
18 :
19 : using namespace client;
20 :
21 : /*!
22 : * @brief Constructor
23 : *
24 : * Constructor of ClientGameEngine class
25 : */
26 2 : ClientGameEngine::ClientGameEngine()
27 : {
28 2 : myself = std::make_shared<shared::Player>();
29 2 : myself->setUsername("PlayerTest");
30 2 : clientMap = std::make_shared<shared::Map>();
31 2 : playerTurn.store(false);
32 2 : endOfTurn.store(false);
33 2 : IATurn.store(false);
34 2 : clientConnectedAndReady.store(false);
35 2 : areTextureLoaded.store(false);
36 2 : }
37 :
38 2 : bool ClientGameEngine::connect(const std::string &serverAddress, int serverPort)
39 : {
40 2 : boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string(serverAddress), serverPort);
41 :
42 2 : boost::asio::ip::tcp::socket clientSocket(io_context);
43 : try
44 : {
45 2 : clientSocket.connect(endpoint);
46 : }
47 0 : catch (const boost::system::system_error &e)
48 : {
49 0 : std::cout << "Error: " << e.what() << std::endl;
50 0 : return false;
51 0 : }
52 2 : myself->setSocket(clientSocket);
53 :
54 2 : std::thread t(&ClientGameEngine::startReceiving, this);
55 :
56 : {
57 2 : std::lock_guard<std::mutex> lock(myself->socketWriteMutex);
58 4 : std::string msg = this->gameId + " " + myself->getName() + "\n";
59 2 : boost::asio::write(myself->getSocket(), boost::asio::buffer(msg));
60 2 : }
61 :
62 2 : t.detach();
63 :
64 2 : return true;
65 2 : }
66 :
67 2 : void ClientGameEngine::startReceiving()
68 : {
69 :
70 15 : while (myself->connectedToSocket.load())
71 : {
72 :
73 15 : boost::asio::streambuf receiveBuffer;
74 15 : boost::system::error_code error;
75 : {
76 15 : std::lock_guard<std::mutex> lock(myself->socketReadMutex);
77 15 : boost::asio::read_until(myself->getSocket(), receiveBuffer, '\n', error);
78 13 : }
79 :
80 13 : if (error == boost::asio::error::operation_aborted)
81 : {
82 0 : myself->disconnectPlayer();
83 0 : continue;
84 : }
85 13 : if (receiveBuffer.size() > 0)
86 : {
87 13 : processMessage(receiveBuffer);
88 13 : receiveBuffer.consume(receiveBuffer.size());
89 : }
90 13 : }
91 0 : }
92 :
93 13 : void ClientGameEngine::processMessage(boost::asio::streambuf &receiveBuffer)
94 : {
95 13 : std::istream receiveStream(&receiveBuffer);
96 13 : std::string messageReceived;
97 26 : while (std::getline(receiveStream, messageReceived))
98 : {
99 13 : if (messageReceived.size() == 0)
100 : {
101 0 : continue;
102 : }
103 13 : else if (messageReceived.find("response") == 0)
104 : {
105 3 : registerServerAnswer(messageReceived);
106 : }
107 10 : else if (messageReceived.find("binary") == 0) // binary reception
108 : {
109 2 : size_t size = std::stoi(messageReceived.substr(7));
110 2 : std::string data = binary.receive(myself, receiveStream, size);
111 2 : registerServerAnswer(data);
112 2 : }
113 8 : else if (messageReceived.find("rulesturn") == 0) // binary reception without response
114 : {
115 0 : shared::RuleArgsStruct ruleArgs;
116 :
117 0 : size_t size = std::stoi(messageReceived.substr(10));
118 0 : std::string bin = binary.receive(myself, receiveStream, size);
119 0 : binary.castToObject(bin, ruleArgs);
120 :
121 0 : runRule(ruleArgs);
122 0 : }
123 : else
124 : {
125 8 : processServerRequest(messageReceived);
126 : }
127 : }
128 13 : }
129 :
130 0 : void ClientGameEngine::runRule(shared::RuleArgsStruct ruleArgs)
131 : {
132 0 : shared::Rules rules;
133 0 : ruleArgs.gameMap = clientMap;
134 0 : if (myself->getName() == ruleArgs.playerName)
135 : {
136 0 : ruleArgs.currentPlayer = myself;
137 0 : rules.runTheRule(ruleArgs);
138 0 : clientGame->rotateTechWheel(myself->getTechLevel());
139 : }
140 : else
141 : {
142 0 : for (auto player : otherPlayers)
143 : {
144 0 : if (player->getName() == ruleArgs.playerName)
145 : {
146 0 : ruleArgs.currentPlayer = player;
147 0 : rules.runTheRule(ruleArgs);
148 : }
149 0 : }
150 : }
151 0 : }
152 :
153 3 : void checkOk(std::string &response)
154 : {
155 3 : if (response.find("ok") == std::string::npos)
156 : {
157 0 : std::cout << "Error in server response: " << response << std::endl;
158 0 : exit(1);
159 : }
160 3 : }
161 :
162 1 : void ClientGameEngine::generateMap(const unsigned height, const unsigned width, const int seed)
163 : {
164 1 : std::unique_lock<std::mutex> lock(myself->qAndA.sharedDataMutex);
165 1 : lock.unlock();
166 1 : if (myself->connectedToSocket.load() == false)
167 : {
168 0 : std::cout << "You are not connected to the server" << std::endl;
169 0 : exit(1);
170 : }
171 1 : else if (clientConnectedAndReady.load() == false)
172 : {
173 0 : std::cout << "Server is not ready" << std::endl;
174 0 : exit(1);
175 : }
176 :
177 1 : if (height > 0)
178 : {
179 1 : lock.lock();
180 1 : myself->qAndA.question = "setmapparam height " + std::to_string(height) + "\n";
181 1 : lock.unlock();
182 1 : askServer();
183 1 : checkOk(myself->qAndA.answer);
184 : }
185 1 : if (width > 0)
186 : {
187 1 : lock.lock();
188 1 : myself->qAndA.question = "setmapparam width " + std::to_string(width) + "\n";
189 1 : lock.unlock();
190 1 : askServer();
191 1 : checkOk(myself->qAndA.answer);
192 : }
193 1 : lock.lock();
194 1 : myself->qAndA.question = "setmapparam generate " + std::to_string(seed) + "\n";
195 1 : lock.unlock();
196 1 : askServer();
197 1 : checkOk(myself->qAndA.answer);
198 1 : }
199 :
200 2 : void ClientGameEngine::loadMap()
201 : {
202 2 : if (myself->connectedToSocket.load() == false)
203 : {
204 0 : std::cout << "You are not connected to the server" << std::endl;
205 0 : exit(1);
206 : }
207 2 : else if (clientConnectedAndReady.load() == false)
208 : {
209 0 : std::cout << "Server is not ready" << std::endl;
210 0 : exit(1);
211 : }
212 2 : std::unique_lock<std::mutex> lock(myself->qAndA.sharedDataMutex);
213 2 : myself->qAndA.question = "getmap\n";
214 2 : lock.unlock();
215 :
216 2 : askServer();
217 2 : lock.lock();
218 2 : if (clientMap == nullptr)
219 : {
220 0 : clientMap = std::make_shared<shared::Map>();
221 : }
222 2 : binary.castToObject(myself->qAndA.answer, *clientMap);
223 2 : lock.unlock();
224 2 : }
225 :
226 5 : void ClientGameEngine::registerServerAnswer(const std::string &response)
227 : {
228 5 : std::lock_guard<std::mutex> lock(myself->qAndA.sharedDataMutex);
229 5 : myself->qAndA.answer = response;
230 5 : myself->qAndA.answerReady = true;
231 5 : myself->qAndA.condition.notify_one();
232 5 : }
233 :
234 8 : void ClientGameEngine::processServerRequest(std::string request)
235 : {
236 8 : if (request.find("chat") == 0)
237 : {
238 2 : request = request.substr(5);
239 2 : printChat(request);
240 : }
241 6 : else if (request.find("playturn") == 0)
242 : {
243 1 : if (myself->getName() == "IA" || myself->getName() == "random")
244 : {
245 0 : IATurn.store(true);
246 : }
247 : else
248 : {
249 1 : playerTurn.store(true);
250 : }
251 : }
252 5 : else if (request.find("connected") == 0)
253 : {
254 2 : request = request.substr(10);
255 2 : clientConnectedAndReady.store(true);
256 :
257 2 : serverGameId = request.substr(request.length() - 6);
258 2 : printChat(request);
259 : }
260 3 : else if (request.find("newplayer") == 0)
261 : {
262 2 : std::string player = request.substr(23);
263 2 : if (clientGame != nullptr)
264 : {
265 0 : clientGame->addPlayer(player);
266 : }
267 2 : request = request.substr(10) + " join the game";
268 2 : printChat(request);
269 :
270 2 : if (player != myself->getName())
271 : {
272 1 : otherPlayers.push_back(std::make_shared<shared::Player>(player));
273 : }
274 2 : }
275 1 : else if (request.find("infoplayer") == 0)
276 : {
277 1 : std::string player = request.substr(11);
278 1 : if (clientGame != nullptr)
279 : {
280 0 : clientGame->addPlayer(player);
281 : }
282 :
283 1 : if (player != myself->getName())
284 : {
285 1 : otherPlayers.push_back(std::make_shared<shared::Player>(player));
286 : }
287 1 : }
288 : else
289 : {
290 0 : std::cout << "Received request: " << request << std::endl;
291 : }
292 8 : }
293 :
294 6 : void ClientGameEngine::printChat(const std::string &message)
295 : {
296 6 : if (clientGame == nullptr)
297 : {
298 6 : return;
299 : }
300 0 : if (clientGame->chatBox != nullptr)
301 : {
302 0 : size_t firstSpace = message.find(" ");
303 0 : std::string chatTime = message.substr(0, firstSpace);
304 0 : size_t secondSpace = message.find(" ", firstSpace + 1);
305 0 : std::string chatUsername = message.substr(firstSpace + 1, secondSpace - firstSpace - 1);
306 0 : std::string chatMessage = message.substr(secondSpace + 1);
307 :
308 0 : clientGame->chatBox->updateChat(chatTime, chatUsername, chatMessage);
309 0 : }
310 : }
311 :
312 5 : void ClientGameEngine::askServer()
313 : {
314 5 : std::unique_lock<std::mutex> responseLock(myself->qAndA.sharedDataMutex);
315 5 : myself->qAndA.answerReady = false;
316 : {
317 5 : std::lock_guard<std::mutex> lock(myself->socketWriteMutex);
318 5 : boost::asio::write(myself->getSocket(), boost::asio::buffer(myself->qAndA.question));
319 5 : }
320 :
321 5 : myself->qAndA.condition.wait(responseLock, [&]
322 10 : { return myself->qAndA.answerReady; });
323 :
324 5 : std::string response = myself->qAndA.answer;
325 5 : myself->qAndA.answerReady = false;
326 5 : }
327 :
328 : /*!
329 : * @brief Print where the user click on the GameWindow
330 : * @param x position on x axis
331 : * @param y position on y axis
332 : */
333 0 : void ClientGameEngine::handleInformation(int x, int y)
334 : {
335 0 : if (playerTurn.load() == false)
336 : {
337 0 : return;
338 : }
339 : std::array<unsigned, 2> position;
340 0 : if (ruleArgsStruct.ruleId == shared::CardsEnum::economy)
341 : {
342 0 : position = {(unsigned)x, (unsigned)y};
343 0 : ruleArgsStruct.caravanMovementPath.push_back(position);
344 : }
345 0 : if (ruleArgsStruct.ruleId == shared::CardsEnum::culture)
346 : {
347 0 : position = {(unsigned)x, (unsigned)y};
348 0 : ruleArgsStruct.pawnsPositions.push_back(position);
349 : }
350 0 : if (ruleArgsStruct.ruleId == shared::CardsEnum::industry) // TODO : add the posibility to build wonder
351 : {
352 0 : position = {(unsigned)x, (unsigned)y};
353 0 : ruleArgsStruct.positionOfCity = position;
354 0 : ruleArgsStruct.industryCardBuildWonder = false;
355 : }
356 0 : if (ruleArgsStruct.ruleId == shared::CardsEnum::military)
357 : {
358 0 : position = {(unsigned)x, (unsigned)y};
359 0 : ruleArgsStruct.pawnsPositions.push_back(position);
360 0 : ruleArgsStruct.militaryCardAttack = false;
361 : }
362 : }
363 :
364 : /*!
365 : * @brief Print which priority card the user wants to play and its difficulty
366 : * @param typePlayed type of the priority card played (economy, science, culture, ...)
367 : * @param difficulty level of difficulty played (0 to 4 for the 5 fields)
368 : */
369 0 : void ClientGameEngine::handlePriorityCardPlay(std::string typePlayed, int difficulty, int boxes)
370 : {
371 0 : if (playerTurn.load() == false)
372 : {
373 0 : return;
374 : }
375 0 : if (typePlayed == "economy")
376 : {
377 0 : clientGame->modifyTextForUser("Click on the hexagons of the path");
378 0 : ruleArgsStruct.ruleId = shared::CardsEnum::economy;
379 : }
380 0 : else if (typePlayed == "science")
381 : {
382 0 : clientGame->modifyTextForUser("you can finish your turn");
383 0 : ruleArgsStruct.ruleId = shared::CardsEnum::science;
384 : }
385 0 : else if (typePlayed == "culture")
386 : {
387 0 : clientGame->modifyTextForUser("place pawns on the hexagons");
388 0 : ruleArgsStruct.ruleId = shared::CardsEnum::culture;
389 : }
390 0 : else if (typePlayed == "army")
391 : {
392 0 : clientGame->modifyTextForUser("choose pawns to reinforce");
393 0 : ruleArgsStruct.ruleId = shared::CardsEnum::military;
394 : }
395 0 : else if (typePlayed == "industry")
396 : {
397 0 : clientGame->modifyTextForUser("place a city");
398 0 : ruleArgsStruct.ruleId = shared::CardsEnum::industry;
399 : }
400 :
401 0 : ruleArgsStruct.numberOfBoxUsed = boxes;
402 : }
403 :
404 : /*!
405 : * @brief Change the Window for nothing, Menu or Game
406 : * @param quitDef if quitDef is true, the game stop, else it change Menu to Game
407 : */
408 2 : void ClientGameEngine::handleQuitMenu(bool quitDef)
409 : {
410 2 : if (quitDef)
411 : {
412 2 : runningWindow.store(0);
413 : // myself->disconnectPlayer();
414 : }
415 : else
416 : {
417 0 : runningWindow.store(runningWindow == MENU ? GAME : MENU);
418 : }
419 2 : }
420 :
421 : /*!
422 : * @brief A player is connecting to a Game
423 : * @param id game ID, = new for a new Game
424 : * @param username player username
425 : * @param server serveur adresse
426 : * @param port port number
427 : */
428 0 : bool ClientGameEngine::tryConnection(std::string id, std::string username, std::string server, std::string port)
429 : {
430 0 : myself->setUsername(username);
431 :
432 : int portNumber;
433 0 : std::stringstream sStream(port);
434 0 : if ((sStream >> portNumber).fail())
435 : {
436 0 : return false;
437 : }
438 :
439 0 : gameId = id;
440 :
441 0 : return connect(server, portNumber);
442 0 : }
443 :
444 2 : void ClientGameEngine::waitToBeReady()
445 : {
446 4 : while (clientConnectedAndReady.load() == false)
447 : {
448 2 : std::this_thread::sleep_for(std::chrono::milliseconds(100));
449 : }
450 2 : }
451 :
452 : /*!
453 : * @brief Start the loop that manage the GameWindow
454 : */
455 0 : void ClientGameEngine::startGameWindow()
456 : {
457 0 : if (myself->connectedToSocket.load() && gameId == "new")
458 : {
459 0 : waitToBeReady();
460 0 : generateMap(11, 15, rand() % 1000000000);
461 0 : loadMap();
462 : }
463 0 : else if (myself->connectedToSocket.load())
464 : {
465 0 : waitToBeReady();
466 0 : loadMap();
467 : }
468 : else
469 : {
470 0 : std::cout << "You are not connected to the server" << std::endl;
471 0 : std::cout << "Map has been generated locally." << std::endl;
472 0 : clientMap->generateRandomMap(rand() % 1000000000);
473 : }
474 :
475 0 : clientGame->mapShared = clientMap;
476 0 : clientGame->startGame();
477 0 : }
478 :
479 : /*!
480 : * @brief Start the loop that manage the MenuWindow
481 : */
482 0 : void ClientGameEngine::startMenuWindow()
483 : {
484 0 : clientMenu->startMenu();
485 0 : }
486 :
487 : /*!
488 : * @brief Loop that manage the entire Engine
489 : */
490 0 : void ClientGameEngine::renderGame()
491 : {
492 0 : clientWindow = std::make_shared<sf::RenderWindow>();
493 0 : clientWindow->create(sf::VideoMode(WINDOW_LENGTH, WINDOW_WIDTH),
494 : "Civilization VII",
495 : sf::Style::Close);
496 :
497 0 : clientWindow->setPosition(sf::Vector2i(0, 0));
498 :
499 0 : clientGame = std::make_unique<GameWindow>();
500 0 : clientMenu = std::make_unique<MenuWindow>();
501 :
502 0 : clientMenu->gameEnginePtr = this;
503 0 : clientGame->gameEnginePtr = this;
504 :
505 0 : while (runningWindow.load())
506 : {
507 0 : if (runningWindow.load() == GAME)
508 : {
509 0 : playGame();
510 : }
511 0 : else if (runningWindow.load() == MENU)
512 : {
513 0 : playMenu();
514 : }
515 : }
516 0 : clientWindow->close();
517 0 : }
518 :
519 : /*!
520 : * @brief Loop that is used when the client is in GameMode
521 : */
522 0 : void ClientGameEngine::playGame()
523 : {
524 :
525 0 : std::thread t(&ClientGameEngine::startGameWindow, this);
526 :
527 0 : long lastUpdateTimer = clientGame->getCurrentTime();
528 :
529 0 : while (areTextureLoaded.load() == false)
530 : ;
531 :
532 0 : while (runningWindow.load() == GAME)
533 : {
534 0 : if (clientGame->getCurrentTime() - lastUpdateTimer > REFRESH_ELEMENT)
535 : {
536 0 : lastUpdateTimer = clientGame->getCurrentTime();
537 0 : clientGame->updateElementTexture();
538 : }
539 0 : if (playerTurn.load())
540 : {
541 0 : clientGame->modifyTextForUser("It's your turn !");
542 0 : playTurn();
543 : }
544 0 : if (IATurn.load())
545 : {
546 0 : randomIA();
547 : }
548 : }
549 0 : t.join();
550 0 : }
551 :
552 0 : void ClientGameEngine::playTurn()
553 : {
554 0 : if (endOfTurn.load())
555 : {
556 0 : clientGame->modifyTextForUser("");
557 0 : std::string struc;
558 0 : binary.castToBinary(ruleArgsStruct, struc);
559 0 : binary.send(myself, struc);
560 0 : ruleArgsStruct = shared::RuleArgsStruct();
561 0 : playerTurn.store(false);
562 0 : endOfTurn.store(false);
563 0 : }
564 0 : }
565 :
566 : /*!
567 : * @brief Loop that is used when the client is in MenuMode
568 : */
569 0 : void ClientGameEngine::playMenu()
570 : {
571 0 : std::thread t(&ClientGameEngine::startMenuWindow, this);
572 0 : t.join();
573 0 : }
574 :
575 : /*!
576 : * @brief Detect an intersection between a point and a rect
577 : * @param point the point
578 : * @param rectangle the rectangle
579 : */
580 0 : bool ClientGameEngine::intersectPointRect(sf::Vector2i point, sf::FloatRect rectangle)
581 : {
582 0 : return (point.x >= rectangle.left &&
583 0 : point.x <= rectangle.left + rectangle.width &&
584 0 : point.y >= rectangle.top &&
585 0 : point.y <= rectangle.top + rectangle.height);
586 : }
587 :
588 0 : void ClientGameEngine::handleEndTurnButton()
589 : {
590 0 : if (playerTurn.load())
591 : {
592 0 : endOfTurn.store(true);
593 : }
594 0 : }
595 :
596 0 : void ClientGameEngine::randomIA()
597 : {
598 0 : std::cout << "randomIA" << std::endl;
599 0 : std::array<shared::CardsEnum, 5> ruleIDList = {shared::CardsEnum::economy, shared::CardsEnum::science, shared::CardsEnum::military, shared::CardsEnum::culture, shared::CardsEnum::industry};
600 0 : shared::CardsEnum cardPlayed = ruleIDList[std::rand() % 5];
601 0 : std::cout << "cardPlayed: " << (int)cardPlayed << std::endl;
602 :
603 0 : ruleArgsStruct.playerName = myself->getName();
604 0 : ruleArgsStruct.ruleId = cardPlayed;
605 0 : unsigned numberOfBox = myself->getNumberOfBox(cardPlayed);
606 0 : std::cout << "numberOfBox: " << numberOfBox << std::endl;
607 0 : unsigned numberOfBoxUsed = std::rand() % (numberOfBox + 1);
608 0 : ruleArgsStruct.numberOfBoxUsed = numberOfBoxUsed;
609 0 : std::cout << "numberOfBoxUsed: " << ruleArgsStruct.numberOfBoxUsed << std::endl;
610 :
611 0 : int difficulty = myself->getDificultyOfCard(cardPlayed);
612 0 : int randomNumber = 0;
613 0 : int exitLoop = 0;
614 : std::array<unsigned, 2> position;
615 0 : std::vector<std::array<unsigned, 2>> neighbors;
616 0 : shared::Rules rules;
617 0 : switch (cardPlayed)
618 : {
619 0 : case shared::CardsEnum::economy:
620 0 : std::cout << "economy" << std::endl;
621 0 : position[0] = (unsigned)(std::rand() % clientMap->getMapWidth());
622 0 : position[1] = (unsigned)(std::rand() % clientMap->getMapHeight());
623 0 : ruleArgsStruct.caravanMovementPath.push_back(position);
624 :
625 0 : randomNumber = std::rand() % (numberOfBoxUsed + difficulty);
626 0 : for (int i = 0; i < randomNumber; i++)
627 : {
628 0 : position[0] = (unsigned)(std::rand() % clientMap->getMapWidth());
629 0 : position[1] = (unsigned)(std::rand() % clientMap->getMapHeight());
630 0 : neighbors = rules.getNeighbors(position[0], position[1], clientMap);
631 0 : ruleArgsStruct.caravanMovementPath.push_back(position);
632 : }
633 0 : break;
634 0 : case shared::CardsEnum::science:
635 0 : std::cout << "science" << std::endl;
636 0 : break;
637 0 : case shared::CardsEnum::military:
638 0 : std::cout << "military" << std::endl;
639 0 : ruleArgsStruct.militaryCardAttack = false;
640 0 : randomNumber = std::rand() % (numberOfBoxUsed + difficulty);
641 0 : for (int i = 0; i < randomNumber; i++)
642 : {
643 0 : position[0] = (unsigned)(std::rand() % clientMap->getMapWidth());
644 0 : position[1] = (unsigned)(std::rand() % clientMap->getMapHeight());
645 0 : ruleArgsStruct.pawnsPositions.push_back(position);
646 : }
647 0 : break;
648 0 : case shared::CardsEnum::culture:
649 0 : std::cout << "culture" << std::endl;
650 0 : randomNumber = std::rand() % (numberOfBoxUsed + 2); // 2=number of pawns for card level 1
651 0 : for (int i = 0; i < randomNumber; i++)
652 : {
653 0 : position[0] = (unsigned)(std::rand() % clientMap->getMapWidth());
654 0 : position[1] = (unsigned)(std::rand() % clientMap->getMapHeight());
655 0 : ruleArgsStruct.pawnsPositions.push_back(position);
656 : }
657 0 : break;
658 0 : case shared::CardsEnum::industry:
659 0 : std::cout << "industry" << std::endl;
660 0 : ruleArgsStruct.industryCardBuildWonder = false;
661 0 : position[0] = (unsigned)(std::rand() % clientMap->getMapWidth());
662 0 : position[1] = (unsigned)(std::rand() % clientMap->getMapHeight());
663 0 : ruleArgsStruct.positionOfCity = position;
664 :
665 0 : break;
666 0 : default:
667 0 : break;
668 : }
669 0 : std::string struc;
670 0 : binary.castToBinary(ruleArgsStruct, struc);
671 0 : binary.send(myself, struc);
672 0 : ruleArgsStruct = shared::RuleArgsStruct();
673 0 : std::cout << "randomIA end" << std::endl;
674 0 : IATurn.store(false);
675 :
676 0 : }
|