diff --git a/CAPI/cpp/.gitignore b/CAPI/cpp/.gitignore
index 291cf41b..5542e213 100755
--- a/CAPI/cpp/.gitignore
+++ b/CAPI/cpp/.gitignore
@@ -23,6 +23,7 @@ mono_crash.*
[Rr]eleases/
x64/
x86/
+cmake/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
diff --git a/CAPI/cpp/API/API.vcxproj b/CAPI/cpp/API/API.vcxproj
index 6b9f8a97..fc7ac859 100755
--- a/CAPI/cpp/API/API.vcxproj
+++ b/CAPI/cpp/API/API.vcxproj
@@ -143,7 +143,7 @@
Console
true
..\lib\debug;%(AdditionalLibraryDirectories)
- absl_bad_any_cast_impl.lib;absl_bad_optional_access.lib;absl_bad_variant_access.lib;absl_base.lib;absl_city.lib;absl_civil_time.lib;absl_cord.lib;absl_cordz_functions.lib;absl_cordz_handle.lib;absl_cordz_info.lib;absl_cordz_sample_token.lib;absl_cord_internal.lib;absl_debugging_internal.lib;absl_demangle_internal.lib;absl_examine_stack.lib;absl_exponential_biased.lib;absl_failure_signal_handler.lib;absl_flags.lib;absl_flags_commandlineflag.lib;absl_flags_commandlineflag_internal.lib;absl_flags_config.lib;absl_flags_internal.lib;absl_flags_marshalling.lib;absl_flags_parse.lib;absl_flags_private_handle_accessor.lib;absl_flags_program_name.lib;absl_flags_reflection.lib;absl_flags_usage.lib;absl_flags_usage_internal.lib;absl_graphcycles_internal.lib;absl_hash.lib;absl_hashtablez_sampler.lib;absl_int128.lib;absl_leak_check.lib;absl_log_severity.lib;absl_low_level_hash.lib;absl_malloc_internal.lib;absl_periodic_sampler.lib;absl_random_distributions.lib;absl_random_internal_distribution_test_util.lib;absl_random_internal_platform.lib;absl_random_internal_pool_urbg.lib;absl_random_internal_randen.lib;absl_random_internal_randen_hwaes.lib;absl_random_internal_randen_hwaes_impl.lib;absl_random_internal_randen_slow.lib;absl_random_internal_seed_material.lib;absl_random_seed_gen_exception.lib;absl_random_seed_sequences.lib;absl_raw_hash_set.lib;absl_raw_logging_internal.lib;absl_scoped_set_env.lib;absl_spinlock_wait.lib;absl_stacktrace.lib;absl_status.lib;absl_statusor.lib;absl_strerror.lib;absl_strings.lib;absl_strings_internal.lib;absl_str_format_internal.lib;absl_symbolize.lib;absl_synchronization.lib;absl_throw_delegate.lib;absl_time.lib;absl_time_zone.lib;address_sorting.lib;cares.lib;descriptor_upb_proto.lib;gpr.lib;grpc++.lib;grpc++_alts.lib;grpc++_error_details.lib;grpc++_unsecure.lib;grpc.lib;grpc_plugin_support.lib;grpc_unsecure.lib;libcrypto.lib;libprotobuf-lited.lib;libprotobufd.lib;libprotocd.lib;libssl.lib;re2.lib;upb.lib;upb_collections.lib;upb_extension_registry.lib;upb_fastdecode.lib;upb_json.lib;upb_mini_table.lib;upb_reflection.lib;upb_textformat.lib;upb_utf8_range.lib;zlibd.lib;Ws2_32.lib;Crypt32.lib;Iphlpapi.lib;%(AdditionalDependencies)
+ absl_bad_any_cast_impl.lib;absl_bad_optional_access.lib;absl_bad_variant_access.lib;absl_base.lib;absl_city.lib;absl_civil_time.lib;absl_cord.lib;absl_cordz_functions.lib;absl_cordz_handle.lib;absl_cordz_info.lib;absl_cordz_sample_token.lib;absl_cord_internal.lib;absl_crc32c.lib;absl_crc_cord_state.lib;absl_crc_cpu_detect.lib;absl_crc_internal.lib;absl_debugging_internal.lib;absl_demangle_internal.lib;absl_die_if_null.lib;absl_examine_stack.lib;absl_exponential_biased.lib;absl_failure_signal_handler.lib;absl_flags.lib;absl_flags_commandlineflag.lib;absl_flags_commandlineflag_internal.lib;absl_flags_config.lib;absl_flags_internal.lib;absl_flags_marshalling.lib;absl_flags_parse.lib;absl_flags_private_handle_accessor.lib;absl_flags_program_name.lib;absl_flags_reflection.lib;absl_flags_usage.lib;absl_flags_usage_internal.lib;absl_graphcycles_internal.lib;absl_hash.lib;absl_hashtablez_sampler.lib;absl_int128.lib;absl_kernel_timeout_internal.lib;absl_leak_check.lib;absl_log_entry.lib;absl_log_flags.lib;absl_log_globals.lib;absl_log_initialize.lib;absl_log_internal_check_op.lib;absl_log_internal_conditions.lib;absl_log_internal_format.lib;absl_log_internal_globals.lib;absl_log_internal_log_sink_set.lib;absl_log_internal_message.lib;absl_log_internal_nullguard.lib;absl_log_internal_proto.lib;absl_log_severity.lib;absl_log_sink.lib;absl_low_level_hash.lib;absl_malloc_internal.lib;absl_periodic_sampler.lib;absl_random_distributions.lib;absl_random_internal_distribution_test_util.lib;absl_random_internal_platform.lib;absl_random_internal_pool_urbg.lib;absl_random_internal_randen.lib;absl_random_internal_randen_hwaes.lib;absl_random_internal_randen_hwaes_impl.lib;absl_random_internal_randen_slow.lib;absl_random_internal_seed_material.lib;absl_random_seed_gen_exception.lib;absl_random_seed_sequences.lib;absl_raw_hash_set.lib;absl_raw_logging_internal.lib;absl_scoped_set_env.lib;absl_spinlock_wait.lib;absl_stacktrace.lib;absl_status.lib;absl_statusor.lib;absl_strerror.lib;absl_strings.lib;absl_strings_internal.lib;absl_string_view.lib;absl_str_format_internal.lib;absl_symbolize.lib;absl_synchronization.lib;absl_throw_delegate.lib;absl_time.lib;absl_time_zone.lib;address_sorting.lib;cares.lib;descriptor_upb_proto.lib;gpr.lib;grpc++.lib;grpc++_alts.lib;grpc++_error_details.lib;grpc++_unsecure.lib;grpc.lib;grpc_plugin_support.lib;grpc_unsecure.lib;libcrypto.lib;libprotobuf-lited.lib;libprotobufd.lib;libprotocd.lib;libssl.lib;re2.lib;upb.lib;upb_collections.lib;upb_extension_registry.lib;upb_fastdecode.lib;upb_json.lib;upb_mini_table.lib;upb_reflection.lib;upb_textformat.lib;upb_utf8_range.lib;zlibd.lib;ws2_32.lib;Crypt32.lib;%(AdditionalDependencies)
@@ -166,7 +166,7 @@
true
true
true
- absl_bad_any_cast_impl.lib;absl_bad_optional_access.lib;absl_bad_variant_access.lib;absl_base.lib;absl_city.lib;absl_civil_time.lib;absl_cord.lib;absl_cordz_functions.lib;absl_cordz_handle.lib;absl_cordz_info.lib;absl_cordz_sample_token.lib;absl_cord_internal.lib;absl_debugging_internal.lib;absl_demangle_internal.lib;absl_examine_stack.lib;absl_exponential_biased.lib;absl_failure_signal_handler.lib;absl_flags.lib;absl_flags_commandlineflag.lib;absl_flags_commandlineflag_internal.lib;absl_flags_config.lib;absl_flags_internal.lib;absl_flags_marshalling.lib;absl_flags_parse.lib;absl_flags_private_handle_accessor.lib;absl_flags_program_name.lib;absl_flags_reflection.lib;absl_flags_usage.lib;absl_flags_usage_internal.lib;absl_graphcycles_internal.lib;absl_hash.lib;absl_hashtablez_sampler.lib;absl_int128.lib;absl_leak_check.lib;absl_log_severity.lib;absl_low_level_hash.lib;absl_malloc_internal.lib;absl_periodic_sampler.lib;absl_random_distributions.lib;absl_random_internal_distribution_test_util.lib;absl_random_internal_platform.lib;absl_random_internal_pool_urbg.lib;absl_random_internal_randen.lib;absl_random_internal_randen_hwaes.lib;absl_random_internal_randen_hwaes_impl.lib;absl_random_internal_randen_slow.lib;absl_random_internal_seed_material.lib;absl_random_seed_gen_exception.lib;absl_random_seed_sequences.lib;absl_raw_hash_set.lib;absl_raw_logging_internal.lib;absl_scoped_set_env.lib;absl_spinlock_wait.lib;absl_stacktrace.lib;absl_status.lib;absl_statusor.lib;absl_strerror.lib;absl_strings.lib;absl_strings_internal.lib;absl_str_format_internal.lib;absl_symbolize.lib;absl_synchronization.lib;absl_throw_delegate.lib;absl_time.lib;absl_time_zone.lib;address_sorting.lib;cares.lib;descriptor_upb_proto.lib;gpr.lib;grpc++.lib;grpc++_alts.lib;grpc++_error_details.lib;grpc++_unsecure.lib;grpc.lib;grpc_plugin_support.lib;grpc_unsecure.lib;libcrypto.lib;libprotobuf-lite.lib;libprotobuf.lib;libprotoc.lib;libssl.lib;re2.lib;upb.lib;upb_collections.lib;upb_extension_registry.lib;upb_fastdecode.lib;upb_json.lib;upb_mini_table.lib;upb_reflection.lib;upb_textformat.lib;upb_utf8_range.lib;zlib.lib;Ws2_32.lib;Crypt32.lib;Iphlpapi.lib;%(AdditionalDependencies)
+ absl_bad_any_cast_impl.lib;absl_bad_optional_access.lib;absl_bad_variant_access.lib;absl_base.lib;absl_city.lib;absl_civil_time.lib;absl_cord.lib;absl_cordz_functions.lib;absl_cordz_handle.lib;absl_cordz_info.lib;absl_cordz_sample_token.lib;absl_cord_internal.lib;absl_crc32c.lib;absl_crc_cord_state.lib;absl_crc_cpu_detect.lib;absl_crc_internal.lib;absl_debugging_internal.lib;absl_demangle_internal.lib;absl_die_if_null.lib;absl_examine_stack.lib;absl_exponential_biased.lib;absl_failure_signal_handler.lib;absl_flags.lib;absl_flags_commandlineflag.lib;absl_flags_commandlineflag_internal.lib;absl_flags_config.lib;absl_flags_internal.lib;absl_flags_marshalling.lib;absl_flags_parse.lib;absl_flags_private_handle_accessor.lib;absl_flags_program_name.lib;absl_flags_reflection.lib;absl_flags_usage.lib;absl_flags_usage_internal.lib;absl_graphcycles_internal.lib;absl_hash.lib;absl_hashtablez_sampler.lib;absl_int128.lib;absl_kernel_timeout_internal.lib;absl_leak_check.lib;absl_log_entry.lib;absl_log_flags.lib;absl_log_globals.lib;absl_log_initialize.lib;absl_log_internal_check_op.lib;absl_log_internal_conditions.lib;absl_log_internal_format.lib;absl_log_internal_globals.lib;absl_log_internal_log_sink_set.lib;absl_log_internal_message.lib;absl_log_internal_nullguard.lib;absl_log_internal_proto.lib;absl_log_severity.lib;absl_log_sink.lib;absl_low_level_hash.lib;absl_malloc_internal.lib;absl_periodic_sampler.lib;absl_random_distributions.lib;absl_random_internal_distribution_test_util.lib;absl_random_internal_platform.lib;absl_random_internal_pool_urbg.lib;absl_random_internal_randen.lib;absl_random_internal_randen_hwaes.lib;absl_random_internal_randen_hwaes_impl.lib;absl_random_internal_randen_slow.lib;absl_random_internal_seed_material.lib;absl_random_seed_gen_exception.lib;absl_random_seed_sequences.lib;absl_raw_hash_set.lib;absl_raw_logging_internal.lib;absl_scoped_set_env.lib;absl_spinlock_wait.lib;absl_stacktrace.lib;absl_status.lib;absl_statusor.lib;absl_strerror.lib;absl_strings.lib;absl_strings_internal.lib;absl_string_view.lib;absl_str_format_internal.lib;absl_symbolize.lib;absl_synchronization.lib;absl_throw_delegate.lib;absl_time.lib;absl_time_zone.lib;address_sorting.lib;cares.lib;descriptor_upb_proto.lib;gpr.lib;grpc++.lib;grpc++_alts.lib;grpc++_error_details.lib;grpc++_unsecure.lib;grpc.lib;grpc_plugin_support.lib;grpc_unsecure.lib;libcrypto.lib;libprotobuf-lite.lib;libprotobuf.lib;libprotoc.lib;libssl.lib;re2.lib;upb.lib;upb_collections.lib;upb_extension_registry.lib;upb_fastdecode.lib;upb_json.lib;upb_mini_table.lib;upb_reflection.lib;upb_textformat.lib;upb_utf8_range.lib;zlib.lib;ws2_32.lib;Crypt32.lib;%(AdditionalDependencies)
..\lib\release;%(AdditionalLibraryDirectories)
diff --git a/CAPI/cpp/API/include/logic.h b/CAPI/cpp/API/include/logic.h
index 689dbb33..70c73b81 100755
--- a/CAPI/cpp/API/include/logic.h
+++ b/CAPI/cpp/API/include/logic.h
@@ -51,7 +51,6 @@ class Logic : public ILogic
int64_t teamID;
THUAI7::PlayerTeam playerTeam;
THUAI7::ShipType shipType;
-
std::unique_ptr timer;
std::thread tAI; // 用于运行AI的线程
diff --git a/CAPI/cpp/API/include/state.h b/CAPI/cpp/API/include/state.h
index a37e8bf9..e7badfe6 100755
--- a/CAPI/cpp/API/include/state.h
+++ b/CAPI/cpp/API/include/state.h
@@ -19,10 +19,10 @@ struct State
// 自身信息,根据playerType的不同,可以调用的值也不同。
std::shared_ptr shipSelf;
std::shared_ptr teamSelf;
-
std::vector> ships;
- std::vector> enemyships;
- std::vector> teams;
+ std::vector> enemyShips;
+ std::shared_ptr enemyTeam;
+
std::vector> bullets;
std::vector> gameMap;
diff --git a/CAPI/cpp/API/include/utils.hpp b/CAPI/cpp/API/include/utils.hpp
index 1ef88575..8e058bc3 100755
--- a/CAPI/cpp/API/include/utils.hpp
+++ b/CAPI/cpp/API/include/utils.hpp
@@ -289,7 +289,11 @@ namespace Proto2THUAI7
auto gameInfo = std::make_shared();
gameInfo->gameTime = allMsg.game_time();
gameInfo->redScore = allMsg.red_team_score();
+ gameInfo->redMoney = allMsg.red_team_score();
+ gameInfo->redHomeHp = allMsg.red_home_hp();
gameInfo->blueScore = allMsg.blue_team_score();
+ gameInfo->blueMoney = allMsg.blue_team_score();
+ gameInfo->blueHomeHp = allMsg.blue_home_hp();
return gameInfo;
}
} // namespace Proto2THUAI7
diff --git a/CAPI/cpp/API/src/AI.cpp b/CAPI/cpp/API/src/AI.cpp
index bb5b42e9..5cee0d82 100755
--- a/CAPI/cpp/API/src/AI.cpp
+++ b/CAPI/cpp/API/src/AI.cpp
@@ -4,12 +4,10 @@
#include "AI.h"
#include "constants.h"
// 注意不要使用conio.h,Windows.h等非标准库
-
// 为假则play()期间确保游戏状态不更新,为真则只保证游戏状态在调用相关方法时不更新,大致一帧更新一次
extern const bool asynchronous = false;
// 选手需要依次将player1到player4的船类型在这里定义
-
extern const std::array shipTypeDict = {
THUAI7::ShipType::CivilianShip,
THUAI7::ShipType::MilitaryShip,
@@ -21,10 +19,7 @@ extern const std::array shipTypeDict = {
void AI::play(IShipAPI& api)
{
- if (this->playerID == 0)
- {
- }
- else if (this->playerID == 1)
+ if (this->playerID == 1)
{
// 玩家1执行操作
}
diff --git a/CAPI/cpp/API/src/logic.cpp b/CAPI/cpp/API/src/logic.cpp
index 76fe381a..187de80a 100755
--- a/CAPI/cpp/API/src/logic.cpp
+++ b/CAPI/cpp/API/src/logic.cpp
@@ -19,7 +19,6 @@ Logic::Logic(int64_t pID, int64_t tID, THUAI7::PlayerType pType, THUAI7::ShipTyp
teamID(tID),
playerType(pType),
shipType(sType)
-
{
currentState = &state[0];
bufferState = &state[1];
@@ -27,9 +26,9 @@ Logic::Logic(int64_t pID, int64_t tID, THUAI7::PlayerType pType, THUAI7::ShipTyp
currentState->mapInfo = std::make_shared();
bufferState->gameInfo = std::make_shared();
bufferState->mapInfo = std::make_shared();
- if (teamID == 1)
+ if (teamID == 0)
playerTeam = THUAI7::PlayerTeam::Red;
- if (teamID == 2)
+ if (teamID == 1)
playerTeam = THUAI7::PlayerTeam::Blue;
}
@@ -44,7 +43,7 @@ std::vector> Logic::GetShips() const
std::vector> Logic::GetEnemyShips() const
{
std::unique_lock lock(mtxState);
- std::vector> temp(currentState->enemyships.begin(), currentState->enemyships.end());
+ std::vector> temp(currentState->enemyShips.begin(), currentState->enemyShips.end());
logger->debug("Called GetEnemyShip");
return temp;
}
@@ -380,20 +379,20 @@ void Logic::LoadBufferSelf(const protobuf::MessageToClient& message)
{
for (const auto& item : message.obj_message())
{
- if (Proto2THUAI7::messageOfObjDict[item.message_of_obj_case()] == THUAI7::MessageOfObj::ShipMessage)
+ if (Proto2THUAI7::messageOfObjDict[item.message_of_obj_case()] == THUAI7::MessageOfObj::ShipMessage && item.ship_message().team_id() == teamID)
{
if (item.ship_message().player_id() == playerID)
{
bufferState->shipSelf = Proto2THUAI7::Protobuf2THUAI7Ship(item.ship_message());
bufferState->ships.push_back(bufferState->shipSelf);
+ logger->debug("Add Self Ship!");
}
else
{
std::shared_ptr ship = Proto2THUAI7::Protobuf2THUAI7Ship(item.ship_message());
- if (ship->teamID == teamID)
- bufferState->ships.push_back(ship);
+ bufferState->ships.push_back(ship);
+ logger->debug("Add Ship!");
}
- logger->debug("Add Ship!");
}
}
}
@@ -403,12 +402,16 @@ void Logic::LoadBufferSelf(const protobuf::MessageToClient& message)
{
if (Proto2THUAI7::messageOfObjDict[item.message_of_obj_case()] == THUAI7::MessageOfObj::TeamMessage)
{
- if (item.team_message().player_id() == playerID)
+ if (item.team_message().team_id() == teamID)
{
bufferState->teamSelf = Proto2THUAI7::Protobuf2THUAI7Team(item.team_message());
- bufferState->teams.push_back(bufferState->teamSelf);
+ logger->debug("Add Self Team!");
+ }
+ else
+ {
+ bufferState->enemyTeam = Proto2THUAI7::Protobuf2THUAI7Team(item.team_message());
+ logger->debug("Add Enemy Team!");
}
- logger->debug("Add Team!");
}
}
}
@@ -427,7 +430,7 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item)
{
if (AssistFunction::HaveView(x, y, item.ship_message().x(), item.ship_message().y(), viewRange, bufferState->gameMap))
{
- bufferState->enemyships.push_back(Proto2THUAI7::Protobuf2THUAI7Ship(item.ship_message()));
+ bufferState->enemyShips.push_back(Proto2THUAI7::Protobuf2THUAI7Ship(item.ship_message()));
logger->debug("Add Enemyship!");
}
}
@@ -440,7 +443,21 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item)
}
break;
case THUAI7::MessageOfObj::FactoryMessage:
- if (AssistFunction::HaveView(x, y, item.factory_message().x(), item.factory_message().y(), viewRange, bufferState->gameMap))
+ if (item.factory_message().team_id() == teamID)
+ {
+ auto pos = std::make_pair(AssistFunction::GridToCell(item.factory_message().x()), AssistFunction::GridToCell(item.factory_message().y()));
+ if (bufferState->mapInfo->factoryState.count(pos) == 0)
+ {
+ bufferState->mapInfo->factoryState.emplace(pos, std::make_pair(item.factory_message().team_id(), item.factory_message().hp()));
+ logger->debug("Add Factory!");
+ }
+ else
+ {
+ bufferState->mapInfo->factoryState[pos].second = item.factory_message().hp();
+ logger->debug("Update Factory!");
+ }
+ }
+ else if (AssistFunction::HaveView(x, y, item.factory_message().x(), item.factory_message().y(), viewRange, bufferState->gameMap))
{
auto pos = std::make_pair(AssistFunction::GridToCell(item.factory_message().x()), AssistFunction::GridToCell(item.factory_message().y()));
if (bufferState->mapInfo->factoryState.count(pos) == 0)
@@ -450,13 +467,27 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item)
}
else
{
- bufferState->mapInfo->factoryState[pos].first = item.factory_message().hp();
+ bufferState->mapInfo->factoryState[pos].second = item.factory_message().hp();
logger->debug("Update Factory!");
}
}
break;
case THUAI7::MessageOfObj::CommunityMessage:
- if (AssistFunction::HaveView(x, y, item.community_message().x(), item.community_message().y(), viewRange, bufferState->gameMap))
+ if (item.community_message().team_id() == teamID)
+ {
+ auto pos = std::make_pair(AssistFunction::GridToCell(item.community_message().x()), AssistFunction::GridToCell(item.community_message().y()));
+ if (bufferState->mapInfo->communityState.count(pos) == 0)
+ {
+ bufferState->mapInfo->communityState.emplace(pos, std::make_pair(item.community_message().team_id(), item.community_message().hp()));
+ logger->debug("Add Community!");
+ }
+ else
+ {
+ bufferState->mapInfo->communityState[pos].second = item.community_message().hp();
+ logger->debug("Update Community!");
+ }
+ }
+ else if (AssistFunction::HaveView(x, y, item.community_message().x(), item.community_message().y(), viewRange, bufferState->gameMap))
{
auto pos = std::make_pair(AssistFunction::GridToCell(item.community_message().x()), AssistFunction::GridToCell(item.community_message().y()));
if (bufferState->mapInfo->communityState.count(pos) == 0)
@@ -466,13 +497,27 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item)
}
else
{
- bufferState->mapInfo->communityState[pos].first = item.community_message().hp();
+ bufferState->mapInfo->communityState[pos].second = item.community_message().hp();
logger->debug("Update Community!");
}
}
break;
case THUAI7::MessageOfObj::FortMessage:
- if (AssistFunction::HaveView(x, y, item.fort_message().x(), item.fort_message().y(), viewRange, bufferState->gameMap))
+ if (item.fort_message().team_id() == teamID)
+ {
+ auto pos = std::make_pair(AssistFunction::GridToCell(item.fort_message().x()), AssistFunction::GridToCell(item.fort_message().y()));
+ if (bufferState->mapInfo->fortState.count(pos) == 0)
+ {
+ bufferState->mapInfo->fortState.emplace(pos, std::make_pair(item.fort_message().team_id(), item.fort_message().hp()));
+ logger->debug("Add Fort!");
+ }
+ else
+ {
+ bufferState->mapInfo->fortState[pos].second = item.fort_message().hp();
+ logger->debug("Update Fort!");
+ }
+ }
+ else if (AssistFunction::HaveView(x, y, item.fort_message().x(), item.fort_message().y(), viewRange, bufferState->gameMap))
{
auto pos = std::make_pair(AssistFunction::GridToCell(item.fort_message().x()), AssistFunction::GridToCell(item.fort_message().y()));
if (bufferState->mapInfo->fortState.count(pos) == 0)
@@ -482,7 +527,7 @@ void Logic::LoadBufferCase(const protobuf::MessageOfObj& item)
}
else
{
- bufferState->mapInfo->fortState[pos].first = item.fort_message().hp();
+ bufferState->mapInfo->fortState[pos].second = item.fort_message().hp();
logger->debug("Update Fort!");
}
}
@@ -554,8 +599,7 @@ void Logic::LoadBuffer(const protobuf::MessageToClient& message)
// 清空原有信息
bufferState->ships.clear();
- bufferState->enemyships.clear();
- bufferState->teams.clear();
+ bufferState->enemyShips.clear();
bufferState->bullets.clear();
bufferState->guids.clear();
@@ -678,8 +722,6 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool f
logger->info("server: {}:{}", IP, port);
if (playerType == THUAI7::PlayerType::Ship)
logger->info("ship ID: {}", playerID);
- else
- logger->info("home ID: {}", playerID);
logger->info("player team: {}", THUAI7::playerTeamDict[playerTeam]);
logger->info("****************************");
@@ -687,39 +729,19 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool f
pComm = std::make_unique(IP, port);
// 构造timer
- if (playerTeam == THUAI7::PlayerTeam::Red)
+ if (playerType == THUAI7::PlayerType::Ship)
{
- if (playerType == THUAI7::PlayerType::Ship)
- {
- if (!file && !print)
- timer = std::make_unique(*this);
- else
- timer = std::make_unique(*this, file, print, warnOnly, playerID);
- }
+ if (!file && !print)
+ timer = std::make_unique(*this);
else
- {
- if (!file && !print)
- timer = std::make_unique(*this);
- else
- timer = std::make_unique(*this, file, print, warnOnly, playerID);
- }
+ timer = std::make_unique(*this, file, print, warnOnly, playerID);
}
- else if (playerTeam == THUAI7::PlayerTeam::Blue)
+ else
{
- if (playerType == THUAI7::PlayerType::Ship)
- {
- if (!file && !print)
- timer = std::make_unique(*this);
- else
- timer = std::make_unique(*this, file, print, warnOnly, playerID);
- }
+ if (!file && !print)
+ timer = std::make_unique(*this);
else
- {
- if (!file && !print)
- timer = std::make_unique(*this);
- else
- timer = std::make_unique(*this, file, print, warnOnly, playerID);
- }
+ timer = std::make_unique(*this, file, print, warnOnly, playerID);
}
// 构造AI线程
@@ -770,7 +792,6 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool f
if (tAI.joinable())
{
logger->info("Join the AI thread!");
-
// 首先开启处理消息的线程
ProcessMessage();
tAI.join();
diff --git a/CAPI/cpp/API/src/main.cpp b/CAPI/cpp/API/src/main.cpp
index 62175243..ff8d180a 100755
--- a/CAPI/cpp/API/src/main.cpp
+++ b/CAPI/cpp/API/src/main.cpp
@@ -65,7 +65,7 @@ int THUAI7Main(int argc, char** argv, CreateAIFunc AIBuilder)
TCLAP::ValueArg teamID("t", "teamID", "Team ID 0,1 valid only", true, -1, &teamIdConstraint);
cmd.add(teamID);
- std::vector validPlayerIDs{0, 1, 2, 3, 4};
+ std::vector validPlayerIDs{0, 1, 2, 3, 4}; // 0代表team
TCLAP::ValuesConstraint playerIdConstraint(validPlayerIDs);
TCLAP::ValueArg playerID("p", "playerID", "Player ID 0,1,2,3,4 valid only", true, -1, &playerIdConstraint);
cmd.add(playerID);
diff --git a/CAPI/cpp/README.md b/CAPI/cpp/README.md
index 3f9593fe..3c262c96 100755
--- a/CAPI/cpp/README.md
+++ b/CAPI/cpp/README.md
@@ -73,7 +73,7 @@ C++ 通信组件与选手接口
- 设置生成方式为静态生成:在项目属性的“C/C++”的“代码生成”的“运行库”中,[Debug 下设置其为“多线程调试(`/MTd`)”](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L137),[Release 下设置其为“多线程(`/MT`)”](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L158)
- 将之前提取的 Debug 和 Release 的 `.lib` 分别放在项目中的单独的文件夹里(THUAI6 使用的是 `CAPI\cpp\lib\debug` 和 `CAPI\cpp\lib\release`),并[使用 `.gitignore` 忽略掉](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/.gitignore#L502)
- 在项目属性的“链接器”的首页的“附加库目录”中分别配置 Debug 和 Release 的 [`.lib` 文件的相应路径](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L166)
- - 在项目属性中的“链接器”的“输入”的“附加依赖库”中分别配置 Debug 和 Release [所需要链接的库的文件名](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L165)。注意 Debug 和 Release 链接的库可能并不完全相同,建议在 cmd 中使用 `dir /b` 将其自动列举并复制。还需要注意需要手动指定链接一些 Windows 自带的 `lib`,例如 `Ws2_32.lib`、`Crypt32.lib`、`Iphlpapi.lib` 等。如果生成过程中不通过,表示找不到一些函数,则在 Google 中搜索该函数,如果发现是 Windows 系统的 API 函数则会搜到[微软官方文档](https://learn.microsoft.com) 的对应链接的页面,则在页面最下方会表明它所在的 `.lib`(例如 [`CreateProcessA` 的页面](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa#requirements)),加进去即可
+ - 在项目属性中的“链接器”的“输入”的“附加依赖库”中分别配置 Debug 和 Release [所需要链接的库的文件名](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L165)。注意 Debug 和 Release 链接的库可能并不完全相同,建议在 cmd 中使用 `dir /b` 将其自动列举并复制。还需要注意需要手动指定链接一些 Windows 自带的 `lib`,例如 `ws2_32.lib`、`Crypt32.lib`、`Iphlpapi.lib` 等。如果生成过程中不通过,表示找不到一些函数,则在 Google 中搜索该函数,如果发现是 Windows 系统的 API 函数则会搜到[微软官方文档](https://learn.microsoft.com) 的对应链接的页面,则在页面最下方会表明它所在的 `.lib`(例如 [`CreateProcessA` 的页面](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa#requirements)),加进去即可
- 然后进行生成解决方案。如果感觉编译的速度过慢,可以在项目属性的 `C/C++` 的“所有选项”中搜索多处理器编译,并[开启(`/MP`)](https://github.com/eesast/THUAI6/blob/ad4db599f97449786e6c910940bf4f69224d5408/CAPI/cpp/API/API.vcxproj#L162)
- 然后开始运行。如果提示缺少一些 DLL,可以把之前保存的 `.dll` 文件(如果有的话)放在与 `.exe` 相同的目录下。该目录为**与 `.sln` 相同目录的**(不是与 `.vcxproj` 相同目录的)`x64\Debug` 和 `x64\Release`
- 如果 x64 的 Debug 和 x64 的 Release 均生成成功,那么找一台没配过的电脑再试一次
diff --git a/CAPI/cpp/grpc/include/absl/algorithm/algorithm.h b/CAPI/cpp/grpc/include/absl/algorithm/algorithm.h
new file mode 100644
index 00000000..865b6d17
--- /dev/null
+++ b/CAPI/cpp/grpc/include/absl/algorithm/algorithm.h
@@ -0,0 +1,162 @@
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: algorithm.h
+// -----------------------------------------------------------------------------
+//
+// This header file contains Google extensions to the standard C++
+// header.
+
+#ifndef ABSL_ALGORITHM_ALGORITHM_H_
+#define ABSL_ALGORITHM_ALGORITHM_H_
+
+#include
+#include
+#include
+
+#include "absl/base/config.h"
+
+namespace absl
+{
+ ABSL_NAMESPACE_BEGIN
+
+ namespace algorithm_internal
+ {
+
+ // Performs comparisons with operator==, similar to C++14's `std::equal_to<>`.
+ struct EqualTo
+ {
+ template
+ bool operator()(const T& a, const U& b) const
+ {
+ return a == b;
+ }
+ };
+
+ template
+ bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2, Pred pred, std::input_iterator_tag, std::input_iterator_tag)
+ {
+ while (true)
+ {
+ if (first1 == last1)
+ return first2 == last2;
+ if (first2 == last2)
+ return false;
+ if (!pred(*first1, *first2))
+ return false;
+ ++first1;
+ ++first2;
+ }
+ }
+
+ template
+ bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2, Pred&& pred, std::random_access_iterator_tag, std::random_access_iterator_tag)
+ {
+ return (last1 - first1 == last2 - first2) &&
+ std::equal(first1, last1, first2, std::forward(pred));
+ }
+
+ // When we are using our own internal predicate that just applies operator==, we
+ // forward to the non-predicate form of std::equal. This enables an optimization
+ // in libstdc++ that can result in std::memcmp being used for integer types.
+ template
+ bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2, algorithm_internal::EqualTo /* unused */, std::random_access_iterator_tag, std::random_access_iterator_tag)
+ {
+ return (last1 - first1 == last2 - first2) &&
+ std::equal(first1, last1, first2);
+ }
+
+ template
+ It RotateImpl(It first, It middle, It last, std::true_type)
+ {
+ return std::rotate(first, middle, last);
+ }
+
+ template
+ It RotateImpl(It first, It middle, It last, std::false_type)
+ {
+ std::rotate(first, middle, last);
+ return std::next(first, std::distance(middle, last));
+ }
+
+ } // namespace algorithm_internal
+
+ // equal()
+ //
+ // Compares the equality of two ranges specified by pairs of iterators, using
+ // the given predicate, returning true iff for each corresponding iterator i1
+ // and i2 in the first and second range respectively, pred(*i1, *i2) == true
+ //
+ // This comparison takes at most min(`last1` - `first1`, `last2` - `first2`)
+ // invocations of the predicate. Additionally, if InputIter1 and InputIter2 are
+ // both random-access iterators, and `last1` - `first1` != `last2` - `first2`,
+ // then the predicate is never invoked and the function returns false.
+ //
+ // This is a C++11-compatible implementation of C++14 `std::equal`. See
+ // https://en.cppreference.com/w/cpp/algorithm/equal for more information.
+ template
+ bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2, Pred&& pred)
+ {
+ return algorithm_internal::EqualImpl(
+ first1, last1, first2, last2, std::forward(pred), typename std::iterator_traits::iterator_category{}, typename std::iterator_traits::iterator_category{}
+ );
+ }
+
+ // Overload of equal() that performs comparison of two ranges specified by pairs
+ // of iterators using operator==.
+ template
+ bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2)
+ {
+ return absl::equal(first1, last1, first2, last2, algorithm_internal::EqualTo{});
+ }
+
+ // linear_search()
+ //
+ // Performs a linear search for `value` using the iterator `first` up to
+ // but not including `last`, returning true if [`first`, `last`) contains an
+ // element equal to `value`.
+ //
+ // A linear search is of O(n) complexity which is guaranteed to make at most
+ // n = (`last` - `first`) comparisons. A linear search over short containers
+ // may be faster than a binary search, even when the container is sorted.
+ template
+ bool linear_search(InputIterator first, InputIterator last, const EqualityComparable& value)
+ {
+ return std::find(first, last, value) != last;
+ }
+
+ // rotate()
+ //
+ // Performs a left rotation on a range of elements (`first`, `last`) such that
+ // `middle` is now the first element. `rotate()` returns an iterator pointing to
+ // the first element before rotation. This function is exactly the same as
+ // `std::rotate`, but fixes a bug in gcc
+ // <= 4.9 where `std::rotate` returns `void` instead of an iterator.
+ //
+ // The complexity of this algorithm is the same as that of `std::rotate`, but if
+ // `ForwardIterator` is not a random-access iterator, then `absl::rotate`
+ // performs an additional pass over the range to construct the return value.
+ template
+ ForwardIterator rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last)
+ {
+ return algorithm_internal::RotateImpl(
+ first, middle, last, std::is_same()
+ );
+ }
+
+ ABSL_NAMESPACE_END
+} // namespace absl
+
+#endif // ABSL_ALGORITHM_ALGORITHM_H_
diff --git a/CAPI/cpp/grpc/include/absl/algorithm/container.h b/CAPI/cpp/grpc/include/absl/algorithm/container.h
new file mode 100644
index 00000000..8babfee2
--- /dev/null
+++ b/CAPI/cpp/grpc/include/absl/algorithm/container.h
@@ -0,0 +1,1627 @@
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: container.h
+// -----------------------------------------------------------------------------
+//
+// This header file provides Container-based versions of algorithmic functions
+// within the C++ standard library. The following standard library sets of
+// functions are covered within this file:
+//
+// * Algorithmic functions
+// * Algorithmic functions
+// * functions
+//
+// The standard library functions operate on iterator ranges; the functions
+// within this API operate on containers, though many return iterator ranges.
+//
+// All functions within this API are named with a `c_` prefix. Calls such as
+// `absl::c_xx(container, ...) are equivalent to std:: functions such as
+// `std::xx(std::begin(cont), std::end(cont), ...)`. Functions that act on
+// iterators but not conceptually on iterator ranges (e.g. `std::iter_swap`)
+// have no equivalent here.
+//
+// For template parameter and variable naming, `C` indicates the container type
+// to which the function is applied, `Pred` indicates the predicate object type
+// to be used by the function and `T` indicates the applicable element type.
+
+#ifndef ABSL_ALGORITHM_CONTAINER_H_
+#define ABSL_ALGORITHM_CONTAINER_H_
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "absl/algorithm/algorithm.h"
+#include "absl/base/macros.h"
+#include "absl/meta/type_traits.h"
+
+namespace absl
+{
+ ABSL_NAMESPACE_BEGIN
+ namespace container_algorithm_internal
+ {
+
+ // NOTE: it is important to defer to ADL lookup for building with C++ modules,
+ // especially for headers like which are not visible from this file
+ // but specialize std::begin and std::end.
+ using std::begin;
+ using std::end;
+
+ // The type of the iterator given by begin(c) (possibly std::begin(c)).
+ // ContainerIter> gives vector::const_iterator,
+ // while ContainerIter> gives vector::iterator.
+ template
+ using ContainerIter = decltype(begin(std::declval()));
+
+ // An MSVC bug involving template parameter substitution requires us to use
+ // decltype() here instead of just std::pair.
+ template
+ using ContainerIterPairType =
+ decltype(std::make_pair(ContainerIter(), ContainerIter()));
+
+ template
+ using ContainerDifferenceType = decltype(std::distance(
+ std::declval>(), std::declval>()
+ ));
+
+ template
+ using ContainerPointerType =
+ typename std::iterator_traits>::pointer;
+
+ // container_algorithm_internal::c_begin and
+ // container_algorithm_internal::c_end are abbreviations for proper ADL
+ // lookup of std::begin and std::end, i.e.
+ // using std::begin;
+ // using std::end;
+ // std::foo(begin(c), end(c));
+ // becomes
+ // std::foo(container_algorithm_internal::begin(c),
+ // container_algorithm_internal::end(c));
+ // These are meant for internal use only.
+
+ template
+ ContainerIter c_begin(C& c)
+ {
+ return begin(c);
+ }
+
+ template
+ ContainerIter c_end(C& c)
+ {
+ return end(c);
+ }
+
+ template
+ struct IsUnorderedContainer : std::false_type
+ {
+ };
+
+ template
+ struct IsUnorderedContainer<
+ std::unordered_map> : std::true_type
+ {
+ };
+
+ template
+ struct IsUnorderedContainer> : std::true_type
+ {
+ };
+
+ // container_algorithm_internal::c_size. It is meant for internal use only.
+
+ template
+ auto c_size(C& c) -> decltype(c.size())
+ {
+ return c.size();
+ }
+
+ template
+ constexpr std::size_t c_size(T (&)[N])
+ {
+ return N;
+ }
+
+ } // namespace container_algorithm_internal
+
+ // PUBLIC API
+
+ //------------------------------------------------------------------------------
+ // Abseil algorithm.h functions
+ //------------------------------------------------------------------------------
+
+ // c_linear_search()
+ //
+ // Container-based version of absl::linear_search() for performing a linear
+ // search within a container.
+ template
+ bool c_linear_search(const C& c, EqualityComparable&& value)
+ {
+ return linear_search(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(value));
+ }
+
+ //------------------------------------------------------------------------------
+ // algorithms
+ //------------------------------------------------------------------------------
+
+ // c_distance()
+ //
+ // Container-based version of the `std::distance()` function to
+ // return the number of elements within a container.
+ template
+ container_algorithm_internal::ContainerDifferenceType c_distance(
+ const C& c
+ )
+ {
+ return std::distance(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c));
+ }
+
+ //------------------------------------------------------------------------------
+ // Non-modifying sequence operations
+ //------------------------------------------------------------------------------
+
+ // c_all_of()
+ //
+ // Container-based version of the `std::all_of()` function to
+ // test if all elements within a container satisfy a condition.
+ template
+ bool c_all_of(const C& c, Pred&& pred)
+ {
+ return std::all_of(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(pred));
+ }
+
+ // c_any_of()
+ //
+ // Container-based version of the `std::any_of()` function to
+ // test if any element in a container fulfills a condition.
+ template
+ bool c_any_of(const C& c, Pred&& pred)
+ {
+ return std::any_of(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(pred));
+ }
+
+ // c_none_of()
+ //
+ // Container-based version of the `std::none_of()` function to
+ // test if no elements in a container fulfill a condition.
+ template
+ bool c_none_of(const C& c, Pred&& pred)
+ {
+ return std::none_of(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(pred));
+ }
+
+ // c_for_each()
+ //
+ // Container-based version of the `std::for_each()` function to
+ // apply a function to a container's elements.
+ template
+ decay_t c_for_each(C&& c, Function&& f)
+ {
+ return std::for_each(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(f));
+ }
+
+ // c_find()
+ //
+ // Container-based version of the `std::find()` function to find
+ // the first element containing the passed value within a container value.
+ template
+ container_algorithm_internal::ContainerIter c_find(C& c, T&& value)
+ {
+ return std::find(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(value));
+ }
+
+ // c_find_if()
+ //
+ // Container-based version of the `std::find_if()` function to find
+ // the first element in a container matching the given condition.
+ template
+ container_algorithm_internal::ContainerIter c_find_if(C& c, Pred&& pred)
+ {
+ return std::find_if(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(pred));
+ }
+
+ // c_find_if_not()
+ //
+ // Container-based version of the `std::find_if_not()` function to
+ // find the first element in a container not matching the given condition.
+ template
+ container_algorithm_internal::ContainerIter c_find_if_not(C& c, Pred&& pred)
+ {
+ return std::find_if_not(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(pred));
+ }
+
+ // c_find_end()
+ //
+ // Container-based version of the `std::find_end()` function to
+ // find the last subsequence within a container.
+ template
+ container_algorithm_internal::ContainerIter c_find_end(
+ Sequence1& sequence, Sequence2& subsequence
+ )
+ {
+ return std::find_end(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), container_algorithm_internal::c_begin(subsequence), container_algorithm_internal::c_end(subsequence));
+ }
+
+ // Overload of c_find_end() for using a predicate evaluation other than `==` as
+ // the function's test condition.
+ template
+ container_algorithm_internal::ContainerIter c_find_end(
+ Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred
+ )
+ {
+ return std::find_end(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), container_algorithm_internal::c_begin(subsequence), container_algorithm_internal::c_end(subsequence), std::forward(pred));
+ }
+
+ // c_find_first_of()
+ //
+ // Container-based version of the `std::find_first_of()` function to
+ // find the first element within the container that is also within the options
+ // container.
+ template
+ container_algorithm_internal::ContainerIter c_find_first_of(C1& container, C2& options)
+ {
+ return std::find_first_of(container_algorithm_internal::c_begin(container), container_algorithm_internal::c_end(container), container_algorithm_internal::c_begin(options), container_algorithm_internal::c_end(options));
+ }
+
+ // Overload of c_find_first_of() for using a predicate evaluation other than
+ // `==` as the function's test condition.
+ template
+ container_algorithm_internal::ContainerIter c_find_first_of(
+ C1& container, C2& options, BinaryPredicate&& pred
+ )
+ {
+ return std::find_first_of(container_algorithm_internal::c_begin(container), container_algorithm_internal::c_end(container), container_algorithm_internal::c_begin(options), container_algorithm_internal::c_end(options), std::forward(pred));
+ }
+
+ // c_adjacent_find()
+ //
+ // Container-based version of the `std::adjacent_find()` function to
+ // find equal adjacent elements within a container.
+ template
+ container_algorithm_internal::ContainerIter c_adjacent_find(
+ Sequence& sequence
+ )
+ {
+ return std::adjacent_find(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence));
+ }
+
+ // Overload of c_adjacent_find() for using a predicate evaluation other than
+ // `==` as the function's test condition.
+ template
+ container_algorithm_internal::ContainerIter c_adjacent_find(
+ Sequence& sequence, BinaryPredicate&& pred
+ )
+ {
+ return std::adjacent_find(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward(pred));
+ }
+
+ // c_count()
+ //
+ // Container-based version of the `std::count()` function to count
+ // values that match within a container.
+ template
+ container_algorithm_internal::ContainerDifferenceType c_count(
+ const C& c, T&& value
+ )
+ {
+ return std::count(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(value));
+ }
+
+ // c_count_if()
+ //
+ // Container-based version of the `std::count_if()` function to
+ // count values matching a condition within a container.
+ template
+ container_algorithm_internal::ContainerDifferenceType c_count_if(
+ const C& c, Pred&& pred
+ )
+ {
+ return std::count_if(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(pred));
+ }
+
+ // c_mismatch()
+ //
+ // Container-based version of the `std::mismatch()` function to
+ // return the first element where two ordered containers differ. Applies `==` to
+ // the first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)).
+ template
+ container_algorithm_internal::ContainerIterPairType c_mismatch(C1& c1, C2& c2)
+ {
+ auto first1 = container_algorithm_internal::c_begin(c1);
+ auto last1 = container_algorithm_internal::c_end(c1);
+ auto first2 = container_algorithm_internal::c_begin(c2);
+ auto last2 = container_algorithm_internal::c_end(c2);
+
+ for (; first1 != last1 && first2 != last2; ++first1, (void)++first2)
+ {
+ // Negates equality because Cpp17EqualityComparable doesn't require clients
+ // to overload both `operator==` and `operator!=`.
+ if (!(*first1 == *first2))
+ {
+ break;
+ }
+ }
+
+ return std::make_pair(first1, first2);
+ }
+
+ // Overload of c_mismatch() for using a predicate evaluation other than `==` as
+ // the function's test condition. Applies `pred`to the first N elements of `c1`
+ // and `c2`, where N = min(size(c1), size(c2)).
+ template
+ container_algorithm_internal::ContainerIterPairType c_mismatch(
+ C1& c1, C2& c2, BinaryPredicate pred
+ )
+ {
+ auto first1 = container_algorithm_internal::c_begin(c1);
+ auto last1 = container_algorithm_internal::c_end(c1);
+ auto first2 = container_algorithm_internal::c_begin(c2);
+ auto last2 = container_algorithm_internal::c_end(c2);
+
+ for (; first1 != last1 && first2 != last2; ++first1, (void)++first2)
+ {
+ if (!pred(*first1, *first2))
+ {
+ break;
+ }
+ }
+
+ return std::make_pair(first1, first2);
+ }
+
+ // c_equal()
+ //
+ // Container-based version of the `std::equal()` function to
+ // test whether two containers are equal.
+ //
+ // NOTE: the semantics of c_equal() are slightly different than those of
+ // equal(): while the latter iterates over the second container only up to the
+ // size of the first container, c_equal() also checks whether the container
+ // sizes are equal. This better matches expectations about c_equal() based on
+ // its signature.
+ //
+ // Example:
+ // vector v1 = <1, 2, 3>;
+ // vector v2 = <1, 2, 3, 4>;
+ // equal(std::begin(v1), std::end(v1), std::begin(v2)) returns true
+ // c_equal(v1, v2) returns false
+
+ template
+ bool c_equal(const C1& c1, const C2& c2)
+ {
+ return ((container_algorithm_internal::c_size(c1) == container_algorithm_internal::c_size(c2)) && std::equal(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2)));
+ }
+
+ // Overload of c_equal() for using a predicate evaluation other than `==` as
+ // the function's test condition.
+ template
+ bool c_equal(const C1& c1, const C2& c2, BinaryPredicate&& pred)
+ {
+ return ((container_algorithm_internal::c_size(c1) == container_algorithm_internal::c_size(c2)) && std::equal(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), std::forward(pred)));
+ }
+
+ // c_is_permutation()
+ //
+ // Container-based version of the `std::is_permutation()` function
+ // to test whether a container is a permutation of another.
+ template
+ bool c_is_permutation(const C1& c1, const C2& c2)
+ {
+ using std::begin;
+ using std::end;
+ return c1.size() == c2.size() &&
+ std::is_permutation(begin(c1), end(c1), begin(c2));
+ }
+
+ // Overload of c_is_permutation() for using a predicate evaluation other than
+ // `==` as the function's test condition.
+ template
+ bool c_is_permutation(const C1& c1, const C2& c2, BinaryPredicate&& pred)
+ {
+ using std::begin;
+ using std::end;
+ return c1.size() == c2.size() &&
+ std::is_permutation(begin(c1), end(c1), begin(c2), std::forward(pred));
+ }
+
+ // c_search()
+ //
+ // Container-based version of the `std::search()` function to search
+ // a container for a subsequence.
+ template
+ container_algorithm_internal::ContainerIter c_search(
+ Sequence1& sequence, Sequence2& subsequence
+ )
+ {
+ return std::search(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), container_algorithm_internal::c_begin(subsequence), container_algorithm_internal::c_end(subsequence));
+ }
+
+ // Overload of c_search() for using a predicate evaluation other than
+ // `==` as the function's test condition.
+ template
+ container_algorithm_internal::ContainerIter c_search(
+ Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred
+ )
+ {
+ return std::search(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), container_algorithm_internal::c_begin(subsequence), container_algorithm_internal::c_end(subsequence), std::forward(pred));
+ }
+
+ // c_search_n()
+ //
+ // Container-based version of the `std::search_n()` function to
+ // search a container for the first sequence of N elements.
+ template
+ container_algorithm_internal::ContainerIter c_search_n(
+ Sequence& sequence, Size count, T&& value
+ )
+ {
+ return std::search_n(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), count, std::forward(value));
+ }
+
+ // Overload of c_search_n() for using a predicate evaluation other than
+ // `==` as the function's test condition.
+ template
+ container_algorithm_internal::ContainerIter c_search_n(
+ Sequence& sequence, Size count, T&& value, BinaryPredicate&& pred
+ )
+ {
+ return std::search_n(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), count, std::forward(value), std::forward(pred));
+ }
+
+ //------------------------------------------------------------------------------
+ // Modifying sequence operations
+ //------------------------------------------------------------------------------
+
+ // c_copy()
+ //
+ // Container-based version of the `std::copy()` function to copy a
+ // container's elements into an iterator.
+ template
+ OutputIterator c_copy(const InputSequence& input, OutputIterator output)
+ {
+ return std::copy(container_algorithm_internal::c_begin(input), container_algorithm_internal::c_end(input), output);
+ }
+
+ // c_copy_n()
+ //
+ // Container-based version of the `std::copy_n()` function to copy a
+ // container's first N elements into an iterator.
+ template
+ OutputIterator c_copy_n(const C& input, Size n, OutputIterator output)
+ {
+ return std::copy_n(container_algorithm_internal::c_begin(input), n, output);
+ }
+
+ // c_copy_if()
+ //
+ // Container-based version of the `std::copy_if()` function to copy
+ // a container's elements satisfying some condition into an iterator.
+ template
+ OutputIterator c_copy_if(const InputSequence& input, OutputIterator output, Pred&& pred)
+ {
+ return std::copy_if(container_algorithm_internal::c_begin(input), container_algorithm_internal::c_end(input), output, std::forward(pred));
+ }
+
+ // c_copy_backward()
+ //
+ // Container-based version of the `std::copy_backward()` function to
+ // copy a container's elements in reverse order into an iterator.
+ template
+ BidirectionalIterator c_copy_backward(const C& src, BidirectionalIterator dest)
+ {
+ return std::copy_backward(container_algorithm_internal::c_begin(src), container_algorithm_internal::c_end(src), dest);
+ }
+
+ // c_move()
+ //
+ // Container-based version of the `std::move()` function to move
+ // a container's elements into an iterator.
+ template
+ OutputIterator c_move(C&& src, OutputIterator dest)
+ {
+ return std::move(container_algorithm_internal::c_begin(src), container_algorithm_internal::c_end(src), dest);
+ }
+
+ // c_move_backward()
+ //
+ // Container-based version of the `std::move_backward()` function to
+ // move a container's elements into an iterator in reverse order.
+ template
+ BidirectionalIterator c_move_backward(C&& src, BidirectionalIterator dest)
+ {
+ return std::move_backward(container_algorithm_internal::c_begin(src), container_algorithm_internal::c_end(src), dest);
+ }
+
+ // c_swap_ranges()
+ //
+ // Container-based version of the `std::swap_ranges()` function to
+ // swap a container's elements with another container's elements. Swaps the
+ // first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)).
+ template
+ container_algorithm_internal::ContainerIter c_swap_ranges(C1& c1, C2& c2)
+ {
+ auto first1 = container_algorithm_internal::c_begin(c1);
+ auto last1 = container_algorithm_internal::c_end(c1);
+ auto first2 = container_algorithm_internal::c_begin(c2);
+ auto last2 = container_algorithm_internal::c_end(c2);
+
+ using std::swap;
+ for (; first1 != last1 && first2 != last2; ++first1, (void)++first2)
+ {
+ swap(*first1, *first2);
+ }
+ return first2;
+ }
+
+ // c_transform()
+ //
+ // Container-based version of the `std::transform()` function to
+ // transform a container's elements using the unary operation, storing the
+ // result in an iterator pointing to the last transformed element in the output
+ // range.
+ template
+ OutputIterator c_transform(const InputSequence& input, OutputIterator output, UnaryOp&& unary_op)
+ {
+ return std::transform(container_algorithm_internal::c_begin(input), container_algorithm_internal::c_end(input), output, std::forward(unary_op));
+ }
+
+ // Overload of c_transform() for performing a transformation using a binary
+ // predicate. Applies `binary_op` to the first N elements of `c1` and `c2`,
+ // where N = min(size(c1), size(c2)).
+ template
+ OutputIterator c_transform(const InputSequence1& input1, const InputSequence2& input2, OutputIterator output, BinaryOp&& binary_op)
+ {
+ auto first1 = container_algorithm_internal::c_begin(input1);
+ auto last1 = container_algorithm_internal::c_end(input1);
+ auto first2 = container_algorithm_internal::c_begin(input2);
+ auto last2 = container_algorithm_internal::c_end(input2);
+ for (; first1 != last1 && first2 != last2;
+ ++first1, (void)++first2, ++output)
+ {
+ *output = binary_op(*first1, *first2);
+ }
+
+ return output;
+ }
+
+ // c_replace()
+ //
+ // Container-based version of the `std::replace()` function to
+ // replace a container's elements of some value with a new value. The container
+ // is modified in place.
+ template
+ void c_replace(Sequence& sequence, const T& old_value, const T& new_value)
+ {
+ std::replace(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), old_value, new_value);
+ }
+
+ // c_replace_if()
+ //
+ // Container-based version of the `std::replace_if()` function to
+ // replace a container's elements of some value with a new value based on some
+ // condition. The container is modified in place.
+ template
+ void c_replace_if(C& c, Pred&& pred, T&& new_value)
+ {
+ std::replace_if(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(pred), std::forward(new_value));
+ }
+
+ // c_replace_copy()
+ //
+ // Container-based version of the `std::replace_copy()` function to
+ // replace a container's elements of some value with a new value and return the
+ // results within an iterator.
+ template
+ OutputIterator c_replace_copy(const C& c, OutputIterator result, T&& old_value, T&& new_value)
+ {
+ return std::replace_copy(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), result, std::forward(old_value), std::forward(new_value));
+ }
+
+ // c_replace_copy_if()
+ //
+ // Container-based version of the `std::replace_copy_if()` function
+ // to replace a container's elements of some value with a new value based on
+ // some condition, and return the results within an iterator.
+ template
+ OutputIterator c_replace_copy_if(const C& c, OutputIterator result, Pred&& pred, const T& new_value)
+ {
+ return std::replace_copy_if(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), result, std::forward(pred), new_value);
+ }
+
+ // c_fill()
+ //
+ // Container-based version of the `std::fill()` function to fill a
+ // container with some value.
+ template
+ void c_fill(C& c, const T& value)
+ {
+ std::fill(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), value);
+ }
+
+ // c_fill_n()
+ //
+ // Container-based version of the `std::fill_n()` function to fill
+ // the first N elements in a container with some value.
+ template
+ void c_fill_n(C& c, Size n, const T& value)
+ {
+ std::fill_n(container_algorithm_internal::c_begin(c), n, value);
+ }
+
+ // c_generate()
+ //
+ // Container-based version of the `std::generate()` function to
+ // assign a container's elements to the values provided by the given generator.
+ template
+ void c_generate(C& c, Generator&& gen)
+ {
+ std::generate(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(gen));
+ }
+
+ // c_generate_n()
+ //
+ // Container-based version of the `std::generate_n()` function to
+ // assign a container's first N elements to the values provided by the given
+ // generator.
+ template
+ container_algorithm_internal::ContainerIter c_generate_n(C& c, Size n, Generator&& gen)
+ {
+ return std::generate_n(container_algorithm_internal::c_begin(c), n, std::forward(gen));
+ }
+
+ // Note: `c_xx()` container versions for `remove()`, `remove_if()`,
+ // and `unique()` are omitted, because it's not clear whether or not such
+ // functions should call erase on their supplied sequences afterwards. Either
+ // behavior would be surprising for a different set of users.
+
+ // c_remove_copy()
+ //
+ // Container-based version of the `std::remove_copy()` function to
+ // copy a container's elements while removing any elements matching the given
+ // `value`.
+ template
+ OutputIterator c_remove_copy(const C& c, OutputIterator result, const T& value)
+ {
+ return std::remove_copy(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), result, value);
+ }
+
+ // c_remove_copy_if()
+ //
+ // Container-based version of the `std::remove_copy_if()` function
+ // to copy a container's elements while removing any elements matching the given
+ // condition.
+ template
+ OutputIterator c_remove_copy_if(const C& c, OutputIterator result, Pred&& pred)
+ {
+ return std::remove_copy_if(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), result, std::forward(pred));
+ }
+
+ // c_unique_copy()
+ //
+ // Container-based version of the `std::unique_copy()` function to
+ // copy a container's elements while removing any elements containing duplicate
+ // values.
+ template
+ OutputIterator c_unique_copy(const C& c, OutputIterator result)
+ {
+ return std::unique_copy(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), result);
+ }
+
+ // Overload of c_unique_copy() for using a predicate evaluation other than
+ // `==` for comparing uniqueness of the element values.
+ template
+ OutputIterator c_unique_copy(const C& c, OutputIterator result, BinaryPredicate&& pred)
+ {
+ return std::unique_copy(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), result, std::forward(pred));
+ }
+
+ // c_reverse()
+ //
+ // Container-based version of the `std::reverse()` function to
+ // reverse a container's elements.
+ template
+ void c_reverse(Sequence& sequence)
+ {
+ std::reverse(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence));
+ }
+
+ // c_reverse_copy()
+ //
+ // Container-based version of the `std::reverse()` function to
+ // reverse a container's elements and write them to an iterator range.
+ template
+ OutputIterator c_reverse_copy(const C& sequence, OutputIterator result)
+ {
+ return std::reverse_copy(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), result);
+ }
+
+ // c_rotate()
+ //
+ // Container-based version of the `std::rotate()` function to
+ // shift a container's elements leftward such that the `middle` element becomes
+ // the first element in the container.
+ template>
+ Iterator c_rotate(C& sequence, Iterator middle)
+ {
+ return absl::rotate(container_algorithm_internal::c_begin(sequence), middle, container_algorithm_internal::c_end(sequence));
+ }
+
+ // c_rotate_copy()
+ //
+ // Container-based version of the `std::rotate_copy()` function to
+ // shift a container's elements leftward such that the `middle` element becomes
+ // the first element in a new iterator range.
+ template
+ OutputIterator c_rotate_copy(
+ const C& sequence,
+ container_algorithm_internal::ContainerIter middle,
+ OutputIterator result
+ )
+ {
+ return std::rotate_copy(container_algorithm_internal::c_begin(sequence), middle, container_algorithm_internal::c_end(sequence), result);
+ }
+
+ // c_shuffle()
+ //
+ // Container-based version of the `std::shuffle()` function to
+ // randomly shuffle elements within the container using a `gen()` uniform random
+ // number generator.
+ template
+ void c_shuffle(RandomAccessContainer& c, UniformRandomBitGenerator&& gen)
+ {
+ std::shuffle(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(gen));
+ }
+
+ //------------------------------------------------------------------------------
+ // Partition functions
+ //------------------------------------------------------------------------------
+
+ // c_is_partitioned()
+ //
+ // Container-based version of the `std::is_partitioned()` function
+ // to test whether all elements in the container for which `pred` returns `true`
+ // precede those for which `pred` is `false`.
+ template
+ bool c_is_partitioned(const C& c, Pred&& pred)
+ {
+ return std::is_partitioned(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward(pred));
+ }
+
+ // c_partition()
+ //
+ // Container-based version of the `std::partition()` function
+ // to rearrange all elements in a container in such a way that all elements for
+ // which `pred` returns `true` precede all those for which it returns `false`,
+ // returning an iterator to the first element of the second group.
+ template