Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b9d57c1
hex: new game
tiedanGH Dec 16, 2024
a711ba0
gold_coins: new special rule
tiedanGH Dec 16, 2024
918a0f4
naval_battle: support custom plane shape
tiedanGH Dec 16, 2024
2a36ec8
fix bugs in checking ready status
tiedanGH Dec 16, 2024
e32e91c
shuffle player id for bread_crisis and world_without_thieves
tiedanGH Dec 16, 2024
e2edbbe
mahjong_17_steps: fix assert on 5 dora that cause game to crash
tiedanGH Dec 16, 2024
e1494a2
six_nimmt: fix bug of duplicate broadcasts
tiedanGH Jan 30, 2025
74f425e
opencomb: new game
tiedanGH Jan 30, 2025
2bebaca
hex: add concede
tiedanGH Feb 11, 2025
28b28fa
opencomb: add yunding battle mode
tiedanGH Feb 16, 2025
8bae592
six_nimmt: 66 head mode multiple change to 3
tiedanGH Feb 25, 2025
43c3f32
opencomb: fix achievement bugs
tiedanGH Mar 13, 2025
f9f9d35
naval_battle: multiple crucial mode
tiedanGH Mar 13, 2025
e09838f
Fix testing error
tiedanGH Mar 21, 2025
97c266b
fix some timeout handle error
tiedanGH May 14, 2025
1869b17
beast_trap_chess: new game
tiedanGH May 14, 2025
3a218d7
long_night: new game
tiedanGH May 14, 2025
81bd21e
set width limit for game list & profile achievements
tiedanGH May 23, 2025
60a65f3
beast_trap_chess: update icon
tiedanGH May 27, 2025
498589c
long_night: refactor walls & grids background logic
tiedanGH Jun 20, 2025
8c9b462
long_night: new GridType and new block
tiedanGH Jul 8, 2025
02ea716
rainbow_treasure_hunter: new game
tiedanGH Jul 8, 2025
cc4e1e5
gold_coins: fix final score miscalculation & option mistakes
tiedanGH Jul 10, 2025
848f743
long_night: modify some rules and add block preview content
tiedanGH Jul 15, 2025
f433e18
crowd: expend to 156 questions (78 formal questions)
tiedanGH Jul 15, 2025
a87484d
crowd: update extra files & fix test errors
tiedanGH Jul 15, 2025
5004cd3
throw_handkerchief: update rule.md
tiedanGH Jul 24, 2025
59ab1a6
rainbow_treasure_hunter: add special items
tiedanGH Jul 24, 2025
c2eb5f3
fix Windows build failure in GitHub Actions (ref: Slontia/mahjong#1)
tiedanGH Jul 24, 2025
17b3b2b
fix compilation errors on MSYS2
tiedanGH Aug 7, 2025
f81d719
fix align game module loading logic on Windows
tiedanGH Aug 9, 2025
5f8c7e3
sync latest changes from remote dev branch (tiedanGH/lgtbot#2)
tiedanGH Aug 11, 2025
527488c
rth & wordle: some small update
tiedanGH Aug 11, 2025
d040f58
hp_killer: add option for killer team to know all civilian codes
tiedanGH Aug 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
submodules: recursive

- name: Configure CMake
run: cmake -G "MinGW Makefiles" -B build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DWITH_GCOV=OFF -DWITH_ASAN=OFF -DWITH_GLOG=OFF -DWITH_SQLITE=ON -DWITH_TEST=ON -DWITH_SIMULATOR=ON -DWITH_GAMES=ON
run: cmake -G "MinGW Makefiles" -B build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DWITH_GCOV=OFF -DWITH_ASAN=OFF -DWITH_GLOG=OFF -DWITH_SQLITE=ON -DWITH_TEST=ON -DWITH_SIMULATOR=ON -DWITH_GAMES=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5

- name: Build
working-directory: build
Expand Down
24 changes: 16 additions & 8 deletions bot_core/bot_ctx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,24 @@ static std::variant<GameHandleMap, const char*> LoadGameModules(const char* cons
return game_handles;
}
#ifdef _WIN32
WIN32_FIND_DATA file_data;
HANDLE file_handle = FindFirstFile((std::string(games_path) + "\\*.dll").c_str(), &file_data);
if (file_handle == INVALID_HANDLE_VALUE) {
return "LoadGameModules: find first file failed";
WIN32_FIND_DATA dir_data;
HANDLE dir_handle = FindFirstFile((std::string(games_path) + "\\*").c_str(), &dir_data);
if (dir_handle == INVALID_HANDLE_VALUE) {
return "LoadGameModules: open directory failed";
}
do {
const auto dll_path = std::string(games_path) + "\\" + file_data.cFileName;
LoadGame(LoadLibrary(dll_path.c_str()), game_handles);
} while (FindNextFile(file_handle, &file_data));
FindClose(file_handle);
if ((dir_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 || strcmp(dir_data.cFileName, ".") == 0 || strcmp(dir_data.cFileName, "..") == 0) {
WarnLog() << "Not the game directory, skip: " << dir_data.cFileName;
continue;
}
std::string dll_path = std::string(games_path) + "\\" + dir_data.cFileName + "\\libgame.dll";
if (GetFileAttributes(dll_path.c_str()) == INVALID_FILE_ATTRIBUTES) {
WarnLog() << "Cannot find libgame.dll, skip: " << dir_data.cFileName;
} else {
LoadGame(LoadLibrary(dll_path.c_str()), game_handles);
}
} while (FindNextFile(dir_handle, &dir_data));
FindClose(dir_handle);
InfoLog() << "Load module count: " << game_handles.size();
#elif __linux__
DIR* d = opendir(games_path);
Expand Down
2 changes: 1 addition & 1 deletion bot_core/db_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ uint64_t InsertMatch(sqlite::database& db, const std::string& game_name, const s
{
db << "INSERT INTO match (game_name, finish_time, group_id, host_user_id, user_count, multiple) VALUES (?,datetime(CURRENT_TIMESTAMP, \'localtime\'),?,?,?,?);"
<< game_name
<< gid
<< (gid ? std::optional{gid->GetStr()} : std::nullopt)
<< host_uid.GetStr()
<< user_count
<< multiple;
Expand Down
4 changes: 2 additions & 2 deletions bot_core/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
#include "utility/log.h"

#ifdef TEST_BOT
static bool enable_markdown_to_image = false;
inline bool enable_markdown_to_image = false;
#else
static bool enable_markdown_to_image = true;
inline bool enable_markdown_to_image = true;
#endif

inline const std::string k_markdown2image_path = (std::filesystem::current_path() / "markdown2image").string(); // TODO: config
Expand Down
4 changes: 2 additions & 2 deletions bot_core/message_handlers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ static ErrCode show_gamelist(BotCtx& bot, const UserID uid, const std::optional<
table.Get(table.Row() - 2, 4).SetContent("<img src=\"file:///" +
(std::filesystem::absolute(bot.game_path()) / game_handle.Info().module_name_ / "icon.png").string() +
"\" style=\"width:70px; height:70px; vertical-align: middle;\">");
table.Get(table.Row() - 1, 1).SetContent(std::string("<font size=\"3\"> ") + game_handle.Info().description_ + "</font>");
table.Get(table.Row() - 1, 1).SetStyle("style=\"width:470px;\"").SetContent(std::string("<font size=\"3\"> ") + game_handle.Info().description_ + "</font>");
}
send_image();
}
Expand Down Expand Up @@ -666,7 +666,7 @@ static ErrCode show_profile(BotCtx& bot, const UserID uid, const std::optional<G
} else {
for (const auto& [name, description] : it->second.Info().achievements_) {
if (name == info.achievement_name_) {
recent_honors_table.GetLastRow(3).SetContent(description);
recent_honors_table.GetLastRow(3).SetStyle("style=\"width:440px;\"").SetContent(description);
break;
}
}
Expand Down
6 changes: 3 additions & 3 deletions bot_core/test_bot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ namespace game {

namespace GAME_MODULE_NAME {

bool AdaptOptions(MsgSenderBase& reply, MyGameOptions& game_options, const GenericOptions& generic_options_readonly,
bool AdaptOptions(MsgSenderBase& reply, CustomOptions& game_options, const GenericOptions& generic_options_readonly,
MutableGenericOptions& generic_options)
{
return true;
Expand All @@ -180,9 +180,9 @@ bool AdaptOptions(MsgSenderBase& reply, MyGameOptions& game_options, const Gener
template <typename T, T V>
constexpr T ValueFunc() { return V; }

uint64_t MaxPlayerNum(const MyGameOptions& options) { return 4; }
uint64_t MaxPlayerNum(const CustomOptions& options) { return 4; }

uint32_t Multiple(const MyGameOptions& options) { return 1; }
uint32_t Multiple(const CustomOptions& options) { return 1; }

class MainStage;
template <typename... SubStages> using SubGameStage = StageFsm<MainStage, SubStages...>;
Expand Down
8 changes: 4 additions & 4 deletions game_framework/game_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ namespace game {

namespace GAME_MODULE_NAME {

#define OPTION_CLASSNAME MyGameOptions
#define OPTION_CLASSNAME CustomOptions
#define OPTION_FILENAME GAME_OPTION_FILENAME
#include "utility/extend_option.h"
#undef OPTION_CLASSNAME
#undef OPTION_FILENAME

class GameOptions : public GameOptionsBase, public MyGameOptions
class GameOptions : public GameOptionsBase, public CustomOptions
{
public:
GameOptions() = default;
Expand All @@ -48,13 +48,13 @@ class GameOptions : public GameOptionsBase, public MyGameOptions
virtual bool SetOption(const char* const msg) override
{
MsgReader msg_reader(msg);
return MyGameOptions::SetOption(msg_reader);
return CustomOptions::SetOption(msg_reader);
}

virtual const char* Info(const bool with_example, const bool with_html_syntax, const char* const prefix) const override
{
thread_local static std::string info;
return (info = MyGameOptions::Info(with_example, with_html_syntax, prefix)).c_str();
return (info = CustomOptions::Info(with_example, with_html_syntax, prefix)).c_str();
}

virtual const char* const* ShortInfo() const override
Expand Down
6 changes: 3 additions & 3 deletions game_framework/stage.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ class VariantSubStage::Impl : public VariantSubStage::Base
class MainStageFactory
{
public:
MainStageFactory(const MyGameOptions& game_options, const GenericOptions& generic_options, MatchBase& match)
MainStageFactory(const CustomOptions& game_options, const GenericOptions& generic_options, MatchBase& match)
: game_options_(std::move(game_options)), generic_options_(generic_options), match_(match) {}

// This function can only be invoked once.
Expand All @@ -307,11 +307,11 @@ class MainStageFactory
return new internal::MainStage(std::make_unique<Fsm>(StageUtility{game_options_, generic_options_, match_}));
}

const MyGameOptions& GetGameOptions() const { return game_options_; }
const CustomOptions& GetGameOptions() const { return game_options_; }
const GenericOptions& GetGenericOptions() const { return generic_options_; }

private:
const MyGameOptions& game_options_;
const CustomOptions& game_options_;
const GenericOptions& generic_options_;
MatchBase& match_;
};
Expand Down
4 changes: 2 additions & 2 deletions game_framework/stage_utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace GAME_MODULE_NAME {

namespace internal {

PublicStageUtility::PublicStageUtility(const MyGameOptions& game_options, const lgtbot::game::GenericOptions& generic_options, MatchBase& match)
PublicStageUtility::PublicStageUtility(const CustomOptions& game_options, const lgtbot::game::GenericOptions& generic_options, MatchBase& match)
: game_options_{game_options}
, generic_options_(generic_options)
, match_(match)
Expand Down Expand Up @@ -103,7 +103,7 @@ void PublicStageUtility::Leave(const PlayerID pid)
{
masker_.SetPermanentInactive(pid);
if (IsInDeduction()) {
Boardcast() << "所有玩家都失去了行动能力,于是游戏将直接推演至终局";
match_.GroupMsgSender()() << "所有玩家都失去了行动能力,于是游戏将直接推演至终局";
}
}

Expand Down
6 changes: 3 additions & 3 deletions game_framework/stage_utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class PublicStageUtility
using AchievementCounts = std::array<uint8_t, Achievement::Count()>;

public:
PublicStageUtility(const MyGameOptions& game_options, const lgtbot::game::GenericOptions& generic_options, MatchBase& match);
PublicStageUtility(const CustomOptions& game_options, const lgtbot::game::GenericOptions& generic_options, MatchBase& match);
PublicStageUtility(PublicStageUtility&&) = default;

// Message functions
Expand Down Expand Up @@ -81,7 +81,7 @@ class PublicStageUtility

// Options

const MyGameOptions& Options() const { return game_options_; }
const CustomOptions& Options() const { return game_options_; }
auto PlayerNum() const { return generic_options_.PlayerNum(); }
const char* ResourceDir() const { return generic_options_.resource_dir_; }

Expand All @@ -102,7 +102,7 @@ class PublicStageUtility
static void TimerCallbackPublic_(void* const p, const uint64_t alert_sec);
static void TimerCallbackPrivate_(void* const p, const uint64_t alert_sec);

const MyGameOptions& game_options_;
const CustomOptions& game_options_;
const GenericOptions& generic_options_;
MatchBase& match_;
PlayerReadyMasker masker_;
Expand Down
10 changes: 5 additions & 5 deletions game_framework/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class GenericOptions;

namespace GAME_MODULE_NAME {

class MyGameOptions;
class CustomOptions;

// =====================================
// Developer-defined constance
Expand All @@ -40,7 +40,7 @@ enum class NewGameMode {
SINGLE_USER, // start game immediately
MULTIPLE_USERS, // wait other users to join
};
using InitOptionsCommand = Command<NewGameMode(MyGameOptions& game_options, MutableGenericOptions& generic_options)>; // command to initialize options
using InitOptionsCommand = Command<NewGameMode(CustomOptions& game_options, MutableGenericOptions& generic_options)>; // command to initialize options
extern const std::vector<InitOptionsCommand> k_init_options_commands;

// =====================================
Expand All @@ -50,15 +50,15 @@ extern const std::vector<InitOptionsCommand> k_init_options_commands;
// Validate the options and adapt them if not valid.
// The return value of false indicates the options are not valid and fail to adapt. In this scenario, the game will fail
// to start.
bool AdaptOptions(MsgSenderBase& reply, MyGameOptions& game_options, const GenericOptions& generic_options_readonly, MutableGenericOptions& generic_options);
bool AdaptOptions(MsgSenderBase& reply, CustomOptions& game_options, const GenericOptions& generic_options_readonly, MutableGenericOptions& generic_options);

// Get the maximum player numbers under the current options.
// The return value of 0 indicates there are no player number limits.
uint64_t MaxPlayerNum(const MyGameOptions& options);
uint64_t MaxPlayerNum(const CustomOptions& options);

// Get the score multiple under the current options.
// The value of 0 indicates it is a match for practice.
uint32_t Multiple(const MyGameOptions& options);
uint32_t Multiple(const CustomOptions& options);

} // namespace GAME_MODULE_NAME

Expand Down
51 changes: 28 additions & 23 deletions game_template/mygame.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,48 @@ class MainStage;
template <typename... SubStages> using SubGameStage = StageFsm<MainStage, SubStages...>;
template <typename... SubStages> using MainGameStage = StageFsm<void, SubStages...>;

// 0 indicates no max-player limits
uint64_t MaxPlayerNum(const MyGameOptions& options) { return 0; }
const GameProperties k_properties {
// The game name which should be unique among all the games.
.name_ = "测试游戏",

// The default score multiple for the game. The value of 0 denotes a testing game.
// We recommend to increase the multiple by one for every 7~8 minutes the game lasts.
uint32_t Multiple(const MyGameOptions& options) { return 0; }
// The game developer which can be shown in the game list image.
.developer_ = "佚名",

// The game name which should be unique among all the games.
const std::string k_game_name = "测试游戏";
// The game description which can be shown in the game list image.
.description_ = "暂无游戏描述",

// The game developer which can be shown in the game list image.
const std::string k_developer = "佚名";
// The true value indicates each user may be assigned with different player IDs in different matches.
.shuffled_player_id_ = false,
};

// The game description which can be shown in the game list image.
const std::string k_description = "暂无游戏描述";
// 0 indicates no max-player limits
uint64_t MaxPlayerNum(const CustomOptions& options) { return 0; }

// The default score multiple for the game. The value of 0 denotes a testing game.
// We recommend to increase the multiple by one for every 7~8 minutes the game lasts.
uint32_t Multiple(const CustomOptions& options) { return 0; }

// The default generic options.
const MutableGenericOptions k_default_generic_options;

// The function is invoked before a game starts. You can make final adaption for the options.
// The return value of false denotes failure to start a game.
bool AdaptOptions(MsgSenderBase& reply, CustomOptions& game_options, const GenericOptions& generic_options_readonly, MutableGenericOptions& generic_options)
{
if (generic_options_readonly.PlayerNum() < 3) {
reply() << "该游戏至少 3 人参加,当前玩家数为 " << generic_options_readonly.PlayerNum();
return false;
}
return true;
}

// The commands for showing more rules information. Users can get the information by "#规则 <game name> <rule command>...".
const std::vector<RuleCommand> k_rule_commands = {};

// The commands for initialize the options when starting a game by "#新游戏 <game name> <init options command>..."
const std::vector<InitOptionsCommand> k_init_options_commands = {
InitOptionsCommand("独自一人开始游戏",
[] (MyGameOptions& game_options, MutableGenericOptions& generic_options)
[] (CustomOptions& game_options, MutableGenericOptions& generic_options)
{
// Set the target player numbers when an user start the game with the "单机" argument.
// It is ok to make `k_init_options_commands` empty.
Expand All @@ -51,17 +67,6 @@ const std::vector<InitOptionsCommand> k_init_options_commands = {
VoidChecker("单机")),
};

// The function is invoked before a game starts. You can make final adaption for the options.
// The return value of false denotes failure to start a game.
bool AdaptOptions(MsgSenderBase& reply, MyGameOptions& game_options, const GenericOptions& generic_options_readonly, MutableGenericOptions& generic_options)
{
if (generic_options_readonly.PlayerNum() < 3) {
reply() << "该游戏至少 3 人参加,当前玩家数为 " << generic_options_readonly.PlayerNum();
return false;
}
return true;
}

// ========== GAME STAGES ==========

class RoundStage;
Expand Down
2 changes: 1 addition & 1 deletion game_util/mahjong_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ static std::string DoraHtml(const std::string& image_path, const std::span<const
const auto append_empty_doras = [&]()
{
constexpr int32_t k_max_dora_num = 5;
assert(doras.size() < k_max_dora_num);
assert(doras.size() <= k_max_dora_num);
for (auto i = doras.size(); i < k_max_dora_num; ++i) {
s += "<img src=\"file:///" + image_path + "/empty_dora.png\"/>";
}
Expand Down
2 changes: 2 additions & 0 deletions games/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ foreach (GAME_DIR ${GAME_DIRS})
target_include_directories(${GAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/${GAME})
target_link_libraries(${GAME} ${GAME_THIRD_PARTIES})
set_target_properties(${GAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${GAME_OUTPUT_PATH}
LIBRARY_OUTPUT_DIRECTORY ${GAME_OUTPUT_PATH}
ARCHIVE_OUTPUT_DIRECTORY ${GAME_OUTPUT_PATH}
OUTPUT_NAME "libgame"
PREFIX "")

Expand Down
8 changes: 4 additions & 4 deletions games/alchemist/mygame.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ const GameProperties k_properties {
.description_ = "通过放置卡牌,让卡牌连成直线获得积分,比拼分数高低的游戏",
};

uint64_t MaxPlayerNum(const MyGameOptions& options) { return 0; } /* 0 means no max-player limits */
uint32_t Multiple(const MyGameOptions& options)
uint64_t MaxPlayerNum(const CustomOptions& options) { return 0; } /* 0 means no max-player limits */
uint32_t Multiple(const CustomOptions& options)
{
return GET_OPTION_VALUE(options, 种子).empty() ? std::min(2U, GET_OPTION_VALUE(options, 回合数) / 10) : 0;
}
Expand All @@ -41,7 +41,7 @@ const std::vector<RuleCommand> k_rule_commands = {};

static int WinScoreThreshold(const bool mode) { return mode ? 200 : 10; }

bool AdaptOptions(MsgSenderBase& reply, MyGameOptions& game_options, const GenericOptions& generic_options_readonly, MutableGenericOptions& generic_options)
bool AdaptOptions(MsgSenderBase& reply, CustomOptions& game_options, const GenericOptions& generic_options_readonly, MutableGenericOptions& generic_options)
{
const auto card_num = GET_OPTION_VALUE(game_options, 颜色) * GET_OPTION_VALUE(game_options, 点数) * GET_OPTION_VALUE(game_options, 副数);
if (GET_OPTION_VALUE(game_options, 回合数) > card_num && GET_OPTION_VALUE(game_options, 副数) > 0) {
Expand All @@ -53,7 +53,7 @@ bool AdaptOptions(MsgSenderBase& reply, MyGameOptions& game_options, const Gener

const std::vector<InitOptionsCommand> k_init_options_commands = {
InitOptionsCommand("独自一人开始游戏",
[] (MyGameOptions& game_options, MutableGenericOptions& generic_options)
[] (CustomOptions& game_options, MutableGenericOptions& generic_options)
{
generic_options.bench_computers_to_player_num_ = 1;
return NewGameMode::SINGLE_USER;
Expand Down
10 changes: 5 additions & 5 deletions games/alter_rps/mygame.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ const GameProperties k_properties {
.developer_ = "森高",
.description_ = "伸出两拳,收回一拳的猜拳游戏",
};
uint64_t MaxPlayerNum(const MyGameOptions& options) { return 2; } /* 0 means no max-player limits */
uint32_t Multiple(const MyGameOptions& options) { return 1; }
uint64_t MaxPlayerNum(const CustomOptions& options) { return 2; } /* 0 means no max-player limits */
uint32_t Multiple(const CustomOptions& options) { return 1; }
const MutableGenericOptions k_default_generic_options;
const std::vector<RuleCommand> k_rule_commands = {};

bool AdaptOptions(MsgSenderBase& reply, MyGameOptions& game_options, const GenericOptions& generic_options_readonly, MutableGenericOptions& generic_options)
bool AdaptOptions(MsgSenderBase& reply, CustomOptions& game_options, const GenericOptions& generic_options_readonly, MutableGenericOptions& generic_options)
{
if (generic_options_readonly.PlayerNum() != 2) {
reply() << "该游戏为双人游戏,必须为2人参加,当前玩家数为" << generic_options_readonly.PlayerNum();
Expand All @@ -45,7 +45,7 @@ bool AdaptOptions(MsgSenderBase& reply, MyGameOptions& game_options, const Gener

const std::vector<InitOptionsCommand> k_init_options_commands = {
InitOptionsCommand("独自一人开始游戏",
[] (MyGameOptions& game_options, MutableGenericOptions& generic_options)
[] (CustomOptions& game_options, MutableGenericOptions& generic_options)
{
generic_options.bench_computers_to_player_num_ = 2;
return NewGameMode::SINGLE_USER;
Expand Down Expand Up @@ -95,7 +95,7 @@ static std::string StarsString(const uint32_t n) {

using CardMap = std::map<Card, CardState>;

static CardMap GetCardMap(const MyGameOptions& option)
static CardMap GetCardMap(const CustomOptions& option)
{
CardMap cards;
const auto emplace_card = [&](const auto& card) {
Expand Down
Loading
Loading