00001
00010 #pragma once
00011
00012 #include <queue>
00013 #include <stack>
00014 #include <list>
00015 #include <bitset>
00016 #include <pthread.h>
00017
00018 using std::queue;
00019 using std::stack;
00020 using std::list;
00021 using std::vector;
00022 using std::bitset;
00023
00024 #include "utils.h"
00025 #include "hash.h"
00026 #include "config.h"
00027
00029 #define MAX_PIECES 16
00030 #define MAX_STEPS 80
00031
00032 #define STEPS_IN_MOVE 4
00033
00034 typedef unsigned long long u64;
00035
00036 #define IS_PLAYER(player) (player == GOLD || player == SILVER)
00037 #define IS_PIECE(piece) ( piece > 0 && piece <= 6)
00038
00039 #define NORTH 8
00040 #define SOUTH -8
00041 #define EAST 1
00042 #define WEST -1
00043
00044 #define BIT_EMPTY -1
00045
00046 #define GOLD 0
00047 #define SILVER 1
00048 #define NO_PLAYER 2
00049
00050 #define NO_SQUARE -1
00051
00052 #define NO_PIECE 0
00053 #define RABBIT 1
00054 #define CAT 2
00055 #define DOG 3
00056 #define HORSE 4
00057 #define CAMEL 5
00058 #define ELEPHANT 6
00059 #define PIECE_NUM 6
00060
00061 #define OPP(player) (1 - player) //opponent
00062 #define BIT_ON(n) (1ULL << (n)) //creates empty board with one bit set on n
00063
00064 #define BIT_LEN 64
00065 #define SQUARE_NUM 64
00066 #define SIDE_SIZE 8
00067
00068 #define RABBITS_NUM 8
00069
00070 #define STEP_PASS 0
00071 #define STEP_SINGLE 1
00072 #define STEP_PUSH 2
00073 #define STEP_PULL 3
00074
00075 #define STEP_NULL 4
00076 #define PLAYER_NUM 2
00077
00078
00079 #define ROW(square) (square/10)
00080
00081 #define COL(square) (square%10)
00082
00083 #define SQUARE_TO_INDEX_64(square) (8*(ROW(square)-1) + (COL(square)-1))
00084 #define INDEX_64_TO_SQUARE(index) ((10 * (index/8 + 1)) + ((index % 8) + 1 ))
00085
00086 #define SQUARE_DISTANCE(s1, s2) (abs(s1/8 - s2/8) + abs(s1%8 - s2%8))
00087
00088 #define OLD_PLAYER_TO_NEW(player) (player == 16 ? GOLD : SILVER)
00089
00090 typedef int player_t;
00091 typedef int piece_t;
00092 typedef int coord_t;
00093
00094 typedef uint stepType_t;
00095
00096
00097 namespace bits{
00098 #define NOT_A_FILE 0xfefefefefefefefeULL
00099 #define NOT_H_FILE 0x7f7f7f7f7f7f7f7fULL
00100 #define NOT_1_RANK 0x00ffffffffffffffULL
00101 #define NOT_8_RANK 0xffffffffffffff00ULL
00102 #define MSB 0x8000000000000000ULL
00103 #define TRAPS 0x0000240000240000ULL
00104 #define FPARITY 0x5555555555555555ULL
00105 #define FULL 0xffffffffffffffffULL
00106 #define EMPTY 0x0ULL
00107 #define IS_TRAP(coord) (BIT_ON(coord) & TRAPS)
00108 #define TRAPS_NUM 4
00109 extern u64 zobrist[2][7][64];
00110 const int TRAP_COORDS[TRAPS_NUM] = {45, 42, 21, 18};
00111 #define TRAP_INDEX_TO_TRAP(index) (bits::TRAP_COORDS[index])
00112
00113
00120 void initZobrist();
00121
00122 extern u64 winRank[2];
00123 extern u64 stepOffset_[2][7][64];
00127 void buildStepOffsets();
00128
00132 u64 str2bits(string str);
00133
00139 int lix(u64& b);
00140
00144 int lixslow(u64& v);
00145
00149 int bitCount(u64 b);
00150
00155 int bitOnOrder(uint index, u64 b);
00156
00160 bool getBit(const u64& b, int n);
00161
00165 bool isTrap(coord_t coord);
00166
00170 ostream& print(ostream& o, const u64& b);
00171
00175 u64 neighbors(u64);
00176
00182 u64 neighborsOne(coord_t coord);
00183
00191 int neighborsOneNum(coord_t coord, u64 mask);
00192
00196 u64 sphere(int center, int radius);
00197
00201 u64 circle(int center, int radius);
00202 }
00203
00204
00211 enum recordAction_e {ACTION_PLACEMENT, ACTION_STEP, ACTION_TRAP_FALL, ACTION_ERROR};
00212
00216 void globalStructuresInit();
00217
00224 bool parsePieceChar(char pieceChar, player_t& player, piece_t& piece);
00225
00229 string coordToStr(coord_t at);
00230
00231 class Board;
00232 class Eval;
00233
00237 class Soldier
00238 {
00239 public:
00240 Soldier(player_t player, piece_t piece, coord_t coord);
00241
00242 string toString();
00243
00244 piece_t piece() { return piece_; }
00245 player_t player() { return player_; }
00246 coord_t coord() { return coord_; }
00247
00248 private:
00249 Soldier(){};
00250
00251 player_t player_;
00252 piece_t piece_;
00253 coord_t coord_;
00254 };
00255
00256 typedef list<Soldier> SoldierList;
00257 typedef SoldierList::iterator SoldierListIter;
00258
00264 class KillInfo
00265 {
00266 public:
00267 KillInfo();
00268 KillInfo(player_t player, piece_t piece, coord_t coord);
00269 void setValues(player_t player, piece_t piece, coord_t coord);
00270 const string toString() const;
00271
00272 private:
00273 bool active_;
00274 player_t player_;
00275 piece_t piece_;
00276 coord_t coord_;
00277 };
00278
00279 class OB_BOARD;
00280
00290 class Step
00291 {
00292 public:
00293 Step();
00294 Step(stepType_t, player_t);
00295 Step(stepType_t, player_t, piece_t, coord_t, coord_t);
00296 Step(stepType_t, player_t, piece_t, coord_t, coord_t, piece_t, coord_t, coord_t);
00297
00298 player_t getPlayer() const;
00299 bool isPass() const;
00300 bool isNull() const;
00301 bool isSingleStep() const;
00302 bool isPushPull() const;
00303
00309 int count() const;
00310
00317 Step toNew() const;
00318
00325 bool inversed(const Step&) const;
00326
00332 bool pieceMoved() const;
00333 bool operator== (const Step&) const;
00334 bool operator<(const Step&) const;
00335
00336 void setValues( stepType_t, player_t, piece_t, coord_t, coord_t );
00337 void setValues( stepType_t, player_t, piece_t, coord_t, coord_t,
00338 piece_t, coord_t, coord_t );
00342 string toString() const;
00343
00344 protected:
00345 stepType_t stepType_;
00346 player_t player_;
00347 piece_t piece_;
00348 coord_t from_;
00349 coord_t to_;
00350
00351 piece_t oppPiece_;
00352 coord_t oppFrom_;
00353 coord_t oppTo_;
00354
00355 friend class Board;
00356 friend class Eval;
00357 friend class OB_Board;
00358 friend class ContextMove;
00359 friend class Move;
00360
00361 private:
00367 const string oneSteptoString(player_t, piece_t, coord_t, coord_t) const;
00368
00369 };
00370
00377 class StepWithKills: public Step
00378 {
00379 public:
00380 StepWithKills(Step step, const Board* board);
00381
00387 string toString() const;
00388
00389 private:
00390 StepWithKills();
00391
00398 void addKills(const Board* board);
00399
00400 KillInfo kills[2];
00401 };
00402
00403 typedef list<Step> StepList;
00404 typedef StepList::iterator StepListIter;
00405
00406
00412 class Move
00413 {
00414 public:
00415 Move();
00416
00420 Move(string moveStr);
00421
00428 void appendStep(Step);
00429
00436 void prependStep(Step);
00437
00444 void appendStepList(StepList);
00445
00451 StepList getStepList() const;
00452
00456 int getStepCount() const;
00457
00461 bool isOpening() const;
00462
00466 player_t getPlayer() const;
00467
00468 bool operator==(const Move& other) const;
00469
00473 string toString() const;
00474
00475 private:
00486 recordAction_e parseRecordActionToken(const string& token, player_t& player,
00487 piece_t& piece, coord_t& from, coord_t& to);
00488
00489 void updateStepCount(const Step& step);
00490
00491 StepList stepList_;
00492 int stepCount_;
00493
00497 bool opening_;
00498 };
00499
00500 typedef list<Move> MoveList;
00501 typedef MoveList::iterator MoveListIter;
00502 typedef vector<Move> MoveVector;
00503 typedef MoveVector::iterator MoveVectorIter;
00504
00505
00506 typedef Step StepArray[MAX_STEPS];
00507
00508 typedef float HeurArray[MAX_STEPS];
00509
00510 typedef list<int> intList;
00511
00512 typedef stack<Board*> Bpool;
00513
00514 typedef u64 Bitboard[2][7];
00515
00523 class Glob {
00524 public:
00525 Glob();
00526 void init();
00527 inline Bpool* bpool() {return bpool_[tti()];}
00528 inline ThirdRep* thirdRep() {return thirdRep_[tti()];}
00529 inline Grand* grand() {return grand_[tti()];}
00530
00531 private:
00535 int tti();
00536
00543 int add_thread();
00544
00545 int threadIds_[MAX_THREADS];
00546 int threadsNum_ ;
00547
00548 pthread_mutex_t lock;
00549 Bpool * bpool_[MAX_THREADS];
00550 ThirdRep * thirdRep_[MAX_THREADS];
00551 Grand * grand_[MAX_THREADS];
00552 };
00553
00554 extern Glob glob;
00555
00556
00563 class ContextMove
00564 {
00565 public:
00566 ContextMove(Move move, const Bitboard& bitboard);
00567
00571 bool applicable(const Bitboard& bitboard, int stepsLeft) const;
00572
00573 Move getMove() const;
00574
00575 float getValue() const;
00576
00577 void update(float sample);
00578
00582 float urgency(player_t player, int total) const;
00583 private:
00584 ContextMove(){};
00585 Move move_;
00586 Bitboard context_;
00587 u64 mask_;
00588 float value_;
00589 int visits_;
00590 };
00591
00592 typedef vector<ContextMove> ContextMoves;
00593 typedef ContextMoves::iterator ContextMovesIter;
00594
00600 class MoveAdvisor
00601 {
00602 public:
00603 MoveAdvisor();
00607 bool getMove(player_t player, const Bitboard& bitboard, int stepsLeft, Move* move);
00608 bool getMoveRand(player_t player, const Bitboard& bitboard, int stepsLeft, Move* move);
00609
00616 bool addMove(const Move & move, const Bitboard& bitboard);
00617
00622 void update(float sample);
00623
00624 private:
00625 bool hasMove(const Move & move, const Bitboard& bitboard);
00626
00627
00628
00629 ContextMoves contextMoves[2];
00631 list<int> playedCMs[2];
00632
00634 bool update_;
00635
00636 int used_;
00637 };
00638
00650 class Board
00651 {
00652
00653 public:
00654
00655 Board(){};
00656
00660 void initNewGame();
00661
00668 bool initFromRecord(const char* fn, bool init_repetitions=false);
00669
00675 bool initFromPosition(const char* fn);
00676
00685 bool initFromPositionCompactString(const string& s);
00686
00694 Step findMCstep();
00695
00699 void findMCmoveAndMake();
00700
00706 bool operator== (const Board& board) const;
00707
00711 void updateThirdRep();
00712
00719 void makeMove(const string& move);
00720
00726 void makeMove(const Move& move);
00727
00736 bool makeStepTryCommit(const Step&);
00737
00743 void commit();
00744
00752 int filterRepetitions(StepArray&, int ) const;
00753
00760 bool isSetupPhase() const;
00761
00769 bool checkKillForward(coord_t from, coord_t to, KillInfo* killInfo=NULL) const;
00770
00774 u64 calcAfterStepSignature(const Step& step) const;
00775
00782 int genStepsNoPass(player_t, StepArray& steps) const;
00783
00787 int genSteps(player_t, StepArray& steps) const;
00788
00797 void getHeuristics(const StepArray& steps, uint stepsNum, HeurArray& heurs) const;
00798
00806 bool canContinue(const Move& move) const;
00807
00813 bool canPass() const;
00814
00818 Step lastStep() const;
00819
00823 bool isMoveBeginning() const;
00824
00825
00826 void updateWinner();
00827
00833 bool goalCheck(player_t player, int stepLimit, Move* move=NULL) const;
00834
00841 bool goalCheck(Move* move=NULL) const;
00842
00851 bool trapCheck( player_t player, coord_t trap, int limit, MoveList* moves, SoldierList* soldiers) const;
00852
00853 bool trapCheck(player_t player, MoveList* moves=NULL, SoldierList* soldiers=NULL) const;
00854
00855 bool trapCheck(coord_t pos, piece_t piece, player_t player,
00856 coord_t trap, int limit, int used, Move* move) const;
00857
00861 static string bitboardToString(const Bitboard & bitb);
00862
00866 string toString() const;
00867
00871 string moveToStringWithKills(const Move& m) const;
00872
00876 u64 getSignature() const;
00877
00881 player_t getWinner() const;
00882
00886 player_t gameOver() const;
00887
00891 player_t getPlayerToMove() const;
00892
00896 const Bitboard& getBitboard() const;
00897
00901 player_t getPlayerToMoveAfterStep(const Step& step) const;
00902
00906 uint getStepCount() const;
00907
00911 uint getStepCountLeft() const;
00912
00913
00914 void *operator new(size_t size);
00915 void operator delete(void* p);
00916
00917 private:
00918
00924 int reachability(int from, int to, player_t player,
00925 int limit, int used, Move * move) const;
00926
00932 void genStepsOne(coord_t coord, player_t player,
00933 StepArray& steps, int& stepsNum) const;
00934
00944 inline void genStepsOneTuned(coord_t coord, player_t player, piece_t piece,
00945 StepArray& steps, int& stepsNum, u64 victims) const;
00946
00950 u64 calcMovable(player_t player) const;
00951
00958 void calcWeaker(player_t player, u64 (&weaker)[7]) const;
00959
00960 void setSquare(coord_t, player_t, piece_t);
00961 void delSquare(coord_t, player_t);
00962 void delSquare(coord_t, player_t, piece_t);
00963
00967 piece_t getPiece(coord_t, player_t) const;
00968
00972 player_t getPlayer(coord_t) const;
00973
00979 int strongerDistance(player_t player, piece_t piece, coord_t coord) const;
00980
00987 u64 strongerWithinDistance(player_t player, piece_t piece,
00988 coord_t coord, int distance) const;
00989
00995 int equalDistance(player_t player, piece_t piece, coord_t coord) const;
00996
00997
01004 player_t strongestPieceOwner(u64 area) const;
01005
01011 player_t strongestPiece(player_t player, u64 area) const;
01012
01020 u64 weaker(player_t player, piece_t piece) const;
01021
01030 u64 stronger(player_t player, piece_t piece) const;
01031
01038 void init(bool newGame=false);
01039
01045 void afterPositionLoad();
01046
01052 player_t sideCharToPlayer(char side) const;
01053
01062 bool findActiveTrapping(MoveVector& moves);
01063
01069 void makeSignature();
01070
01079 void makeStep(const Step& step);
01080
01088 Step chooseStepWithKnowledge(StepArray& steps, uint stepsNum) const;
01089
01097 bool stepIsVirtualPass( Step& ) const;
01098
01106 bool stepIsThirdRepetition(const Step& ) const;
01107
01111 u64 getPreMoveSignature() const;
01112
01113 Bitboard bitboard_;
01114
01115 static bool classInit;
01116 static ThirdRep* thirdRep_;
01117 static Eval* eval_;
01118
01120 u64 signature_;
01121
01123 u64 preMoveSignature_;
01124
01126 u64 preStepSignature_;
01127
01129 Step lastStep_;
01130
01131
01132 uint moveCount_;
01133
01134
01135
01136 uint stepCount_;
01137
01138 player_t toMove_;
01139 player_t winner_;
01140
01141 friend class Eval;
01142 };