Author: Bo Persson
Date: 03:14:27 08/01/03
Go up one level in this thread
On July 30, 2003 at 15:04:28, Russell Reagan wrote:
>On July 30, 2003 at 03:51:35, Bo Persson wrote:
>
>>The Piece class is of course just a wrapper around your int or enum. Using lots
>>of small inlined functions, you can get (at least) the same speed as with C,
>>while making the code much more readable.
>>
>>I very much prefer code like
>>
>>if (Piece.isKing())
>>if (Piece.isBlack())
>>
>>over
>>
>>if (Piece & KING_MASK)
>>if (!(Piece & COLOR_MASK))
>>
>>because I find it much more readable. You also get all the Piece access code in
>>one place, "piece.h". If you later find that your new compiler prefers "((Piece
>>& COLOR_MASK) == 0)", you can change that in your isBlack() function and be
>>done. Very convenient!
>
>I like that kind of code too, but I run into problems. For instance, what is
>your board? Usually I would use an array of int with enum values (wpawn, brook,
>empty, etc.), but a piece (in real world object terms) can't be "empty".
Of course it can be empty! The default constructor Piece() results in an empty
position.
> So now
>we have to create a square class and have pointers to pieces or something, and
>now we have to check pointers, and we are really just doing extra unneeded work
>for the sake of keeping everything an object.
My Square class doesn't hold pieces, but is used to index the board. The board
contains an array of pieces (and some bitmaps as an alternate representaion).
bool Board::isEmpty(Square) can be implemented as MyPieces[square] == Piece()
or you can have a
Piece Board::operator[](Square) and use
if (board[square] == Piece())
or add that to an isEmpty() function in the Piece class, to get
if (board[square].isEmpty())
All of this implemented as small inline functions, that the compiler can see
thru. A competent compiler, like MSVC or Intel C++, will do this at least as
well as accessing
global_array[someindex] & SOME_MASK
>
>What good is using an object model doing if it's slowing us down and causing us
>headache?
It doesn't have to be slower, and I actually get less of a headache when the
code is "pretty".
> I mentioned that the point of OOP was arriving at correct code, and
>probably if we struggled with this for a while we'd arrive back at the array of
>ints, which works very well, and is probably the simplest, fastest solution
>anyway. "Keep it simple" is something I've had a lot of trouble doing when
>trying to use OOP.
>
>
>>It can be very beneficial to hide the implementation, because then you can
>>change it if you find a better one later.
>
>Not if there is no later because you bang your head against the wall for so long
>trying to cram bitboards onto an object model that you've lost all life force :)
I have only been doing this for 20 years, so I wouldn't know. :-)
>
>
>>Other classes shouldn't care that much about how Board is organized. If they
>>want to know anything, they can ask the Board. :-) If it hasn't already got the
>>proper "question" to ask, you will have to write one *in the Board class* not in
>>the search or the move generator.
>
>Tell me, how is a MoveGenerator going to efficiently generate moves if it
>doesn't know the Board uses bitboards? I suppose we could create a kind of
>abstract "piece list" or "piece set" class, which could be implemented either as
>a bitboard or an array of pieces, but I think we digress here, creating extra
>work for the sake of keeping an object oriented approach.
Extra work for me or for the computer?
I haven't though of this explicitly of this before, but it seems like I treat
bitbards as piece set objects. Glad you asked!
The move generator is created with a reference (or is it a pointer?) to the
current position, a board class. It can then ask for UnmovedPieces to get
candidates for pieces to move (or rather the set of squares where these pieces
reside).
Then loop, something like
   while (!MovingPieces.isEmpty())
   {
      const Square FromSquare = MovingPieces.GetOne();
      BitBoard Targets = Board.AttacksFrom(FromSquare);
      Targets.RestrictTo(AllPieces(Opponent()));   // to get captures only
      while (!Targets.isEmpty())
      {
         const Square ToSquare = Targets.GetOne();
         MoveList.Add(FromSquare, ToSquare, etc.);
      }
   }
from the top of my head...
Bo Persson
bop2@telia.com
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.