Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Design: what would your objects be?

Author: Daniel Clausen

Date: 05:50:12 07/03/02

Go up one level in this thread


Hi

On July 03, 2002 at 06:46:40, Sune Fischer wrote:

>Did you describe your program or mine? :)
>Except for the Game class, which I call Tree class, then I recognize it all :)

Well, I also have a Tree class. :) But it is used during the search and contains
(beside the position) also the PV for the plies and stuff like that.


>There are a few things though, I'd like to hear how you've solved them.
>
>TimeControl() - do you have a special class for that, if so why, what should I
>do with a time object when I just need to pick the time?

I'm reworking this part at the moment and I'm not sure in which direction at the
moment. :) But what I have/keep for sure is a simple Clock class, which has
methods start() and passedTime().


>FirstOne() - to read the first bit off a bitboard, where should I put this
>when I don't have a BitBoard class (and I don't see how to make one)?

I have a bitboard class. :) The methods firstOne64, lastOne64 etc are just
static methods though. So I don't have to instantiate an object of type BitBoard
first. The bitboard class doesn't have a state (ie no instance variables) and
therefore I chose to make all methods static. This has the disadvantage that I
can't just make a subclass and overwrite the methods later, but I don't think I
want to do that anyhow. (Hi Murphy :)


>SetupMisc() - things like hash, killer and history tables, flags for
>communication  and all kinds of things. It doesn't really belong anywhere IMO.

I have such a method too (it's a method of the Tree class) but I dislike it very
much. And the vague name 'SetupMisc' suggests already, that it could be worth it
to think about the design here a bit. :) [the name I use is 'reset' which is not
really better, especially since it does not only initialize the tree.. :)]

The main reason for such a method in my case is the fact that I chose to use
static methods quite often. For example I have to reset counters like
'nPositionsSearched' before really searching. If the 'search algorithm' would be
a real object, I these counters would simply be member variables, which are
initialized in the constructor of the search algorithm object. IMHO the much
better design, but of course with a bit more ooverhead.


>isDraw() - checks for repetition (needs the Tree) and checks for material
>(needs the Board).

I don't check for repetition during search for the moment. :) I do have a
utility class which contains a method 'bool isDraw(const Board& board)' though.
The 'game driver object' uses this method.


>Should I make a special evaluation class, seems it would always and
>only depend on the Board.

I have an Evaluator class. (the method evaluate(const Board& board, int alpha,
int beta) is static) The method evaluate itself calls several static methods
again which don't belong to the public interface though. I want my board class
to only provide simple methods like 'toFEN()' and stuff like that.


>ProbeHash() - should the hash be an object, it needs a Board.

HashTable will be an object in my case. (with non-static methods) This way it's
easy to have multiple hashtable objects (maybe I want that later, maybe I don't)


>MakeMove is really more of a Board type function IMO, although it is also one
>of the things that will get stuck between two classes.

I have a seperate utility class (called MakeMove, a bad name I know) with static
methods for that.


>Then there are things such as reading from the book which requires knowledge
>of the Board or Tree, but shouldn't it have a class of its own when the book
>is a true object, albeit just a FILE pointer?

Can't comment on that yet, since my book-implementation is a quick
hack-implementation, nothing more.

>One of the things I always get stuck with in this OOP is that some things feel
>like they should be put into their own class, but there is never any use for
>an object of the class, other than to call those functions. For instance I
>have functions to make random numbers, to convert ASCII characters, that sort
>of simple things.

Feel free to make classes with only static methods. :) The class is 'only' used
as a namespace then, but that's ok in my book. As soon as you _do_ have state to
store though, it's dangerous.

Consider this for example:

class SearchAlgorith
{
   public:
      static move_t search(const Board& board, size_t depth);
      static ULONG  nPositionsSearched(void);

   private:
      static ULONG nPositionsSearched;
};

Now imagine what happens when you become multi-threaded in the search..

I see 2 solutions to this:

(a)
Use some kind of semaphore around the nPositionsSearched variable.

(b)
Use seperate SearchAlgorithm objects and add the nPositionsSearched at the end.

Solution (b) looks nicer/simpler to me.


>I wouldn't know what to do with a 'random' object, I just need the random
>number, not the object. It means I first must declare a random object
>to get a random number, pretty silly IMO.

Although my random generator has state, I chose to only have static methods. I
don't cosider this a problem since I only use it at startup and therefore don't
have a thread-problem. (Hi Murphy :)

Sargon



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.