From 9091232b609de875894379b3903b555c0a53957e Mon Sep 17 00:00:00 2001 From: Loic Guegan Date: Wed, 11 Jan 2023 10:46:14 +0100 Subject: [PATCH] Add engine evaluation bar --- TODO.md | 2 +- src/game_tab/GameTab.cpp | 2 +- src/game_tab/left_panel/GameTabLeftPanel.cpp | 8 ++- src/game_tab/left_panel/GameTabLeftPanel.hpp | 4 +- src/game_tab/left_panel/board/BoardCanvas.cpp | 62 +++++++++---------- src/game_tab/left_panel/board/BoardCanvas.hpp | 2 + src/game_tab/right_panel/LiveEngineDialog.cpp | 3 +- src/game_tab/right_panel/LiveEngineDialog.hpp | 1 + 8 files changed, 47 insertions(+), 37 deletions(-) diff --git a/TODO.md b/TODO.md index 182605b..469f3b3 100644 --- a/TODO.md +++ b/TODO.md @@ -11,7 +11,7 @@ - [x] Clean and debug DragNDrop in BoardCanvas ## Additional Features - - [ ] Add a live evaluation bar to the BoardCanvas + - [x] Add a live evaluation bar to the BoardCanvas - [x] Be able to draw arrows on the Board - [x] Highlight the last played move - [ ] Be able to play against an engine diff --git a/src/game_tab/GameTab.cpp b/src/game_tab/GameTab.cpp index def90f8..ef71048 100644 --- a/src/game_tab/GameTab.cpp +++ b/src/game_tab/GameTab.cpp @@ -30,7 +30,7 @@ GameTab::GameTab(wxFrame *parent, std::shared_ptr game) Bind(GAME_CHANGE, &GameTab::OnGameChange, this, wxID_ANY); Bind(SHOW_ENGINE_EVALUATION, [p=this](wxCommandEvent &event){ EngineEvaluation *eval=(EngineEvaluation*)(event.GetClientData()); - p->board_panel->SetEngineArrows(eval->best_lines); + p->board_panel->SetEngineEvaluation(*eval); free(eval); }); } diff --git a/src/game_tab/left_panel/GameTabLeftPanel.cpp b/src/game_tab/left_panel/GameTabLeftPanel.cpp index cfe0de8..5a1ae44 100644 --- a/src/game_tab/left_panel/GameTabLeftPanel.cpp +++ b/src/game_tab/left_panel/GameTabLeftPanel.cpp @@ -60,6 +60,7 @@ GameTabLeftPanel::GameTabLeftPanel(wxFrame *parent, std::shared_ptr game) } void GameTabLeftPanel::OnPlay(wxCommandEvent &event) { + engine_arrows.clear(); // Remove displayed engine arrows std::string move=event.GetString().ToStdString(); int size=move.size(); char promote=(char)event.GetInt(); @@ -84,17 +85,18 @@ void GameTabLeftPanel::OnPlay(wxCommandEvent &event) { Notify(true); // Redraw event is move failed! Otherwise piece not resets to it initial position after dragging } -void GameTabLeftPanel::SetEngineArrows(std::vector arrows){ +void GameTabLeftPanel::SetEngineEvaluation(EngineEvaluation eval){ engine_arrows.clear(); float scale=1; unsigned char color=0; - for(auto const &arrow:arrows){ + for(auto const &arrow: eval.best_lines){ std::string src=arrow.substr(0,2); std::string dst=arrow.substr(2,2); engine_arrows.push_back({src,dst,wxColour(color,color,color),scale}); scale=std::max(0.1,scale-0.25); color=std::min(255,color+70); } + eval_cp=eval.eval; Notify(true); } @@ -136,6 +138,8 @@ void GameTabLeftPanel::Notify(bool skip_animation) { gs.mat_white=game->IsCheckmate(false); gs.arrows=engine_arrows; gs.promotion=promote_on; + gs.show_evalbar=engine_arrows.size()>0; + gs.eval=eval_cp/100; 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 4cc2cb6..d438dc6 100644 --- a/src/game_tab/left_panel/GameTabLeftPanel.hpp +++ b/src/game_tab/left_panel/GameTabLeftPanel.hpp @@ -4,6 +4,7 @@ #include "board/BoardCanvas.hpp" #include "ochess.hpp" #include "base_tab/gamebase/GameBase.hpp" +#include "game_tab/right_panel/LiveEngineDialog.hpp" // Foreign events wxDECLARE_EVENT(GAME_CHANGE, wxCommandEvent); @@ -16,6 +17,7 @@ class GameTabLeftPanel : public TabGameLeftPanel { std::vector engine_arrows; std::string promote_on; std::string promotion_move; + float eval_cp; public: GameTabLeftPanel(wxFrame *parent, std::shared_ptr game); @@ -25,5 +27,5 @@ public: void OnRefreshBoard(wxCommandEvent &event); void ApplyPreferences(); void SetSaveToolEnable(bool state){game_toolbar->EnableTool(0,state);}; - void SetEngineArrows(std::vector arrows); + void SetEngineEvaluation(EngineEvaluation eval); }; \ No newline at end of file diff --git a/src/game_tab/left_panel/board/BoardCanvas.cpp b/src/game_tab/left_panel/board/BoardCanvas.cpp index 3b65e91..97ca3ad 100644 --- a/src/game_tab/left_panel/board/BoardCanvas.cpp +++ b/src/game_tab/left_panel/board/BoardCanvas.cpp @@ -123,18 +123,7 @@ void BoardCanvas::ApplyPreferences() { } void BoardCanvas::SetupBoard(const GameState &new_gs) { - gs.board = new_gs.board; - gs.is_black_turn = new_gs.is_black_turn; - gs.captures = new_gs.captures; - gs.white=new_gs.white; - gs.black=new_gs.black; - gs.mat_white=new_gs.mat_white; - gs.mat_black=new_gs.mat_black; - gs.black_time=new_gs.black_time; - gs.white_time=new_gs.white_time; - gs.squares_hl=new_gs.squares_hl; - gs.arrows=new_gs.arrows; - gs.promotion=new_gs.promotion; + gs=new_gs; Refresh(); } @@ -286,25 +275,6 @@ void BoardCanvas::DrawBoard(wxDC &dc) { } } - // Draw badge - dc.SetPen(wxPen(*wxBLACK, 3)); - std::uint32_t badgeY = boardY; - std::uint32_t badgeWidth = square_width / 2; - if (gs.is_black_turn) { - dc.SetBrush(*wxBLACK_BRUSH); - if (black_side) { - badgeY = boardY + (8 * square_width) - badgeWidth; - } - } else { - dc.SetBrush(*wxWHITE_BRUSH); - if (!black_side) { - badgeY = boardY + (8 * square_width) - badgeWidth; - } - } - wxRect badge(boardX + (8 * square_width) + badgeWidth/2, badgeY, badgeWidth, - badgeWidth); - dc.DrawRectangle(badge); - // Draw captures (+player names) first for white then for black std::uint32_t captures_size = t_captures->GetPiecesSizes(); std::uint8_t padding = 10; @@ -452,6 +422,36 @@ void BoardCanvas::DrawBoard(wxDC &dc) { offset++; } } + + // Draw engine evaluation bar + if(gs.show_evalbar){ + short w=35,p=20,range=20,border=8; + short bar_height=8*square_width-2*border; + float visible_px=10; // Part of the bar that will always be visible no matter the evaluation + float eval=gs.eval; + float eval_norm=range/2+std::min(std::max((-(float)range/2),eval),(float)range/2); + float evalbar_height=(eval_norm/(float)range)*bar_height; + evalbar_height=std::min(std::max(visible_px,evalbar_height),bar_height-visible_px); + wxLogDebug("%f",((float)eval_norm/(float)(range/2))); + dc.SetPen(wxNullPen); + dc.SetBrush(*wxBLACK_BRUSH); + dc.DrawRectangle(wxRect(boardX+8*square_width+p,boardY,w,8*square_width)); + dc.SetBrush(*wxWHITE_BRUSH); + if(!black_side){ + dc.DrawRectangle(wxRect(boardX+8*square_width+p+border,boardY+border+bar_height-evalbar_height,w-2*border,evalbar_height)); + }else { + dc.DrawRectangle(wxRect(boardX+8*square_width+p+border,boardY+border,w-2*border,evalbar_height)); + } + // Convert eval to string: + char buffer[20]; // maximum expected length of the float + std::snprintf(buffer, 20, "%.1f", eval); + wxString evalstr(buffer); + if(eval>0) + evalstr="+"+evalstr; + + wxSize evalstr_size=dc.GetTextExtent(evalstr); + dc.DrawText(evalstr,boardX+8*square_width+p+(w/2-evalstr_size.x/2),boardY-evalstr_size.y); + } } void BoardCanvas::MouseEvent(wxMouseEvent &event) { diff --git a/src/game_tab/left_panel/board/BoardCanvas.hpp b/src/game_tab/left_panel/board/BoardCanvas.hpp index a7193f3..e7f28dd 100644 --- a/src/game_tab/left_panel/board/BoardCanvas.hpp +++ b/src/game_tab/left_panel/board/BoardCanvas.hpp @@ -81,6 +81,8 @@ typedef struct GameState { bool is_black_turn; bool mat_black; bool mat_white; + bool show_evalbar=false; + float eval=0; ClockTime black_time={-1,-1,-1}, white_time={-1,-1,-1}; } GameState; diff --git a/src/game_tab/right_panel/LiveEngineDialog.cpp b/src/game_tab/right_panel/LiveEngineDialog.cpp index 2413d0b..64d75e3 100644 --- a/src/game_tab/right_panel/LiveEngineDialog.cpp +++ b/src/game_tab/right_panel/LiveEngineDialog.cpp @@ -112,7 +112,8 @@ void LiveEngineDialog::OnTimerTick(wxTimerEvent &event) { ids.push_back(line.first); } std::sort(ids.begin(),ids.end()); - + if(ids.size()>0) + eval->eval=lines[ids[0]].score_cp; // Now fill eval and lines_list for (int &id:ids) { auto const &line=lines[id]; diff --git a/src/game_tab/right_panel/LiveEngineDialog.hpp b/src/game_tab/right_panel/LiveEngineDialog.hpp index 69e3af1..fa4ea83 100644 --- a/src/game_tab/right_panel/LiveEngineDialog.hpp +++ b/src/game_tab/right_panel/LiveEngineDialog.hpp @@ -9,6 +9,7 @@ wxDECLARE_EVENT(SHOW_ENGINE_EVALUATION, wxCommandEvent); typedef struct EngineEvaluation { std::vector best_lines; + float eval=0; } EngineEvaluation; class LiveEngineDialog : public DialogLiveEngine {