// This is -*- c++ -*- code

#ifndef __ANTICHESS_BOARD_H__
#define __ANTICHESS_BOARD_H__

#include <6170.h>
#include "chess_display_board.h"
#include <chess_capture_move.h>
#include <chess_capture_move.h>

class antichess_board : public chess_display_board {
    
    // Overview: This class is the actual level at which an antichess
    // board will be seen.  It is a subtype of board and
    // chess_display_board, but actuates their purely virtual methods.

  public:

    // Constructors and Destructors

    antichess_board(istream &initial_format);
    // Effects: Constructs an antichess_board that is not associated
    // with any game.  If initial_format fails to meet the description
    // stated in the design document, this will be initialized to meet
    // the empty board, and calls to initialized_correctly will return
    // false.  Otherwise, the board will correspond to the description
    // in initial_format, and initialized_correctly will return true.

    virtual ~antichess_board();
    // Effects: Frees any resources associated with the antichess_board.
    // Because garbage collection is performed, calling this
    // destructor is not strictly necessary, but if it is known that a
    // board wil not be needed, destroying it may avoid heap
    // fragmentation.


    // Methods

    bool is_legal_move(move &m, int player_num) const;

    game::move_result  apply(move &m, int player_num);

    bool unapply(move &m, int player_num);
    
    int winner();
    
    move_generator * valid_moves(int player_num) const;

    bool valid_move_available(int player_num) const;
    
    bool are_valid_move_available(int player_num, bool check_turn) const;
    // Checks 0 <= player_num < players()
    // Effects: Returns true if this player has valid moves available,
    // checking if it is his turn depending upon the status of
    // check_turn, else returns false.

    value eval_move_delta (int p_pov, move &m, int p_mover) const;
    
    value evaluate( int player_num) const;
    
    board * clone() const;

    long suggest_time(long time_left) const;

    static typeinfo_t typeinfo;
    
    void * force (typeinfo_t &t);

  protected:

    void clone_part(antichess_board &ab) const;
    
  private:

    game::move_result  apply_internal(chess_capture_move *m, int player_num);
    value evaluation;
    
    antichess_board();
    // Effects: Creates a blank antichess_board.
    
    antichess_board(const antichess_board &);
    void operator= (antichess_board &);
};

void add_to_array(chess_capture_move mv,array<chess_capture_move> *forces,
		  array<chess_capture_move> *normal);

#endif
