Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: c++ code question

Author: Hristo

Date: 22:23:36 11/24/03

Go up one level in this thread


On November 25, 2003 at 00:05:16, Russell Reagan wrote:

>On November 24, 2003 at 23:55:47, macaroni wrote:
>
>>I want to parse the pointer of a move list into the function so it can be
>>changed inside the function, the bottom of your two would parse it in to be used
>>by the function wouldn't it?
>>Lets say I use the top one. How would I then call MoveGenerator? with
>>'MoveCount=MoveGenerator(turn, &AllMoves);' where allmoves is an array with 100
>>elements? and if so, once inside the function MoveGenerator, how do I edit
>>AllMoves (*List)?
>>thanks for helping.
>
>This is how I would do it, given your requirements.
>
>int MoveGenerator ( int turn, Move * List );
>
>Move AllMoves[100];
>
>int MoveCount = MoveGenerator( turn, AllMoves );
>
>It sounds like you're confused about what an array is. When you declare an
>array, such as "Move AllMoves[100];", AllMoves is a pointer to an array of 100
>elements of Move. So that is why you can just pass it to the function like I did
>above. When you do:
>
>SomeMove = AllMoves[8]; // get the 9th move
>
>That is the same as:
>
>SomeMove = *(AllMoves + (8 * sizeof(Move)))

Russell,
you are putting on such a valiant attempt to help. ;-)

Considering the general state of confusion about pointer and arrays, Macaroni
should know that using vector subscribe operator would cause the same problems
as using a raw pointer without checking the bounds.
char ca[10];
vector<char> va(10); // allocate for ten elements

for (int i=0; i< 20; ++i){
  ca[i] = 0; // runtime error after i > 9
  va[i] = 0; // runtime error after i > 9
}

vectors will not check out of bounds conditions when used in such way.
However if the push_back is used then the vector will grow itself automatically,
but performance would go out of the window.

vector<char> va(10); // allocate for 10 elements

for (int i=0; i < 100; ++i){
  va.push_back(i);
}


Another way to structure the code could be:

typedef struct Move{
public:
   unsigned char from;
   unsigned char to;
};

1) Using vectors in the most simple and not very efficient way.
typedef std::vector<Move> MovesVector;

int MoveGenerator ( int turn, MovesVector& moves ){
  Move current_move;
  moves.clear();// clear the array
  // Start generating moves
  // and when a move is available add it to the array
  moves.push_back(current_move);
  return moves.size();
}


2) Using a simple wrapper, to mainly avoid clearing the array all the time:

class MyMovesArray{
public:
  MyMovesList(int intialSize=100):
    maxStor(initialSize),
    available(0)
  {
     storage = new Move[maxStor];
  }
  ~MyMovesList(){
    if (storage)
      delete []storage;
  }
  /** allow this thing to grow */
  void grow(int howMuch){
    Move* newStorage = new Move[maxStor+howMuch];
    // copy the old content into the new storage.
    ....
    // remember the new max storage size
    maxStor += howMuch;
    // Remember the new storage
    if (storage)
      delete []storage;
    storage = newStorage;
  }
  /** Clear the contents */
  inline void clear(){
    available = 0;
  }
  //
  Move* storage;
  int maxStor;
  int available;
};


int MoveGenerator ( int turn, MyMovesArray& moves ){
  moves.clear(); // very fast.
  while (moves.available < moves.maxStor){
    moves.sorage[moves.available++] = currentMove;
    // if needed grow the array.
    // brak if no more moves can be generated ...
  }
  return moves.available;
};



Regards,
Hristo



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.