Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: eval() in or out of board structure?

Author: Russell Reagan

Date: 13:09:08 02/13/04

Go up one level in this thread


On February 13, 2004 at 15:04:31, Anthony Cozzie wrote:

>However, your board structure is at the heart of everything you do -
>make/unmake, eval, movegen, search, everything.  You are simply not going to be
>able to abstract this away without a _large_ performance hit.

A point of clarification: "using classes" does not always mean "modular". Using
a class to represent the chess board shouldn't need to cause any overhead at
all. The main purpose of a chess board class, IMO, is to maintain the validity
of the private data. Speicifically, the board should match up with the piece
lists or bitboards.

I am talknig about encapsulation, while I think you are talking about
modularity. I confused the two for a long time, and I agree that if you try to
make everything completely modular, you can take on huge performance hits.

For chess, I say throw modularity out the window for the most part. Modularity
is where you treat each object like a black box. The philosophy that objects
shouldn't know how other objects are implemented. That's a nice idea, but it
doesn't work very well in a chess program. Imagine if your chess board knew
nothing about squares, pieces, colors, castling rights, moves, and so on. You
could make it work, but it would be way slow with virtually no added benefit.

Encapsulation on the other hand is just creating a class to act as a manager.
The class makes sure things get initialized correctly, and that you as the
programmer can't do nasty or stupid things easily to invalidate the private
data. It's okay if you know that the board class uses bitboards internally, and
even if you have member functions that return bitboards like white_pawns() or
enemy_knights(int color). The point of encapsulation in that case is to make
sure you can't modify the white_pawns bitboard whenever you'd like (or on
accident).

class board
{
private:
public:
    // board gets initialized
    board ();

    // board only gets modified here
    void make_move(move m);
    void undo_move(move m);

    // accessor member functions
    const piece & operator [] (square s);

    // if you want bitboards...
    bitboard pawns (color c);
    bitboard knights (color c);
    bitboard all_pieces ();
    bitboard rotated90();
    // ...
};

All of this will get inlined so there is no overhead vs. using a struct for
this, plus you can do error checking internally in a debug build if you want.
This way you can still do if (board[i] == white_pawn), but you can't do if
(board[i] = white_pawn). If you mistype, the compiler will complain about you
modifying a const variable and your data will still be valid (piece lists will
match up with the board). If you just use an array for the board, you just
invalidated the board because now board[i] has a white_pawn on it, but there no
white_pawn in the piece list for square i.



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.