// Copyright 1993 by Jon Dart.  All Rights Reserved.

#ifndef _MOVE_ARRAY_H
#define _MOVE_ARRAY_H

#include "board.h"
#include "emove.h"
#include "pool.h"

class Move_Array;
#ifndef __AFXCOLL_H__
#include <afxcoll.h>
#endif

class Move_Record
{
     // holds info on a move made during the game or during a search
     // operation.	      

     public:

     Move_Record(const Board &board, const ExtendedMove &move);
     // "board" is the board position after the move.
	     
     Move_Record();
     // create a null record.  Used only to initialize storage.
     
     ~Move_Record()
     {
     }
     
     const ExtendedMove &move() const
     {
 	     return my_move;
     }
     
     const hash_t hashcode() const
     {
	     return my_hashcode;
     }
     
     int operator == ( const Move_Record &l ) const;
     int operator != ( const Move_Record &l ) const;
     
     void *operator new (size_t size)
     {
 	return allocator.allocate(size);
     }
    
     void *operator new (size_t, void *p)
     {
 	return p;    
     }

     void operator delete( void *p )
     {
	allocator.free(p);    
     }
    
     static void freeAll( BOOL final )
     {
	allocator.freeAll(final);
     }
    
     private:
	     
     ExtendedMove my_move;	    
     hash_t my_hashcode;	    
     static Pool allocator;
};

class Move_Array
{
     // Maintains a list of moves made in the game so far or in
     // the search process.	     
	     
     public:	     
	
     Move_Array();
     // create a Move_Array.
	     
     virtual ~Move_Array();	     

     void add_move( const Board &board, const ExtendedMove &emove );
     // add a move to the Move_Array. "board" is the position after the
     // move is made.	     
	     
     void remove_move();
     // remove the most recently added move to the Move_Array.
	     
     // return the total number of half-moves in the game:
     unsigned num_moves() const
     {
         return arr.GetSize();
     }
     
     unsigned num_moves(const ColorType side);

     const ExtendedMove &move( const unsigned n );
     // return the nth move in the Move_Array.  0 <= n <= num_moves - 1.
	
     int rep_count( const Board &board) const;
     // returns a repetition count: how many times the board position
     // has occurred in the game. 
	     
     int rep_count( const Board &board, int start) const;
     // returns a repetition count: how many times the board position
     // has occurred in the game, couting from move #start.
	     
     void clear();
     // remove everything from the Move_Array
	     
     const Move_Record &operator[](int n) const
     {
	return *((Move_Record*)arr[n]);
     }
	     
     private:
	     
     enum {Rep_Table_Size = 128}; 
	     
     int rep_table[Rep_Table_Size];
     
     CPtrArray arr;
};

#endif

