Esempio n. 1
0
void eval_and_sort(
  const evaluator& e, board& b, piece_colour pc, 
  move* movelist, int num_moves)
{
  for (int i = 0; i < num_moves; i++)
  {
    move& m = movelist[i];
    // TODO have the idea of score at a particular depth
    b.do_move(m);
    m.score = e.calc_score(b, pc);
    b.undo_move();
  }

  std::sort(movelist, movelist + num_moves, move_sorter());

#ifdef SHOW_SORTED_MOVES_LIST
  std::cout << "Sorted moves list: ";
  for (int i = 0; i < num_moves; i++)
  {
    move& m = movelist[i];
    std::cout << m << " (" << m.score << ") ";
  }
  std::cout << "\n";
#endif
}
Esempio n. 2
0
double strategySimple::boardValue( const board& brd, const hash_map<string,int>* context ) const
{
    // start with pips^2
    
    double val=brd.pipsq();
    
    // dislike singletons, giant towers; like blocked-off spots next each other
    
    int check;
    int run=0, maxRun=0;
    
    for( int i=0; i<24; i++ )
    {
        check = brd.checker(i);
        if( check == 1 )
            val -= singletonWeight;
        if( check > 5 )
            val -= towerWeight * ( check - 5 );
        if( check > 1 )
        {
            run ++;
            if( run > maxRun ) maxRun = run;
        }
        else
            run = 0;
    }
    
    val += runWeight * ( maxRun - 1 );
    
    return val;
}
Esempio n. 3
0
   void displayCall(){
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  drawBoard(11);  
  
  int x, y; char owner;
  while(true){
     cout<<"Enter (row) [space] (column)"<<endl;
     cout<<"Ex: 1 11 or 11 5"<<endl;
     cin>>x>>y;
     if(x>0 && x<=11 && y>0 && y<=11 && hexBoard.getVector()[x-1][y-1].owner == '-'){
        owner = 'R'; 
        break;
     }
  }
  x--; y--; //used for translating input of 1-11 to data of 0-10
  hexBoard.placePiece(x, y, owner);
  posNode temp = posNode(x,y,owner);
  board.push_back(temp);

  for(auto element: board)
     colorHex(element.coordX, element.coordY, element.owner);

  drawBoard(11);
  drawRects();
 
  glutSwapBuffers();
  char winner = ' ';
  determineWinner(connectivityMatrix, hexBoard, boardWidth, winner, false);
  if(winner == 'R') exit(0);
}
Esempio n. 4
0
double strategytdexp4::getOutputBackgammonLossValue( const vector<double>& middles, const board& brd ) const
{
    // special case - if the player 0 has taken any pieces in, the gammon loss prob is zero
    
    if( brd.bornIn0Raw() > 0 ) return 0;
    
    // also if there are no player 0 pieces in player 1's box, the backgammon win prob is zero
    
    vector<int> checks( brd.checkers0Raw() );
    bool foundOne = brd.hit0Raw() > 0;
    if( !foundOne )
        for( int i=18; i<24; i++ )
            if( checks.at(i) > 0 )
            {
                foundOne = true;
                break;
            }
    if( !foundOne ) return 0;
    
    // otherwise calculate the network value
    
    double val=0;
    for( int i=0; i<nMiddle; i++ )
        val += outputBackgammonLossWeights.at(i) * middles.at(i);
    val += outputBackgammonLossWeights.at(nMiddle); // bias node
    return  1. / ( 1 + exp( -val ) );
}
Esempio n. 5
0
double strategytdexp4::boardValue( const board& brd, const hash_map<string,int>* context ) const
{
    // get the inputs from the board, assuming the player holds the dice
    
    vector<double> inputs = getInputValues( brd, brd.perspective() );
    
    // calculate the middle layer node values
    
    vector<double> middles = getMiddleValues( inputs );
    
    // calculate the output node values from the middles
    
    double probWin            = getOutputProbValue( middles );
    double probCondGammonWin  = getOutputGammonWinValue( middles, brd );
    double probCondGammonLoss = getOutputGammonLossValue( middles, brd );
    double probCondBgWin      = getOutputBackgammonWinValue( middles, brd );
    double probCondBgLoss     = getOutputBackgammonLossValue( middles, brd );
    
    // calculate the expected number of points the player will win. probWin
    // corresponds to the probability of a win (any win); probCondGammon
    // corresponds to the probability of a gammon conditional on a win;
    // probCondGammonLoss corresponds to the probability of a gammon loss
    // conditional on a loss. Ditto for backgammon win/loss conditional probs.
    
    double ppg = probWin         * ( 1 * ( 1 - probCondGammonWin )  + 2 * probCondGammonWin  * ( 1 - probCondBgWin  ) + 3 * probCondGammonWin  * probCondBgWin  )
               - ( 1 - probWin ) * ( 1 * ( 1 - probCondGammonLoss ) + 2 * probCondGammonLoss * ( 1 - probCondBgLoss ) + 3 * probCondGammonLoss * probCondBgLoss );
    
    // the ppg is always from player 0's perspective. But we want it from the board
    // perspective.
    
    if( brd.perspective() == 0 )
        return ppg;
    else
        return -ppg;
}
Esempio n. 6
0
 // aplica un backtracking amarat pe fiecare dintre cele 4 directii cardinale
 // (la rascruce de vanturi) si calculeaza in momentul in care ajunge la adancimea 
 // maxima (fundul putului) calculeaza un punctaj pentru fiecare mutare
 // din pacate drumul inapoi nu are gropi k ar mai fi taiat din punctaj 
 int getMovePoints(board previousBoard, int currentDepth, vector<int> mutari) {
   position posXYEnemy = previousBoard.getPlayerPosition(2); 
   position posXYMyPlayer = previousBoard.getPlayerPosition(1); 
   if (currentDepth >= maxDepth_ || 
       previousBoard.getPossibleMoves(posXYEnemy) == 0 ||
       previousBoard.getPossibleMoves(posXYMyPlayer) == 0 
       ) {
     return getPoints(previousBoard, mutari, 1 /*Player1*/);    
   } else {
     int maxProfit = 0; 
     for (int i = 0; i < 4; i++) {
       int eachProfit = 0; 
       board tempBoard = previousBoard.copyBoard(); 
       position myPosition = tempBoard.getPlayerPosition(1);
       if (tempBoard.isEmpty(i, myPosition)) {
         tempBoard.doMove(i,1);
         mutari.push_back(i);
         eachProfit = getMovePoints(tempBoard, currentDepth + 1, mutari);
         if (eachProfit > maxProfit) {
           maxProfit = eachProfit;     
         }
         mutari.pop_back(); 
       }
     }
     return maxProfit;
   }
 }
