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

📄 endgame.cpp

📁 c+++ game uploading now
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            k++;
            pt = pt->succ;
            pt->square = sqnum;
	        pt->hole_id = HoleId[sqnum];
        }
    }
    pt->succ = NULL;
    assert(k<=MAXEMPTIES);
}

int EndGame::NoParEndSolve (uchar *board, int alpha, int beta, 
              int color, int empties, int discdiff, int prevmove )
{
   *_posSearched++;
   int score = -infinity;
   int oppcol = 2-color;
   int sqnum,j,ev;
   EmList *em, *old_em;
   for(old_em = &EmHead, em = old_em->succ; em!=NULL;
       old_em = em, em = em->succ){
      /* go thru list of possible move-squares */
      sqnum = em->square;
      j = DoFlips( board, sqnum, color, oppcol );
      if(j){ /* legal move */
          /* place your disc: */
          *(board+sqnum) = color;
          /* delete square from empties list: */
	  old_em->succ = em->succ;
          if(empties==2){ /* So, now filled but for 1 empty: */
             int j1;
             j1 = CountFlips( board, EmHead.succ->square, oppcol, color);
             if(j1){ /* I move then he moves */
                ev = discdiff + 2*(j-j1);
             }
             else{ /* he will have to pass */
                j1 = CountFlips(board, EmHead.succ->square, color, oppcol);
		ev = discdiff + 2*j;
                if(j1){ /* I pass then he passes then I move */
		  ev += 2 * (j1 + 1);
                }
                else{ /* I move then both must pass, so game over */

                   ev++;

                }
             }
          }
          else{
             ev = -NoParEndSolve(board, -beta, -alpha, 
                      oppcol, empties-1, -discdiff-2*j-1, sqnum);
          }
          UndoFlips( j, oppcol );
          /* un-place your disc: */
          *(board+sqnum) = EMPTY;
          /* restore deleted empty square: */
	  old_em->succ = em;

          if(ev > score){ /* better move: */
             score = ev;
             if(ev > alpha){
                alpha = ev;
                if(ev >= beta){ /* cutoff */
                   return score;
                }
             }
          }
       }
    }
    if(score == -infinity){  /* No legal move */
       if(prevmove == 0){ /* game over: */
          return discdiff;
       }
       else /* I pass: */ return
          -NoParEndSolve( board, -beta, -alpha, oppcol, empties, -discdiff, 0);
    }
    return score;
}
   
int EndGame::ParEndSolve(uchar *board, int alpha, int beta, 
            int color, int empties, int discdiff, int prevmove )
{
   *_posSearched++;
   int score = -infinity;
   int oppcol = 2-color;
   int sqnum,j,ev;
   EmList *em, *old_em;
   uint parity_mask;
   int par, holepar;

   for ( par = 1, parity_mask = RegionParity; par >= 0;
	 par--, parity_mask = ~parity_mask ) {

   for(old_em = &EmHead, em=old_em->succ; em!=NULL;
       old_em = em, em = em->succ){
      /* go thru list of possible move-squares */
      holepar = em->hole_id;
      if ( holepar & parity_mask ) {
      sqnum = em->square;
      j = DoFlips( board, sqnum, color, oppcol );
      if(j){ /* legal move */
          /* place your disc: */
          *(board+sqnum) = color;
          /* update parity: */
          RegionParity ^= holepar;
          /* delete square from empties list: */
	  old_em->succ = em->succ;
          if(empties<=1+USE_PARITY)
             ev = -NoParEndSolve(board, -beta, -alpha, 
                   oppcol, empties-1, -discdiff-2*j-1, sqnum);
          else
             ev = -ParEndSolve(board, -beta, -alpha, 
                   oppcol, empties-1, -discdiff-2*j-1, sqnum);
          UndoFlips( j, oppcol );
          /* restore parity of hole */
          RegionParity ^= holepar;
          /* un-place your disc: */
          *(board+sqnum) = EMPTY;
          /* restore deleted empty square: */
	  old_em->succ = em;

          if(ev > score){ /* better move: */
             score = ev;
             if(ev > alpha){
                alpha = ev;
                if(ev >= beta){ 
                   return score;
	       }
	    }
	 }
       }
    }}
    }

    if(score == -infinity){  /* No legal move found */
       if(prevmove == 0){ /* game over: */
          return discdiff;
       }
       else /* I pass: */ return
          -ParEndSolve( board, -beta, -alpha, oppcol, empties, -discdiff, 0);
    }
    return score;
}

int EndGame::count_mobility( uchar *board, int color )
{
  int oppcol = 2 - color;
  int mobility;
  int square;
  struct EmList *em;

  mobility = 0;
  for ( em = EmHead.succ; em != NULL; em = em->succ ) {
    square = em->square;
    if ( AnyFlips( board, square, color, oppcol ) )
      mobility++;
  }

  return mobility;
}


