How do I model a chessboard when programming a computer to play chess?

后端 未结 14 2281
夕颜
夕颜 2021-01-31 10:13

What data structures would you use to represent a chessboard for a computer chess program?

相关标签:
14条回答
  • 2021-01-31 10:31
    int[8][8]
    
    0=no piece
    1=king
    2=queen
    3=rook
    4=knight
    5=bishop
    6=pawn
    

    use positive ints for white and negative ints for black

    0 讨论(0)
  • 2021-01-31 10:31

    I actually wouldn't model the chess board, I'd just model the position of the pieces. You can have bounds for the chess board then.

    Piece.x= x position of piece
    Piece.y= y position of piece
    
    0 讨论(0)
  • 2021-01-31 10:35

    Using a bitboard would be an efficient way to represent the state of a chess board. The basic idea is that you use 64bit bitsets to represent each of the squares on the board, where first bit usually represents A1 (the lower left square), and the 64th bit represents H8 (the diagonally opposite square). Each type of piece (pawn, king, etc.) of each player (black, white) gets its own bit board and all 12 of these boards makes up the game state. For more information check out this Wikipedia article.

    0 讨论(0)
  • 2021-01-31 10:36

    I would use a multidimensional array so that each element in an array is a grid reference to a square on the board.

    Thus

    board = arrary(A = array (1,2,3,4,5,5,6,7,8),
                   B = array (12,3,.... etc...
                   etc...          
                   )
    

    Then board[A][1] is then the board square A1.

    In reality you would use numbers not letters to help keep your maths logic for where pieces are allowed to move to simple.

    0 讨论(0)
  • 2021-01-31 10:40

    An alternative to the standard 8x8 board is the 10x12 mailbox (so-called because, uh, I guess it looks like a mailbox). This is a one-dimensional array that includes sentinels around its "borders" to assist with move generation. It looks like this:

    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, "a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8", -1,
    -1, "a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7", -1,
    -1, "a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6", -1,
    -1, "a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5", -1,
    -1, "a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4", -1,
    -1, "a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3", -1,
    -1, "a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2", -1,
    -1, "a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1", -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
    

    You can generate that array like this (in JavaScript):

    function generateEmptyBoard() {
        var row = [];
        for(var i = 0; i < 120; i++) {
            row.push((i < 20 || i > 100 || !(i % 10) || i % 10 == 9) 
                ? -1 
                : i2an(i));
        }
        return row;
    }
    
    // converts an index in the mailbox into its corresponding value in algebraic notation
    function i2an(i) {
        return "abcdefgh"[(i % 10) - 1] + (10 - Math.floor(i / 10));
    }
    

    Of course, in a real implementation you'd put actual piece objects where the board labels are. But you'd keep the negative ones (or something equivalent). Those locations make move generation a lot less painful because you can easily tell when you've run off the board by checking for that special value.

    Let's first look at generating the legal moves for the knight (a non-sliding piece):

    function knightMoves(square, board) {
        var i = an2i(square);
        var moves = [];
        [8, 12, 19, 21].forEach(function(offset) {
            [i + offset, i - offset].forEach(function(pos) {
                // make sure we're on the board
                if (board[pos] != -1) {
                    // in a real implementation you'd also check whether 
                    // the squares you encounter are occupied
                    moves.push(board[pos]);
                }
            });
        });
        return moves;
    }
    
    // converts a position in algebraic notation into its location in the mailbox
    function an2i(square) {
        return "abcdefgh".indexOf(square[0]) + 1 + (10 - square[1]) * 10;
    }
    

    We know that the valid Knight moves are a fixed distance from the piece's starting point, so we only needed to check that those locations are valid (i.e. not sentinel squares).

    The sliding pieces aren't much harder. Let's look at the bishop:

    function bishopMoves(square, board) {
        var oSlide = function(direction) {
            return slide(square, direction, board);
        }
        return [].concat(oSlide(11), oSlide(-11), oSlide(9), oSlide(-9)); 
    }
    
    function slide(square, direction, board) {
        var moves = [];
        for(var pos = direction + an2i(square); board[pos] != -1; pos += direction) {
            // in a real implementation you'd also check whether 
            // the squares you encounter are occupied
            moves.push(board[pos]);
        }
        return moves;
    }
    

    Here are some examples:

    knightMoves("h1", generateEmptyBoard()) => ["f2", "g3"]
    bishopMoves("a4", generateEmptyBoard()) => ["b3", "c2", "d1", "b5", "c6", "d7", "e8"]
    

    Note that the slide function is a general implementation. You should be able to model the legal moves of the other sliding pieces fairly easily.

    0 讨论(0)
  • 2021-01-31 10:41

    Initially, use an 8 * 8 integer array to represent the chess board.

    You can start programing using this notation. Give point values for the pieces. For example:

    **White**
    9 = white queen
    5 = white rook
    3 = bishop
    3 = knight
    1 = pawn
    
    **black**
    -9 = white queen
    -5 = white rook
    -3 = bishop
    -3 = knight
    -1 = pawn
    
    White King: very large positive number
    Black King: very large negative number
    

    etc. (Note that the points given above are approximations of trading power of each chess piece)

    After you develop the basic backbones of your application and clearly understand the working of the algorithms used, try to improve the performance by using bit boards.

    In bit boards, you use eight 8 -bit words to represent the boards. This representation needs a board for each chess piece. In one bit board you will be storing the position of the rook while in another you will be storing the position of the knight... etc

    Bit boards can improve the performance of your application very much because manipulating the pieces with bit boards are very easy and fast.

    As you pointed out,

    Most chessprograms today, especially those that run on a 64 bit CPU, use a bitmapped approach to represent a chessboard and generate moves. x88 is an alternate board model for machines without 64 bit CPUs.

    0 讨论(0)
提交回复
热议问题