Esempio n. 7
0
bool doublestratmatch::takeDouble( strategyprob& strat, const board& b, int cube )
{
    // need probabilities when the opponent holds the dice; that's what the strategy's
    // boardProbabilities returns so just use that.
    
    gameProbabilities probs( boardProbabilities(strat,b,false) );
    
    // calculate the equity at the doubled cube level assuming the player holds the dice
    
    interpMEdata deadME( equityInterpFn( probs, b.perspective(), 2*cube, b.perspective(), true ) );
    interpMEdata liveME( equityInterpFn( probs, b.perspective(), 2*cube, b.perspective(), false ) );
    
    double equityDouble = cubeLifeIndex*liveME(probs.probWin) + (1-cubeLifeIndex)*deadME(probs.probWin);
    
    // calculate the equity we'd give up if we passed. Respect the Crawford rule.
    
    int n = b.perspective() == 0 ? currMatch->getTarget() - currMatch->playerScore() : currMatch->getTarget() - currMatch->opponentScore();
    int m = b.perspective() == 0 ? currMatch->getTarget() - currMatch->opponentScore() : currMatch->getTarget() - currMatch->playerScore();
    
    double singleLossME;
    if( n == 1 )
        singleLossME = MET.matchEquityPostCrawford(m-cube);
    else if( m == 1 )
        singleLossME = -1;
    else
        singleLossME = MET.matchEquity(n, m-cube);

    return equityDouble > singleLossME;
}
Esempio n. 8
0
    board min_node(board &current, vector <string> &traverse_log, const int depth, const bool prune, const node from, const bool save_log) const {
        assert(depth >= 0 && depth <= cutoff);
        //cout << get_node_name(current) << endl;
        int v = MAX_INT;
        
        /*if (depth == cutoff) {
            v = current.eval(who);
        }*/
        
        board best = current;
        
        if ((current.who != current.whom && depth == cutoff) || !current.has_legal_move() || (!current.is_root && abs(current.eval(who)) == WINNING)) {
            best.val = current.eval(who);
            if (save_log) {
                traverse_log.push_back(log_string(current, depth, best.val, prune));
            }
            return best;
        }
        if (save_log) {
            traverse_log.push_back(log_string(current, depth, v, prune));
        }

        for (auto e: current.candidate) {
            board next = current.move(e);
            next.history.push_back(e);
            
            int delta_depth = current.whom != current.who;
            
            if (depth == cutoff && delta_depth) {
                best.val = current.eval(who);
                return best;
            }
            
            if (next.whom == next.who) {          //Still player's turn
                next = min_node(next, traverse_log, depth + delta_depth, prune, MIN_NODE, save_log);
            } else {
                next = max_node(next, traverse_log, depth + delta_depth, prune, MIN_NODE, save_log);
            }
            
            if (next.val < v) {
                v = next.val;
                best = next;
            }
            if (prune) {
                if (best.val <= current.alpha) {
                    if (save_log) {
                        traverse_log.push_back(log_string(current, depth, v, prune));
                    }
                    return best;
                }
                current.beta = min(current.beta, best.val);
            }
            if (save_log) {
                traverse_log.push_back(log_string(current, depth, v, prune));
            }
            //cout << get_node_name(current) << endl;
        }
        return best;
    }
