app/puzzle_session.h¶
solving a tactics puzzle on the physical board
(docs/lichess-docs/PLAN.md §6).
Two things are load-bearing and easy to get wrong:
THE SESSION OWNS THE BOARD’S IDENTITY. It keeps a PieceTracker across puzzles, so the next puzzle’s setup is planned as a delta from where the pieces physically are (PLAN §4). A puzzle position is ~20-25 pick-and-places; resetting to the start between puzzles would make the feature unusably slow. This is also why solve() does not reset the board, and why the caller must tell the session the truth via prepare() or setBoardIdentity() if the pieces are ever moved behind its back.
THERE IS NO HINT PATH, BY CONSTRUCTION. Solving a Lichess puzzle on the board moves the player’s real Lichess puzzle rating, and Lichess forbids engine assistance. So this session takes no IHintSource — not one that is switched off, one that does not exist (PLAN §8). puzzle_session_test static_asserts that no such constructor can be added.
Pure: no HTTP, no Qt, no hardware. Runs against SimBackend in CTest.
-
namespace kirin
Enums
-
struct PuzzleResult¶
- #include <puzzle_session.h>
-
class PuzzleSession¶
- #include <puzzle_session.h>
Public Functions
-
PuzzleSession(IEngine &engine, IBoardBackend &backend)¶
-
~PuzzleSession()¶
-
PuzzleSession(const PuzzleSession&) = delete¶
-
PuzzleSession &operator=(const PuzzleSession&) = delete¶
-
void addListener(PuzzleSessionListener *listener)¶
-
void start()¶
-
void solve(const Puzzle &puzzle, const PuzzleSessionConfig &config = {})¶
-
void submitHumanMove(const std::string &uci)¶
-
void stop()¶
-
void shutdown()¶
-
inline PuzzleState state() const¶
-
void setBoardIdentity(const BoardIdentity &identity)¶
-
BoardIdentity boardIdentity() const¶
-
int pickNext(const std::vector<Puzzle> &batch, const PuzzleSessionConfig &config = {}) const¶
Private Functions
-
void run()¶
-
void solvePuzzle(const Puzzle&, const PuzzleSessionConfig&)¶
-
bool setUpPosition(const Puzzle&, const PuzzleSessionConfig&)¶
-
bool awaitCorrectSetup()¶
-
bool isSolverMoveCorrect(const Puzzle&, size_t ply, const HumanMoveResult&)¶
-
void commitMove(int encodedMove)¶
-
void setState(PuzzleState s)¶
-
void emitSetupBegan(int ops)¶
-
void emitSetupEnded(int ops, int elapsedMs)¶
-
void emitMismatch(const BoardMismatchInfo&)¶
-
void emitCorrect(const std::string &uci)¶
-
void emitWrong(const std::string &uci, const std::string &expected)¶
-
void emitReply(const std::string &uci)¶
-
void emitFinished(const PuzzleResult&)¶
-
void emitInfo(const std::string&)¶
-
void emitError(const std::string&)¶
Private Members
-
IBoardBackend &backend_¶
-
std::vector<PuzzleSessionListener*> listeners_¶
-
std::thread worker_¶
-
std::mutex cmdMutex_¶
-
std::condition_variable cmdCv_¶
-
std::atomic<bool> stopRequested_ = {false}¶
-
std::atomic<bool> shutdownRequested_ = {false}¶
-
std::atomic<PuzzleState> state_ = {PuzzleState::Idle}¶
-
mutable std::mutex identityMutex_¶
-
PieceTracker tracker_¶
Private Static Attributes
-
static constexpr int kMismatchPollMs = 500¶
-
struct Command¶
-
PuzzleSession(IEngine &engine, IBoardBackend &backend)¶
-
struct PuzzleSessionConfig¶
- #include <puzzle_session.h>
-
class PuzzleSessionListener¶
- #include <puzzle_session.h>
Subclassed by kirin::PuzzleLedAssist
Public Functions
-
virtual ~PuzzleSessionListener() = default¶
-
inline virtual void onStateChanged(PuzzleState)¶
-
inline virtual void onSetupBegan(int ops)¶
-
inline virtual void onSetupEnded(int ops, int elapsedMs)¶
-
inline virtual void onBoardMismatch(const BoardMismatchInfo&)¶
-
inline virtual void onCorrectMove(const std::string &uci)¶
-
inline virtual void onWrongMove(const std::string &uci, const std::string &expected)¶
-
inline virtual void onReply(const std::string &uci)¶
-
inline virtual void onPuzzleFinished(const PuzzleResult&)¶
-
inline virtual void onInfo(const std::string&)¶
-
inline virtual void onError(const std::string&)¶
-
virtual ~PuzzleSessionListener() = default¶
-
struct PuzzleResult¶