Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: A question about varaibles that I should give to functions in C++

Author: Hristo

Date: 03:38:30 08/01/04

Go up one level in this thread


On August 01, 2004 at 06:12:03, Gerd Isenberg wrote:

>On August 01, 2004 at 01:07:10, Uri Blass wrote:
>
>>My code until today used a lot of global varaibles and I decided based on advice
>>of Dann Corbit to use a class for time management.
>>
>>I have a many varaibles in class for time management and
>>I hesitate which parameters to give to the functions.
>>
>>I will give an example:
>>
>>I want to have a procedure to update the remaining number of moves to the time
>>control in the beginning of every search(this varaible is used for other
>>varaibles like the target time.
>>
>>The procedure is using the following varaibles:
>>1)num_moves_1(number of moves in the first time control)
>>2)num_moves_2(number of moves in the second time control)
>>3)num_moves_3(number of moves in the third time control)
>>4)hply(history ply of the game)
>>
>>I think to call the procedure not inside the class so it cannot get directly
>>num_moves_1 or num_moves_2 or num_moves_3
>>
>>I can write seperate functions to return num_moves_1 inside the class and use
>>these functions outside of the class but I am not sure if it is a good idea(no
>>experience in C++).
>>
>>Another possibility is not to give the functions the parameters of
>>num_moves_1,num_moves_2,num_moves_3 because their value is known inside the
>>class so it is not needed.
>>
>>What do you suggest?
>>
>>Uri
>
>Hi Uri,
>
>yes, putting time control variables and services into a struct/class is a good
>idea.
>
>Basically you hide your n num_moves and n times_to_num_moves, which got
>initialized at construction time or via some setters with appropriate
>parameters.
>
>I suggest not to keep track of elapsed time and history of the game inside this
>class, but to have a memberfunction with hply and elapsed time parameter to get
>the average and maximum thinking time (or some vector of suggested times for
>different cases incapsulated in some other class) for the next move.
>
>For most programs it is fine to have a single object for that, therefore you can
>choose static class variables as well as static members (dynamic size is 0) -
>and you don't need to construct such a singleton object as either a global, or
>via new on the heap or as a local variable on the stack, it acts more like a
>namespace:
>
>// static class
>class CTimeControl
>{
>   enum {MAX_CONTROLS = 4};
>   enum MODES {BLITZ, TOURNAMENT1, ...};
>protected:
>   static MODES m_Mode;
>   static int m_Num_moves[MAX_CONTROLS];
>   static int m_Times_to_num_moves, [MAX_CONTROLS];
>   ...
>public: // interface
>   static void setBlitz(...);
>   static int setTournament(int nControls,.. );
>   static MODES getMode(...);
>   ...
>   static int getAverageTimeForNextMove(int nMovesPlays, Time ellapsed);
>   static int getMaxTimeForNextMove(int nMovesPlays, Time ellapsed);
>   ...
>};
>
>// with explicit implementation and initialization of
>//  the static data members in some c++ file
>int CTimeControl::m_Mode = CTimeControl::BLITZ;
>int CTimeControl::m_Num_moves[MAX_CONTROLS] = {40,20,20,20};
>int CTimeControl::m_Times_to_num_moves[MAX_CONTROLS]= {60*120,60*60,30*60,5*60};
>
>
>A statefull game object (or a sub-object of it) keeps track of moves played and
>time ellapsed. It is also responsible to control the associated search.
>
>Of course there are many other solutions, but it may be a simple way to start
>and to delegate the getTimeForMove to some central instance.
>

Gerd,
by making everything static, you have essentially added a namespace to a bunch
of "C" functions. ;-)

Another approach to handling time could be the usage of an interface and
instances of specialized classes. For instance;

/** interface class. Basically defines what all TimeControls objects should be
able to do. */
class TimeControl{
public:
  TimeControl(){}
  virtual ~TimeControl(){}
  /**
   * Interface function, which has to be implemented in the specialized classes.
   */

  /** Start the time */
  virtual void start() = 0;
  /** pause the time */
  virtual void pause() = 0;

  /**
   * Allow the specific time implementation determine whether a move should be
made ASAP.
   * This where the logic pertaining to different time modes can be implemented.
   */
   virtual shoudMoveNow() = 0;
  /**
    * Inform the object that a move was made.
    */
  virtual void moved() = 0;
};

Then you can implement different version of this class.

class BlitzTimeControl: public TimeControl{
... /* implement the pure virtual functions here. */
};

class RegularTimeControl: public TimeControl{
... /* implement the pure virtual functions here. */
};


Then, in your engine, you can use just the TimeControl interface.


void evaluate(TimeControl* tc, Other variables ){
  ...
  if (tc->shouldMoveNow()){
    makeMove();
    tc->moved();
  }
}


The only place where you would worry (check) for the type of game-time-control
is going to be your game initialization code, where you would instantiate the
appropriate Time Control object.

Regards,
Hristo


>Gerd



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.