Esempio n. 9
0
	bool operator()(move a, move b)
	{
		if (base.moveGains(a) > base.moveGains(b))
			return true;
		if (base.moveGains(a) < base.moveGains(b))
			return false;
		return b < a;
	}
Esempio n. 10
0
double doublestratmatch::equity( strategyprob& strat, const board& b, int cube, bool ownsCube, bool holdsDice )
{
    gameProbabilities probs( boardProbabilities(strat, b, holdsDice) );
    int cubeOwner = ownsCube ? b.perspective() : 1-b.perspective();
    interpMEdata deadME( equityInterpFn(probs, b.perspective(), cube, cubeOwner,true) );
    interpMEdata liveME( equityInterpFn(probs, b.perspective(), cube, cubeOwner,false) );
    
    return cubeLifeIndex*liveME(probs.probWin) + (1-cubeLifeIndex)*deadME(probs.probWin);
}
board_turn agent_neural_statistical::doTurn ( board b, int player ) {

	/*

		This will be called when the agents needs to make a move.

		You are provided with
			-the board b: This is the current board state.
			-the int player: This is the player number of this agent on the board b.

		All your tiles on the board will have the contents of the int player.

		for all your tiles t, t.getContents ( ) = player.

		You cannot add on more arguments for this function.

	*/

	cout << "Player #" << player << "s turn, neural statistical agent.\n";

	b.print ( );

	auto originalBoard = b;
	int nRotations = b.rotateForPerspective ( player );

	board_turn t;

	vector < board_turn > possibleTurns = b.findAllPossibleTurns ( player );

	board_turn bestTurn = possibleTurns [ 0 ];
	double bestScore = 0;

	for ( size_t i = 0; i < possibleTurns.size ( ); ++ i ) {

		board b2 = b;
		b2.makeTurn ( possibleTurns [ i ] );

		vector < double > indata ( 121, 0 );
		for ( size_t i = 0; i < indata.size ( ); ++ i ) indata [ i ] = lib::intToIndata ( b.intToTile ( i ) -> getContents ( ), player );

		double score = nn.run ( indata ) [ 0 ];

		if ( bestScore < score ) {

			bestTurn = possibleTurns [ i ];
			bestScore = score;

		}

	}

	bestTurn.rotate ( 6 - nRotations );

	return bestTurn;

}
result  player::max(pos& p , board& b)
{
	if(b.checkGameState()==LOSS)
		{	
		return LOSS;
		}
	/* This function will play KNOT or AI's moves */
	if(b.getLevel()==9)
		{
			return DRAW;
		}
	else 
	{
		/* if found winning move in next step . Prune everything else
           It stops the process of finding the suitable move as soon 
           as the winning move is found.
		*/ 
		bool flag=false;
		/* Saves the current best coordinate/Box in the current state*/
		int *coord=new int[2];

		result finalResult = LOSS;
		for ( int i=0 ; i<3 ; i++)
			{
				for ( int j=0 ; j<3 ; j++)
				{	
					if(b.mMatrix[i][j]==NONE)
					{

						board tempBoard=b;
						tempBoard.mMatrix[i][j]=KNOT;
						result res=mini(p ,tempBoard);
						if(res>=finalResult)
						{
							coord[0]=i;
							coord[1]=j;
							finalResult=res;
							
							if(res==WIN)
							{
								flag=true;
								break;
							}
						}
					}
				}
				if(flag==true)
					break;
			}

		p.r=coord[0];
		p.c=coord[1];	

	return finalResult;
	}
}
Esempio n. 13
0
	bool operator()(pair<int, move> a, pair<int, move> b)
	{
		if (a.first > b.first)
			return true;
		if (a.first < b.first)
			return false;
		if (base.moveGains(a.second) > base.moveGains(b.second))
			return true;
		if (base.moveGains(a.second) < base.moveGains(b.second))
			return false;
		return b.second < a.second;
	}
