⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 boards.h

📁 c+++ game uploading now
💻 H
📖 第 1 页 / 共 2 页
字号:
/**
 @file
 Various board representations.
*/
#if !defined _BOARDS_H_
#define _BOARDS_H_
#include <cassert>
#include <cstring>

namespace Othello
{
    
    /**
      a large value, the maximum score possible */
    const int infinity=128;

    /**
      square names, s mean sentinel, p means playable */
    enum squareindex
    {
        s00, s01, s02, s03, s04, s05, s06, s07, s08, s09,
        s10, p11, p12, p13, p14, p15, p16, p17, p18, s19,
        s20, p21, p22, p23, p24, p25, p26, p27, p28, s29,
        s30, p31, p32, p33, p34, p35, p36, p37, p38, s39,
        s40, p41, p42, p43, p44, p45, p46, p47, p48, s49,
        s50, p51, p52, p53, p54, p55, p56, p57, p58, s59,
        s60, p61, p62, p63, p64, p65, p66, p67, p68, s69,
        s70, p71, p72, p73, p74, p75, p76, p77, p78, s79,
        s80, p81, p82, p83, p84, p85, p86, p87, p88, s89,
        s90, s91, s92, s93, s94, s95, s96, s97, s98, s99
    };

    /**
      square values are stored using one byte */
    typedef signed char squarevalue;

    /**
      an empty square, encoded with 0 */
    const squarevalue empty=0;

    /**
      a square with a black disc, encoded with 1 */
    const squarevalue black=1;

    /**
      a square with a white disc, encoded with -1 */
    const squarevalue white= -black;

    /**
      a sentinel square, this is placed around the board */
    const squarevalue sentl=3;
    
    /**
      gui helper trash, means a legal square for the side in turn */
    const squarevalue _gui__possible=4; 

    /**
      gui helper trash, means a hinted square for the player */
    const squarevalue _gui__hint=5;  


    /**
     see Michael Buro: "An Evaluation Function for Othello Based on 
     Statistics" */
    struct PreComp
    {
        int *Index;      /**< pointer to a pattern index*/
        int PlaceOffset; /**< distance from current pattern index and that after a place */
        int FlipOffset;  /**< distance from current pattern index and that after a flip*/
    
        PreComp(int *index, int place)
            :Index(index), PlaceOffset(place), FlipOffset(2*place)
        {}
    
        PreComp()
        {}
    };

    /** 
      @enum GameValueType different game value types */
    enum GameValueType
    {
        notvalid,   /**< not a valid value. */
        lowerbound, /**< a lower bound on the position value. */
        upperbound, /**< an upper bound on the position value. */
        exact       /**< an exact position value. */
    };


    /**
     describes a TTBoard (entry into transposition table).
     NOTE: sizeof(TTBoard) MUST BE EXACTLY 8 bytes !!!!!!!!!
     convincing the VC++ 6.0 compiler to use no aligment on this structure
     had proven to be a genuine nightmare, pack options are all but useless 
     and who would have thought that rearanging the members would produce 
     differents sizes, not a hint of that in MSDN. Hope that gcc will be more
     helpfull. */
    #pragma pack(push, 1)
    class TTBoard
    {
    private:
        /** identifies this board, almost unique */
        unsigned int lock32;

        /** best move is, 6 bits (if position is a leave then this 
         field has no meaning */
        unsigned char _bmove:6;

        /** what type of value do we strore here:
           notvalid, lowerbound, upperbound, exactvalue */
        unsigned char _vtype:2;

        /**from how deep did we got the value of this node
          NOTE: I want to prevent a re-search of a node searched in a previous
          pass (MT) in the current ID iteration; range (0..31)  5 bites */
        unsigned char _depth:5;

    public:
        /** whos turn is it */
        unsigned char isblacksturn:1;

    private:
        /** "time" or search stamp */
        unsigned char _stamp:2;

        /** board configuration value: it may be the true value
         an upper bound or a lower bound over it. range is -64:64, 
         bigger or less marks a win; 8 bits */
        signed char _value;

        /**
          private trash, 8 bites to make this structure nicely word aligned
          TODO: use this to store the other bound */
        char _trash:8;

    public:

        /**
         @return search stamp of this entry */
        unsigned int SearchStamp() const
        {
            return _stamp;
        }
 
        /**
         sets the lock to a given value */
        void SetLock32(unsigned int lock)
        {
            lock32=lock;
        }

        /**
         sets the best move */
        void SetBestMove(int x)
        {
            assert(Persil[x]!=-1);
            _bmove=Persil[x];
        }

        /**
         @return the best move */
        unsigned int BestMove() const
        {
            //best move is stored 0..63, but the engine uses 0..99 so
            //do a conversion
            return AntiPersil[_bmove];
        }
    
        /**
          @return the value of this position */
        int Value() const
        {
            return _value;
        }
    
        /**
          @return an upper bound over the value of the node
          if there is no such defined then returns +infinity */
        int UpperBound() const
        {
            //if exact upper bound or value then return value
            if(_vtype==upperbound || _vtype==exact) 
                return _value;
            //else (not valid or lower bound) return infinity
            return infinity;
        }

        /**
         sets an upperbound, from the given depth */ 
        void SetUpperBound(int value, unsigned int depth)
        {
            assert(value>=-127 && value<=127);
            //if new value is shalower then no update is needed
            if(_depth>depth)
                return;
            //if new value is deeper then always perform the update
            else if(_depth<depth)
            {
                _value=static_cast<signed char>(value);
                //mark that we have an upper bound
                _vtype=upperbound;
                //set new dept
                _depth=static_cast<unsigned char>(depth);
                return;
            }
            //we have an update from equal depth
            switch(_vtype)
            {
                case notvalid:
                    //do update
                    _value=static_cast<signed char>(value);
                    //mark that we have an upper bound
                    _vtype=upperbound;
                    break;
                case lowerbound:
                    //if bounds collide then we have an exact value
                    if(_value==value)
                        _vtype=exact;
                    else
                    {	
                        //owerwrite old entry
                        //TODO can I do something more here ???
                        _value=static_cast<signed char>(value);
                        //mark that we have an upper bound
                        _vtype=upperbound;
                    }
                    break;
                case upperbound:
                    //if new bound is tighter then update
                    if(_value>value)
                        _value=static_cast<signed char>(value);
                    break;
                case exact:
                    //we have an exact value, do nothing
                    break;
            }
        }
    
        /**
         sets an exact game value for this position */
        void SetExact(int value, int depth)
        {
            _value=static_cast<signed char>(value);
            _vtype=exact;
            _depth=static_cast<unsigned char>(depth);
        }

        /** 
          @return a lower bound over the value of the node 
          if undefined then returns -infinity */
        int LowerBound() const
        {
            //if exact value or lower bound then return value
            if(_vtype==lowerbound || _vtype==exact)
                return _value;
            //else (if not valid or upper bound) return -infnity;
            return -infinity;
        }

        /**
         sets a lowerbound, from the given depth */ 
        void SetLowerBound(int value, unsigned int depth)
        {
            assert(value>=-127 && value<=127);
            //if new value is shalower then no need for an update
            if(_depth>depth)
                return;
            //if new value is deeper then always perform the update
            else if(_depth<depth)
            {
                _value=static_cast<signed char>(value);
                //mark that we have an lower bound
                _vtype=lowerbound;
                //set new depth
                _depth=static_cast<unsigned char>(depth);
                return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -