void Client::updated() { stillAlive(); // get the information in statusBuffer statusBuffer = client->status(); // and deal with what it says if(statusBuffer.section("?", 0, 0) == "ERROR") { if (statusBuffer.section("?", 1, 1) == "FATAL") { emit disconnect(statusBuffer.section("?", 2, 2), thread); } else if (statusBuffer.section("?", 1, 1) == "RECOVERABLE") { emit couldntConnect(statusBuffer.section("?", 2, 2), thread); } else emit jobFailed("Bad plugin error string.", thread); } else if (statusBuffer.section("?", 0, 0) == "PROGRESS") { // here is the status update code emit changed(statusBuffer.section("?", 1, 1), thread, statusBuffer.section("?", 2, 2).toInt()); } else if (statusBuffer.section("?", 0, 0) == "CONNECTED") { // yay! It connected... now get to it, slacker emit connected(statusBuffer.section("?", 1, 1), thread); } else if (statusBuffer.section("?", 0, 0) == "RESULT") { if (statusBuffer.section("?", 1, 1) == "TRUE") { if (!Loaded) { Loaded = true; emit continueRender("Loaded file successfully", thread); } } else // emit to say that the result was bad emit jobFailed("Job Failed", thread); } else if (statusBuffer.section("?", 0, 0) == "ECHO") { emit echo(statusBuffer.section("?",1,-1), thread); } else if (statusBuffer.section("?", 0, 0) == "OUTPUT") { // can change later to check for successful creation of filename emit echo(statusBuffer.section("?", 1, 1), thread); emit jobDone("Job finished", thread); } else emit echo(statusBuffer, thread); }
bool Highlighter::isRunning() const { if (!started_) return false; return stillAlive(); }
std::vector<bool> Halite::processNextFrame(std::vector<bool> alive) { //Update alive frame counts for(unsigned char a = 0; a < number_of_players; a++) if(alive[a]) alive_frame_count[a]++; //Create threads to send/receive data to/from players. The threads should return a float of how much time passed between the end of their message being sent and the end of the AI's message being sent. std::vector< std::future<unsigned int> > frameThreads(std::count(alive.begin(), alive.end(), true)); unsigned char threadLocation = 0; //Represents place in frameThreads. //Figure out how long each AI is permitted to respond without penalty in milliseconds. std::vector<int> allowableTimesToRespond(number_of_players); const int BOT_FRAME_TIMEOUT_MILLIS = 50 + ((game_map.map_width * game_map.map_height) / 2); for(unsigned char a = 0; a < number_of_players; a++) allowableTimesToRespond[a] = BOT_FRAME_TIMEOUT_MILLIS; //Stores the messages sent by bots this frame for(unsigned char a = 0; a < number_of_players; a++) { if(alive[a]) { frameThreads[threadLocation] = std::async(&Networking::handleFrameNetworking, &networking, allowableTimesToRespond[a], a + 1, game_map, &player_moves[a]); threadLocation++; } } std::vector< std::vector<unsigned char> > moveDirections(game_map.map_height, std::vector<unsigned char>(game_map.map_width, 0)); //Join threads. Figure out if the player responded in an allowable amount of time or if the player has timed out. std::vector<unsigned short> permissibleTime(number_of_players, false); threadLocation = 0; //Represents place in frameThreads. for(unsigned char a = 0; a < number_of_players; a++) { if(alive[a]) { unsigned short millis = frameThreads[threadLocation].get(); if(millis < BOT_FRAME_TIMEOUT_MILLIS) { permissibleTime[a] = true; } // There was an exception in the networking thread or the player timed out. Either way, kill their thread else { if(!program_output_style) std::cout << player_names[a] << " timed out\n"; permissibleTime[a] = false; networking.killPlayer(a + 1); } threadLocation++; total_response_time[a] += millis; } } std::vector< std::map<hlt::Location, unsigned char> > pieces(number_of_players); //For each player, use their moves to create the pieces map. for(unsigned char a = 0; a < number_of_players; a++) if(alive[a]) { //Add in pieces according to their moves. Also add in a second piece corresponding to the piece left behind. for(auto b = player_moves[a].begin(); b != player_moves[a].end(); b++) if(game_map.inBounds(b->loc) && game_map.getSite(b->loc, STILL).owner == a + 1) { if(b->dir == STILL) { if(game_map.getSite(b->loc, STILL).strength + game_map.getSite(b->loc, STILL).production <= 255) game_map.getSite(b->loc, STILL).strength += game_map.getSite(b->loc, STILL).production; else game_map.getSite(b->loc, STILL).strength = 255; //Update full still count full_still_count[a]++; //Add to full production full_production_count[a] += game_map.getSite(b->loc, STILL).production; } //Update full caridnal count. else full_cardinal_count[a]++; //Update moves moveDirections[b->loc.y][b->loc.x] = b->dir; hlt::Location newLoc = game_map.getLocation(b->loc, b->dir); if(pieces[a].count(newLoc)) { if(short(pieces[a][newLoc]) + game_map.getSite(b->loc, STILL).strength <= 255) pieces[a][newLoc] += game_map.getSite(b->loc, STILL).strength; else pieces[a][newLoc] = 255; } else { pieces[a].insert(std::pair<hlt::Location, unsigned char>(newLoc, game_map.getSite(b->loc, STILL).strength)); } //Add in a new piece with a strength of 0 if necessary. if(!pieces[a].count(b->loc)) { pieces[a].insert(std::pair<hlt::Location, unsigned char>(b->loc, 0)); } //Erase from the game map so that the player can't make another move with the same piece. game_map.getSite(b->loc, STILL).owner = 0; game_map.getSite(b->loc, STILL).strength = 0; } } //Add in all of the remaining pieces whose moves weren't specified. for(unsigned short a = 0; a < game_map.map_height; a++) for(unsigned short b = 0; b < game_map.map_width; b++) { hlt::Location l = { b, a }; hlt::Site & s = game_map.getSite(l, STILL); if(s.owner != 0) { if(short(s.strength) + s.production <= 255) { s.strength += s.production; } else s.strength = 255; if(pieces[s.owner - 1].count(l)) { if(short(pieces[s.owner - 1][l]) + s.strength <= 255) pieces[s.owner - 1][l] += s.strength; else pieces[s.owner - 1][l] = 255; } else { pieces[s.owner - 1].insert(std::pair<hlt::Location, unsigned char>(l, s.strength)); } //Add to full production full_production_count[s.owner - 1] += s.production; //Update full still count full_still_count[s.owner - 1]++; //Erase from game map. s.owner = 0; s.strength = 0; } } std::vector< std::map<hlt::Location, unsigned short> > toInjure(number_of_players); std::vector< std::vector<unsigned short> > injureMap(game_map.map_height, std::vector<unsigned short>(game_map.map_width, 0)); //Sweep through locations and find the correct damage for each piece. Start by applying damage within only the active strengths. for(unsigned char a = 0; a != game_map.map_height; a++) for(unsigned short b = 0; b < game_map.map_width; b++) { hlt::Location l = { b, a }; for(unsigned short c = 0; c < number_of_players; c++) if(alive[c] && pieces[c].count(l)) { for(unsigned short d = 0; d < number_of_players; d++) if(d != c && alive[d]) { hlt::Location tempLoc = l; //Check 'STILL' square. We also need to deal with the threshold here: if(pieces[d].count(tempLoc)) { //Apply damage, but not more than they have strength: if(toInjure[d].count(tempLoc)) toInjure[d][tempLoc] += pieces[c][l]; else toInjure[d].insert(std::pair<hlt::Location, unsigned short>(tempLoc, pieces[c][l])); } //Check 'NORTH' square: tempLoc = game_map.getLocation(l, NORTH); if(pieces[d].count(tempLoc)) { //Apply damage, but not more than they have strength: if(toInjure[d].count(tempLoc)) toInjure[d][tempLoc] += pieces[c][l]; else toInjure[d].insert(std::pair<hlt::Location, unsigned short>(tempLoc, pieces[c][l])); } //Check 'EAST' square: tempLoc = game_map.getLocation(l, EAST); if(pieces[d].count(tempLoc)) { //Apply damage, but not more than they have strength: if(toInjure[d].count(tempLoc)) toInjure[d][tempLoc] += pieces[c][l]; else toInjure[d].insert(std::pair<hlt::Location, unsigned short>(tempLoc, pieces[c][l])); } //Check 'SOUTH' square: tempLoc = game_map.getLocation(l, SOUTH); if(pieces[d].count(tempLoc)) { //Apply damage, but not more than they have strength: if(toInjure[d].count(tempLoc)) toInjure[d][tempLoc] += pieces[c][l]; else toInjure[d].insert(std::pair<hlt::Location, unsigned short>(tempLoc, pieces[c][l])); } //Check 'WEST' square: tempLoc = game_map.getLocation(l, WEST); if(pieces[d].count(tempLoc)) { //Apply damage, but not more than they have strength: if(toInjure[d].count(tempLoc)) toInjure[d][tempLoc] += pieces[c][l]; else toInjure[d].insert(std::pair<hlt::Location, unsigned short>(tempLoc, pieces[c][l])); } } if(game_map.getSite(l, STILL).strength > 0) { if(toInjure[c].count(l)) toInjure[c][l] += game_map.getSite(l, STILL).strength; else toInjure[c].insert(std::pair<hlt::Location, unsigned short>(l, game_map.getSite(l, STILL).strength)); injureMap[l.y][l.x] += pieces[c][l]; } } } //Injure and/or delete pieces. Note >= rather than > indicates that pieces with a strength of 0 are killed. for(unsigned char a = 0; a < number_of_players; a++) if(alive[a]) { for(auto b = toInjure[a].begin(); b != toInjure[a].end(); b++) { //Apply damage. if(b->second >= pieces[a][b->first]) pieces[a].erase(b->first); else pieces[a][b->first] -= b->second; } } //Apply damage to map pieces. for(int a = 0; a < game_map.map_height; a++) for(int b = 0; b < game_map.map_width; b++) { if(game_map.contents[a][b].strength < injureMap[a][b]) game_map.contents[a][b].strength = 0; else game_map.contents[a][b].strength -= injureMap[a][b]; game_map.contents[a][b].owner = 0; } //Add pieces back into the map. for(unsigned char a = 0; a < number_of_players; a++) { for(auto b = pieces[a].begin(); b != pieces[a].end(); b++) { game_map.getSite(b->first, STILL).owner = a + 1; game_map.getSite(b->first, STILL).strength = b->second; } } std::vector<unsigned char> * turn = new std::vector<unsigned char>; turn->reserve(game_map.map_height * game_map.map_width * 2.25); for(auto a = moveDirections.begin(); a != moveDirections.end(); a++) for(auto b = a->begin(); b != a->end(); b++) { turn->push_back(*b); } unsigned char presentOwner = game_map.contents.begin()->begin()->owner; std::list<unsigned char> strengths; short numPieces = 0; for(auto a = game_map.contents.begin(); a != game_map.contents.end(); a++) for(auto b = a->begin(); b != a->end(); b++) { if(numPieces == 255 || b->owner != presentOwner) { turn->push_back(numPieces); turn->push_back(presentOwner); for(auto b = strengths.begin(); b != strengths.end(); b++) turn->push_back(*b); strengths.clear(); numPieces = 0; presentOwner = b->owner; } numPieces++; strengths.push_back(b->strength); } //Final output set: turn->push_back(numPieces); turn->push_back(presentOwner); for(auto b = strengths.begin(); b != strengths.end(); b++) turn->push_back(*b); turn->shrink_to_fit(); //Add to full game: full_game.push_back(turn); //Check if the game is over: std::vector<bool> stillAlive(number_of_players, false); for(unsigned short a = 0; a < game_map.map_height; a++) for(unsigned short b = 0; b < game_map.map_width; b++) if(game_map.contents[a][b].owner != 0) { full_territory_count[game_map.contents[a][b].owner - 1]++; full_strength_count[game_map.contents[a][b].owner - 1] += game_map.contents[a][b].strength; full_production_count[game_map.contents[a][b].owner - 1] += game_map.contents[a][b].strength; stillAlive[game_map.contents[a][b].owner - 1] = true; } //Check for bots which have timed out. for(unsigned char a = 0; a < permissibleTime.size(); a++) if(alive[a] && !permissibleTime[a]) { stillAlive[a] = false; timeout_tags.insert(a + 1); } return stillAlive; }