From 79a204a56af2707ee1ea1074966473294aad8992 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Sun, 30 Apr 2023 17:07:22 +0100 Subject: Chess: Allow stockfish to be used if available The stockfish chess engine can now be selected from the engine menu if the port has been installed. --- Userland/Games/Chess/CMakeLists.txt | 2 +- Userland/Games/Chess/main.cpp | 70 +++++++++++++++++++++++++++---------- 2 files changed, 52 insertions(+), 20 deletions(-) diff --git a/Userland/Games/Chess/CMakeLists.txt b/Userland/Games/Chess/CMakeLists.txt index e1bc90fd2b..8eb2191c43 100644 --- a/Userland/Games/Chess/CMakeLists.txt +++ b/Userland/Games/Chess/CMakeLists.txt @@ -13,4 +13,4 @@ set(SOURCES ) serenity_app(Chess ICON app-chess) -target_link_libraries(Chess PRIVATE LibChess LibConfig LibFileSystemAccessClient LibGfx LibGUI LibCore LibMain LibDesktop) +target_link_libraries(Chess PRIVATE LibChess LibConfig LibFileSystem LibFileSystemAccessClient LibGfx LibGUI LibCore LibMain LibDesktop) diff --git a/Userland/Games/Chess/main.cpp b/Userland/Games/Chess/main.cpp index 62db52d1d2..9edf65d3e7 100644 --- a/Userland/Games/Chess/main.cpp +++ b/Userland/Games/Chess/main.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2020, the SerenityOS developers. * Copyright (c) 2023, Sam Atkins + * Copyright (c) 2023, Tim Ledbetter * * SPDX-License-Identifier: BSD-2-Clause */ @@ -9,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +23,32 @@ #include #include +struct EngineDetails { + StringView command; + StringView name { command }; + String path {}; +}; + +static Vector s_all_engines { + { "ChessEngine"sv }, + { "stockfish"sv, "Stockfish"sv }, +}; + +static ErrorOr> available_engines() +{ + Vector available_engines; + for (auto& engine : s_all_engines) { + auto path_or_error = FileSystem::resolve_executable_from_environment(engine.command); + if (path_or_error.is_error()) + continue; + + engine.path = path_or_error.release_value(); + TRY(available_engines.try_append(engine)); + } + + return available_engines; +} + ErrorOr serenity_main(Main::Arguments arguments) { TRY(Core::System::pledge("stdio rpath recvfd sendfd thread proc exec unix")); @@ -38,8 +66,11 @@ ErrorOr serenity_main(Main::Arguments arguments) auto window = TRY(GUI::Window::try_create()); auto widget = TRY(window->set_main_widget()); + auto engines = TRY(available_engines()); + for (auto const& engine : engines) + TRY(Core::System::unveil(engine.path, "x"sv)); + TRY(Core::System::unveil("/res", "r")); - TRY(Core::System::unveil("/bin/ChessEngine", "x")); TRY(Core::System::unveil("/bin/GamesSettings", "x")); TRY(Core::System::unveil("/tmp/session/%sid/portal/launch", "rw")); TRY(Core::System::unveil("/tmp/session/%sid/portal/filesystemaccess", "rw")); @@ -135,24 +166,25 @@ ErrorOr serenity_main(Main::Arguments arguments) engines_action_group.add_action(human_engine_checkbox); TRY(engine_submenu->try_add_action(human_engine_checkbox)); - auto action = GUI::Action::create_checkable("ChessEngine", [&](auto& action) { - auto new_engine = Engine::construct(action.text()); - new_engine->on_connection_lost = [&]() { - if (!widget->want_engine_move()) - return; - - auto rc = GUI::MessageBox::show(window, "Connection to the chess engine was lost while waiting for a move. Do you want to try again?"sv, "Chess"sv, GUI::MessageBox::Type::Question, GUI::MessageBox::InputType::YesNo); - if (rc == GUI::Dialog::ExecResult::Yes) - widget->input_engine_move(); - else - human_engine_checkbox->activate(); - }; - widget->set_engine(move(new_engine)); - widget->input_engine_move(); - }); - engines_action_group.add_action(*action); - - TRY(engine_submenu->try_add_action(*action)); + for (auto const& engine : engines) { + auto action = GUI::Action::create_checkable(engine.name, [&](auto&) { + auto new_engine = Engine::construct(engine.path); + new_engine->on_connection_lost = [&]() { + if (!widget->want_engine_move()) + return; + + auto rc = GUI::MessageBox::show(window, "Connection to the chess engine was lost while waiting for a move. Do you want to try again?"sv, "Chess"sv, GUI::MessageBox::Type::Question, GUI::MessageBox::InputType::YesNo); + if (rc == GUI::Dialog::ExecResult::Yes) + widget->input_engine_move(); + else + human_engine_checkbox->activate(); + }; + widget->set_engine(move(new_engine)); + widget->input_engine_move(); + }); + engines_action_group.add_action(*action); + TRY(engine_submenu->try_add_action(*action)); + } auto help_menu = TRY(window->try_add_menu("&Help"_short_string)); TRY(help_menu->try_add_action(GUI::CommonActions::make_command_palette_action(window))); -- cgit v1.2.3