Esempio n. 14
0
void gen_move::generate_move(const board& b, int side, location_list& valid_moves)
{
  location_list::location m ;

  for(m.y = 0 ; m.y < 8 ; m.y++) {
    for(m.x = 0 ; m.x < 8 ; m.x++) {
      if(b.get_at(m) == board::EMPTY && b.check_move_at(m, side)) {
        valid_moves.insert(m) ;
      }
    }
  }
}
Esempio n. 15
0
double GeometricRandomPlayout::state_value(board& b){
	if (b.black_has_won()){
		return 1.0;
	}
	if (b.white_has_won()){
		return 0.0;
	}
	if (b.is_ended()){
		return 0.5;
	}
	double hval = h.evaluate(b);
	return (1/(1+exp(-hval)));
}
Esempio n. 16
0
evaluate::score evaluate::eval(const board& b, board::piece side, int turn)
{
  score s ;
  int turn_num ;

  assert(side == board::BLACK || side == board::WHITE) ;

  turn_num = b.get_black_count() + b.get_white_count() ;
  this->side = side ;
  if(turn_num >= 48) return end_eval(b, turn) ;
  s = recur_eval(b, turn, level, turn_num, -9999999) ;
  return s ;
}
Esempio n. 17
0
 // merge in sens invers al parcurgerii miscarilor si calculeaza
 // un punctaj pentru fiecare mutare
 // citez : "Drumurile noastre poate... Se vor intalni vreodata"
 int getPoints(board someBoard, vector<int> mutari, int playerNo) {
   int punctajFinal = 0;
   int posX = someBoard.getPlayerPositionX(playerNo);
   int posY = someBoard.getPlayerPositionY(playerNo); 
   position posXY =  someBoard.getPlayerPosition(playerNo);   
   int mutariPosibile = someBoard.getPossibleMoves(posXY);
   int punctajTemp = awardPoints(mutariPosibile);
   punctajFinal += punctajTemp;
   for (int i = mutari.size() - 1; i >= 0; i--) {
     switch (mutari[i]) {
       case (UP)    : posX ++;
                      mutariPosibile = someBoard.getPossibleMoves(posX,posY);
                      punctajTemp = awardPoints(mutariPosibile);
                      punctajFinal += punctajTemp;
       break;
       case (DOWN)  : posX --;
                      mutariPosibile = someBoard.getPossibleMoves(posX,posY);
                      punctajTemp = awardPoints(mutariPosibile);
                      punctajFinal += punctajTemp;
       break; 
       case (LEFT)  : posY ++;
                      mutariPosibile = someBoard.getPossibleMoves(posX,posY);
                      punctajTemp = awardPoints(mutariPosibile);
                      punctajFinal += punctajTemp;
       break;
       case (RIGHT) : posY --;
                      mutariPosibile = someBoard.getPossibleMoves(posX,posY);
                      punctajTemp = awardPoints(mutariPosibile);
                      punctajFinal += punctajTemp;
       break;
     }        
   }
   return punctajFinal;
 }
