diff --git a/CMakeLists.txt b/CMakeLists.txt index 721c240..1404831 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,23 +1,33 @@ cmake_minimum_required(VERSION 3.13) +# Set C and C++ and versions set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 20) +# Set default build type to Release +if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE) + message("Using by default the Release build") + message("To build the Debug version pass the option -DCMAKE_BUILD_TYPE=Debug to CMake") +endif () + +# Include the Raspberry Pi Pico SDK import script include(pico_sdk_import.cmake) +# Project project(tic-tac-toe C CXX ASM) # Initialise the Raspberry Pi Pico SDK pico_sdk_init() # Add executable -add_executable(tic-tac-toe main.cpp Game.cpp Move.cpp LCD_I2C.cpp TM1637.cpp Keypad.cpp Player.cpp Player.hpp BoardManager.cpp BoardManager.hpp Utility.hpp IPlayerStrategy.cpp IPlayerStrategy.hpp) +add_executable(tic-tac-toe main.cpp Game.cpp Move.cpp LCD_I2C.cpp TM1637.cpp Keypad.cpp Player.cpp BoardManager.cpp IPlayerStrategy.cpp) include_directories(${CMAKE_CURRENT_LIST_DIR}) pico_generate_pio_header(tic-tac-toe ${CMAKE_CURRENT_LIST_DIR}/TM1637.pio) # Add program info pico_set_program_name(tic-tac-toe "Tic-Tac-Toe LCD Game") -pico_set_program_version(tic-tac-toe "2.0") +pico_set_program_version(tic-tac-toe "1.0.0") pico_set_program_url(tic-tac-toe "https://github.com/cristiancristea00/tic-tac-toe") pico_set_program_description(tic-tac-toe "Copyright (c) 2021 Cristian Cristea") @@ -28,7 +38,17 @@ pico_enable_stdio_usb(tic-tac-toe 0) # Add the libraries to the build target_link_libraries(tic-tac-toe pico_stdlib pico_multicore hardware_i2c hardware_pio) +# Add pico extras pico_add_extra_outputs(tic-tac-toe) +# Set float and double implementation pico_set_float_implementation(tic-tac-toe pico) -pico_set_double_implementation(tic-tac-toe pico) \ No newline at end of file +pico_set_double_implementation(tic-tac-toe pico) + +# Set Debug build compiler arguments +set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wfatal-errors -Wpedantic -Wall -Wextra -Wshadow=local -Wdouble-promotion -Wformat=2 -Wformat-overflow=2 -Wformat-nonliteral -Wformat-security -Wformat-truncation=2 -Wnull-dereference -Wimplicit-fallthrough=3 -Wshift-overflow=2 -Wswitch-default -Wunused-parameter -Wunused-const-variable=2 -Wstrict-overflow=4 -Wstringop-overflow=3 -Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=noreturn -Wmissing-noreturn -Wsuggest-attribute=malloc -Wsuggest-attribute=format -Wmissing-format-attribute -Wsuggest-attribute=cold -Walloc-zero -Walloca -Wattribute-alias=2 -Wduplicated-branches -Wcast-qual") +set(CMAKE_C_FLAGS_DEBUG "-g -O0 -Wfatal-errors -Wpedantic -Wall -Wextra -Wshadow=local -Wdouble-promotion -Wformat=2 -Wformat-overflow=2 -Wformat-nonliteral -Wformat-security -Wformat-truncation=2 -Wnull-dereference -Wimplicit-fallthrough=3 -Wshift-overflow=2 -Wswitch-default -Wunused-parameter -Wunused-const-variable=2 -Wstrict-overflow=4 -Wstringop-overflow=3 -Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=noreturn -Wmissing-noreturn -Wsuggest-attribute=malloc -Wsuggest-attribute=format -Wmissing-format-attribute -Wsuggest-attribute=cold -Walloc-zero -Walloca -Wattribute-alias=2 -Wduplicated-branches -Wcast-qual") + +# Set Release build compiler arguments +set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -Wfatal-errors -Wpedantic -Wall -Wextra -Wshadow=local -Wdouble-promotion -Wformat=2 -Wformat-overflow=2 -Wformat-nonliteral -Wformat-security -Wformat-truncation=2 -Wnull-dereference -Wimplicit-fallthrough=3 -Wshift-overflow=2 -Wswitch-default -Wunused-parameter -Wunused-const-variable=2 -Wstrict-overflow=4 -Wstringop-overflow=3 -Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=noreturn -Wmissing-noreturn -Wsuggest-attribute=malloc -Wsuggest-attribute=format -Wmissing-format-attribute -Wsuggest-attribute=cold -Walloc-zero -Walloca -Wattribute-alias=2 -Wduplicated-branches -Wcast-qual -funroll-loops -finline-functions -fno-builtin") +set(CMAKE_C_FLAGS_RELEASE "-Ofast -Wfatal-errors -Wpedantic -Wall -Wextra -Wshadow=local -Wdouble-promotion -Wformat=2 -Wformat-overflow=2 -Wformat-nonliteral -Wformat-security -Wformat-truncation=2 -Wnull-dereference -Wimplicit-fallthrough=3 -Wshift-overflow=2 -Wswitch-default -Wunused-parameter -Wunused-const-variable=2 -Wstrict-overflow=4 -Wstringop-overflow=3 -Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=noreturn -Wmissing-noreturn -Wsuggest-attribute=malloc -Wsuggest-attribute=format -Wmissing-format-attribute -Wsuggest-attribute=cold -Walloc-zero -Walloca -Wattribute-alias=2 -Wduplicated-branches -Wcast-qual -funroll-loops -finline-functions -fno-builtin") \ No newline at end of file diff --git a/Game.cpp b/Game.cpp index e21c863..7631b59 100644 --- a/Game.cpp +++ b/Game.cpp @@ -241,7 +241,7 @@ void Game::Internal_Play() noexcept { if (second_player_turn) { - auto move = second_player->GetNextMove(BoardManager::Instance()->GetGameBoard(), keypad.get()); + auto move = second_player->GetNextMove(BoardManager::Instance()->GetGameBoard()); BoardManager::Instance()->GetGameBoard() = BoardManager::Instance()->GetResultBoard( BoardManager::Instance()->GetGameBoard(), move, second_player->GetSymbol()); second_player_turn = false; @@ -255,7 +255,7 @@ void Game::Internal_Play() noexcept { static Move move; - move = first_player->GetNextMove(BoardManager::Instance()->GetGameBoard(), keypad.get()); + move = first_player->GetNextMove(BoardManager::Instance()->GetGameBoard()); BoardManager::Instance()->GetGameBoard() = BoardManager::Instance()->GetResultBoard( BoardManager::Instance()->GetGameBoard(), move, first_player->GetSymbol()); } @@ -310,7 +310,7 @@ inline auto Game::Get_User() const noexcept -> PlayerSymbol void Game::Key_Poller_Runner() noexcept { static bool light_on {false}; - static Key key {Key::UNKOWN}; + static Key key {Key::UNKNOWN}; auto * keypad = reinterpret_cast (multicore_fifo_pop_blocking()); auto * lcd = reinterpret_cast(multicore_fifo_pop_blocking()); diff --git a/Game.hpp b/Game.hpp index 457d8a0..caa031d 100644 --- a/Game.hpp +++ b/Game.hpp @@ -12,12 +12,12 @@ #include #include +#include "IPlayerStrategy.hpp" #include "LCD_I2C.hpp" -#include "Player.hpp" -#include "Move.hpp" #include "TM1637.hpp" #include "Keypad.hpp" -#include "IPlayerStrategy.hpp" +#include "Player.hpp" +#include "Move.hpp" #include #include diff --git a/IPlayerStrategy.cpp b/IPlayerStrategy.cpp index 958cc5a..51d5be5 100644 --- a/IPlayerStrategy.cpp +++ b/IPlayerStrategy.cpp @@ -44,7 +44,7 @@ auto IPlayerStrategy::GetRNG() noexcept -> std::mt19937 & return random_number_generator; } -auto EasyStrategy::GetNextMove(Utility::Board const & current_board, Keypad * const /*keypad*/) noexcept -> Move +auto EasyStrategy::GetNextMove(Utility::Board const & current_board) noexcept -> Move { if (BoardManager::Instance()->IsTerminal(current_board)) { @@ -61,7 +61,7 @@ auto EasyStrategy::GetName() const noexcept -> std::string_view return "EASY"; } -auto MediumStrategy::GetNextMove(Utility::Board const & current_board, Keypad * const /*keypad*/) noexcept -> Move +auto MediumStrategy::GetNextMove(Utility::Board const & current_board) noexcept -> Move { if (BoardManager::Instance()->IsTerminal(current_board)) { @@ -185,7 +185,7 @@ auto HardStrategy::Get_Possible_Moves(Board const & current_board) const return possible_moves; } -auto HardStrategy::GetNextMove(Utility::Board const & current_board, Keypad * const /*keypad*/) noexcept -> Move +auto HardStrategy::GetNextMove(Utility::Board const & current_board) noexcept -> Move { if (BoardManager::Instance()->IsTerminal(current_board)) { @@ -199,9 +199,8 @@ auto HardStrategy::GetNextMove(Utility::Board const & current_board, Keypad * co { if (BoardManager::Instance()-> IsWinner(BoardManager::Instance()->GetCurrentPlayer(current_board), - BoardManager::Instance()->GetResultBoard(current_board, ACTION, - BoardManager::Instance()-> - GetCurrentPlayer(current_board)))) + BoardManager::Instance()->GetResultBoard(current_board, ACTION, BoardManager::Instance()-> + GetCurrentPlayer(current_board)))) { return ACTION; } @@ -215,13 +214,13 @@ auto HardStrategy::GetName() const noexcept -> std::string_view return "HARD"; } -auto HumanStrategy::GetNextMove(Board const & current_board, Keypad * const keypad) noexcept -> Move +auto HumanStrategy::GetNextMove(Utility::Board const & current_board) noexcept -> Move { static Move move; do { - move = Keypad::ActionFromKey(keypad->GetPressedKey()); + move = Keypad::ActionFromKey(Keypad::GetPressedKey()); } while (!BoardManager::Instance()->IsValidAction(current_board, move)); return move; diff --git a/IPlayerStrategy.hpp b/IPlayerStrategy.hpp index 32ff39e..bb4a592 100644 --- a/IPlayerStrategy.hpp +++ b/IPlayerStrategy.hpp @@ -18,8 +18,6 @@ #include #include -class Keypad; - class IPlayerStrategy { private: @@ -66,7 +64,7 @@ class IPlayerStrategy * @param current_board The board to be analysed * @return A move */ - [[nodiscard]] virtual auto GetNextMove(Utility::Board const & current_board, Keypad * keypad) noexcept -> Move = 0; + [[nodiscard]] virtual auto GetNextMove(Utility::Board const & current_board) noexcept -> Move = 0; /** * Gets the strategy's name. @@ -116,7 +114,7 @@ class EasyStrategy final : public IPlayerStrategy * @param current_board The board to be analysed * @return A random move */ - [[nodiscard]] auto GetNextMove(Utility::Board const & current_board, Keypad * keypad) noexcept -> Move final; + [[nodiscard]] auto GetNextMove(Utility::Board const & current_board) noexcept -> Move final; /** * Gets the strategy's name. @@ -167,7 +165,7 @@ class MediumStrategy final : public IPlayerStrategy * @param current_board The board to be analysed * @return A somewhat good move */ - [[nodiscard]] auto GetNextMove(Utility::Board const & current_board, Keypad * keypad) noexcept -> Move final; + [[nodiscard]] auto GetNextMove(Utility::Board const & current_board) noexcept -> Move final; /** * Gets the strategy's name. @@ -254,7 +252,7 @@ class HardStrategy final : public IPlayerStrategy * @param current_board The board to be analysed * @return The best move */ - [[nodiscard]] auto GetNextMove(Utility::Board const & current_board, Keypad * keypad) noexcept -> Move final; + [[nodiscard]] auto GetNextMove(Utility::Board const & current_board) noexcept -> Move final; /** * Gets the strategy's name. @@ -304,7 +302,7 @@ class HumanStrategy final : public IPlayerStrategy * @param current_board The board to be analysed * @return The input move */ - [[nodiscard]] auto GetNextMove(Utility::Board const & current_board, Keypad * keypad) noexcept -> Move final; + [[nodiscard]] auto GetNextMove(Utility::Board const & current_board) noexcept -> Move final; /** * Gets the strategy's name. diff --git a/Keypad.cpp b/Keypad.cpp index 2ecc503..c75522f 100644 --- a/Keypad.cpp +++ b/Keypad.cpp @@ -11,8 +11,7 @@ using Utility::PlayerSymbol; -Keypad::Keypad(array const & rows, array const & columns) noexcept - : rows(rows), columns(columns) +Keypad::Keypad(array const & rows, array const & columns) noexcept : rows(rows), columns(columns) { Init(); } @@ -57,18 +56,18 @@ auto Keypad::Key_Poller() const noexcept -> Key } } } - return Key::UNKOWN; + return Key::UNKNOWN; } auto Keypad::GetKeyFromPoller() const noexcept -> Key { - Key key {Key::UNKOWN}; + Key key {Key::UNKNOWN}; do { key = Key_Poller(); } - while (key == Key::UNKOWN); + while (key == Key::UNKNOWN); return key; } diff --git a/Keypad.hpp b/Keypad.hpp index c9415f7..657a6e7 100644 --- a/Keypad.hpp +++ b/Keypad.hpp @@ -26,7 +26,7 @@ enum class Key KEY5, KEY6, KEY7, KEY8, KEY9, KEY10, KEY11, KEY12, KEY13, KEY14, KEY15, KEY16, - UNKOWN + UNKNOWN }; class Keypad final diff --git a/LCD_I2C.hpp b/LCD_I2C.hpp index 3d46bf0..a51dca4 100644 --- a/LCD_I2C.hpp +++ b/LCD_I2C.hpp @@ -283,7 +283,7 @@ class LCD_I2C final * Creates a custom character by specifying the location in memory to be * stored (8 locations maximum, starting from 0) and an array of 8 bytes. * @code - * constexpr uint8_t BELL[8] = {0x04, 0x0E, 0x0E, 0x1F, 0x00, 0x04, 0x00, 0x00}; + * constexpr std::array BELL = {0x04, 0x0E, 0x0E, 0x1F, 0x00, 0x04, 0x00, 0x00}; * @endcode * * @param location The memory address diff --git a/Player.cpp b/Player.cpp index 070b00f..03568b2 100644 --- a/Player.cpp +++ b/Player.cpp @@ -10,6 +10,7 @@ #include "Player.hpp" using Utility::PlayerSymbol; +using Utility::Board; Player::Player(PlayerSymbol symbol, IPlayerStrategy * const strategy) noexcept : symbol(symbol), strategy(strategy) {} @@ -28,7 +29,7 @@ void Player::SetSymbol(PlayerSymbol player_symbol) noexcept symbol = player_symbol; } -auto Player::GetNextMove(Utility::Board const & current_board, Keypad * const keypad) noexcept -> Move +auto Player::GetNextMove(Board const & current_board) noexcept -> Move { - return strategy->GetNextMove(current_board, keypad); + return strategy->GetNextMove(current_board); } \ No newline at end of file diff --git a/Player.hpp b/Player.hpp index 0545ce6..2f6dbb9 100644 --- a/Player.hpp +++ b/Player.hpp @@ -59,6 +59,6 @@ class Player * @param current_board The board to be analysed * @return A move */ - [[nodiscard]] auto GetNextMove(Utility::Board const & current_board, Keypad * keypad) noexcept -> Move; + [[nodiscard]] auto GetNextMove(Utility::Board const & current_board) noexcept -> Move; }; diff --git a/main.cpp b/main.cpp index 5f93533..c089f61 100644 --- a/main.cpp +++ b/main.cpp @@ -1,9 +1,7 @@ #include -#include - -#include "Game.hpp" #include "Keypad.hpp" +#include "Game.hpp" int main() { diff --git a/pico_sdk_import.cmake b/pico_sdk_import.cmake index 28efe9e..e07ccf5 100644 --- a/pico_sdk_import.cmake +++ b/pico_sdk_import.cmake @@ -1,8 +1,3 @@ -# This is a copy of /external/pico_sdk_import.cmake - -# This can be dropped into an external project to help locate this SDK -# It should be include()ed prior to project() - if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")