mirror of
https://gitlab.com/manzerbredes/ochess.git
synced 2025-04-07 02:26:29 +02:00
Add engine evaluation bar
This commit is contained in:
parent
5fac6bf7af
commit
9091232b60
8 changed files with 47 additions and 37 deletions
2
TODO.md
2
TODO.md
|
@ -11,7 +11,7 @@
|
||||||
- [x] Clean and debug DragNDrop in BoardCanvas
|
- [x] Clean and debug DragNDrop in BoardCanvas
|
||||||
|
|
||||||
## Additional Features
|
## 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] Be able to draw arrows on the Board
|
||||||
- [x] Highlight the last played move
|
- [x] Highlight the last played move
|
||||||
- [ ] Be able to play against an engine
|
- [ ] Be able to play against an engine
|
||||||
|
|
|
@ -30,7 +30,7 @@ GameTab::GameTab(wxFrame *parent, std::shared_ptr<Game> game)
|
||||||
Bind(GAME_CHANGE, &GameTab::OnGameChange, this, wxID_ANY);
|
Bind(GAME_CHANGE, &GameTab::OnGameChange, this, wxID_ANY);
|
||||||
Bind(SHOW_ENGINE_EVALUATION, [p=this](wxCommandEvent &event){
|
Bind(SHOW_ENGINE_EVALUATION, [p=this](wxCommandEvent &event){
|
||||||
EngineEvaluation *eval=(EngineEvaluation*)(event.GetClientData());
|
EngineEvaluation *eval=(EngineEvaluation*)(event.GetClientData());
|
||||||
p->board_panel->SetEngineArrows(eval->best_lines);
|
p->board_panel->SetEngineEvaluation(*eval);
|
||||||
free(eval);
|
free(eval);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ GameTabLeftPanel::GameTabLeftPanel(wxFrame *parent, std::shared_ptr<Game> game)
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameTabLeftPanel::OnPlay(wxCommandEvent &event) {
|
void GameTabLeftPanel::OnPlay(wxCommandEvent &event) {
|
||||||
|
engine_arrows.clear(); // Remove displayed engine arrows
|
||||||
std::string move=event.GetString().ToStdString();
|
std::string move=event.GetString().ToStdString();
|
||||||
int size=move.size();
|
int size=move.size();
|
||||||
char promote=(char)event.GetInt();
|
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
|
Notify(true); // Redraw event is move failed! Otherwise piece not resets to it initial position after dragging
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameTabLeftPanel::SetEngineArrows(std::vector<std::string> arrows){
|
void GameTabLeftPanel::SetEngineEvaluation(EngineEvaluation eval){
|
||||||
engine_arrows.clear();
|
engine_arrows.clear();
|
||||||
float scale=1;
|
float scale=1;
|
||||||
unsigned char color=0;
|
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 src=arrow.substr(0,2);
|
||||||
std::string dst=arrow.substr(2,2);
|
std::string dst=arrow.substr(2,2);
|
||||||
engine_arrows.push_back({src,dst,wxColour(color,color,color),scale});
|
engine_arrows.push_back({src,dst,wxColour(color,color,color),scale});
|
||||||
scale=std::max(0.1,scale-0.25);
|
scale=std::max(0.1,scale-0.25);
|
||||||
color=std::min(255,color+70);
|
color=std::min(255,color+70);
|
||||||
}
|
}
|
||||||
|
eval_cp=eval.eval;
|
||||||
Notify(true);
|
Notify(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,6 +138,8 @@ void GameTabLeftPanel::Notify(bool skip_animation) {
|
||||||
gs.mat_white=game->IsCheckmate(false);
|
gs.mat_white=game->IsCheckmate(false);
|
||||||
gs.arrows=engine_arrows;
|
gs.arrows=engine_arrows;
|
||||||
gs.promotion=promote_on;
|
gs.promotion=promote_on;
|
||||||
|
gs.show_evalbar=engine_arrows.size()>0;
|
||||||
|
gs.eval=eval_cp/100;
|
||||||
if(m){
|
if(m){
|
||||||
// There should be a valid src_hl or dst_hl ortherwise it explode:
|
// There should be a valid src_hl or dst_hl ortherwise it explode:
|
||||||
std::string src_hl, dst_hl;
|
std::string src_hl, dst_hl;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "board/BoardCanvas.hpp"
|
#include "board/BoardCanvas.hpp"
|
||||||
#include "ochess.hpp"
|
#include "ochess.hpp"
|
||||||
#include "base_tab/gamebase/GameBase.hpp"
|
#include "base_tab/gamebase/GameBase.hpp"
|
||||||
|
#include "game_tab/right_panel/LiveEngineDialog.hpp"
|
||||||
|
|
||||||
// Foreign events
|
// Foreign events
|
||||||
wxDECLARE_EVENT(GAME_CHANGE, wxCommandEvent);
|
wxDECLARE_EVENT(GAME_CHANGE, wxCommandEvent);
|
||||||
|
@ -16,6 +17,7 @@ class GameTabLeftPanel : public TabGameLeftPanel {
|
||||||
std::vector<GameState::Arrow> engine_arrows;
|
std::vector<GameState::Arrow> engine_arrows;
|
||||||
std::string promote_on;
|
std::string promote_on;
|
||||||
std::string promotion_move;
|
std::string promotion_move;
|
||||||
|
float eval_cp;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameTabLeftPanel(wxFrame *parent, std::shared_ptr<Game> game);
|
GameTabLeftPanel(wxFrame *parent, std::shared_ptr<Game> game);
|
||||||
|
@ -25,5 +27,5 @@ public:
|
||||||
void OnRefreshBoard(wxCommandEvent &event);
|
void OnRefreshBoard(wxCommandEvent &event);
|
||||||
void ApplyPreferences();
|
void ApplyPreferences();
|
||||||
void SetSaveToolEnable(bool state){game_toolbar->EnableTool(0,state);};
|
void SetSaveToolEnable(bool state){game_toolbar->EnableTool(0,state);};
|
||||||
void SetEngineArrows(std::vector<std::string> arrows);
|
void SetEngineEvaluation(EngineEvaluation eval);
|
||||||
};
|
};
|
|
@ -123,18 +123,7 @@ void BoardCanvas::ApplyPreferences() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoardCanvas::SetupBoard(const GameState &new_gs) {
|
void BoardCanvas::SetupBoard(const GameState &new_gs) {
|
||||||
gs.board = new_gs.board;
|
gs=new_gs;
|
||||||
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;
|
|
||||||
Refresh();
|
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
|
// Draw captures (+player names) first for white then for black
|
||||||
std::uint32_t captures_size = t_captures->GetPiecesSizes();
|
std::uint32_t captures_size = t_captures->GetPiecesSizes();
|
||||||
std::uint8_t padding = 10;
|
std::uint8_t padding = 10;
|
||||||
|
@ -452,6 +422,36 @@ void BoardCanvas::DrawBoard(wxDC &dc) {
|
||||||
offset++;
|
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) {
|
void BoardCanvas::MouseEvent(wxMouseEvent &event) {
|
||||||
|
|
|
@ -81,6 +81,8 @@ typedef struct GameState {
|
||||||
bool is_black_turn;
|
bool is_black_turn;
|
||||||
bool mat_black;
|
bool mat_black;
|
||||||
bool mat_white;
|
bool mat_white;
|
||||||
|
bool show_evalbar=false;
|
||||||
|
float eval=0;
|
||||||
ClockTime black_time={-1,-1,-1}, white_time={-1,-1,-1};
|
ClockTime black_time={-1,-1,-1}, white_time={-1,-1,-1};
|
||||||
} GameState;
|
} GameState;
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,8 @@ void LiveEngineDialog::OnTimerTick(wxTimerEvent &event) {
|
||||||
ids.push_back(line.first);
|
ids.push_back(line.first);
|
||||||
}
|
}
|
||||||
std::sort(ids.begin(),ids.end());
|
std::sort(ids.begin(),ids.end());
|
||||||
|
if(ids.size()>0)
|
||||||
|
eval->eval=lines[ids[0]].score_cp;
|
||||||
// Now fill eval and lines_list
|
// Now fill eval and lines_list
|
||||||
for (int &id:ids) {
|
for (int &id:ids) {
|
||||||
auto const &line=lines[id];
|
auto const &line=lines[id];
|
||||||
|
|
|
@ -9,6 +9,7 @@ wxDECLARE_EVENT(SHOW_ENGINE_EVALUATION, wxCommandEvent);
|
||||||
|
|
||||||
typedef struct EngineEvaluation {
|
typedef struct EngineEvaluation {
|
||||||
std::vector<std::string> best_lines;
|
std::vector<std::string> best_lines;
|
||||||
|
float eval=0;
|
||||||
} EngineEvaluation;
|
} EngineEvaluation;
|
||||||
|
|
||||||
class LiveEngineDialog : public DialogLiveEngine {
|
class LiveEngineDialog : public DialogLiveEngine {
|
||||||
|
|
Loading…
Add table
Reference in a new issue