Esempio n. 18
0
bool search::bfs(){
	pop();
	temp_state.move_left();
	temp_state.display();
	if(is_goal()){
		return true;
	}
	push();
	temp_state.move_right();
	temp_state.display();
	if(is_goal()){
		return true;
	}
	push();
	
	temp_state.move_top();
	if(is_goal()){
		return true;
	}
	temp_state.display();
	push();
	
	temp_state.move_bottom();
	if(is_goal()){
		return true;
	}
	temp_state.display();
	push();

	bfs();

}
int max_value(board b, int d, int player, int pos)
{
	int alpha = -9999;
	bool turn = b.board_update(player, pos);
	if (!turn && (d == depth))
	{
		if (b.terminal_check()) b.end_game(player);
		print_minimax(player, pos, d, evaluation(b));
	}
	if (turn)
	{
		int beta = 9999;
		print_minimax(player, pos, d, beta);
		if (b.terminal_check())
		{
			b.end_game(player);
			beta = evaluation(b);
			print_minimax(player, pos, d, beta);
			return beta;
		}
		for (int i = 2; i <= b.b_size / 2; i++)
		{
			if (b.board_value(player, i) == 0) {}
			else
			{
				beta = min(beta, max_value(b, d, player, i));
				print_minimax(player, pos, d, beta);
			}
		}
		return beta;
	}
	else if (d != depth)
	{
		print_minimax(player, pos, d, alpha);
		if (b.terminal_check())
		{
			b.end_game(player);
			alpha = evaluation(b);
			print_minimax(player, pos, d, alpha);
			return alpha;
		}
		vector<int> a(1);
		for (int i = 2; i <= b.b_size / 2; i++)
		{
			if (b.board_value((player + 1) % 2, i) == 0) {}
			else
			{
				alpha = max(alpha, min_value(b, d + 1, (player + 1) % 2, i, false, 0, a));
				print_minimax(player, pos, d, alpha);
			}
		}
	}
	else alpha = evaluation(b);
	return alpha;
}
Esempio n. 20
0
int evaluate::count_move(const board& b, int side) 
{
  int count = 0 ;
  location_list::location m ;

  for(m.y = 0 ; m.y < 8 ; m.y++) {
    for(m.x = 0 ; m.x < 8 ; m.x++) {
      if(b.get_at(m) == board::EMPTY && b.check_move_at(m, side)) {
        count++ ;
      }
    }
  }
  return count ;
}
result player::mini( pos& p , board& b )
{
	if(b.checkGameState()==WIN)
		return WIN;
	else
	{
		result finalResult=WIN;
			/*	This Function will simulate Human moves and try to reduce the score
				Human will go for the move by which he can win*/
		for ( int i=0  ;i<3 ; i++)
		{
			for ( int j=0 ; j<3 ; j++)
			{
				board tempBoard=b; 
				if(tempBoard.mMatrix[i][j]==NONE)
				{
					tempBoard.mMatrix[i][j]=CROSS;
					
					result res=max(p ,tempBoard);
					if(res<finalResult)
						{
							finalResult=res; 

						}
				}
			}
		}
		return finalResult;
	}
}
void player::test(board& b)
{
	pos p ;
	max(p,b);
	b.set(KNOT , p.r , p.c);
	
}
Esempio n. 23
0
string game::generate_fen(const board &bd)
{
    std::string fen;
    int8_t space = 0;
    for (int8_t rank = board::RANK_NUM - 1; rank >= 0; --rank) {
        for (int8_t file = 0; file < board::FILE_NUM; ++file) {
            auto p = bd.at(file, rank);
            if (p) {
                if (space != 0) {
                    fen.push_back(static_cast<char>(space) + '0');
                    space = 0;
                }
                fen.push_back(p->abbr_name());
            } else {
                space++;
            }
        }
        if (space != 0) {
            fen.push_back(static_cast<char>(space) + '0');
            space = 0;
        }
        fen.push_back('/');
    }
    fen.pop_back();//remove last '/'
    return fen;
}
Esempio n. 24
0
bool findMove(board b, move &bestMove, int wtime, int btime, int movestogo)
{
	if (queryBook(b, bestMove))
	{
		clock_t start = clock();
		while (clock() < start + CLOCKS_PER_SEC/10);
		return true;
	}
	
	clock_t deadline = 0;
	clock_t hardline = 0;
	if (b.getToMove())
	{
		if (btime != 0)
		{
			int target = btime/(movestogo+MOVE_LEAWAY) - OVERHEAD;
			deadline = (CLOCKS_PER_SEC/1000)*target + clock();
			hardline = (CLOCKS_PER_SEC/1000)*HARDLINE_FACTOR*target+clock();
		}
	}
	else
	{
		if (wtime != 0)
		{
			int target = wtime/(movestogo+MOVE_LEAWAY) - OVERHEAD;
			deadline = (CLOCKS_PER_SEC/1000)*target + clock();
			hardline = (CLOCKS_PER_SEC/1000)*HARDLINE_FACTOR*target+clock();
		}
	}
	
	if (deadline != 0)
		return calcMoveID(b, bestMove, deadline, hardline);
	else
		return calcMove(b, bestMove);
}
Esempio n. 25
0
bool calcMove(board b, move &bestMove)
{
	vector<move> moves = b.genMoves();
	moveOrderer order(b);
	sort(moves.begin(), moves.end(), order);
	
	if (moves.size() == 0)
		return false;
	
	int besti = -1;
	int bestScore = -MATESCORE_MAX;
	for (int i=0; i<moves.size(); i++)
	{
		board temp = b;
		temp.executeMove(moves[i]);
		pushHistory(temp);
		int curScore = minimax(DEPTH, temp, -MATESCORE_MAX, -bestScore+50, 0)+rand()%50;
		popHistory();
		if (curScore > bestScore)
		{
			besti = i;
			bestScore = curScore;
		}
	}
	
	bestMove = moves[besti];
	return true;
}
Esempio n. 26
0
	//If this move will close any of the surrounding cells
	point will_close_any(const board & board, point idx, border_names border)
	{
		auto orig_idx = idx;
		auto orig_idx2 = idx;
		switch (border)
		{
		case top:    orig_idx2 += point(0, -1); break;
		case left:   orig_idx2 += point(-1, 0); break;
		case right:  orig_idx2 += point(1, 0); break;
		case bottom: orig_idx2 += point(0, 1); break;
		}

		class board copy(board);
		fix_move(idx, border);

		if ((board.at(idx).owner & player_owned) != empty)
			return false;

		copy.place(idx, border);

		point idx2;
		if (border == top)  idx2 = idx + point(0, -1);
		if (border == left) idx2 = idx + point(-1, 0);

		if (border_change(board, copy, orig_idx, 3, 4))
			return orig_idx;

		if (border_change(board, copy, orig_idx2, 3, 4))
			return orig_idx2;

		return point(-1, -1);
	}