int EndGame::FastestFirstEndSolve( uchar *board, int alpha, int beta, 
		      int color, int empties, int discdiff,int prevmove )
{
  int i, j;
  int score = -infinity;
  int oppcol = 2 - color;
  int sqnum, ev;
  int flipped;
  int moves, mobility;
  int best_value, best_index;
  EmList *em, *old_em;
  EmList *move_ptr[64];
  int holepar;
  int goodness[64];
  
  *_posSearched++;
  
  moves = 0;
  for ( old_em = &EmHead, em = old_em->succ; em != NULL;
	old_em = em, em = em->succ ) {
    sqnum = em->square;
    flipped = DoFlips( board, sqnum, color, oppcol );
    if ( flipped ) {
      board[sqnum] = color;
      old_em->succ = em->succ;
      mobility = count_mobility( board, oppcol );
      old_em->succ = em;
      UndoFlips( flipped, oppcol );
      board[sqnum] = EMPTY;
      move_ptr[moves] = em;
      goodness[moves] = -mobility;
      moves++;
    }
  }

  if ( moves != 0 ) {
    for ( i = 0; i < moves; i++ ) {
      best_value = goodness[i];
      best_index = i;
      for ( j = i + 1; j < moves; j++ )
	if ( goodness[j] > best_value ) {
	  best_value = goodness[j];
	  best_index = j;
	}
      em = move_ptr[best_index];
      move_ptr[best_index] = move_ptr[i];
      goodness[best_index] = goodness[i];

      sqnum = em->square;
      holepar = em->hole_id;
      j = DoFlips( board, sqnum, color, oppcol );
      board[sqnum] = color;
      RegionParity ^= holepar;
      em->pred->succ = em->succ;
      if ( em->succ != NULL )
	em->succ->pred = em->pred;
      if ( empties <= FASTEST_FIRST + 1 )
	ev = -ParEndSolve( board, -beta, -alpha, oppcol, empties - 1,
			   -discdiff - 2 * j - 1, sqnum);
      else
	ev = -FastestFirstEndSolve( board, -beta, -alpha, oppcol,
				    empties - 1, -discdiff - 2 * j - 1,
				    sqnum);
      UndoFlips( j, oppcol );
      RegionParity ^= holepar;
      board[sqnum] = EMPTY;
      em->pred->succ = em;
      if ( em->succ != NULL )
	em->succ->pred = em;

      if ( ev > score ) { /* better move: */
	score = ev;
	if ( ev > alpha ) {
	  alpha = ev;
	  if ( ev >= beta )
	    return score;
	}
      }
    }
  }
  else {
    if ( prevmove == 0 ) 
      return discdiff;
    else  /* I pass: */
      score = -FastestFirstEndSolve( board, -beta, -alpha, oppcol,
				     empties, -discdiff, 0);
  }

  return score;
}

int EndGame::EndSolve (uchar *board, int alpha, int beta, 
               int color, int empties, int discdiff, int prevmove )
{
  if ( empties > FASTEST_FIRST )
    return FastestFirstEndSolve(board,alpha,beta,color,empties,discdiff,prevmove);
  else {
   if(empties <= (2>USE_PARITY ? 2 : USE_PARITY) )
      return NoParEndSolve(board,alpha,beta,color,empties,discdiff,prevmove);
   else 
   return ParEndSolve(board,alpha,beta,color,empties,discdiff,prevmove);
  }
}

inline void EndGame::Adjust(int &t)
{
    if(t>63)
        t-=63;
    if(t<-63)
        t+=63;
}

#include <cstring>

const int EndGame::translator[10*10]=
{
    0, 0, 0, 0, 0, 0, 0, 0, 0,0,
    0,10,11,12,13,14,15,16,17,0,
    0,19,20,21,22,23,24,25,26,0,
    0,28,29,30,31,32,33,34,35,0,
    0,37,38,39,40,41,42,43,44,0,
    0,46,47,48,49,50,51,52,53,0,
    0,55,56,57,58,59,60,61,62,0,
    0,64,65,66,67,68,69,70,71,0,
    0,73,74,75,76,77,78,79,80,0,
    0, 0, 0, 0, 0, 0, 0, 0, 0,0,
};

unsigned int *EndGame::_posSearched;

int EndGame::Solve(int alpha, int beta, unsigned int &posSearched)
{
    _posSearched=&posSearched;
    Adjust(alpha); 
    Adjust(beta);
    memset(board, DUMMY, sizeof(board));
    for(uint i=p11; i<s89; i++)
    {
        const int p=translator[i];
        if(p)
            board[p]=actualb.table[i]+1;
    }

    PrepareToSolve(board);

    const int color=actualb.isblacksturn?BLACK:WHITE;
    const int d_diff=actualb.isblacksturn?actualb.CountBlack()-actualb.CountWhite():
                                          actualb.CountWhite()-actualb.CountBlack();
    int ret=EndSolve(board, alpha, beta, color,
                    actualb.CountEmpty(), d_diff,1);
 
    if(ret>0)
        return ret+63;
    if(ret<0)
        return ret-63;
    return ret;
}
#endif //#if defined _ENDGAME_TEST_

⌨️ 快捷键说明

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