게시판장기로 이해하는 규칙 엔진과 평가 함수 탐색예제 소스

예제 소스

장기로 이해하는 규칙 엔진과 평가 함수 탐색 · 파일 59개

Game.h

#pragma once

#include "Types.h"

#include <array>
#include <optional>
#include <string>
#include <vector>

class Game {
public:
    Game();

    void newGame(Formation cho, Formation han);
    // 임의 국면 설정 (기보 분석용). 이전 수순/반복 기록은 비움
    void setPosition(const std::array<Piece, 90>& squares, Side toMove);

    Piece at(Pos p) const;
    Side sideToMove() const { return sideToMove_; }
    GameResult result() const { return result_; }
    bool bikjangEnabled() const { return bikjangEnabled_; }
    void setBikjangEnabled(bool enabled) { bikjangEnabled_ = enabled; }
    // 같은 국면 허용 횟수. 0 이하이면 반복 금지 규칙을 쓰지 않음
    void setRepetitionLimit(int limit) { repetitionLimit_ = limit; }

    std::vector<Move> legalMoves() const;
    std::vector<Pos> legalTargets(Pos from) const;
    bool tryMove(Pos from, Pos to);
    bool passTurn();
    bool resign(Side side);
    bool claimBikjang();
    bool undo();

    bool isCheck(Side side) const;
    bool isBikjang() const;
    Pos kingPos(Side side) const;
    std::optional<Move> lastMove() const;
    const std::vector<Move>& history() const { return history_; }

    int pieceScore(Side side) const;
    std::vector<Piece> capturedBy(Side side) const;

    std::string moveText(const Move& move) const;

    // AI 탐색용: 이미 합법으로 검증된 수만 적용
    void applyTrusted(const Move& move);
    void finishTurn();

private:
    Piece& ref(Pos p);
    const Piece& ref(Pos p) const;

    void clear();
    void placeFormation(Side side, Formation formation);
    void recomputeKings();

    std::vector<Move> pseudoMoves(Side side) const;
    void addPieceMoves(Pos from, Piece piece, std::vector<Move>& out) const;
    void addKingAdvisorMoves(Pos from, Piece piece, std::vector<Move>& out) const;
    void addChariotMoves(Pos from, Piece piece, std::vector<Move>& out) const;
    void addCannonMoves(Pos from, Piece piece, std::vector<Move>& out) const;
    void addHorseMoves(Pos from, Piece piece, std::vector<Move>& out) const;
    void addElephantMoves(Pos from, Piece piece, std::vector<Move>& out) const;
    void addPawnMoves(Pos from, Piece piece, std::vector<Move>& out) const;
    void addSliderOnLine(Pos from, Piece piece, const std::array<Pos, 3>& line, bool cannon,
                         std::vector<Move>& out) const;

    void pushMove(Pos from, Pos to, Piece piece, std::vector<Move>& out) const;
    bool attacks(Pos target, Side attacker) const;
    bool onPalaceDiagonalStep(Pos a, Pos b) const;
    std::string positionKey() const;
    int repetitionCount(const std::string& key) const;
    bool isForbiddenRepetition() const;

    std::array<Piece, 90> squares_{};
    Side sideToMove_ = Side::Cho;
    GameResult result_ = GameResult::Playing;
    Pos choKing_{4, 8};
    Pos hanKing_{4, 1};
    std::vector<Move> history_;
    std::vector<Piece> capturedCho_;  // 초가 잡은 말
    std::vector<Piece> capturedHan_;
    bool bikjangEnabled_ = true;
    int repetitionLimit_ = 3;
    int consecutivePasses_ = 0;
    std::vector<std::string> positionKeys_;  // 시작 국면 + 매 수 이후
};