diff --git a/src/logger/proto b/src/logger/proto index c681c2ec..f5e44402 160000 --- a/src/logger/proto +++ b/src/logger/proto @@ -1 +1 @@ -Subproject commit c681c2ec597acd79c4b08e8385a24896626628ce +Subproject commit f5e44402736c123572df3015d5048bec1a450fa3 diff --git a/src/logger/src/logger.cpp b/src/logger/src/logger.cpp index e59c9ddf..149a9045 100644 --- a/src/logger/src/logger.cpp +++ b/src/logger/src/logger.cpp @@ -103,6 +103,7 @@ void Logger::logState() { auto bots = state->getBots(); auto towers = state->getTowers(); auto scores = state->getScores(); + auto score_manager = state->getScoreManager(); // Things logged only in first turn if (turn_count == 1) { @@ -188,6 +189,20 @@ void Logger::logState() { inst_count = 0; } + // Log turn winners + auto turn_winner = score_manager->getTurnWinner(); + switch (turn_winner) { + case PlayerId::PLAYER1: + game_state->set_turn_winner(proto::Winner::PLAYER1); + break; + case PlayerId::PLAYER2: + game_state->set_turn_winner(proto::Winner::PLAYER2); + break; + case PlayerId::PLAYER_NULL: + game_state->set_turn_winner(proto::Winner::TIE); + break; + } + // Log the errors, clear the error vectors for (auto &player_errors : errors) { auto player_error_struct = game_state->add_player_errors(); diff --git a/src/player_code/src/player_code.cpp b/src/player_code/src/player_code.cpp index efffbe5d..27e579c4 100644 --- a/src/player_code/src/player_code.cpp +++ b/src/player_code/src/player_code.cpp @@ -9,6 +9,92 @@ namespace player_code { using namespace player_state; -State PlayerCode::update(State state) { return state; } +State PlayerCode::update(State state) { + static int64_t num_turn = 0; + ++num_turn; + uint64_t num_state_bots = state.bots.size(), + num_flags = state.flag_offsets.size(); + uint64_t bot_count = 0, flag_count = 0; + + // Assigning a quarter of them to move into the center flag + for (; bot_count < num_state_bots / 4; ++bot_count) { + auto &bot = state.bots[bot_count]; + auto flag_position = state.flag_offsets[flag_count++]; + flag_count %= num_flags; + bot.move(flag_position); + } + + // Assinging another quarter to move ahead of the flag locations and create + // towers + if (num_turn % 100 == 0) { + for (; bot_count < num_state_bots / 2; ++bot_count) { + auto &bot = state.bots[bot_count]; + auto flag_position = state.flag_offsets[(flag_count++) % num_flags]; + auto nearest_buildable_position = + findNearestFreePosition(state, flag_position); + // logr << "Transforming bot\n"; + bot.transform(nearest_buildable_position); + } + } else { + // Going to enemy base and blasting + for (; bot_count < num_state_bots / 2; ++bot_count) { + auto &bot = state.bots[bot_count]; + bot.blast(Constants::Map::PLAYER2_BASE_POSITION); + } + } + + // Assigning half of the bots to create towers near enemy base location + if (num_turn % 100 == 0) { + for (; bot_count < num_state_bots; ++bot_count) { + auto &bot = state.bots[bot_count]; + auto enemy_base = Constants::Map::PLAYER2_BASE_POSITION; + auto nearest_buildable_position = + findNearestFreePosition(state, enemy_base); + bot.transform(nearest_buildable_position); + } + } else { + // Try to transform in any flag + for (; bot_count < num_state_bots; ++bot_count) { + auto &bot = state.bots[bot_count]; + auto flag_position = state.flag_offsets[flag_count++]; + flag_count %= num_flags; + bot.move(flag_position); + } + } + + // Checking if enemy bots are in range and blasting + uint64_t tower_count = state.towers.size(); + + for (uint64_t tower_index = 0; tower_index < tower_count; ++tower_index) { + // Finding total number of enemy units in range + uint64_t enemy_actors = 0; + auto &tower = state.towers[tower_index]; + uint64_t tower_range = tower.impact_radius; + + for (int64_t enemy_bot_index = 0; + enemy_bot_index < state.enemy_bots.size(); ++enemy_bot_index) { + auto &bot = state.enemy_bots[enemy_bot_index]; + if (tower.position.distance(bot.position) <= tower_range) { + ++enemy_actors; + } + } + + for (int64_t enemy_tower_index = 0; + enemy_tower_index < state.enemy_towers.size(); + ++enemy_tower_index) { + auto &enemy_tower = state.enemy_towers[enemy_tower_index]; + if (tower.position.distance(enemy_tower.position) <= tower_range) { + ++enemy_actors; + } + } + + if (enemy_actors >= 0) { + // logr << "Tower is blasting\n"; + tower.blast(); + } + } + + return state; +} } // namespace player_code diff --git a/src/state/include/state/score_manager/score_manager.h b/src/state/include/state/score_manager/score_manager.h index 0df19f1f..b5539819 100644 --- a/src/state/include/state/score_manager/score_manager.h +++ b/src/state/include/state/score_manager/score_manager.h @@ -33,6 +33,11 @@ class STATE_EXPORT ScoreManager { */ std::array num_towers; + /** + * Stores the player with more actor value in a given turn + */ + PlayerId turn_winner; + /** * Get points based on number of bots and towers owned by the player * @@ -95,5 +100,12 @@ class STATE_EXPORT ScoreManager { * @return std::array */ std::array getBotCounts() const; + + /** + * Returns the winner of the turn + * + * @return PlayerId + */ + PlayerId getTurnWinner() const; }; } // namespace state diff --git a/src/state/src/score_manager/score_manager.cpp b/src/state/src/score_manager/score_manager.cpp index faf1510c..d54347aa 100644 --- a/src/state/src/score_manager/score_manager.cpp +++ b/src/state/src/score_manager/score_manager.cpp @@ -9,10 +9,12 @@ namespace state { ScoreManager::ScoreManager() - : scores({0, 0}), num_bots({0, 0}), num_towers({0, 0}) {} + : scores({0, 0}), num_bots({0, 0}), num_towers({0, 0}), + turn_winner(PlayerId::PLAYER_NULL) {} ScoreManager::ScoreManager(std::array scores) - : scores(scores), num_bots({0, 0}), num_towers({0, 0}) {} + : scores(scores), num_bots({0, 0}), num_towers({0, 0}), + turn_winner(PlayerId::PLAYER_NULL) {} double ScoreManager::getPlayerPoints(PlayerId player_id) const { using namespace Constants::Score; @@ -61,12 +63,15 @@ void ScoreManager::updateScores() { auto points_1 = getPlayerPoints(PlayerId::PLAYER1); auto points_2 = getPlayerPoints(PlayerId::PLAYER2); - if (points_1 == points_2) + if (points_1 == points_2) { + turn_winner = PlayerId::PLAYER_NULL; return; - auto dominant_player_id = - points_1 > points_2 ? PlayerId::PLAYER1 : PlayerId::PLAYER2; - scores[static_cast(dominant_player_id)]++; + } + turn_winner = points_1 > points_2 ? PlayerId::PLAYER1 : PlayerId::PLAYER2; + scores[static_cast(turn_winner)]++; } +PlayerId ScoreManager::getTurnWinner() const { return turn_winner; } + std::array ScoreManager::getScores() const { return scores; } } // namespace state diff --git a/test/logger/logger_test.cpp b/test/logger/logger_test.cpp index 584dd2de..59d9c316 100644 --- a/test/logger/logger_test.cpp +++ b/test/logger/logger_test.cpp @@ -141,6 +141,9 @@ TEST_F(LoggerTest, WriteReadTest) { std::array scores1 = {100, 100}; std::array scores2 = {300, 200}; + EXPECT_CALL(*state, getScoreManager()) + .Times(4) + .WillRepeatedly(Return(score_manager.get())); EXPECT_CALL(*state, getScores()) .WillOnce(Return(scores1)) .WillRepeatedly(Return(scores2)); @@ -209,6 +212,8 @@ TEST_F(LoggerTest, WriteReadTest) { ASSERT_EQ(game->states(0).player_errors(1).errors(0), 2); ASSERT_EQ(game->states(0).player_errors(1).errors(1), 3); + EXPECT_EQ(game->states(0).turn_winner(), proto::Winner::TIE); + // Check if the mapping got set and the message string matches auto error_map = *game->mutable_error_map(); ASSERT_EQ(error_map[game->states(0).player_errors(0).errors(0)],