面向对象设计的国际象棋引擎

我想用面向对象的想法设计一个象棋引擎作为练习。 目前,我的国际象棋引擎大多是程序性编写的,我很难从对象的角度思考国际象棋引擎(决定接下来做哪一步的过程似乎并不基于'真实生活对象'尽可能多的例子是)目前我想到的设计是:

为了做出决定,发动机将需要一个位置,合法的动作,并能够进行分析未来排列的动作。 所以

  • 该位置具有法定移动集合和基于位置的分数

  • 人工智能“大脑”可以进入一个位置,并能够对其位置进行理论上的移动

  • 电脑播放器有一个位置以及决定最佳移动的“大脑”

  • 我正沿着正确的轨道走吗? 一般来说,如何设计类似于国际象棋引擎的东西,以面向对象的方式进行设计?


    我不完全确定你的问题,但希望这可以推动你朝着正确的方向前进。

    你需要的是:

  • 董事会(代表64个领域和其余的部分)
  • 件(更简单的类型是首选,由于性能,fx枚举会做)
  • 移动(件移动,旧领域,新领域和新领域的内容)
  • MoveGenerator(为了在给定的电路板实例上生成可能的移动)
  • StaticValueGenerator(为白色或黑色视角生成给定电路板实例的值)
  • 您可以将您的电路板表示为二维数组,这使得坐标读取容易,但性能可怕。 如果你仍然希望它易于眼睛,一维数组是更有效的选择。 示例如下:

    public class Board
    {
        ///<summary>Chess board</summary>
        /// 0  1  2  3  4  5  6  7
        /// 8  9  10 11 12 13 14 15
        /// 16 17 18 19 20 21 22 23
        /// 24 25 26 27 28 29 30 31
        /// 32 33 34 35 36 37 38 39
        /// 40 41 42 43 44 45 46 47
        /// 48 49 50 51 52 53 54 55
        /// 56 57 58 59 60 61 62 63
        public Piece[] Pieces;
    
        //Is it white or blacks turn?
        public bool IsWhiteTurn { get; set; }
    
        public Piece GetField(int index)
        {
            return Pieces[index];
        }
    
        public Board CopyBoardAndDoMove(Move m)
        {
           //todo
        }
    }
    

    碎片可以像这样表示:

    public enum Piece 
    {
        Empty =0,
    
        WhitePawn = 1,
        WhiteRook = 2,
        WhiteKnight = 3,
        WhiteBishop = 4,
        WhiteQueen = 5,
        WhiteKing =6,
    
        BlackPawn = -1,
        BlackRook = -2,
        BlackKnight = -3,
        BlackBishop = -4,
        BlackQueen = -5,
        BlackKing = -6
    }
    

    移动可以像这样表示:

    public class SimpleMoveType
    {
        public SimpleMoveType(Piece chessPiece, Piece content, int oldField, int newField, SpecialMoves special = SpecialMoves.None)
        {
            ChessPiece = chessPiece;
            Content = content;
            NewField = newField;
            OldField = oldField;
            Special = special;
        }
    
        //The Piece to move
        public Piece ChessPiece { get; set; }
    
        //The Piece in the new field, if any.
        public Piece Content { get; set; }
    
        //index of new field
        public int NewField { get; set; }
    
        //index of old field
        public int OldField { get; set; }
    
        //Special move like promotion, castling effects the Piece or other pieces
        //In case it's a special move, we need this info to apply the move to the Board.
        public SpecialMoves Special { get; set; }
    }
    
    public enum SpecialMoves
    {
        None = 0,
        EnPassant,
        PawnTwoStepStart, //When a pawn makes its fist move it can move to fields forward
        Promotion,
        CastlingKingSide,
        CastlingQueenSide,
    
        PromotionKnight,
        PromotionBishop,
        PromotionRook
    }
    

    那么你将需要一个移动发生器。 在你进行任何进一步工作之前,你必须决定你是否想要合法或合法的合法行动。 法律行为是一个痛苦的执行,但sodu法律行动可能真的很难调试和发现问题。 相信我,这在前10次尝试中并不完美。

    移动生成器应该是这样的:

    public class MoveGenerator : IMoveGenerator
    {
        private readonly IMoveContainer _moveContainer;
    
        public MoveGenerator(IMoveContainer moveContainer)
        {
            _moveContainer = moveContainer;
        }
    
        public List<SimpleMoveType> GetPsoudoLegalMoves(SimpleBoard b)
        {
            var moves = new List<SimpleMoveType>();
            var white = b.White;
    
            for (int i = 0; i < 64; i++)
            {
                moves.AddRange(GetMoves(i, b, white);
            }
    
            return moves;
        }
    
        private List<SimpleMoveType> GetMove(int indexBoardPosition, Board b, bool isWhiteTurn)
        {
            //TODO
        }
    }
    

    现在是游戏逻辑(“大脑”)。 AI应该是min-max或alpha beta搜索树实现。 叶子是板子。 每一个可能的举动都会产生一个新的叶子(板)。 应该计算棋盘的价值,关于应该做下一步棋的棋手(黑色或白色)。

    静态值可以用多种方式计算。 一个简单的方法是让你的作品指向棋盘上的位置,并为棋子赋予价值。 如果一块棋子丢失了,棋盘的价值就会下降。 是一个对手拍摄,你的董事会将获得价值。

    件数的例子:

    国王10.000(如果棋盘上的任何东西都加起来,如果比赛结束了)

    女王900

    塔500

    主教300

    骑士300

    典当100

    这个职位的价值可以由Kaare Danielsen从这些表中计算出来: 在这里输入图像描述

    国际象棋程序设计是一个很大的项目,所以我建议看看这个wiki。 我建议在移动生成器中添加一些很好的单元测试。 这是项目第一阶段错误的首要原因。 我基于perft结果实施了很多测试,并为我吸引了很多bug。

    玩的开心 :)


    这个位置看起来更像是一名球员的状态。 我会有一个棋盘对象,其状态是棋子的放置位置,以及只允许有效移动的方法。 玩家对象都可以访问棋盘并可以评估他们的位置和移动。 玩家的控制器可以是AI大脑或用户输入的GUI。

    链接地址: http://www.djcxy.com/p/84653.html

    上一篇: Object orientated design for chess engine

    下一篇: Connect Chess Engine with C++ GUI Program