Compare commits

..
Author SHA1 Message Date
admin 0dc0a6d5e6 Load Shardok terrain textures by battle month 2026-06-17 07:26:15 -07:00
442 changed files with 5089 additions and 7026 deletions
-26
View File
@@ -22,32 +22,6 @@ common --per_file_copt=src/test/cpp/.*@-Wno-sign-compare
common --per_file_copt=src/test/cpp/.*@-Wno-unknown-warning-option
common --host_cxxopt="--std=c++23"
# C++ sanitizer configs for targeted Shardok safety checks.
# Example: bazel test --config=asan //src/test/cpp/net/eagle0/shardok/library/...
build:asan --compilation_mode=dbg
build:asan --strip=never
build:asan --copt=-fno-omit-frame-pointer
build:asan --copt=-Wno-macro-redefined
build:asan --copt=-fsanitize=address
build:asan --linkopt=-fsanitize=address
test:asan --test_env=ASAN_OPTIONS=detect_leaks=0:strict_init_order=1
build:ubsan --compilation_mode=dbg
build:ubsan --strip=never
build:ubsan --copt=-fno-omit-frame-pointer
build:ubsan --copt=-Wno-macro-redefined
build:ubsan --copt=-fsanitize=undefined
build:ubsan --linkopt=-fsanitize=undefined
test:ubsan --test_env=UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1
build:tsan --compilation_mode=dbg
build:tsan --strip=never
build:tsan --copt=-fno-omit-frame-pointer
build:tsan --copt=-Wno-macro-redefined
build:tsan --copt=-fsanitize=thread
build:tsan --linkopt=-fsanitize=thread
test:tsan --test_env=TSAN_OPTIONS=halt_on_error=1
common --javacopt="-Xlint:-options"
# Prefer protobuf's prebuilt protoc toolchain instead of building protoc from
-32
View File
@@ -1,32 +0,0 @@
Checks: >
-*,
bugprone-*,
performance-*,
readability-*,
modernize-*,
cppcoreguidelines-*,
-bugprone-easily-swappable-parameters,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-macro-usage,
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-cppcoreguidelines-pro-bounds-constant-array-index,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-pro-type-const-cast,
-cppcoreguidelines-pro-type-reinterpret-cast,
-cppcoreguidelines-pro-type-union-access,
-cppcoreguidelines-pro-type-vararg,
-modernize-use-trailing-return-type,
-readability-convert-member-functions-to-static,
-readability-function-cognitive-complexity,
-readability-identifier-length,
-readability-magic-numbers
WarningsAsErrors: ''
HeaderFilterRegex: 'src/(main|test)/cpp/net/eagle0/(shardok|common)/.*'
FormatStyle: file
CheckOptions:
readability-braces-around-statements.ShortStatementLines: '1'
readability-function-size.LineThreshold: '160'
readability-function-size.StatementThreshold: '80'
readability-function-size.BranchThreshold: '20'
modernize-use-nullptr.NullMacros: 'NULL'
+2 -26
View File
@@ -23,7 +23,6 @@ on:
- "ci/github_actions/build_unity_mac.sh"
- "ci/github_actions/ensure_bazel_installed.sh"
- ".github/actions/setup-bazel/**"
- "ci/github_actions/detect_addressables_changes.sh"
- "ci/github_actions/upload_addressables.sh"
- "ci/github_actions/ensure_unity_installed.sh"
- "src/main/csharp/net/eagle0/clients/unity/eagle0/ProjectSettings/ProjectVersion.txt"
@@ -50,11 +49,8 @@ on:
- "scripts/notarize_wait.sh"
- "ci/github_actions/build_mac.sh"
- "ci/github_actions/build_unity_mac.sh"
- "ci/github_actions/ensure_unity_installed.sh"
- "ci/github_actions/ensure_bazel_installed.sh"
- ".github/actions/setup-bazel/**"
- "ci/github_actions/detect_addressables_changes.sh"
- "src/main/csharp/net/eagle0/clients/unity/eagle0/ProjectSettings/ProjectVersion.txt"
- "src/main/csharp/net/eagle0/clients/unity/eagle0/ProjectSettings/ProjectSettings.asset"
- ".bazelrc"
- "ci/mac/**"
@@ -125,25 +121,11 @@ jobs:
- name: Clean stale files
run: |
git clean -ffd
LIBRARY_DIR="src/main/csharp/net/eagle0/clients/unity/eagle0/Library"
VERSION_CACHE="$LIBRARY_DIR/.last_unity_version"
PROJECT_VERSION_FILE="src/main/csharp/net/eagle0/clients/unity/eagle0/ProjectSettings/ProjectVersion.txt"
CURRENT_VERSION=$(grep "m_EditorVersion:" "$PROJECT_VERSION_FILE" | head -1 | sed 's/m_EditorVersion: //')
# Nuke Library/ when Unity version changes to avoid import loops
if [ -f "$VERSION_CACHE" ]; then
CACHED_VERSION=$(cat "$VERSION_CACHE")
if [ "$CACHED_VERSION" != "$CURRENT_VERSION" ]; then
echo "Unity version changed ($CACHED_VERSION -> $CURRENT_VERSION) -- clearing Library/"
rm -rf "$LIBRARY_DIR"
fi
fi
# Only clear Bee/ when C# files were added/deleted/renamed (structural
# changes that stale the DAG). Content-only modifications are handled by
# Bee's incremental compilation. See persist_library.sh for background.
BEE_DIR="$LIBRARY_DIR/Bee"
SHA_FILE="$LIBRARY_DIR/.last_built_sha"
BEE_DIR="src/main/csharp/net/eagle0/clients/unity/eagle0/Library/Bee"
SHA_FILE="src/main/csharp/net/eagle0/clients/unity/eagle0/Library/.last_built_sha"
if [ -f "$SHA_FILE" ] && [ -d "$BEE_DIR" ]; then
LAST_SHA=$(cat "$SHA_FILE")
if git diff --diff-filter=ADR --name-only "$LAST_SHA" HEAD -- '*.cs' '*.csproj' '*.asmdef' 2>/dev/null | grep -q .; then
@@ -200,12 +182,6 @@ jobs:
mkdir -p src/main/csharp/net/eagle0/clients/unity/eagle0/Library
git rev-parse HEAD > src/main/csharp/net/eagle0/clients/unity/eagle0/Library/.last_built_sha
- name: Save Unity version for Library/ cache invalidation
if: success()
run: |
mkdir -p src/main/csharp/net/eagle0/clients/unity/eagle0/Library
grep "m_EditorVersion:" src/main/csharp/net/eagle0/clients/unity/eagle0/ProjectSettings/ProjectVersion.txt | head -1 | sed 's/m_EditorVersion: //' > src/main/csharp/net/eagle0/clients/unity/eagle0/Library/.last_unity_version
- name: Check if should deploy
id: check-deploy
run: |
+1 -3
View File
@@ -18,7 +18,6 @@ on:
- "ci/github_actions/test_unity_editmode.sh"
- "ci/github_actions/ensure_bazel_installed.sh"
- ".github/actions/setup-bazel/**"
- "ci/github_actions/detect_addressables_changes.sh"
- "ci/github_actions/upload_addressables.sh"
- "ci/github_actions/ensure_unity_installed.sh"
- "src/main/csharp/net/eagle0/clients/unity/eagle0/ProjectSettings/ProjectVersion.txt"
@@ -43,7 +42,6 @@ on:
- "ci/github_actions/test_unity_editmode.sh"
- "ci/github_actions/ensure_bazel_installed.sh"
- ".github/actions/setup-bazel/**"
- "ci/github_actions/detect_addressables_changes.sh"
- "ci/github_actions/upload_addressables.sh"
- "ci/github_actions/ensure_unity_installed.sh"
- "src/main/csharp/net/eagle0/clients/unity/eagle0/ProjectSettings/ProjectVersion.txt"
@@ -287,7 +285,7 @@ jobs:
./ci/github_actions/detect_addressables_changes.sh "$BASE_SHA" "${{ github.sha }}"
- name: Build Windows unity
run: ./ci/github_actions/build_unity.sh "${{ env.EAGLE0_BUILD_DIR }}/eagle0WIN" true "${{ steps.addressables.outputs.changed }}"
run: ./ci/github_actions/build_unity.sh "${{ env.EAGLE0_BUILD_DIR }}/eagle0WIN" "${{ steps.addressables.outputs.changed }}" "${{ steps.addressables.outputs.changed }}"
- name: Save build SHA for Bee/ cache invalidation
if: success()
+1 -1
View File
@@ -294,7 +294,7 @@ to be used for different players or game situations within the same server proce
**C# (Unity Client):**
- Located in `/src/main/csharp/net/eagle0/clients/unity/eagle0/`
- Uses Unity 6.5 (6000.5.0f1) with comprehensive protobuf integration (100+ .proto files)
- Uses Unity 6 (6000.4.10f1) with comprehensive protobuf integration (100+ .proto files)
- Key components: `EagleConnection.cs` (gRPC client), `EagleGameController.cs` (main game logic)
- Real-time bidirectional streaming with server via `PersistentClientConnection.cs`
- Strategic map UI in `Assets/Eagle/`, tactical battle UI in `Assets/Shardok/`
-14
View File
@@ -59,20 +59,6 @@ if [ $UNITY_EXIT_CODE -ne 0 ]; then
exit $UNITY_EXIT_CODE
fi
if [ ! -f "$LOG_PATH" ]; then
echo ""
echo "ERROR: Unity exited successfully but did not write an editor log at $LOG_PATH"
exit 1
fi
if [ ! -f "$BUILD_PATH/Data/Raw/aa/settings.json" ]; then
echo ""
echo "ERROR: iOS player is missing Addressables runtime data at:"
echo " $BUILD_PATH/Data/Raw/aa/settings.json"
echo "Build Addressables before packaging the player so Addressables can initialize at runtime."
exit 1
fi
# Fail the build if any prefab references are broken — this produces a player
# that launches but has null Inspector fields, which is hard to debug.
if grep -q "Missing Prefab" "$LOG_PATH"; then
-8
View File
@@ -57,14 +57,6 @@ if [ ! -f "$LOG_PATH" ]; then
exit 1
fi
if [ ! -f "$BUILD_DIR/eagle0_Data/StreamingAssets/aa/settings.json" ]; then
echo ""
echo "ERROR: Windows player is missing Addressables runtime data at:"
echo " $BUILD_DIR/eagle0_Data/StreamingAssets/aa/settings.json"
echo "Build Addressables before packaging the player so Addressables can initialize at runtime."
exit 1
fi
# Fail the build if any prefab references are broken — this produces a player
# that launches but has null Inspector fields, which is hard to debug.
if grep -q "Missing Prefab" "$LOG_PATH"; then
@@ -28,6 +28,7 @@ else
"$UNITY_PROJECT/Assets/AustraliaAnimalsPackv1/"
"$UNITY_PROJECT/Assets/Music/"
"$UNITY_PROJECT/Assets/Editor/BuildScript.cs"
"ci/github_actions/upload_addressables.sh"
)
is_addressables_input() {
+2 -10
View File
@@ -49,7 +49,7 @@ check_modules_installed() {
fi
;;
mac)
if ! has_mac_il2cpp_support "$unity_path" "$unity_app_contents_path"; then
if ! has_il2cpp_variation "${unity_app_contents_path}/PlaybackEngines/MacStandaloneSupport/Variations"; then
echo "✗ Mac IL2CPP module not installed for Unity ${UNITY_VERSION}"
return 1
fi
@@ -67,7 +67,7 @@ check_modules_installed() {
echo "✗ iOS module missing"
missing=1
fi
if ! has_mac_il2cpp_support "$unity_path" "$unity_app_contents_path"; then
if ! has_il2cpp_variation "${unity_app_contents_path}/PlaybackEngines/MacStandaloneSupport/Variations"; then
echo "✗ Mac IL2CPP module missing"
missing=1
fi
@@ -84,14 +84,6 @@ check_modules_installed() {
return 0
}
has_mac_il2cpp_support() {
local unity_path="$1"
local unity_app_contents_path="$2"
has_il2cpp_variation "${unity_app_contents_path}/PlaybackEngines/MacStandaloneSupport/Variations" ||
has_il2cpp_variation "${unity_path}/PlaybackEngines/MacStandaloneSupport/Variations"
}
has_il2cpp_variation() {
local variations_path="$1"
local variation
+6 -56
View File
@@ -18,11 +18,7 @@ SERVER_DATA="$UNITY_PROJECT/ServerData/$BUILD_TARGET"
# DigitalOcean Spaces configuration (same region as other eagle0 buckets)
DO_ENDPOINT="https://sfo3.digitaloceanspaces.com"
DO_BUCKET="eagle0-assets"
DEFAULT_MAX_UPLOAD_BYTES=$((1024 * 1024 * 1024))
DEFAULT_MAX_SINGLE_FILE_BYTES=$((512 * 1024 * 1024))
MAX_UPLOAD_BYTES=${ADDRESSABLES_MAX_UPLOAD_BYTES:-$DEFAULT_MAX_UPLOAD_BYTES}
MAX_SINGLE_FILE_BYTES=${ADDRESSABLES_MAX_SINGLE_FILE_BYTES:-$DEFAULT_MAX_SINGLE_FILE_BYTES}
TOP_UPLOAD_COUNT=${ADDRESSABLES_TOP_UPLOAD_COUNT:-20}
UPLOAD_WARNING_BYTES=$((1024 * 1024 * 1024))
COMMON_PATHS="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
export PATH="${COMMON_PATHS}:${PATH}"
@@ -55,17 +51,6 @@ file_size() {
fi
}
append_summary() {
if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then
echo "$1" >> "$GITHUB_STEP_SUMMARY"
fi
}
budget_enabled() {
local value=$1
[ "$value" -gt 0 ]
}
summarize_pending_uploads() {
local sync_args_file
sync_args_file=$(mktemp)
@@ -106,59 +91,24 @@ summarize_pending_uploads() {
fi
echo "Addressables upload preflight: $upload_count changed files, $(format_bytes "$upload_bytes") to upload."
append_summary "## Addressables upload preflight"
append_summary ""
append_summary "- Target: \`$BUILD_TARGET\`"
append_summary "- Changed files: \`$upload_count\`"
append_summary "- Changed upload bytes: \`$(format_bytes "$upload_bytes")\`"
append_summary "- Upload byte budget: \`$(format_bytes "$MAX_UPLOAD_BYTES")\`"
append_summary "- Single-file budget: \`$(format_bytes "$MAX_SINGLE_FILE_BYTES")\`"
local guardrail_failed=0
if [ "$upload_bytes" -ge "$UPLOAD_WARNING_BYTES" ]; then
echo "WARNING: Addressables upload is expected to exceed $(format_bytes "$UPLOAD_WARNING_BYTES")."
echo "A small asset change may have invalidated an oversized bundle; inspect the largest pending uploads below."
fi
if [ -s "$uploads_file" ]; then
echo "Largest pending Addressables uploads:"
append_summary ""
append_summary "### Largest pending uploads"
append_summary ""
append_summary "| Size | Path |"
append_summary "| ---: | --- |"
sort -nr "$uploads_file" > "$sorted_uploads_file"
local listed_uploads=0
while IFS=$'\t' read -r size path; do
if [ "$listed_uploads" -ge "$TOP_UPLOAD_COUNT" ]; then
if [ "$listed_uploads" -ge 20 ]; then
break
fi
local relative_path=${path#"$SERVER_DATA"/}
echo " $(format_bytes "$size") $relative_path"
append_summary "| $(format_bytes "$size") | \`$relative_path\` |"
listed_uploads=$((listed_uploads + 1))
done < "$sorted_uploads_file"
if budget_enabled "$MAX_SINGLE_FILE_BYTES"; then
while IFS=$'\t' read -r size path; do
if [ "$size" -gt "$MAX_SINGLE_FILE_BYTES" ]; then
local relative_path=${path#"$SERVER_DATA"/}
echo "ERROR: Pending Addressables upload '$relative_path' is $(format_bytes "$size"), exceeding single-file budget $(format_bytes "$MAX_SINGLE_FILE_BYTES")."
append_summary ""
append_summary ":x: \`$relative_path\` exceeds the single-file budget at \`$(format_bytes "$size")\`."
guardrail_failed=1
fi
done < "$uploads_file"
fi
fi
if budget_enabled "$MAX_UPLOAD_BYTES" && [ "$upload_bytes" -gt "$MAX_UPLOAD_BYTES" ]; then
echo "ERROR: Addressables upload is expected to send $(format_bytes "$upload_bytes"), exceeding budget $(format_bytes "$MAX_UPLOAD_BYTES")."
echo "A small asset change may have invalidated an oversized bundle; inspect the largest pending uploads above."
append_summary ""
append_summary ":x: Changed upload bytes exceed budget: \`$(format_bytes "$upload_bytes")\` > \`$(format_bytes "$MAX_UPLOAD_BYTES")\`."
guardrail_failed=1
fi
if [ "$guardrail_failed" -ne 0 ]; then
echo "Refusing to upload Addressables. Raise ADDRESSABLES_MAX_UPLOAD_BYTES or ADDRESSABLES_MAX_SINGLE_FILE_BYTES only after confirming the upload is intentional."
exit 1
fi
}
-12
View File
@@ -103,18 +103,6 @@ and protect fragile specialists.
a prisoner, add the Warden custody bonus to that prisoner's `factionBiases(rulingFactionId)`.
- For Shardok, start with a single-turn guard status before attempting more complex interception chains
**Current Follow-Up Priorities:**
- Teach the Shardok AI when to use the Warden evacuation command. The command is valuable when the Warden's side has
captured enemy heroes and can secure them by leaving the battle, especially when the battle outcome is uncertain or
trending against that side.
- Add the strategic passive custody bonus: each round, prisoners in a province guarded by a ruling-faction Warden should
get a small accumulated positive bias toward joining that faction. Prefer storing this as an addition to the existing
`factionBiases` entry rather than changing the global `roundsInType` multiplier, so the bonus only reflects rounds
actually spent under Warden custody.
- Make tactical AI more protective of heroes at risk of capture when a Warden may be present. Warden evacuation makes
captured heroes harder to recover, so the AI should treat exposing high-value heroes to capture as more dangerous than
before. This matters even when the AI does not have perfect knowledge that a Warden is in the battle.
### 2. HERALD (Morale & Communication Specialist)
**Fantasy:** The inspiring leader who rallies troops and carries messages across the battlefield.
-33
View File
@@ -1,33 +0,0 @@
#!/bin/bash
# Runs the repository-pinned clang-tidy binary from the workspace root.
#
# Bazel's `run` command executes clang-tidy from its runfiles tree, which makes
# workspace-relative source paths and .clang-tidy discovery fail. This wrapper
# builds the tool and then invokes the produced binary directly.
set -e
export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH"
repo_root="$(git rev-parse --show-toplevel)"
if [ "$#" -eq 0 ]; then
echo "Usage: scripts/run-clang-tidy.sh [clang-tidy args] <files> [-- <compiler args>]"
echo ""
echo "Examples:"
echo " scripts/run-clang-tidy.sh --verify-config"
echo " scripts/run-clang-tidy.sh src/main/cpp/net/eagle0/shardok/library/CombatDamage.hpp -- -I$repo_root -std=c++23"
exit 2
fi
bazel build @llvm_toolchain//:clang-tidy
bazel_bin="$(bazel info bazel-bin)"
clang_tidy="$bazel_bin/external/toolchains_llvm++llvm+llvm_toolchain/clang-tidy"
if [ ! -x "$clang_tidy" ]; then
echo "Unable to find clang-tidy binary at $clang_tidy"
exit 1
fi
"$clang_tidy" --config-file="$repo_root/.clang-tidy" "$@"
-1
View File
@@ -1,7 +1,6 @@
#!/bin/zsh
/opt/homebrew/bin/s3cmd sync \
--acl-public \
--exclude="*dream_log.txt" \
--exclude="*.DS_Store" \
--delete-removed \
@@ -6,8 +6,8 @@
// Copyright © 2017 none. All rights reserved.
//
#ifndef EAGLE0_COMMON_FILESYSTEM_UTILS_HPP
#define EAGLE0_COMMON_FILESYSTEM_UTILS_HPP
#ifndef FilesystemUtils_hpp
#define FilesystemUtils_hpp
#include <string>
#include <vector>
@@ -36,4 +36,4 @@ public:
static auto LoadFromPath(const string& path) -> byte_vector;
};
#endif // EAGLE0_COMMON_FILESYSTEM_UTILS_HPP
#endif /* FilesystemUtils_hpp */
+3 -3
View File
@@ -6,8 +6,8 @@
// Copyright © 2018 none. All rights reserved.
//
#ifndef EAGLE0_COMMON_MAP_UTILS_HPP
#define EAGLE0_COMMON_MAP_UTILS_HPP
#ifndef MapUtils_hpp
#define MapUtils_hpp
#include <string>
#include <unordered_map>
@@ -19,4 +19,4 @@ auto IntForKey(const std::unordered_map<std::string, std::string>& map, const st
auto BoolForKey(const std::unordered_map<std::string, std::string>& map, const std::string& key)
-> bool;
#endif // EAGLE0_COMMON_MAP_UTILS_HPP
#endif /* MapUtils_hpp */
@@ -6,8 +6,8 @@
// Copyright © 2019 none. All rights reserved.
//
#ifndef EAGLE0_COMMON_PROTOBUF_WARNING_SUPPRESSION_HPP
#define EAGLE0_COMMON_PROTOBUF_WARNING_SUPPRESSION_HPP
#ifndef ProtobufWarningSuppression_h
#define ProtobufWarningSuppression_h
#define SUPPRESS_PROTOBUF_WARNINGS \
_Pragma("GCC diagnostic ignored \"-Wpragmas\"") \
@@ -19,4 +19,4 @@
"GCC diagnostic ignored \"-Wshorten-64-to-32\"") \
_Pragma("GCC diagnostic ignored \"-Wnested-anon-types\"")
#endif // EAGLE0_COMMON_PROTOBUF_WARNING_SUPPRESSION_HPP
#endif /* ProtobufWarningSuppression_h */
@@ -6,13 +6,11 @@
// Copyright (c) 2015 none. All rights reserved.
//
#ifndef EAGLE0_COMMON_RANDOM_GENERATOR_HPP
#define EAGLE0_COMMON_RANDOM_GENERATOR_HPP
#ifndef __eagle0__ShardokRandomGenerator__
#define __eagle0__ShardokRandomGenerator__
#include <cstddef>
#include <memory>
#include <random>
#include <vector>
class RandomGenerator;
@@ -24,10 +22,6 @@ private:
public:
RandomGenerator() = default;
RandomGenerator(const RandomGenerator&) = default;
auto operator=(const RandomGenerator&) -> RandomGenerator& = default;
RandomGenerator(RandomGenerator&&) = default;
auto operator=(RandomGenerator&&) -> RandomGenerator& = default;
virtual ~RandomGenerator() = default;
@@ -41,7 +35,7 @@ public:
template<class T>
auto RandomElement(const std::vector<T>& vec) -> T {
return vec.at(static_cast<std::size_t>(IntBelow(static_cast<int>(vec.size()))));
return vec[IntBelow((int)vec.size())];
}
static auto ChanceOpenEndedPercentileAtOrAbove(double value) -> double;
@@ -62,4 +56,4 @@ public:
auto IntBetween(int min, int max) -> int override; // inclusive, exclusive (min<=return<max)
};
#endif // EAGLE0_COMMON_RANDOM_GENERATOR_HPP
#endif /* defined(__eagle0__ShardokRandomGenerator__) */
@@ -6,11 +6,10 @@
// Copyright © 2018 none. All rights reserved.
//
#ifndef EAGLE0_COMMON_SEQUENCE_RANDOM_GENERATOR_HPP
#define EAGLE0_COMMON_SEQUENCE_RANDOM_GENERATOR_HPP
#ifndef SequenceRandomGenerator_h
#define SequenceRandomGenerator_h
#include <memory>
#include <utility>
#include <vector>
#include "src/main/cpp/net/eagle0/common/RandomGenerator.hpp"
@@ -25,22 +24,22 @@
// which produces: initial=2 (triggers open-ended), accumulated=52, final=2-52=-50
class SequenceRandomGenerator : public ::RandomGenerator {
private:
std::vector<double> sequence;
const std::vector<double> sequence;
size_t position = 0;
auto DoubleZeroToOne() -> double override {
const double nextVal = sequence.at(position);
const double nextVal = sequence[position];
position++;
if (position >= sequence.size()) { position = 0; }
return nextVal;
}
public:
explicit SequenceRandomGenerator(std::vector<double> s) : sequence(std::move(s)) {}
explicit SequenceRandomGenerator(std::vector<double> s) : sequence(std::move(s)), position(0) {}
static auto WithSequence(const std::vector<double>& s)
-> std::shared_ptr<SequenceRandomGenerator> {
return std::make_shared<SequenceRandomGenerator>(s);
}
};
#endif // EAGLE0_COMMON_SEQUENCE_RANDOM_GENERATOR_HPP
#endif /* SequenceRandomGenerator_h */
+4 -4
View File
@@ -6,14 +6,14 @@
// Copyright © 2018 none. All rights reserved.
//
#ifndef EAGLE0_COMMON_TSV_PARSER_HPP
#define EAGLE0_COMMON_TSV_PARSER_HPP
#ifndef TsvParser_hpp
#define TsvParser_hpp
#include <string>
#include <unordered_map>
#include <vector>
using StringMap = std::unordered_map<std::string, std::string>;
typedef std::unordered_map<std::string, std::string> StringMap;
// Parses a TSV, with the first column becoming map keys and subsequent columns becoming values
// for different maps in the returned vector.
@@ -23,4 +23,4 @@ public:
std::vector<StringMap> ParseColumnEntryTsv(std::string tsv);
};
#endif // EAGLE0_COMMON_TSV_PARSER_HPP
#endif /* TsvParser_hpp */
@@ -6,8 +6,8 @@
// Copyright © 2017 none. All rights reserved.
//
#ifndef EAGLE0_COMMON_BYTE_VECTOR_HPP
#define EAGLE0_COMMON_BYTE_VECTOR_HPP
#ifndef byte_vector_h
#define byte_vector_h
#include <cstdint>
#include <cstring>
@@ -184,4 +184,4 @@ inline auto operator<<(std::ostream& ostr, byte_vector vec) -> std::ostream& {
return ostr;
}
#endif // EAGLE0_COMMON_BYTE_VECTOR_HPP
#endif /* byte_vector_h */
@@ -141,8 +141,9 @@ public:
// Default implementation: no filtering, so filtered index = original index
[[nodiscard]] virtual size_t mapFilteredIndexToOriginal(
size_t filteredIndex,
const MCTSGameState& /*state*/) const {
const MCTSGameState& state) const {
// Default: no filtering, index stays the same
(void)state; // Suppress unused parameter warning
return filteredIndex;
}
@@ -157,4 +158,4 @@ public:
} // namespace mcts
} // namespace shardok
#endif // EAGLE0_MCTS_GAME_ENGINE_HPP
#endif // EAGLE0_MCTS_GAME_ENGINE_HPP
@@ -69,6 +69,25 @@ cc_binary(
],
)
cc_binary(
name = "random_battle_runner",
srcs = ["RandomBattleRunner.cpp"],
copts = COPTS,
data = [
"//src/main/resources/net/eagle0/shardok:battalion_types",
"//src/main/resources/net/eagle0/shardok:settings",
"//src/main/resources/net/eagle0/shardok/maps",
],
deps = [
"//src/main/cpp/net/eagle0/common:byte_vector",
"//src/main/cpp/net/eagle0/common:filesystem_utils",
"//src/main/cpp/net/eagle0/common:unit_conversions",
"//src/main/cpp/net/eagle0/shardok/library:shardok_c_types",
"//src/main/cpp/net/eagle0/shardok/server:games_manager",
"//src/main/protobuf/net/eagle0/common:random_units_cc_proto",
],
)
cc_library(
name = "map_info_calculator",
srcs = ["MapInfoCalculator.cpp"],
@@ -22,7 +22,7 @@ int main(const int argc, char** argv) {
const std::string outputPath = argv[2];
const byte_vector mapProtoBytes = byte_vector::FromPath(inputPath);
net::eagle0::shardok::common::HexMap mapProto;
mapProto.ParseFromArray(mapProtoBytes.data(), static_cast<int>(mapProtoBytes.size()));
mapProto.ParseFromArray(mapProtoBytes.data(), (int)mapProtoBytes.size());
ModifyMap(mapProto);
const std::string outputString = mapProto.SerializeAsString();
@@ -36,7 +36,7 @@ void ModifyMap(HexMapProto& map) {
for (int i = 0; i < map.terrain_size(); i++) {
const auto existingTerrainType = map.terrain(i).type();
const auto newTerrain =
static_cast<net::eagle0::shardok::common::Terrain_Type>(existingTerrainType + 2);
(net::eagle0::shardok::common::Terrain_Type)(existingTerrainType + 2);
map.mutable_terrain(i)->set_type(newTerrain);
}
}
@@ -4,15 +4,13 @@
#include "MapInfoCalculator.hpp"
#include <cstdlib>
#include <iostream>
#include "src/main/cpp/net/eagle0/shardok/ai/AIWaterCrossingCalculator.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/fb_helpers/HexMapHelpers.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/util/HexMapUtils.hpp"
#include "src/main/cpp/net/eagle0/shardok/util/MapLoader.hpp"
using namespace shardok;
using std::endl;
auto LoadMapFb(const string& mapName) -> Wrapper<HexMap> {
const HexMapProto mapProto = LoadMap(mapName);
@@ -42,7 +40,7 @@ auto CalculateMap(
const auto* positionList = hexMap->attacker_starting_positions()->Get(i);
if (positionList->positions()->size() < 1) continue;
if (positionList->positions()->size() != 10) {
std::cerr << "Should have 10 starting positions!" << '\n';
printf("Should have 10 starting positions!");
abort();
}
@@ -65,4 +63,4 @@ auto CalculateMap(
}
return info;
}
}
@@ -16,11 +16,11 @@ using namespace shardok;
using std::map;
using std::string;
struct alignas(64) OneMapInfo {
struct OneMapInfo {
uint32_t castleCount;
string name;
map<int, int> positionsRequiringCrossing;
};
} __attribute__((aligned(64)));
auto CalculateMap(
const string& mapName,
@@ -2,7 +2,6 @@
// Created by Dan Crosby on 4/18/22.
//
#include <fstream>
#include <iostream>
#include <memory>
@@ -12,16 +11,15 @@
#include "src/main/cpp/net/eagle0/shardok/util/MapLoader.hpp"
using namespace shardok;
using std::endl;
auto main(const int argc, char** argv) -> int {
FilesystemUtils::SetExecPath(argv[0]);
std::ostream* outputStreamPtr = &std::cout;
std::ofstream outputFile{};
if (argc > 1) {
const string outputPath = argv[1];
outputFile.open(outputPath);
outputStreamPtr = &outputFile;
outputStreamPtr = new std::ofstream(outputPath);
}
std::ostream& outputStream = *outputStreamPtr;
@@ -43,29 +41,29 @@ auto main(const int argc, char** argv) -> int {
bool firstMap = true;
for (const OneMapInfo& mapInfo : mapInfos) {
if (firstMap) {
outputStream << '\n';
outputStream << endl;
firstMap = false;
} else {
outputStream << "," << '\n';
outputStream << "," << endl;
}
outputStream << " {" << '\n';
outputStream << R"( "name": ")" << mapInfo.name << "\"," << '\n';
outputStream << " {" << endl;
outputStream << R"( "name": ")" << mapInfo.name << "\"," << endl;
outputStream << " \"castleCount\": " << mapInfo.castleCount << "," << '\n';
outputStream << " \"castleCount\": " << mapInfo.castleCount << "," << endl;
outputStream << " \"positions\": {";
bool firstPosition = true;
for (const auto& [position, count] : mapInfo.positionsRequiringCrossing) {
if (firstPosition) {
outputStream << '\n';
outputStream << endl;
firstPosition = false;
} else {
outputStream << "," << '\n';
outputStream << "," << endl;
}
outputStream << " \"" << position << "\": " << count;
}
outputStream << '\n' << " }" << '\n' << " }";
outputStream << endl << " }" << endl << " }";
}
outputStream << '\n' << "]" << '\n';
outputStream << endl << "]" << endl;
}
@@ -0,0 +1,127 @@
//
// Created by Dan Crosby on 3/29/21.
//
#include <memory>
#include <numeric>
#include <random>
#include <thread>
#include "src/main/cpp/net/eagle0/common/FilesystemUtils.hpp"
#include "src/main/cpp/net/eagle0/common/UnitConversions.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/ShardokCTypes.h"
#include "src/main/cpp/net/eagle0/shardok/server/ShardokGamesManager.hpp"
#include "src/main/protobuf/net/eagle0/common/random_units.pb.h"
using net::eagle0::common::RandomUnits;
using std::shared_ptr;
using std::vector;
constexpr int THREAD_COUNT = 16;
#define FIXED_SEED true
#if FIXED_SEED
std::mt19937 g;
#else
std::random_device rd;
std::mt19937 g(rd());
#endif
vector<string> fileNames{};
using namespace shardok;
ShardokGamesManager* manager;
auto randInt(const int lowInc, const int hiInc) {
return std::uniform_int_distribution(lowInc, hiInc)(g);
}
void runBattle(const vector<shared_ptr<const UnitProto>>& units) {
auto mapName = fileNames[randInt(0, (int)fileNames.size() - 1)];
auto month = randInt(1, 12);
auto p1UnitCount = randInt(1, 20);
vector<UnitProto> p1Units{};
for (int i = 0; i < p1UnitCount; i++) {
auto unit = *units[i];
unit.set_player_id(0);
p1Units.push_back(unit);
}
auto p2UnitCount = randInt(1, 20);
vector<UnitProto> p2Units{};
for (int i = p1UnitCount; i < p1UnitCount + p2UnitCount; i++) {
auto unit = *units[i];
unit.set_player_id(1);
p2Units.push_back(unit);
}
printf("map name is %s, %d attacking %d\n", mapName.c_str(), p1UnitCount, p2UnitCount);
vector<VictoryConditionProto> attVictoryConditions{
VictoryConditionProto::VICTORY_CONDITION_HOLDS_CRITICAL_TILES,
VictoryConditionProto::VICTORY_CONDITION_LAST_PLAYER_STANDING};
vector<VictoryConditionProto> defVictoryConditions{
VictoryConditionProto::VICTORY_CONDITION_LAST_PLAYER_STANDING,
VictoryConditionProto::VICTORY_CONDITION_WIN_AFTER_MAX_ROUNDS};
auto p1 = PlayerInfoWithUnits(0, true, 5, false, 10000, attVictoryConditions, {}, p1Units);
auto p2 = PlayerInfoWithUnits(1, false, 7, false, 10000, defVictoryConditions, {}, p2Units);
string gameId = std::to_string(randInt(INT_MIN, INT_MAX));
manager->LockedCreateSpecifiedGame(gameId, {p1, p2}, mapName, "", month, "");
}
auto LoadUnits() -> vector<shared_ptr<const UnitProto>> {
const auto bytes = byte_vector::FromPath("/tmp/random_heroes.bin");
RandomUnits commonUnits;
commonUnits.ParseFromArray(bytes.data(), (int)bytes.size());
printf("Loaded %d units\n", commonUnits.units_size());
vector<shared_ptr<const UnitProto>> units{};
units.reserve(commonUnits.units_size());
for (const auto& commonUnit : commonUnits.units()) {
// FIXME: assumes 2 players
units.push_back(std::make_shared<const UnitProto>(ConvertUnit(commonUnit, 0, {0, 1})));
}
std::shuffle(units.begin(), units.end(), g);
return units;
}
[[noreturn]] void runBattlesThread(const vector<shared_ptr<const UnitProto>>& units) {
while (true) { runBattle(units); }
}
auto main(int argc, char** argv) -> int {
#if FIXED_SEED
std::srand(4564564);
g.seed(378473);
#else
std::srand(std::time(nullptr));
#endif
FilesystemUtils::SetExecPath(argv[0]);
auto randomUnits = LoadUnits();
printf("Map file directory is %s\n", FilesystemUtils::MapFilesDirectory().c_str());
fileNames = FilesystemUtils::FilesInDirectory(FilesystemUtils::MapFilesDirectory(), ".e0m");
for (auto& fileName : fileNames) { fileName.resize(fileName.size() - 4); }
manager = new ShardokGamesManager(nullptr, std::vector<std::string>());
std::thread threads[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
threads[i] = std::thread(runBattlesThread, randomUnits);
}
for (auto& thread : threads) { thread.join(); }
}
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 6/19/23.
//
#ifndef EAGLE0_SHARDOK_AI_AI_ATTACK_GROUPS_HPP
#define EAGLE0_SHARDOK_AI_AI_ATTACK_GROUPS_HPP
#ifndef EAGLE0_AIATTACKGROUPS_HPP
#define EAGLE0_AIATTACKGROUPS_HPP
#include <functional>
#include <vector>
@@ -77,4 +77,4 @@ auto GenerateTargetPriorities(
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_ATTACK_GROUPS_HPP
#endif // EAGLE0_AIATTACKGROUPS_HPP
@@ -20,7 +20,7 @@ using Unit = net::eagle0::shardok::storage::fb::Unit;
using std::shared_ptr;
using std::vector;
class alignas(128) AttackLocations {
class AttackLocations {
private:
const MapIndex rowCount;
const MapIndex columnCount;
@@ -147,9 +147,9 @@ public:
adjacentLocations += cs;
allLocations += cs;
}
};
} __attribute__((aligned(128)));
struct alignas(128) AttackLocationsCache {
struct AttackLocationsCache {
private:
const MapIndex rowCount;
const MapIndex columnCount;
@@ -166,7 +166,7 @@ public:
auto CachedLocations(const Coords& singleTarget, bool lateGame) -> const AttackLocations&;
auto CachedLocations(const CoordsSet& targets, bool lateGame) -> AttackLocations;
auto CachedLocations(const vector<const Unit*>& enemies, bool lateGame) -> AttackLocations;
};
} __attribute__((aligned(128)));
using ALCache = std::unique_ptr<AttackLocationsCache>;
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 1/9/22.
//
#ifndef EAGLE0_SHARDOK_AI_AI_ATTACKER_STRATEGY_SELECTOR_HPP
#define EAGLE0_SHARDOK_AI_AI_ATTACKER_STRATEGY_SELECTOR_HPP
#ifndef EAGLE0_AIATTACKERSTRATEGYSELECTOR_HPP
#define EAGLE0_AIATTACKERSTRATEGYSELECTOR_HPP
#include "src/main/cpp/net/eagle0/shardok/ai/AIAttackLocations.hpp"
#include "src/main/cpp/net/eagle0/shardok/ai/AICommonTypes.hpp"
@@ -32,4 +32,4 @@ public:
};
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_ATTACKER_STRATEGY_SELECTOR_HPP
#endif // EAGLE0_AIATTACKERSTRATEGYSELECTOR_HPP
@@ -22,11 +22,11 @@ namespace shardok {
// No need to forward declare internal functions - use the public interface instead
// Helper constants and static variables
static const std::vector<double> kAverageSequence = {0.5};
static const auto kAverageGenerator = std::make_shared<SequenceRandomGenerator>(kAverageSequence);
static const std::vector<double> _averageSequence = {0.5};
static const auto _averageGenerator = std::make_shared<SequenceRandomGenerator>(_averageSequence);
constexpr bool kMultithread = true;
constexpr bool kLogging = false;
#define MULTITHREAD true
#define LOGGING_ 0
// Helper function to determine if a command type is deterministic
static auto IsDeterministic(const CommandType type) -> bool {
@@ -49,7 +49,6 @@ static auto IsDeterministic(const CommandType type) -> bool {
case net::eagle0::shardok::common::FORTIFY_COMMAND:
case net::eagle0::shardok::common::BECOME_OUTLAW_COMMAND:
case net::eagle0::shardok::common::HOLY_WAVE_COMMAND:
case net::eagle0::shardok::common::EVACUATE_PRISONERS_COMMAND:
case net::eagle0::shardok::common::REPAIR_COMMAND: return true;
default: return false;
}
@@ -237,16 +236,15 @@ auto AICommandEvaluator::EvaluateWithRandomness(
return lookaheadFuture.get();
};
if constexpr (kMultithread) {
auto launchPolicy =
remainingLookahead == 1 ? std::launch::async : std::launch::deferred;
returnValue.lookaheadScore = std::async(launchPolicy, lookaheadLambda);
} else {
std::promise<EvaluationResult> p;
returnValue.lookaheadScore = p.get_future();
auto lambdaResult = lookaheadLambda();
p.set_value(lambdaResult);
}
#if MULTITHREAD
auto launchPolicy = remainingLookahead == 1 ? std::launch::async : std::launch::deferred;
returnValue.lookaheadScore = std::async(launchPolicy, lookaheadLambda);
#else
std::promise<EvaluationResult> p;
returnValue.lookaheadScore = p.get_future();
auto lambdaResult = lookaheadLambda();
p.set_value(lambdaResult);
#endif
}
return returnValue;
@@ -303,23 +301,22 @@ auto AICommandEvaluator::FindBestCommand(
minDistToEnemies = 0.0; // No enemies found
}
if constexpr (kLogging) {
// Log command count and distance metrics for performance analysis
const auto allCommandCount = guessedDescriptors->size();
const auto filteredCommandCount = filteredIndices.size();
const int currentRound = gameState->current_round();
#if LOGGING_
// Log command count and distance metrics for performance analysis
const auto allCommandCount = guessedDescriptors->size();
const auto filteredCommandCount = filteredIndices.size();
const int currentRound = gameState->current_round();
printf("AI_COMMAND_COUNT: Round %d, Player %d, Defender %d, MinDist %.1f, Commands %zu -> "
"%zu "
"(%.1f%% filtered)\n",
currentRound,
static_cast<int>(pid),
isDefender ? 1 : 0,
minDistToEnemies,
allCommandCount,
filteredCommandCount,
100.0 * (allCommandCount - filteredCommandCount) / allCommandCount);
}
printf("AI_COMMAND_COUNT: Round %d, Player %d, Defender %d, MinDist %.1f, Commands %zu -> %zu "
"(%.1f%% filtered)\n",
currentRound,
static_cast<int>(pid),
isDefender ? 1 : 0,
minDistToEnemies,
allCommandCount,
filteredCommandCount,
100.0 * (allCommandCount - filteredCommandCount) / allCommandCount);
#endif
const auto commandCount = filteredIndices.size();
@@ -354,7 +351,7 @@ auto AICommandEvaluator::FindBestCommand(
originalIndex,
remainingLookahead,
maxRepeatCount,
kAverageGenerator,
_averageGenerator,
guessedEngine,
attackerStrategy,
allCastleCoords,
@@ -522,7 +519,7 @@ auto AICommandEvaluator::EvaluateCommand(
commandIndex,
remainingLookahead,
maxRepeatCount,
kAverageGenerator,
_averageGenerator,
guessedEngine,
attackerStrategy,
allCastleCoords,
@@ -3,8 +3,8 @@
// Separated from AIScoreCalculator to isolate pure state scoring from lookahead logic.
//
#ifndef EAGLE0_SHARDOK_AI_AI_COMMAND_EVALUATOR_HPP
#define EAGLE0_SHARDOK_AI_AI_COMMAND_EVALUATOR_HPP
#ifndef EAGLE0_AICOMMANDEVALUATOR_HPP
#define EAGLE0_AICOMMANDEVALUATOR_HPP
#include <chrono>
#include <future>
@@ -114,4 +114,4 @@ private:
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_COMMAND_EVALUATOR_HPP
#endif // EAGLE0_AICOMMANDEVALUATOR_HPP
@@ -2,8 +2,8 @@
// Filter obviously bad commands to reduce search space for AI
//
#ifndef EAGLE0_SHARDOK_AI_AI_COMMAND_FILTER_HPP
#define EAGLE0_SHARDOK_AI_AI_COMMAND_FILTER_HPP
#ifndef EAGLE0_AICOMMANDFILTER_HPP
#define EAGLE0_AICOMMANDFILTER_HPP
#include <memory>
#include <vector>
@@ -116,4 +116,4 @@ private:
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_COMMAND_FILTER_HPP
#endif // EAGLE0_AICOMMANDFILTER_HPP
@@ -3,8 +3,8 @@
// Common type definitions used across AI utility functions
//
#ifndef EAGLE0_SHARDOK_AI_AI_COMMON_TYPES_HPP
#define EAGLE0_SHARDOK_AI_AI_COMMON_TYPES_HPP
#ifndef EAGLE0_AICOMMONTYPES_HPP
#define EAGLE0_AICOMMONTYPES_HPP
#include <functional>
@@ -20,4 +20,4 @@ using BattalionTypeGetter = std::function<BattalionTypeSPtr(BattalionTypeId)>;
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_COMMON_TYPES_HPP
#endif // EAGLE0_AICOMMONTYPES_HPP
@@ -2,8 +2,8 @@
// AI System Types and Configuration
//
#ifndef EAGLE0_SHARDOK_AI_AI_CONFIG_HPP
#define EAGLE0_SHARDOK_AI_AI_CONFIG_HPP
#ifndef EAGLE0_AI_CONFIG_HPP
#define EAGLE0_AI_CONFIG_HPP
namespace shardok {
@@ -22,4 +22,4 @@ enum class ScoringCalculatorType {
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_CONFIG_HPP
#endif // EAGLE0_AI_CONFIG_HPP
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 8/30/23.
//
#ifndef EAGLE0_SHARDOK_AI_AI_DEFENDER_STRATEGY_SELECTOR_HPP
#define EAGLE0_SHARDOK_AI_AI_DEFENDER_STRATEGY_SELECTOR_HPP
#ifndef EAGLE0_AIDEFENDERSTRATEGYSELECTOR_HPP
#define EAGLE0_AIDEFENDERSTRATEGYSELECTOR_HPP
#include "src/main/cpp/net/eagle0/shardok/ai/AIAttackLocations.hpp"
#include "src/main/cpp/net/eagle0/shardok/ai/AICommonTypes.hpp"
@@ -26,4 +26,4 @@ public:
};
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_DEFENDER_STRATEGY_SELECTOR_HPP
#endif // EAGLE0_AIDEFENDERSTRATEGYSELECTOR_HPP
@@ -55,12 +55,12 @@ auto DefenderDistanceBuf(
const bool includeUndead) -> double {
const auto &locationsToAttackMe = alCache->CachedLocations(defenderLocation, lateGame);
struct alignas(8) WithoutAndWith {
struct WithoutAndWith {
int without;
int with;
WithoutAndWith(const int a, const int b) : without(a), with(b) {}
};
} __attribute__((aligned(8)));
vector<WithoutAndWith> pointCosts{};
pointCosts.reserve(attackerUnits.size());
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 5/10/21.
//
#ifndef EAGLE0_SHARDOK_AI_AI_DISTANCE_DEBUF_HPP
#define EAGLE0_SHARDOK_AI_AI_DISTANCE_DEBUF_HPP
#ifndef EAGLE0_AIDISTANCEDEBUF_HPP
#define EAGLE0_AIDISTANCEDEBUF_HPP
#include "AIAttackLocations.hpp"
#include "src/main/cpp/net/eagle0/shardok/ai/AICommonTypes.hpp"
@@ -29,4 +29,4 @@ auto DefenderDistanceBuf(
bool includeUndead) -> double;
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_DISTANCE_DEBUF_HPP
#endif // EAGLE0_AIDISTANCEDEBUF_HPP
@@ -2,8 +2,8 @@
// Temporary AI experiment switches used by benchmark-only EXPERIMENTAL runs.
//
#ifndef EAGLE0_SHARDOK_AI_AI_EXPERIMENT_CONFIG_HPP
#define EAGLE0_SHARDOK_AI_AI_EXPERIMENT_CONFIG_HPP
#ifndef EAGLE0_AI_EXPERIMENT_CONFIG_HPP
#define EAGLE0_AI_EXPERIMENT_CONFIG_HPP
#include <cstdlib>
#include <string>
@@ -20,4 +20,4 @@ inline auto IsAIExperiment(const int id) -> bool { return CurrentAIExperimentId(
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_EXPERIMENT_CONFIG_HPP
#endif // EAGLE0_AI_EXPERIMENT_CONFIG_HPP
@@ -6,8 +6,8 @@
// and flee vs fight evaluation for final round scenarios
//
#ifndef EAGLE0_SHARDOK_AI_AI_FLEE_DECISION_CALCULATOR_HPP
#define EAGLE0_SHARDOK_AI_AI_FLEE_DECISION_CALCULATOR_HPP
#ifndef AIFleeDecisionCalculator_hpp
#define AIFleeDecisionCalculator_hpp
#include "src/main/cpp/net/eagle0/shardok/library/ShardokCommand.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/ShardokEngine.hpp"
@@ -63,4 +63,4 @@ private:
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_FLEE_DECISION_CALCULATOR_HPP
#endif /* AIFleeDecisionCalculator_hpp */
@@ -226,7 +226,6 @@ double AIHeuristicWeighting::GetCommandWeight(
// === ZERO WEIGHT - NEVER SELECT (0.0) ===
// Explicitly bad actions
case CommandType::FLEE_COMMAND: return 0.0; // Never flee in simulation
case CommandType::EVACUATE_PRISONERS_COMMAND: return 0.0;
case CommandType::RETREAT_COMMAND: return 0.0;
case CommandType::BECOME_OUTLAW_COMMAND: return 0.0; // Never become outlaw
case CommandType::DISMISS_UNIT_COMMAND:
@@ -3,8 +3,8 @@
// Provides O(1) weights based on command type and context
//
#ifndef EAGLE0_SHARDOK_AI_AI_HEURISTIC_WEIGHTING_HPP
#define EAGLE0_SHARDOK_AI_AI_HEURISTIC_WEIGHTING_HPP
#ifndef EAGLE0_AI_HEURISTIC_WEIGHTING_HPP
#define EAGLE0_AI_HEURISTIC_WEIGHTING_HPP
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-redundant-constexpr-static-def"
@@ -37,4 +37,4 @@ public:
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_HEURISTIC_WEIGHTING_HPP
#endif // EAGLE0_AI_HEURISTIC_WEIGHTING_HPP
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 8/31/23.
//
#ifndef EAGLE0_SHARDOK_AI_AI_MINIMUM_DISTANCE_AND_TARGET_HPP
#define EAGLE0_SHARDOK_AI_AI_MINIMUM_DISTANCE_AND_TARGET_HPP
#ifndef EAGLE0_AIMINIMUMDISTANCEANDTARGET_HPP
#define EAGLE0_AIMINIMUMDISTANCEANDTARGET_HPP
#include <utility>
#include <vector>
@@ -34,4 +34,4 @@ auto MinimumDistance(
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_MINIMUM_DISTANCE_AND_TARGET_HPP
#endif // EAGLE0_AIMINIMUMDISTANCEANDTARGET_HPP
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 4/7/21.
//
#ifndef EAGLE0_SHARDOK_AI_AI_SCORE_UTILITIES_HPP
#define EAGLE0_SHARDOK_AI_AI_SCORE_UTILITIES_HPP
#ifndef EAGLE0_AISCOREUTILITIES_HPP
#define EAGLE0_AISCOREUTILITIES_HPP
#include <vector>
@@ -31,4 +31,4 @@ auto PlayerInfoForPid(const GameStateW &, PlayerId pid) -> const PlayerInfo *;
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_SCORE_UTILITIES_HPP
#endif // EAGLE0_AISCOREUTILITIES_HPP
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 1/10/22.
//
#ifndef EAGLE0_SHARDOK_AI_AI_STRATEGY_HPP
#define EAGLE0_SHARDOK_AI_AI_STRATEGY_HPP
#ifndef EAGLE0_AISTRATEGY_HPP
#define EAGLE0_AISTRATEGY_HPP
#include "src/main/cpp/net/eagle0/shardok/ai/AIAttackGroups.hpp"
@@ -34,4 +34,4 @@ auto CrossRiversStrategy(const CoordsSet& targetLocations) -> AIStrategy;
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_STRATEGY_HPP
#endif // EAGLE0_AISTRATEGY_HPP
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 07/04/25.
//
#ifndef EAGLE0_SHARDOK_AI_AI_TIME_BUDGET_HPP
#define EAGLE0_SHARDOK_AI_AI_TIME_BUDGET_HPP
#ifndef EAGLE0_AITIMEBUDGET_HPP
#define EAGLE0_AITIMEBUDGET_HPP
#include <atomic>
#include <chrono>
@@ -48,4 +48,4 @@ auto CalculateTimeBudget(
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_TIME_BUDGET_HPP
#endif // EAGLE0_AITIMEBUDGET_HPP
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 4/7/21.
//
#ifndef EAGLE0_SHARDOK_AI_AI_UNIT_SCORE_CALCULATOR_HPP
#define EAGLE0_SHARDOK_AI_AI_UNIT_SCORE_CALCULATOR_HPP
#ifndef EAGLE0_AIUNITSCORECALCULATOR_HPP
#define EAGLE0_AIUNITSCORECALCULATOR_HPP
#include "src/main/cpp/net/eagle0/shardok/library/action_point_distances/ActionPointDistances.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/map/CoordsSet.hpp"
@@ -53,4 +53,4 @@ auto UnitValue(
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_UNIT_SCORE_CALCULATOR_HPP
#endif // EAGLE0_AIUNITSCORECALCULATOR_HPP
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 12/29/21.
//
#ifndef EAGLE0_SHARDOK_AI_AI_WATER_CROSSING_CALCULATOR_HPP
#define EAGLE0_SHARDOK_AI_AI_WATER_CROSSING_CALCULATOR_HPP
#ifndef EAGLE0_AIWATERCROSSINGCALCULATOR_HPP
#define EAGLE0_AIWATERCROSSINGCALCULATOR_HPP
#include "src/main/cpp/net/eagle0/shardok/ai/AICommonTypes.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/GameStateW.hpp"
@@ -23,8 +23,7 @@ static inline void AssertValid(const Coords& c, const HexMap* hexMap) {
if (!valid) {
std::stringstream str;
str << "Invalid coords " << static_cast<int>(c.row()) << ", "
<< static_cast<int>(c.column());
str << "Invalid coords " << (int)c.row() << ", " << (int)c.column();
throw ShardokInternalErrorException(str.str());
}
@@ -86,4 +85,4 @@ auto WaterCrossingScore(
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_WATER_CROSSING_CALCULATOR_HPP
#endif // EAGLE0_AIWATERCROSSINGCALCULATOR_HPP
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 1/5/22.
//
#ifndef EAGLE0_SHARDOK_AI_AI_WATER_CROSSING_COMMAND_CHOOSER_HPP
#define EAGLE0_SHARDOK_AI_AI_WATER_CROSSING_COMMAND_CHOOSER_HPP
#ifndef EAGLE0_AIWATERCROSSINGCOMMANDCHOOSER_HPP
#define EAGLE0_AIWATERCROSSINGCOMMANDCHOOSER_HPP
#include <utility>
@@ -44,4 +44,4 @@ public:
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_AI_WATER_CROSSING_COMMAND_CHOOSER_HPP
#endif // EAGLE0_AIWATERCROSSINGCOMMANDCHOOSER_HPP
@@ -19,7 +19,7 @@
namespace shardok {
constexpr bool kDebugIterativeDeepeningTimings = true;
#define DEBUG_ITERATIVE_DEEPENING_TIMINGS 1
IterativeDeepeningAI::IterativeDeepeningAI(
const PlayerId playerId,
@@ -54,9 +54,9 @@ auto IterativeDeepeningAI::IterativeSearch(
// DEBUG: Clear TT to see if that's causing the suspicious depth reaching
// g_transpositionTable.clear(); // Uncomment to test without cross-search caching
if (commands->empty()) {
if (kDebugIterativeDeepeningTimings) {
printf("ID AI: Commands are empty, returning early\n");
}
#if DEBUG_ITERATIVE_DEEPENING_TIMINGS
printf("ID AI: Commands are empty, returning early\n");
#endif
result.searchCompleted = true;
return result;
}
@@ -168,23 +168,23 @@ auto IterativeDeepeningAI::IterativeSearch(
// Log if best command changed from previous depth
if (currentDepth > 1 && currentBestCommand != previousBestCommand) {
if (kDebugIterativeDeepeningTimings) {
printf("ID AI: Best command changed at depth %lu:\n", currentDepth);
printf(" Depth %lu best: command %zu (score %.2f) - type: %s\n",
currentDepth - 1,
previousBestCommand,
scoresByDepth[previousBestCommand][currentDepth - 1],
net::eagle0::shardok::common::CommandType_Name(
(*commands)[previousBestCommand]->GetCommandType())
.c_str());
printf(" Depth %lu best: command %zu (score %.2f) - type: %s\n",
currentDepth,
currentBestCommand,
currentBestScore,
net::eagle0::shardok::common::CommandType_Name(
(*commands)[currentBestCommand]->GetCommandType())
.c_str());
}
#if DEBUG_ITERATIVE_DEEPENING_TIMINGS
printf("ID AI: Best command changed at depth %lu:\n", currentDepth);
printf(" Depth %lu best: command %zu (score %.2f) - type: %s\n",
currentDepth - 1,
previousBestCommand,
scoresByDepth[previousBestCommand][currentDepth - 1],
net::eagle0::shardok::common::CommandType_Name(
(*commands)[previousBestCommand]->GetCommandType())
.c_str());
printf(" Depth %lu best: command %zu (score %.2f) - type: %s\n",
currentDepth,
currentBestCommand,
currentBestScore,
net::eagle0::shardok::common::CommandType_Name(
(*commands)[currentBestCommand]->GetCommandType())
.c_str());
#endif
}
previousBestCommand = currentBestCommand;
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 07/04/25.
//
#ifndef EAGLE0_SHARDOK_AI_ITERATIVE_DEEPENING_AI_HPP
#define EAGLE0_SHARDOK_AI_ITERATIVE_DEEPENING_AI_HPP
#ifndef EAGLE0_ITERATIVEDEEPENINGAI_HPP
#define EAGLE0_ITERATIVEDEEPENINGAI_HPP
#include <chrono>
#include <future>
@@ -111,4 +111,4 @@ private:
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_ITERATIVE_DEEPENING_AI_HPP
#endif // EAGLE0_ITERATIVEDEEPENINGAI_HPP
@@ -8,6 +8,8 @@
#include "ShardokAIClient.hpp"
#define DEBUG_FLEE_DECISIONS
// Enable to dump game state and debug tree to /tmp for debugging
// #define ENABLE_MCTS_DEBUG_DUMP
@@ -41,7 +43,6 @@ using net::eagle0::shardok::api::ActionResultView;
using net::eagle0::shardok::api::GameStateView;
static constexpr bool kPerformanceLogging = true;
static constexpr bool kDebugFleeDecisions = true;
void ApplyUpdate(GameStateView & /*currentView*/, const ActionResultView & /*update*/) {}
@@ -467,7 +468,12 @@ auto ShardokAIClient::FinalRoundAttackerChooseCommandIndex(
maxRounds,
minimumFleeOddsThreshold,
desperateFleeThreshold,
kDebugFleeDecisions);
#ifdef DEBUG_FLEE_DECISIONS
true // Enable debug logging
#else
false
#endif
);
if (fleeDecision.shouldFlee) {
CommandChoiceResults results{};
@@ -6,8 +6,8 @@
// Copyright © 2017 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_AI_SHARDOK_AI_CLIENT_HPP
#define EAGLE0_SHARDOK_AI_SHARDOK_AI_CLIENT_HPP
#ifndef ShardokAIClient_hpp
#define ShardokAIClient_hpp
#include <vector>
@@ -95,4 +95,4 @@ public:
};
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_SHARDOK_AI_CLIENT_HPP
#endif /* ShardokAIClient_hpp */
@@ -2,8 +2,8 @@
// TranspositionTable.hpp - Cache for game state evaluations to avoid redundant calculations
//
#ifndef EAGLE0_SHARDOK_AI_TRANSPOSITION_TABLE_HPP
#define EAGLE0_SHARDOK_AI_TRANSPOSITION_TABLE_HPP
#ifndef EAGLE0_TRANSPOSITIONTABLE_HPP
#define EAGLE0_TRANSPOSITIONTABLE_HPP
#include <atomic>
#include <cstdint>
@@ -88,4 +88,4 @@ extern TranspositionTable g_transpositionTable;
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_TRANSPOSITION_TABLE_HPP
#endif // EAGLE0_TRANSPOSITIONTABLE_HPP
@@ -2,8 +2,8 @@
// Shardok-specific MCTS AI that wraps the abstract implementation
//
#ifndef EAGLE0_SHARDOK_AI_MCTS_SHARDOK_MCTSAI_HPP
#define EAGLE0_SHARDOK_AI_MCTS_SHARDOK_MCTSAI_HPP
#ifndef EAGLE0_SHARDOK_MCTSAI_HPP
#define EAGLE0_SHARDOK_MCTSAI_HPP
#include <memory>
#include <vector>
@@ -68,4 +68,4 @@ private:
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_MCTS_SHARDOK_MCTSAI_HPP
#endif // EAGLE0_SHARDOK_MCTSAI_HPP
@@ -2,8 +2,8 @@
// Shardok-specific action adapter for MCTS
//
#ifndef EAGLE0_SHARDOK_AI_MCTS_ADAPTERS_SHARDOK_ACTION_HPP
#define EAGLE0_SHARDOK_AI_MCTS_ADAPTERS_SHARDOK_ACTION_HPP
#ifndef EAGLE0_SHARDOK_ACTION_HPP
#define EAGLE0_SHARDOK_ACTION_HPP
#include <memory>
#include <string>
@@ -58,4 +58,4 @@ private:
} // namespace shardok::mcts
#endif // EAGLE0_SHARDOK_AI_MCTS_ADAPTERS_SHARDOK_ACTION_HPP
#endif // EAGLE0_SHARDOK_ACTION_HPP
@@ -2,8 +2,8 @@
// Shardok-specific game engine adapter for MCTS
//
#ifndef EAGLE0_SHARDOK_AI_MCTS_ADAPTERS_SHARDOK_GAME_ENGINE_HPP
#define EAGLE0_SHARDOK_AI_MCTS_ADAPTERS_SHARDOK_GAME_ENGINE_HPP
#ifndef EAGLE0_SHARDOK_GAME_ENGINE_HPP
#define EAGLE0_SHARDOK_GAME_ENGINE_HPP
#include <atomic>
#include <functional>
@@ -141,4 +141,4 @@ public:
} // namespace mcts
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_MCTS_ADAPTERS_SHARDOK_GAME_ENGINE_HPP
#endif // EAGLE0_SHARDOK_GAME_ENGINE_HPP
@@ -2,8 +2,8 @@
// Shardok-specific game state adapter for MCTS
//
#ifndef EAGLE0_SHARDOK_AI_MCTS_ADAPTERS_SHARDOK_GAME_STATE_HPP
#define EAGLE0_SHARDOK_AI_MCTS_ADAPTERS_SHARDOK_GAME_STATE_HPP
#ifndef EAGLE0_SHARDOK_GAME_STATE_HPP
#define EAGLE0_SHARDOK_GAME_STATE_HPP
#include <memory>
@@ -80,4 +80,4 @@ private:
} // namespace mcts
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_MCTS_ADAPTERS_SHARDOK_GAME_STATE_HPP
#endif // EAGLE0_SHARDOK_GAME_STATE_HPP
@@ -2,8 +2,8 @@
// Factory for creating Shardok-specific MCTS components
//
#ifndef EAGLE0_SHARDOK_AI_MCTS_ADAPTERS_SHARDOK_MCTS_FACTORY_HPP
#define EAGLE0_SHARDOK_AI_MCTS_ADAPTERS_SHARDOK_MCTS_FACTORY_HPP
#ifndef EAGLE0_SHARDOK_MCTS_FACTORY_HPP
#define EAGLE0_SHARDOK_MCTS_FACTORY_HPP
#include <functional>
#include <memory>
@@ -67,4 +67,4 @@ public:
} // namespace mcts
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_MCTS_ADAPTERS_SHARDOK_MCTS_FACTORY_HPP
#endif // EAGLE0_SHARDOK_MCTS_FACTORY_HPP
@@ -2,8 +2,8 @@
// Created by dancrosby on 3/4/20.
//
#ifndef EAGLE0_SHARDOK_AI_SCORE_AI_SCORE_CALCULATOR_HPP
#define EAGLE0_SHARDOK_AI_SCORE_AI_SCORE_CALCULATOR_HPP
#ifndef EAGLE0_AISCORECALCULATOR_HPP
#define EAGLE0_AISCORECALCULATOR_HPP
#include <future>
@@ -53,4 +53,4 @@ public:
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_SCORE_AI_SCORE_CALCULATOR_HPP
#endif // EAGLE0_AISCORECALCULATOR_HPP
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 4/11/21.
//
#ifndef EAGLE0_SHARDOK_AI_SCORE_AI_VICTORY_CONDITION_SCORE_CALCULATOR_HPP
#define EAGLE0_SHARDOK_AI_SCORE_AI_VICTORY_CONDITION_SCORE_CALCULATOR_HPP
#ifndef EAGLE0_AIVICTORYCONDITIONSCORECALCULATOR_HPP
#define EAGLE0_AIVICTORYCONDITIONSCORECALCULATOR_HPP
#include <vector>
@@ -48,4 +48,4 @@ auto LastPlayerStandingVictoryScore(
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_SCORE_AI_VICTORY_CONDITION_SCORE_CALCULATOR_HPP
#endif // EAGLE0_AIVICTORYCONDITIONSCORECALCULATOR_HPP
@@ -3,8 +3,8 @@
// Uses bounded linear scoring tuned for MCTS exploration/exploitation balance
//
#ifndef EAGLE0_SHARDOK_AI_SCORE_MCTS_OPTIMIZED_AI_SCORE_CALCULATOR_HPP
#define EAGLE0_SHARDOK_AI_SCORE_MCTS_OPTIMIZED_AI_SCORE_CALCULATOR_HPP
#ifndef EAGLE0_MCTSOPTIMIZEDAISCORECALCULATOR_HPP
#define EAGLE0_MCTSOPTIMIZEDAISCORECALCULATOR_HPP
#include <memory>
@@ -29,4 +29,4 @@ using ALCache = std::unique_ptr<AttackLocationsCache>;
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_SCORE_MCTS_OPTIMIZED_AI_SCORE_CALCULATOR_HPP
#endif // EAGLE0_MCTSOPTIMIZEDAISCORECALCULATOR_HPP
@@ -41,6 +41,9 @@ class StandardAIScoreCalculator;
// Anonymous namespace for helper functions that don't need access to scorer
namespace {
#define LOGGING_ 0
#define PERFORMANCE_LOGGING_ 0
// Performance logging for AttackerScoreForState
struct AttackerScorePerformanceLogger {
static constexpr int LOG_INTERVAL = 100000;
@@ -2,8 +2,8 @@
// Standard implementation of AIScoreCalculator
//
#ifndef EAGLE0_SHARDOK_AI_SCORE_STANDARD_AI_SCORE_CALCULATOR_HPP
#define EAGLE0_SHARDOK_AI_SCORE_STANDARD_AI_SCORE_CALCULATOR_HPP
#ifndef EAGLE0_STANDARDAISCORECALCULATOR_HPP
#define EAGLE0_STANDARDAISCORECALCULATOR_HPP
#include <memory>
@@ -34,4 +34,4 @@ using ALCache = std::unique_ptr<AttackLocationsCache>;
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_SCORE_STANDARD_AI_SCORE_CALCULATOR_HPP
#endif // EAGLE0_STANDARDAISCORECALCULATOR_HPP
@@ -3,8 +3,8 @@
// This file is private to the ai/score package
//
#ifndef EAGLE0_SHARDOK_AI_SCORE_PRIVATE_AI_SCORE_CALCULATOR_SHARED_UTILITIES_HPP
#define EAGLE0_SHARDOK_AI_SCORE_PRIVATE_AI_SCORE_CALCULATOR_SHARED_UTILITIES_HPP
#ifndef EAGLE0_AI_SCORE_CALCULATOR_SHARED_UTILITIES_HPP
#define EAGLE0_AI_SCORE_CALCULATOR_SHARED_UTILITIES_HPP
#include <vector>
@@ -92,4 +92,4 @@ auto AttackerMultiplierForTargetDistance(
} // namespace score_calculator_internal
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_SCORE_PRIVATE_AI_SCORE_CALCULATOR_SHARED_UTILITIES_HPP
#endif // EAGLE0_AI_SCORE_CALCULATOR_SHARED_UTILITIES_HPP
@@ -92,7 +92,6 @@ auto AbstractAIScoreCalculator::CalculateUnitsScoreComponents(
case net::eagle0::shardok::storage::fb::UnitStatus_NEVER_ENTERED_UNIT:
case net::eagle0::shardok::storage::fb::UnitStatus_OUTLAWED_UNIT:
case net::eagle0::shardok::storage::fb::UnitStatus_EVACUATED_UNIT:
case net::eagle0::shardok::storage::fb::UnitStatus_SECURED_UNIT:
case net::eagle0::shardok::storage::fb::UnitStatus_RESERVE_UNIT:
case net::eagle0::shardok::storage::fb::UnitStatus_RETREATED_UNIT:
case net::eagle0::shardok::storage::fb::UnitStatus_RESERVED_SLOT:
@@ -3,8 +3,8 @@
// This file is private to the ai/score package
//
#ifndef EAGLE0_SHARDOK_AI_SCORE_PRIVATE_ABSTRACT_AI_SCORE_CALCULATOR_HPP
#define EAGLE0_SHARDOK_AI_SCORE_PRIVATE_ABSTRACT_AI_SCORE_CALCULATOR_HPP
#ifndef EAGLE0_ABSTRACT_AI_SCORE_CALCULATOR_HPP
#define EAGLE0_ABSTRACT_AI_SCORE_CALCULATOR_HPP
#include <memory>
#include <unordered_map>
@@ -178,4 +178,4 @@ private:
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_SCORE_PRIVATE_ABSTRACT_AI_SCORE_CALCULATOR_HPP
#endif // EAGLE0_ABSTRACT_AI_SCORE_CALCULATOR_HPP
@@ -21,7 +21,7 @@ std::unique_ptr<BattleConfigProto> AiBattleConfigLoader::LoadFromJsonFile(
const std::string& filepath) {
std::ifstream file(filepath);
if (!file.is_open()) {
std::cerr << "Failed to open config file: " << filepath << '\n';
std::cerr << "Failed to open config file: " << filepath << std::endl;
return nullptr;
}
@@ -41,7 +41,7 @@ std::unique_ptr<BattleConfigProto> AiBattleConfigLoader::LoadFromJsonString(
google::protobuf::util::JsonStringToMessage(jsonString, config.get(), options);
if (!status.ok()) {
std::cerr << "Failed to parse JSON config: " << status.message() << '\n';
std::cerr << "Failed to parse JSON config: " << status.message() << std::endl;
return nullptr;
}
@@ -103,7 +103,7 @@ std::string AiBattleConfigLoader::ToJsonString(const BattleConfigProto& config)
const auto status = google::protobuf::util::MessageToJsonString(config, &jsonString, options);
if (!status.ok()) {
std::cerr << "Failed to convert config to JSON: " << status.message() << '\n';
std::cerr << "Failed to convert config to JSON: " << status.message() << std::endl;
return "";
}
@@ -2,8 +2,8 @@
// AI Battle Simulator Configuration Loader
//
#ifndef EAGLE0_SHARDOK_AI_BATTLE_SIMULATOR_AI_BATTLE_CONFIG_HPP
#define EAGLE0_SHARDOK_AI_BATTLE_SIMULATOR_AI_BATTLE_CONFIG_HPP
#ifndef EAGLE0_AI_BATTLE_CONFIG_HPP
#define EAGLE0_AI_BATTLE_CONFIG_HPP
#include <memory>
#include <string>
@@ -44,4 +44,4 @@ public:
} // namespace ai_battle_simulator
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_BATTLE_SIMULATOR_AI_BATTLE_CONFIG_HPP
#endif // EAGLE0_AI_BATTLE_CONFIG_HPP
@@ -744,8 +744,7 @@ BattleResult AiBattleSimulator::RunBattlePhase(
auto availableCommands = engine.GetAvailableCommandProtos(currentPlayer, false);
if (availableCommands.empty()) {
std::cout << "No commands available for player " << static_cast<int>(currentPlayer)
<< "\n";
std::cout << "No commands available for player " << (int)currentPlayer << "\n";
break;
}
@@ -2,8 +2,8 @@
// AI Battle Simulator - Runs AI vs AI battles to completion
//
#ifndef EAGLE0_SHARDOK_AI_BATTLE_SIMULATOR_AI_BATTLE_SIMULATOR_HPP
#define EAGLE0_SHARDOK_AI_BATTLE_SIMULATOR_AI_BATTLE_SIMULATOR_HPP
#ifndef EAGLE0_AI_BATTLE_SIMULATOR_HPP
#define EAGLE0_AI_BATTLE_SIMULATOR_HPP
#include <memory>
#include <optional>
@@ -149,4 +149,4 @@ private:
} // namespace ai_battle_simulator
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_BATTLE_SIMULATOR_AI_BATTLE_SIMULATOR_HPP
#endif // EAGLE0_AI_BATTLE_SIMULATOR_HPP
@@ -78,7 +78,7 @@ auto ParseCommandLineArgs(int argc, char* argv[]) -> PerformanceTestConfig {
} // namespace
int main(int argc, char* argv[]) {
std::cout << "Starting AI Performance Runner..." << '\n';
std::cout << "Starting AI Performance Runner..." << std::endl;
// Set exec path so FilesystemUtils can find resource files
FilesystemUtils::SetExecPath(argv[0]);
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 2025-01-15.
//
#ifndef EAGLE0_SHARDOK_AI_PERFORMANCE_RUNNER_AI_PERFORMANCE_RUNNER_HPP
#define EAGLE0_SHARDOK_AI_PERFORMANCE_RUNNER_AI_PERFORMANCE_RUNNER_HPP
#ifndef EAGLE0_AIPERFORMANCERUNNER_HPP
#define EAGLE0_AIPERFORMANCERUNNER_HPP
#include <chrono>
#include <map>
@@ -52,4 +52,4 @@ struct PerformanceTestConfig {
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_PERFORMANCE_RUNNER_AI_PERFORMANCE_RUNNER_HPP
#endif // EAGLE0_AIPERFORMANCERUNNER_HPP
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 2025-01-15.
//
#ifndef EAGLE0_SHARDOK_AI_PERFORMANCE_RUNNER_PERFORMANCE_TEST_GAME_STATE_BUILDER_HPP
#define EAGLE0_SHARDOK_AI_PERFORMANCE_RUNNER_PERFORMANCE_TEST_GAME_STATE_BUILDER_HPP
#ifndef EAGLE0_PERFORMANCETESTGAMESTATEBUILDER_HPP
#define EAGLE0_PERFORMANCETESTGAMESTATEBUILDER_HPP
#include <flatbuffers/flatbuffers.h>
@@ -85,4 +85,4 @@ private:
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_PERFORMANCE_RUNNER_PERFORMANCE_TEST_GAME_STATE_BUILDER_HPP
#endif // EAGLE0_PERFORMANCETESTGAMESTATEBUILDER_HPP
@@ -3,8 +3,8 @@
// Used by both AI Performance Runner and AI Battle Simulator
//
#ifndef EAGLE0_SHARDOK_AI_TESTING_COMMON_AI_CLIENT_FACTORY_HPP
#define EAGLE0_SHARDOK_AI_TESTING_COMMON_AI_CLIENT_FACTORY_HPP
#ifndef EAGLE0_AI_CLIENT_FACTORY_HPP
#define EAGLE0_AI_CLIENT_FACTORY_HPP
#include <memory>
@@ -68,4 +68,4 @@ public:
} // namespace ai_testing_common
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_TESTING_COMMON_AI_CLIENT_FACTORY_HPP
#endif // EAGLE0_AI_CLIENT_FACTORY_HPP
@@ -3,8 +3,8 @@
// Used by both AI Performance Runner and AI Battle Simulator
//
#ifndef EAGLE0_SHARDOK_AI_TESTING_COMMON_GAME_PHASE_RUNNER_HPP
#define EAGLE0_SHARDOK_AI_TESTING_COMMON_GAME_PHASE_RUNNER_HPP
#ifndef EAGLE0_GAME_PHASE_RUNNER_HPP
#define EAGLE0_GAME_PHASE_RUNNER_HPP
#include <functional>
@@ -61,4 +61,4 @@ public:
} // namespace ai_testing_common
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_TESTING_COMMON_GAME_PHASE_RUNNER_HPP
#endif // EAGLE0_GAME_PHASE_RUNNER_HPP
@@ -3,8 +3,8 @@
// Used by both AI Performance Runner and AI Battle Simulator
//
#ifndef EAGLE0_SHARDOK_AI_TESTING_COMMON_GAME_SETTINGS_FACTORY_HPP
#define EAGLE0_SHARDOK_AI_TESTING_COMMON_GAME_SETTINGS_FACTORY_HPP
#ifndef EAGLE0_GAME_SETTINGS_FACTORY_HPP
#define EAGLE0_GAME_SETTINGS_FACTORY_HPP
#include <memory>
@@ -36,4 +36,4 @@ public:
} // namespace ai_testing_common
} // namespace shardok
#endif // EAGLE0_SHARDOK_AI_TESTING_COMMON_GAME_SETTINGS_FACTORY_HPP
#endif // EAGLE0_GAME_SETTINGS_FACTORY_HPP
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 4/6/21.
//
#ifndef EAGLE0_SHARDOK_CONTROLLER_GAME_UPDATE_RECEIVER_HPP
#define EAGLE0_SHARDOK_CONTROLLER_GAME_UPDATE_RECEIVER_HPP
#ifndef EAGLE0_GAMEUPDATERECEIVER_HPP
#define EAGLE0_GAMEUPDATERECEIVER_HPP
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-redundant-constexpr-static-def"
@@ -31,4 +31,4 @@ public:
};
} // namespace shardok
#endif // EAGLE0_SHARDOK_CONTROLLER_GAME_UPDATE_RECEIVER_HPP
#endif // EAGLE0_GAMEUPDATERECEIVER_HPP
@@ -11,7 +11,6 @@
#include <execinfo.h>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <ranges>
#include <string>
@@ -116,8 +115,8 @@ auto ShardokGameController::LockedAIClientForPid(PlayerId pid) const
}
void ShardokGameController::DoAIThread() {
std::cout << "Entering AI thread." << '\n';
if (aiClients.empty()) { std::cout << "No AI players, exiting AI thread." << '\n'; }
printf("Entering AI thread.\n");
if (aiClients.empty()) { printf("No AI players, exiting AI thread.\n"); }
while (aiThreadKeepGoing) {
// Phase 1: Gather data for AI decision (brief lock)
@@ -155,7 +154,7 @@ void ShardokGameController::DoAIThread() {
// Lock released - polls can now get through
if (availableCommands->empty()) {
std::cout << "no commands for player " << playerId << '\n';
printf("no commands for player %d\n", playerId);
continue;
}
@@ -178,7 +177,7 @@ void ShardokGameController::DoAIThread() {
// Verify state hasn't changed while we were thinking
if (engine->GetUnfilteredHistoryCount() != expectedHistoryCount) {
// State changed (e.g., human posted command) - re-evaluate
std::cout << "AI: State changed while thinking, re-evaluating" << '\n';
printf("AI: State changed while thinking, re-evaluating\n");
continue;
}
@@ -209,8 +208,12 @@ void ShardokGameController::DoAIThread() {
aiThreadKeepGoing = !engine->GameIsOver();
}
} catch (const std::exception &e) {
std::cerr << "AI thread exception in game " << cachedGameId << ", player " << playerId
<< ", round " << gsv.current_round() << ": " << e.what() << '\n';
fprintf(stderr,
"AI thread exception in game %s, player %d, round %d: %s\n",
cachedGameId.c_str(),
playerId,
gsv.current_round(),
e.what());
void *backtraceArray[20];
const int backtraceSize = backtrace(backtraceArray, 20);
@@ -224,7 +227,7 @@ void ShardokGameController::DoAIThread() {
break;
}
}
std::cout << "Exiting AI thread." << '\n';
printf("Exiting AI thread.\n");
}
ShardokGameController::~ShardokGameController() {
@@ -271,7 +274,7 @@ void ShardokGameController::PostCommand(
const auto expectedToken = static_cast<int64_t>(engine->GetUnfilteredHistoryCount());
if (token < expectedToken) {
std::cout << "Double token in postCommand" << '\n';
printf("Double token in postCommand\n");
// The client is missing some updates; probably it's a double-submit
// Let's just ignore and see how it goes
} else if (token > expectedToken) {
@@ -319,7 +322,7 @@ void ShardokGameController::PostPlacementCommands(
const auto expectedToken = static_cast<int64_t>(engine->GetUnfilteredHistoryCount());
if (token < expectedToken) {
std::cout << "Double token in postPlacementCommands" << '\n';
printf("Double token in postPlacementCommands\n");
// The client is missing some updates; probably it's a double-submit
// Let's just ignore and see how it goes
} else if (token > expectedToken) {
@@ -6,8 +6,8 @@
// Copyright © 2017 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_CONTROLLER_SHARDOK_GAME_CONTROLLER_HPP
#define EAGLE0_SHARDOK_CONTROLLER_SHARDOK_GAME_CONTROLLER_HPP
#ifndef ShardokGameController_hpp
#define ShardokGameController_hpp
#include <atomic>
#include <functional>
@@ -213,4 +213,4 @@ public:
};
} // namespace shardok
#endif // EAGLE0_SHARDOK_CONTROLLER_SHARDOK_GAME_CONTROLLER_HPP
#endif /* ShardokGameController_hpp */
@@ -2,8 +2,8 @@
// Created by dancrosby on 3/22/20.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_ACTION_COST_HPP
#define EAGLE0_SHARDOK_LIBRARY_ACTION_COST_HPP
#ifndef EAGLE0_ACTIONCOST_HPP
#define EAGLE0_ACTIONCOST_HPP
#include <cstdint>
@@ -11,45 +11,37 @@
namespace shardok {
struct ActionCost {
enum class ActionCostType : uint8_t {
enum ActionCostType : uint8_t {
impossible, // This action cannot be performed at any price.
standard, // This is a normal action, that requires and consumes the specified number of
// points.
usesAll // This action requires the minimum points, but consumes anything that is left.
};
static constexpr ActionCostType impossible = ActionCostType::impossible;
static constexpr ActionCostType standard = ActionCostType::standard;
static constexpr ActionCostType usesAll = ActionCostType::usesAll;
ActionCostType type;
ActionPoints points;
constexpr ActionCost(const ActionCostType type, const ActionPoints points) noexcept
: type(type),
points(points) {}
ActionCost(const ActionCostType type, const ActionPoints points) : type(type), points(points) {}
[[nodiscard]] constexpr auto IsPossible(const ActionPoints cmpPoints) const noexcept -> bool {
[[nodiscard]] bool IsPossible(const ActionPoints cmpPoints) const {
return type != impossible && cmpPoints >= points;
}
[[nodiscard]] constexpr auto operator==(const ActionCost &rhs) const noexcept -> bool {
bool operator==(const ActionCost &rhs) const {
return type == rhs.type && points == rhs.points;
}
[[nodiscard]] static constexpr auto StandardActionCost(const ActionPoints points) noexcept
-> ActionCost {
static inline auto StandardActionCost(const ActionPoints points) -> ActionCost {
return ActionCost{ActionCost::standard, points};
}
[[nodiscard]] static constexpr auto UsesAllActionCost(const ActionPoints points) noexcept
-> ActionCost {
return {ActionCost::usesAll, points};
static inline auto UsesAllActionCost(const ActionPoints points) -> ActionCost {
return ActionCost(ActionCost::usesAll, points);
}
};
inline constexpr ActionCost IMPOSSIBLE_ACTION_COST{ActionCost::impossible, 0};
const ActionCost IMPOSSIBLE_ACTION_COST{ActionCost::impossible, 0};
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_ACTION_COST_HPP
#endif // EAGLE0_ACTIONCOST_HPP
@@ -6,8 +6,8 @@
// Copyright © 2018 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_AVAILABLE_COMMANDS_FACTORY_HPP
#define EAGLE0_SHARDOK_LIBRARY_AVAILABLE_COMMANDS_FACTORY_HPP
#ifndef AvailableCommandsFactory_hpp
#define AvailableCommandsFactory_hpp
#include <optional>
#include <vector>
@@ -46,4 +46,4 @@ public:
};
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_AVAILABLE_COMMANDS_FACTORY_HPP
#endif /* AvailableCommandsFactory_hpp */
@@ -6,8 +6,8 @@
// Copyright (c) 2014 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_BATTALION_TYPE_HPP
#define EAGLE0_SHARDOK_LIBRARY_BATTALION_TYPE_HPP
#ifndef __eagle0__BattalionType__
#define __eagle0__BattalionType__
#include <array>
#include <cstdint>
@@ -111,8 +111,8 @@ struct BattalionType {
if (HasCastle(terrain.modifier())) {
const double castleIntegrity = terrain.modifier().castle().integrity().value();
return ((castleIntegrity * damageTakenMultiplierForCastle) +
((100.0 - castleIntegrity) * terrainTypeMultiplier)) /
return (castleIntegrity * damageTakenMultiplierForCastle +
(100.0 - castleIntegrity) * terrainTypeMultiplier) /
100.0;
}
return terrainTypeMultiplier;
@@ -125,8 +125,8 @@ struct BattalionType {
if (terrain->modifier().castle().present()) {
const double castleIntegrity = terrain->modifier().castle().integrity();
return ((castleIntegrity * damageTakenMultiplierForCastle) +
((100.0 - castleIntegrity) * terrainTypeMultiplier)) /
return (castleIntegrity * damageTakenMultiplierForCastle +
(100.0 - castleIntegrity) * terrainTypeMultiplier) /
100.0;
}
return terrainTypeMultiplier;
@@ -199,8 +199,7 @@ struct BattalionType {
auto terrainCost = GetCostToEnterTerrainType(terrain.type());
if (HasSnow(terrain.modifier())) {
terrainCost.points +=
static_cast<int>(snowPenalty * terrain.modifier().snow().integrity().value());
terrainCost.points += int(snowPenalty * terrain.modifier().snow().integrity().value());
}
return terrainCost;
}
@@ -216,9 +215,7 @@ struct BattalionType {
if (tm.ice().present()) return costToEnterIce;
auto terrainCost = GetCostToEnterTerrainType(terrainType);
if (tm.snow().present()) {
terrainCost.points += static_cast<int>(snowPenalty * tm.snow().integrity());
}
if (tm.snow().present()) { terrainCost.points += int(snowPenalty * tm.snow().integrity()); }
return terrainCost;
}
@@ -259,15 +256,8 @@ struct BattalionType {
const double trainingDifference = chargerTraining - defenderTraining;
const double trainingValue =
trainingDifferenceMultiplierForStunChanceOnCharge * trainingDifference;
OtherFactor trainingFactor =
MakeOtherFactor(static_cast<int16_t>(trainingValue), "training difference");
return MakeOdds(
static_cast<int16_t>(baseStunChanceOnCharge),
0,
0,
0,
{},
{trainingFactor});
OtherFactor trainingFactor = MakeOtherFactor((int16_t)trainingValue, "training difference");
return MakeOdds((int16_t)baseStunChanceOnCharge, 0, 0, 0, {}, {trainingFactor});
}
[[nodiscard]] auto GetDailyFoodCostPerTroop() const -> double {
@@ -278,7 +268,7 @@ struct BattalionType {
-> std::shared_ptr<const BattalionType>;
};
using BattalionTypeSPtr = std::shared_ptr<const BattalionType>;
typedef std::shared_ptr<const BattalionType> BattalionTypeSPtr;
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_BATTALION_TYPE_HPP
#endif /* defined(__eagle0__BattalionType__) */
@@ -6,20 +6,15 @@
// Copyright (c) 2014 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_COMBAT_DAMAGE_HPP
#define EAGLE0_SHARDOK_LIBRARY_COMBAT_DAMAGE_HPP
#ifndef __eagle0__CombatDamage__
#define __eagle0__CombatDamage__
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <string>
#include <vector>
namespace shardok {
// Normal and penetrating damage for each kind
enum class DamageType : std::uint8_t {
enum DamageType {
DamageType_slashing = 0,
DamageType_puncturing,
DamageType_stabbing,
@@ -32,17 +27,6 @@ enum class DamageType : std::uint8_t {
NUM_DAMAGE_TYPES
};
inline constexpr DamageType DamageType_slashing = DamageType::DamageType_slashing;
inline constexpr DamageType DamageType_puncturing = DamageType::DamageType_puncturing;
inline constexpr DamageType DamageType_stabbing = DamageType::DamageType_stabbing;
inline constexpr DamageType DamageType_crushing = DamageType::DamageType_crushing;
inline constexpr DamageType DamageType_fire = DamageType::DamageType_fire;
inline constexpr DamageType DamageType_cold = DamageType::DamageType_cold;
inline constexpr DamageType DamageType_lightning = DamageType::DamageType_lightning;
inline constexpr DamageType DamageType_aessence = DamageType::DamageType_aessence;
inline constexpr DamageType DamageType_impact = DamageType::DamageType_impact;
inline constexpr int NUM_DAMAGE_TYPES = static_cast<int>(DamageType::NUM_DAMAGE_TYPES);
static inline bool DamageTypeGetsTerrainDefense(const DamageType type) {
switch (type) {
case DamageType_slashing:
@@ -63,21 +47,9 @@ static inline bool DamageTypeGetsTerrainDefense(const DamageType type) {
}
struct CombatDamage {
private:
static constexpr size_t kDamageValueCount = 2 * static_cast<size_t>(NUM_DAMAGE_TYPES);
const std::vector<double> damageByType;
std::array<double, kDamageValueCount> damageByType{};
[[nodiscard]] static constexpr auto NormalIndex(const DamageType type) -> size_t {
return 2 * static_cast<size_t>(type);
}
[[nodiscard]] static constexpr auto PenetratingIndex(const DamageType type) -> size_t {
return NormalIndex(type) + 1;
}
public:
CombatDamage() = default;
CombatDamage() : damageByType{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} {};
CombatDamage(
const double sl,
const double pu,
@@ -117,40 +89,37 @@ public:
im,
pim} {}
explicit CombatDamage(const std::vector<double>& byType) {
std::copy_n(
byType.begin(),
std::min(byType.size(), damageByType.size()),
damageByType.begin());
}
CombatDamage(const std::vector<double> byType) : damageByType(byType) {}
[[nodiscard]] auto GetNormalDamageOfType(const DamageType type) const -> double {
return damageByType.at(NormalIndex(type));
}
[[nodiscard]] auto GetPenetratingDamageOfType(const DamageType type) const -> double {
return damageByType.at(PenetratingIndex(type));
CombatDamage(const CombatDamage& toCopy) : damageByType(toCopy.damageByType) {}
public:
double GetNormalDamageOfType(const DamageType type) const { return damageByType[2 * type]; }
double GetPenetratingDamageOfType(const DamageType type) const {
return damageByType[2 * type + 1];
};
bool operator==(const CombatDamage& cmpr) const { return damageByType == cmpr.damageByType; }
bool operator==(const CombatDamage& cmpr) const {
for (size_t type = 0; type < 2 * NUM_DAMAGE_TYPES; type++) {
if (damageByType[type] != cmpr.damageByType[type]) return false;
}
return true;
}
bool operator!=(const CombatDamage& cmpr) const { return !(*this == cmpr); }
bool operator<=(const CombatDamage& cmpr) const {
return std::ranges::equal(
damageByType,
cmpr.damageByType,
[](const double damage, const double comparedDamage) {
return damage <= comparedDamage;
});
for (size_t type = 0; type < 2 * NUM_DAMAGE_TYPES; type++) {
if (damageByType[type] > cmpr.damageByType[type]) return false;
}
return true;
}
bool operator>=(const CombatDamage& cmpr) const {
return std::ranges::equal(
damageByType,
cmpr.damageByType,
[](const double damage, const double comparedDamage) {
return damage >= comparedDamage;
});
for (size_t type = 0; type < 2 * NUM_DAMAGE_TYPES; type++) {
if (damageByType[type] < cmpr.damageByType[type]) return false;
}
return true;
}
bool operator>(const CombatDamage& cmpr) const { return ((*this >= cmpr) && !(*this == cmpr)); }
@@ -243,11 +212,11 @@ public:
.Build();
}
[[nodiscard]] auto ToString() const -> std::string {
std::array<char, 1024> buffer{};
std::string ToString() const {
char buffer[1024];
snprintf(
buffer.data(),
buffer.size(),
buffer,
1024,
"slashing=%f / %f, puncturing=%f / %f, stabbing=%f / %f, crushing=%f / %f, "
"fire=%f / "
"%f, cold=%f / %f, lightning=%f / %f, aessence=%f / %f, impact=%f / %f",
@@ -270,7 +239,7 @@ public:
GetNormalDamageOfType(DamageType_impact),
GetPenetratingDamageOfType(DamageType_impact));
return {buffer.data()};
return std::string(buffer);
}
class Builder {
@@ -296,7 +265,7 @@ public:
double penetrating_impact = 0.0;
public:
Builder() = default;
Builder() {}
Builder& SetSlashing(const double sl) {
slashing = sl;
return *this;
@@ -423,8 +392,9 @@ public:
return *this;
}
[[nodiscard]] auto Build() const -> CombatDamage {
return {slashing,
CombatDamage Build() {
return CombatDamage(
slashing,
puncturing,
stabbing,
crushing,
@@ -441,16 +411,21 @@ public:
penetrating_cold,
penetrating_lightning,
penetrating_aessence,
penetrating_impact};
penetrating_impact);
}
};
[[nodiscard]] auto ToBuilder() const -> Builder {
Builder ToBuilder() {
Builder builder = Builder();
for (int i = 0; i < static_cast<int>(NUM_DAMAGE_TYPES); i++) {
const auto type = static_cast<DamageType>(i);
builder.SetDamageByType(type, false, this->GetNormalDamageOfType(type));
builder.SetDamageByType(type, true, this->GetPenetratingDamageOfType(type));
for (int i = 0; i < (int)NUM_DAMAGE_TYPES; i++) {
builder.SetDamageByType(
(DamageType)i,
false,
this->GetNormalDamageOfType((DamageType)i));
builder.SetDamageByType(
(DamageType)i,
true,
this->GetPenetratingDamageOfType((DamageType)i));
}
return builder;
}
@@ -459,4 +434,4 @@ public:
inline CombatDamage operator*(const double factor, const CombatDamage& dmg) { return dmg * factor; }
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_COMBAT_DAMAGE_HPP
#endif /* defined(__eagle0__CombatDamage__) */
@@ -6,8 +6,8 @@
// Copyright © 2018 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_FIRE_UTILS_HPP
#define EAGLE0_SHARDOK_LIBRARY_FIRE_UTILS_HPP
#ifndef FireManager_hpp
#define FireManager_hpp
#include "CombatDamage.hpp"
#include "PercentileRollOdds.hpp"
@@ -51,4 +51,4 @@ auto GetStartFireOdds(
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_FIRE_UTILS_HPP
#endif /* FireManager_hpp */
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 2025-01-15.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_GAME_STATE_W_HPP
#define EAGLE0_SHARDOK_LIBRARY_GAME_STATE_W_HPP
#ifndef EAGLE0_GAMESTATEW_HPP
#define EAGLE0_GAMESTATEW_HPP
#include <cstdint>
@@ -108,4 +108,4 @@ public:
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_GAME_STATE_W_HPP
#endif // EAGLE0_GAMESTATEW_HPP
@@ -6,8 +6,8 @@
// Copyright © 2018 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_PERCENTILE_ROLL_ODDS_HPP
#define EAGLE0_SHARDOK_LIBRARY_PERCENTILE_ROLL_ODDS_HPP
#ifndef PercentileRollOdds_hpp
#define PercentileRollOdds_hpp
#include <string>
#include <vector>
@@ -18,8 +18,8 @@
#pragma GCC diagnostic pop
namespace shardok {
using PercentileRollOdds = net::eagle0::shardok::storage::Odds;
using OtherFactor = net::eagle0::shardok::storage::Odds_OtherFactor;
typedef net::eagle0::shardok::storage::Odds PercentileRollOdds;
typedef net::eagle0::shardok::storage::Odds_OtherFactor OtherFactor;
double BonusFromStat(double stat);
@@ -50,4 +50,4 @@ bool PercentileRollSucceeds(const PercentileRollOdds &odds, double roll);
int16_t GetSuccessChance(const PercentileRollOdds &odds);
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_PERCENTILE_ROLL_ODDS_HPP
#endif /* PercentileRollOdds_hpp */
@@ -6,8 +6,8 @@
// Copyright (c) 2014 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_SHARDOK_ACTION_HPP
#define EAGLE0_SHARDOK_LIBRARY_SHARDOK_ACTION_HPP
#ifndef __eagle0__ShardokAction__
#define __eagle0__ShardokAction__
#include <vector>
@@ -30,7 +30,7 @@ class IllegalActionException : public ShardokException {
std::string description;
public:
explicit IllegalActionException(const std::string& d) : ShardokException(d) {}
explicit IllegalActionException(const std::string& d) : ShardokException(d){};
};
// Encapsulates any action that changes game state
@@ -69,8 +69,8 @@ public:
class ShardokAction;
using ActionSPtr = std::shared_ptr<ShardokAction>;
using ActionList = std::vector<ActionSPtr>;
typedef std::shared_ptr<ShardokAction> ActionSPtr;
typedef std::vector<ActionSPtr> ActionList;
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_SHARDOK_ACTION_HPP
#endif /* defined(__eagle0__ShardokAction__) */
@@ -6,8 +6,8 @@
// Copyright © 2017 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_SHARDOK_CTYPES_H
#define EAGLE0_SHARDOK_LIBRARY_SHARDOK_CTYPES_H
#ifndef ShardokCTypes_h
#define ShardokCTypes_h
#include <cstdint>
#include <string>
@@ -23,13 +23,9 @@ using RoundId = int32_t;
using MapIndex = int8_t;
using ActionPoints = uint8_t;
enum class AttackOrientation : std::uint8_t { front, flank, rear };
inline constexpr AttackOrientation front = AttackOrientation::front;
inline constexpr AttackOrientation flank = AttackOrientation::flank;
inline constexpr AttackOrientation rear = AttackOrientation::rear;
enum AttackOrientation { front, flank, rear };
constexpr PlayerId UNCONTROLLED_PLAYER_ID = 99;
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_SHARDOK_CTYPES_H
#endif /* ShardokCTypes_h */
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 4/4/20.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_SHARDOK_COMMAND_HPP
#define EAGLE0_SHARDOK_LIBRARY_SHARDOK_COMMAND_HPP
#ifndef EAGLE0_SHARDOKCOMMAND_HPP
#define EAGLE0_SHARDOKCOMMAND_HPP
#include <memory>
#include <vector>
@@ -26,7 +26,7 @@ private:
const PlayerId playerId;
protected:
explicit ShardokCommand(const PlayerId pid) : playerId(pid) {}
explicit ShardokCommand(const PlayerId pid) : playerId(pid){};
public:
[[nodiscard]] virtual auto GetCommandType() const -> CommandType = 0;
@@ -63,4 +63,4 @@ using CommandListSPtr = shared_ptr<const CommandList>;
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_SHARDOK_COMMAND_HPP
#endif // EAGLE0_SHARDOKCOMMAND_HPP
@@ -11,7 +11,6 @@
#include <algorithm>
#include <optional>
#include <ranges>
#include <unordered_map>
#include <utility>
#include <vector>
@@ -700,29 +699,7 @@ auto ShardokEngine::UncachedGetAvailableCommands(
reinforcementPositions);
}
using SecuredByPlayerByUnitId = std::unordered_map<UnitId, PlayerId>;
auto SecuredByPlayerByUnitIdFromHistory(
const vector<ShardokActionWithResultingState> &actionHistory) -> SecuredByPlayerByUnitId {
SecuredByPlayerByUnitId securedByPlayerByUnitId;
for (const auto &actionWithResultingState : actionHistory) {
for (const auto &resolvedUnit : actionWithResultingState.action_result().resolved_units()) {
if (resolvedUnit.status() !=
net::eagle0::shardok::storage::ResolvedUnit_UnitStatus_SECURED_UNIT) {
continue;
}
if (!resolvedUnit.has_secured_by_player()) { continue; }
const auto *unit = reinterpret_cast<const Unit *>(resolvedUnit.unit_bytes().data());
securedByPlayerByUnitId[unit->unit_id()] = resolvedUnit.secured_by_player().value();
}
}
return securedByPlayerByUnitId;
}
void AddUnits(
vector<net::eagle0::shardok::storage::ResolvedUnit> &to,
const Units &from,
const SecuredByPlayerByUnitId &securedByPlayerByUnitId) {
void AddUnits(vector<net::eagle0::shardok::storage::ResolvedUnit> &to, const Units &from) {
for (const auto &unit : from) {
net::eagle0::shardok::storage::ResolvedUnit ru{};
@@ -752,13 +729,6 @@ void AddUnits(
ru.set_status(
net::eagle0::shardok::storage::ResolvedUnit_UnitStatus_EVACUATED_UNIT);
break;
case net::eagle0::shardok::storage::fb::UnitStatus_SECURED_UNIT:
ru.set_status(net::eagle0::shardok::storage::ResolvedUnit_UnitStatus_SECURED_UNIT);
if (const auto it = securedByPlayerByUnitId.find(unit->unit_id());
it != securedByPlayerByUnitId.end()) {
ru.mutable_secured_by_player()->set_value(it->second);
}
break;
case net::eagle0::shardok::storage::fb::UnitStatus_RESERVE_UNIT:
case net::eagle0::shardok::storage::fb::UnitStatus_NEVER_ENTERED_UNIT:
case net::eagle0::shardok::storage::fb::UnitStatus_RESERVED_SLOT:
@@ -783,7 +753,7 @@ auto ShardokEngine::EndGameUnits() const -> vector<net::eagle0::shardok::storage
const auto &gs = GetCurrentGameState();
vector<net::eagle0::shardok::storage::ResolvedUnit> endgameUnits;
AddUnits(endgameUnits, *gs->units(), SecuredByPlayerByUnitIdFromHistory(actionHistory));
AddUnits(endgameUnits, *gs->units());
return endgameUnits;
}
@@ -6,8 +6,8 @@
// Copyright (c) 2015 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_SHARDOK_ENGINE_HPP
#define EAGLE0_SHARDOK_LIBRARY_SHARDOK_ENGINE_HPP
#ifndef __eagle0__ShardokEngine__
#define __eagle0__ShardokEngine__
#include <flatbuffers/flatbuffers.h>
@@ -254,4 +254,4 @@ public:
};
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_SHARDOK_ENGINE_HPP
#endif /* defined(__eagle0__ShardokEngine__) */
@@ -6,8 +6,8 @@
// Copyright © 2017 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_SHARDOK_EXCEPTION_HPP
#define EAGLE0_SHARDOK_LIBRARY_SHARDOK_EXCEPTION_HPP
#ifndef ShardokException_h
#define ShardokException_h
#include <exception>
#include <string>
@@ -19,7 +19,7 @@ using std::string;
class ShardokException : public std::exception {
protected:
string description;
explicit ShardokException(string desc) : description(std::move(desc)) {}
explicit ShardokException(string desc) : description(std::move(desc)){};
public:
[[nodiscard]] auto what() const noexcept -> const char* override {
@@ -59,4 +59,4 @@ public:
};
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_SHARDOK_EXCEPTION_HPP
#endif /* ShardokException_h */
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 1/11/21.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_UNIT_PLACEMENT_INFO_HPP
#define EAGLE0_SHARDOK_LIBRARY_UNIT_PLACEMENT_INFO_HPP
#ifndef EAGLE0_UNITPLACEMENTINFO_HPP
#define EAGLE0_UNITPLACEMENTINFO_HPP
#include "src/main/cpp/net/eagle0/shardok/library/ShardokCTypes.h"
@@ -20,4 +20,4 @@ struct UnitPlacementInfo {
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_UNIT_PLACEMENT_INFO_HPP
#endif // EAGLE0_UNITPLACEMENTINFO_HPP
@@ -6,8 +6,8 @@
// Copyright © 2019 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_FIRE_OUT_ACTION_FACTORY_HPP
#define EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_FIRE_OUT_ACTION_FACTORY_HPP
#ifndef FireOutActionFactory_hpp
#define FireOutActionFactory_hpp
#include "src/main/cpp/net/eagle0/shardok/library/ShardokAction.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/settings/GameSettings.hpp"
@@ -38,4 +38,4 @@ public:
};
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_FIRE_OUT_ACTION_FACTORY_HPP
#endif /* FireOutActionFactory_hpp */
@@ -27,12 +27,11 @@ auto FireSpreadActionFactory::MakeFireSpreadAction(
const int16_t weatherFactor =
settings.GetFirePropensityByWeatherConditions(weather->conditions());
int relativeWindDirection =
static_cast<int>(weather->wind().direction()) - static_cast<int>(direction);
int relativeWindDirection = (int)weather->wind().direction() - (int)direction;
if (relativeWindDirection < 0) relativeWindDirection += 6;
const int windIntensity = static_cast<int>(
weather->wind().speed_in_mph() *
settings.Backing().fire_propensity_wind_speed_multiplier());
const int windIntensity =
(int)(weather->wind().speed_in_mph() *
settings.Backing().fire_propensity_wind_speed_multiplier());
int16_t windFactor;
switch (relativeWindDirection) {
@@ -6,8 +6,8 @@
// Copyright © 2019 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_FIRE_SPREAD_ACTION_FACTORY_HPP
#define EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_FIRE_SPREAD_ACTION_FACTORY_HPP
#ifndef FireSpreadActionFactory_hpp
#define FireSpreadActionFactory_hpp
#include "src/main/cpp/net/eagle0/shardok/library/ShardokAction.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/map/Coordinates.hpp"
@@ -41,4 +41,4 @@ public:
};
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_FIRE_SPREAD_ACTION_FACTORY_HPP
#endif /* FireSpreadActionFactory_hpp */
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 2/16/21.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_ICE_AND_SNOW_ADJUSTMENT_ACTION_FACTORY_HPP
#define EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_ICE_AND_SNOW_ADJUSTMENT_ACTION_FACTORY_HPP
#ifndef EAGLE0_ICEANDSNOWADJUSTMENTACTIONFACTORY_HPP
#define EAGLE0_ICEANDSNOWADJUSTMENTACTIONFACTORY_HPP
#include "src/main/cpp/net/eagle0/shardok/library/ShardokAction.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/map/Coordinates.hpp"
@@ -49,4 +49,4 @@ public:
};
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_ICE_AND_SNOW_ADJUSTMENT_ACTION_FACTORY_HPP
#endif // EAGLE0_ICEANDSNOWADJUSTMENTACTIONFACTORY_HPP
@@ -6,8 +6,8 @@
// Copyright © 2019 none. All rights reserved.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_METEOR_CAST_ACTION_FACTORY_HPP
#define EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_METEOR_CAST_ACTION_FACTORY_HPP
#ifndef MeteorCastActionFactory_hpp
#define MeteorCastActionFactory_hpp
#include "src/main/cpp/net/eagle0/shardok/library/ShardokAction.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/settings/GameSettings.hpp"
@@ -25,4 +25,4 @@ public:
};
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_METEOR_CAST_ACTION_FACTORY_HPP
#endif /* MeteorCastActionFactory_hpp */
@@ -2,8 +2,8 @@
// Created by Dan Crosby on 11/29/20.
//
#ifndef EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_PLAYER_SETUP_COMMAND_FACTORY_HPP
#define EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_PLAYER_SETUP_COMMAND_FACTORY_HPP
#ifndef EAGLE0_PLAYERSETUPCOMMANDFACTORY_HPP
#define EAGLE0_PLAYERSETUPCOMMANDFACTORY_HPP
#include <optional>
#include <vector>
@@ -22,7 +22,7 @@ private:
const SettingsGetter settings;
public:
explicit PlayerSetupCommandFactory(const SettingsGetter& getter) : settings(getter) {}
explicit PlayerSetupCommandFactory(const SettingsGetter& getter) : settings(getter){};
auto AddAvailablePlaceAndHideUnitCommandsForOneUnit(
CommandList& existingCommands,
@@ -40,4 +40,4 @@ public:
} // namespace shardok
#endif // EAGLE0_SHARDOK_LIBRARY_ACTION_FACTORIES_PLAYER_SETUP_COMMAND_FACTORY_HPP
#endif // EAGLE0_PLAYERSETUPCOMMANDFACTORY_HPP

Some files were not shown because too many files have changed in this diff Show More