Esempio n. 27
0
bool abstract_piece::can_i_move(const board &m_board) const
{
    int8_t pieces_in_between = 0;
    bool found_one_g = false;
    bool am_i_in_between = false;
    for (int8_t irank = 0; irank < board::RANK_NUM; irank++) {
        auto piece = m_board.at(pos.file, irank);
        if (piece) {
            if (found_one_g) {
                if (piece->is_king()) {
                    break;
                }
                
                pieces_in_between++;
                if (*piece == *this) {
                    am_i_in_between = true;
                }
            } else if (piece->is_king()) {
                found_one_g = true;
            }
        }
    }
    
    return !am_i_in_between || pieces_in_between != 1;
}
Esempio n. 28
0
/*
Less-than operator
*/
bool board::operator< (board &compareMe){
	if (compareMe.score() < score()){
		return true;
	} else {
	return false;
	}
}
Esempio n. 29
0
int CalcWinPoint(const board::Board& board, const board::State state) {
  using board::countBoard;
  auto num = countBoard(board); 
  if (state == board::State::BLACK) {
    return (num.first - num.second) * 1000;
  } else {
    return (num.second - num.first) * 1000;
  }
}
Esempio n. 30
0
evaluate::score evaluate::end_eval(const board&b , int turn)
{
  score s ;
  location_list::location move ;
  location_list::iterator iter ;
  location_list move_list ;
  board buffer_b ;

  #pragma omp atomic
  evaluate::ecount++ ;

  gen_move::generate_move(b, turn, move_list) ;
  if(move_list.is_empty()) {
    gen_move::generate_move(b, (turn+1)%2, move_list) ;
    if(move_list.is_empty()) {    
      if(side == board::BLACK) 
        return b.get_black_count() >= b.get_white_count() ? 9999990 : -9999990 ;
      else 
        return b.get_white_count() >= b.get_black_count() ? 9999990 : -9999990 ;
    } else {
      turn = (turn + 1) % 2 ;
    }
  }

  if(side == turn) {
    for(iter = move_list.begin() ; iter != move_list.end() ; iter++) {
      buffer_b = b ;
      move = *iter ;
      buffer_b.move_at(move, turn)  ;
      s = end_eval(buffer_b, (turn+1)%2) ;
      if(s > 0) return s ;
    }
    return -9999990 ;
  } else {
    for(iter = move_list.begin() ; iter != move_list.end() ; iter++) {
      buffer_b = b ;
      move = *iter ;
      buffer_b.move_at(move, turn)  ;
      s = end_eval(buffer_b, (turn+1)%2) ;
      if(s < 0) return s ;
    }
    return 9999990 ;
  }
}