diff --git a/TODO.md b/TODO.md index bb40991..182605b 100644 --- a/TODO.md +++ b/TODO.md @@ -1,7 +1,7 @@ # TODO ## Before releasing v0.1.0 - - [ ] Implement pawn promotions in BoardCanvas + - [x] Implement pawn promotions in BoardCanvas - [x] Debug animations (have a more reliable approach (can segfault when clicking on variations in the editor)) - [x] In BoardCanvas search for a workaround of the dynamic allocation of adata.buffer (on canvas resize) - [x] Bind the chess game editor settings to EditorPrefs.hpp diff --git a/libs/chessarbiter b/libs/chessarbiter index 6f48bec..6ebd968 160000 --- a/libs/chessarbiter +++ b/libs/chessarbiter @@ -1 +1 @@ -Subproject commit 6f48becb9186a399e3a4dddb778570e7057752c7 +Subproject commit 6ebd96825576b2da8e8acf2ac85d0b82a7531424 diff --git a/src/game_tab/Game.cpp b/src/game_tab/Game.cpp index def179c..315a4de 100644 --- a/src/game_tab/Game.cpp +++ b/src/game_tab/Game.cpp @@ -100,6 +100,12 @@ bool Game::IsCheckmate(bool forBlack){ return !arbiter.IsBlackTurn() && arbiter.IsCheckMate(); } +bool Game::IsPromotionMove(std::string absolute_move){ + arbiter.Setup(GetFen()); + arbiter.Play(absolute_move); + return(arbiter.WasPawnPromotion()); +} + bool Game::Play(std::string move,char promotion) { wxLogDebug("Playing move %s", move); std::string fen = GetFen(); diff --git a/src/game_tab/Game.hpp b/src/game_tab/Game.hpp index 2fa9bcd..ddf5cf6 100644 --- a/src/game_tab/Game.hpp +++ b/src/game_tab/Game.hpp @@ -32,6 +32,7 @@ public: bool Play(std::string move,char promotion='q'); bool IsBlackToPlay(); bool IsCheckmate(bool forBlack); + bool IsPromotionMove(std::string absolute_move); void Previous(); void Next(); void DeleteMove(HalfMove *m); diff --git a/src/game_tab/left_panel/GameTabLeftPanel.cpp b/src/game_tab/left_panel/GameTabLeftPanel.cpp index 65d77f0..cfe0de8 100644 --- a/src/game_tab/left_panel/GameTabLeftPanel.cpp +++ b/src/game_tab/left_panel/GameTabLeftPanel.cpp @@ -25,7 +25,6 @@ GameTabLeftPanel::GameTabLeftPanel(wxFrame *parent, std::shared_ptr game) // Bind events: Bind(PLAY_MOVE_EVENT, &GameTabLeftPanel::OnPlay, this, wxID_ANY); - Bind(PLAY_PROMOTE, &GameTabLeftPanel::OnPromote,this); Bind(wxEVT_BUTTON, [bc=board_canvas](wxCommandEvent &event){bc->Zoom(10);}, ZOOM_IN_BTN); Bind(wxEVT_BUTTON, [bc=board_canvas](wxCommandEvent &event){bc->Zoom(-10);}, ZOOM_OUT_BTN); Bind(wxEVT_BUTTON, [bc=board_canvas](wxCommandEvent &event){bc->Swap();}, SWAP_BTN); @@ -60,19 +59,28 @@ GameTabLeftPanel::GameTabLeftPanel(wxFrame *parent, std::shared_ptr game) }); } -void GameTabLeftPanel::OnPromote(wxCommandEvent &event){ - char piece=event.GetString()[0]; - wxLogDebug("Promote to %c",piece); -} - void GameTabLeftPanel::OnPlay(wxCommandEvent &event) { std::string move=event.GetString().ToStdString(); - if (game->Play(move)) { - // Notify other classes - wxCommandEvent event(GAME_CHANGE, GetId()); - event.SetEventObject(this); - ProcessEvent(event); + int size=move.size(); + char promote=(char)event.GetInt(); + // First check if it is a promotion move (to prompt the user for a piece) + if(size>0 && game->IsPromotionMove(move)){ + promote_on=move.substr(2,2); // Will trigger the piece prompt on next Notify() + promotion_move=move; // Save the move that should be played for the promotion + } else { + if(size==0){ // It is a promotion move? + move=promotion_move; // Play the save promotion move + promote_on.clear(); // Clear user prompte (cf. Notify()) + promotion_move.clear(); + } + if(game->Play(move,promote)){ + // Notify other classes + wxCommandEvent event(GAME_CHANGE, GetId()); + event.SetEventObject(this); + ProcessEvent(event); + } } + Notify(true); // Redraw event is move failed! Otherwise piece not resets to it initial position after dragging } @@ -127,6 +135,7 @@ void GameTabLeftPanel::Notify(bool skip_animation) { gs.mat_black=game->IsCheckmate(true); gs.mat_white=game->IsCheckmate(false); gs.arrows=engine_arrows; + gs.promotion=promote_on; if(m){ // There should be a valid src_hl or dst_hl ortherwise it explode: std::string src_hl, dst_hl; diff --git a/src/game_tab/left_panel/GameTabLeftPanel.hpp b/src/game_tab/left_panel/GameTabLeftPanel.hpp index 8a40e38..4cc2cb6 100644 --- a/src/game_tab/left_panel/GameTabLeftPanel.hpp +++ b/src/game_tab/left_panel/GameTabLeftPanel.hpp @@ -14,6 +14,8 @@ class GameTabLeftPanel : public TabGameLeftPanel { bool repeat; HalfMove *last_move; std::vector engine_arrows; + std::string promote_on; + std::string promotion_move; public: GameTabLeftPanel(wxFrame *parent, std::shared_ptr game); @@ -21,7 +23,6 @@ public: void OnPlay(wxCommandEvent &event); void OnGotoMove(wxCommandEvent &event); void OnRefreshBoard(wxCommandEvent &event); - void OnPromote(wxCommandEvent &event); void ApplyPreferences(); void SetSaveToolEnable(bool state){game_toolbar->EnableTool(0,state);}; void SetEngineArrows(std::vector arrows); diff --git a/src/game_tab/left_panel/board/BoardCanvas.cpp b/src/game_tab/left_panel/board/BoardCanvas.cpp index 7f045f9..3b65e91 100644 --- a/src/game_tab/left_panel/board/BoardCanvas.cpp +++ b/src/game_tab/left_panel/board/BoardCanvas.cpp @@ -9,7 +9,6 @@ tmp=rot_m.TransformPoint(tmp); \ (PT).x+=xsrc;(PT).y+=ysrc;} wxDEFINE_EVENT(PLAY_MOVE_EVENT, wxCommandEvent); -wxDEFINE_EVENT(PLAY_PROMOTE, wxCommandEvent); BoardCanvas::BoardCanvas(wxFrame *parent) : wxPanel(parent), black_side(false), frozen(false), @@ -469,17 +468,16 @@ void BoardCanvas::MouseEvent(wxMouseEvent &event) { if((char)('a' + file)==gs.promotion[0]){ std::uint8_t prank=abs((int)gs.promotion[1]-(int)(char)('1' + rank)); if(prank<=3){ - wxLogDebug("%d",(int)prank); - wxCommandEvent event(PLAY_PROMOTE, GetId()); + wxCommandEvent event(PLAY_MOVE_EVENT, GetId()); event.SetEventObject(this); if(prank==1) - event.SetString("r"); + event.SetInt((int)'r'); else if(prank==2) - event.SetString("b"); + event.SetInt((int)'b'); else if(prank==3) - event.SetString("n"); + event.SetInt((int)'n'); else - event.SetString("q"); + event.SetInt((int)'q'); ProcessEvent(event); } } @@ -531,6 +529,7 @@ void BoardCanvas::MouseEvent(wxMouseEvent &event) { std::to_string(+active_square.y + 1) + ((char)('a' + file)) + std::to_string(rank + 1); event.SetString(move); + event.SetInt((int)'q'); // Promote to queen by default ProcessEvent(event); } else { // If square not valid just redraw (place piece back to its square) diff --git a/src/game_tab/left_panel/board/BoardCanvas.hpp b/src/game_tab/left_panel/board/BoardCanvas.hpp index efd917b..a7193f3 100644 --- a/src/game_tab/left_panel/board/BoardCanvas.hpp +++ b/src/game_tab/left_panel/board/BoardCanvas.hpp @@ -12,7 +12,6 @@ // Local events wxDECLARE_EVENT(PLAY_MOVE_EVENT, wxCommandEvent); -wxDECLARE_EVENT(PLAY_PROMOTE, wxCommandEvent); #define REFRESH_MOUSE_LOCATION() \ { \