예제 #1
0
void Board8x8::generateBishopMoves(uint row, uint col, MoveList & moveList)
{
  uint index = getIndex(row, col);
  generateMoves(mBishopMovesNorthEast[index], row, col, moveList, true);
  generateMoves(mBishopMovesSouthWest[index], row, col, moveList, true);
  generateMoves(mBishopMovesNorthWest[index], row, col, moveList, true);
  generateMoves(mBishopMovesSouthEast[index], row, col, moveList, true);
}
예제 #2
0
void Board8x8::generateRookMoves(uint row, uint col, MoveList & moveList)
{
  uint index = getIndex(row, col);
  generateMoves(mRookMovesNorth[index], row, col, moveList, true);
  generateMoves(mRookMovesSouth[index], row, col, moveList, true);
  generateMoves(mRookMovesEast[index], row, col, moveList, true);
  generateMoves(mRookMovesWest[index], row, col, moveList, true);
}
예제 #3
0
파일: Knight.cpp 프로젝트: qzmp/Chess
list<Movement> Knight::generateMoves(GameStatus& currentStatus){
	list<Movement> moves;

	//top top left
	moves.splice(moves.end(), generateMoves(currentStatus, -1, -2));

	//bottom top left
	moves.splice(moves.end(), generateMoves(currentStatus, -2, -1));

	//top top right
	moves.splice(moves.end(), generateMoves(currentStatus, 1, -2));

	//bottom top right
	moves.splice(moves.end(), generateMoves(currentStatus, 2, -1));

	//top bottom right
	moves.splice(moves.end(), generateMoves(currentStatus, 2, -1));

	//bottom bottom right
	moves.splice(moves.end(), generateMoves(currentStatus, 1, 2));

	//top bottom left
	moves.splice(moves.end(), generateMoves(currentStatus, -1, 2));

	//bottom bottom left
	moves.splice(moves.end(), generateMoves(currentStatus, -2, 1));

	return moves;
}
예제 #4
0
bool ChessBoard::isLegalMove(int mv)
{
    int sqSrc, sqDst, pcSrc, pcDst;
    sqSrc = SRC(mv);
    sqDst = DST(mv);
    if (sqSrc==sqDst)
    {
        return false;
    }
    pcSrc = m_data[sqSrc];
    pcDst = m_data[sqDst];
    if (side(pcSrc)==side(pcDst))
    {
        return false;
    }

    Moves mvs;
    generateMoves(sqSrc, mvs);
    for(int i=0; i<mvs.count(); i++)
    {
        if (mvs[i]==mv)
        {
            return true;
        }
    }
    return false;
}
예제 #5
0
bool LosersBoard::vIsLegalMove(const Move& move)
{
	bool isCapture = (captureType(move) != Piece::NoPiece);
	if (m_captureKey != key()
	&&  !isCapture)
	{
		m_captureKey = key();
		m_canCapture = false;

		QVarLengthArray<Move> moves;
		generateMoves(moves);

		for (int i = 0; i < moves.size(); i++)
		{
			if (captureType(moves[i]) != Piece::NoPiece
			&&  WesternBoard::vIsLegalMove(moves[i]))
			{
				m_canCapture = true;
				break;
			}
		}
	}

	if (!isCapture && m_canCapture)
		return false;
	return WesternBoard::vIsLegalMove(move);
}
예제 #6
0
int ChessBoard::test1_max(int depth, int& mv)
{
    if (depth==0)
    {
        mv = 0;
        return m_vlBlack - m_vlRed;
    }
    Moves mvs;
    //int selfSide = m_sdPlayer;
    int best = -999999;
    generateMoves(mvs);
    for(int i=0; i<mvs.count(); i++)
    {
        int oldVal = m_vlBlack - m_vlRed;
        int pcCapture;
        if (makeMove(mvs[i], pcCapture))
        {
            int temp_mv;
            int val = test1_min(depth-1, temp_mv);
            if (val>best)
            {
               best = val;
               mv = mvs[i];
            }
            undoMakeMove(mvs[i], pcCapture);
        }

        int newVal = m_vlBlack - m_vlRed;
        Q_ASSERT(oldVal==newVal);
    }
    return best;
}
예제 #7
0
파일: c2.c 프로젝트: chriskonnertz/c2-chess
/**
* KI macht einen zufaelligen Zug.
* Gibt 1 zurueck, wenn ein Zug ausgefuehrt wurde, sonst 0.
*/
char aiSimpleMove(struct GameState *gs) {
	char moves[28 * 16 * 2]; // keine Initialiserung!
	short movesCounter;

	generateMoves(gs, moves, &movesCounter);

	short found = 0;
	short move;
	for (move = 0; move < movesCounter; move += 2) {
		short pieceFrom = (*gs).board[moves[move]];
		short pieceTo = (*gs).board[moves[move + 1]];

		doMovePartial(gs, moves[move], moves[move + 1]);

		short check = isCheck(gs);

		(*gs).board[moves[move]] = pieceFrom;
		(*gs).board[moves[move + 1]] = pieceTo;

		if (check) { // Schach?
			moves[move] = 0;
		} else {
			found++;
		}
	}

	if (found == 0) {
		if (isCheck(gs)) {
			printInfo("KI ist Schachmatt!\n");	
		} else {
			printInfo("KI ist Patt gesetzt!\n");
		}
		return 0;
	}

	short r = rand() % found;
	found = 0;
	for (move = 0; move < movesCounter; move += 2) {
		if (moves[move] != 0) {
			if (found == r) {
				break;
			}
			found++;
		}
	}

	char c1[] = "??"; char c2[] = "??";
	convertIndexToCoord(moves[move], c1); convertIndexToCoord(moves[move + 1], c2);
	if ((*gs).board[moves[move + 1]] == 0) {
		printInfo("KI zieht mit %c von %s nach %s.\n", getPieceSymbolAsChar((*gs).board[moves[move]]), c1, c2);	
	} else {
		printInfo("KI zieht mit %c von %s nach %s und schlaegt %c.\n", getPieceSymbolAsChar((*gs).board[moves[move]]), c1, c2, getPieceSymbolAsChar((*gs).board[moves[move + 1]]));	
	}

	doMovePartial(gs, moves[move], moves[move + 1]);
	doMoveFinal(gs, moves[move], moves[move + 1]);

	return 1;
}
예제 #8
0
uchar Board0x88::generateOpponentMoves(MoveList & moveList)
{
  uchar sideToMove = mSideToMove;
  mSideToMove = !mSideToMove;
  generateMoves(moveList);
  mSideToMove = sideToMove;
  return moveList.size();
}
예제 #9
0
void ChessBoard::generateMoves(Moves& mvs)
{
    for(int sq=0; sq<256; sq++)
    {
        int pc = m_data[sq];
        if (!pc) continue;
        if (side(pc) == m_sdPlayer)
        {
            generateMoves(sq, mvs);
        }
    }
}
예제 #10
0
파일: moves.c 프로젝트: kervinck/floyd
long long moveTest(Board_t self, int depth)
{
        if (depth <= 0)
                return 1;
        long long total = 0;
        int moveList[maxMoves];
        int nrMoves = generateMoves(self, moveList);
        for (int i=0; i<nrMoves; i++) {
                makeMove(self, moveList[i]);
                if (wasLegalMove(self))
                        total += moveTest(self, depth - 1);
                undoMove(self);
        }
        return total;
}
예제 #11
0
// This function should not be called by engines, it would be greatly inefficient
// It exists simply to find the legal moves for a particular
// square, such as is needed when running in a GUI
uchar Board0x88::generateMoves(uchar row, uchar col, MoveList & moveList)
{
  MoveList allMoves;
  uchar totalMoves = generateMoves(allMoves);

  for (uchar i = 0; i < totalMoves; i++) {
    if (allMoves[i].sourceRow == row && allMoves[i].sourceCol == col) {
      makeMove(allMoves[i]);
      if (!isCellAttacked(mKingIndex[!mSideToMove], mSideToMove) )
        moveList.addMove(allMoves[i]);
      unmakeMove(allMoves[i]);
    }
  }
  return moveList.size();
}
예제 #12
0
Move Board::randomMove()
{
    Move m;
    MoveList list;

    generateMoves(list);
    int l = list.getLength();

    int j = (::rand() % l) +1;

    while(j != 0) {
        list.getNext(m, Move::none);
        j--;
    }

    return m;
}
예제 #13
0
void Board8x8::generateKingMoves(uint row, uint col, MoveList & moveList)
{
  uint index = getIndex(row, col);
  generateMoves(mKingMoves[index], row, col, moveList, false);

  bool queenSide = (mWhiteToMove) ? mWhiteCastleQueenSide : mBlackCastleQueenSide;
  bool kingSide = (mWhiteToMove) ? mWhiteCastleKingSide : mBlackCastleKingSide;
  uint rowCheck = (mWhiteToMove) ? WHITE_KING_START_ROW : BLACK_KING_START_ROW;

  if (kingSide && getPieceType(rowCheck, 5) == NoPiece && getPieceType(rowCheck, 6) == NoPiece) {
    bool canCastle = true;
    uint attackCol = 4;
    while (attackCol <= 6) {
      if (isCellAttacked(rowCheck, attackCol, mWhiteToMove)) {
        canCastle = false;
        break;
      }
      attackCol++;
    }

    if (canCastle) {
      Move newMove(rowCheck, 4, rowCheck, 6);
      newMove.setKingCastle();
      moveList.addMove(newMove);
    }
  }

  if (queenSide && getPieceType(rowCheck,3) == NoPiece && getPieceType(rowCheck,2) == NoPiece && getPieceType(rowCheck,1) == NoPiece) {
    bool canCastle = true;
    uint attackCol = 4;
    while (attackCol >= 2) {
      if (isCellAttacked(rowCheck, attackCol, mWhiteToMove)) {
        canCastle = false;
        break;
      }
      attackCol--;
    }

    if (canCastle) {
      Move newMove(rowCheck, 4, rowCheck, 2);
      newMove.setQueenCastle();
      moveList.addMove(newMove);
    }
  }
}
예제 #14
0
파일: Board.cpp 프로젝트: weidendo/qenolaba
Move Board::randomMove()
{
    Move m;
    MoveList list;

    generateMoves(list);
    int l = list.getLength();

    // FIXME: start with random seed using qsrand() somewhere
    int j = (qrand() % l) +1;

    while(j != 0) {
	list.getNext(m, Move::none);
	j--;
    }

    return m;
}
bool CheckersBoard::makeMove(const std::array<std::array<uint8_t, 8>, 8> &i_board, const bool color)
{
	//Bool to determine if move is valid
	bool validMove = false;
	//Generate moves
	generateMoves(color);

	for(Move &possible_move: move_List)
	{
		if(i_board == possible_move.move_board)
		{
			validMove = true;
			board = i_board;
		}
	}

	return validMove;	
}
예제 #16
0
파일: AI.cpp 프로젝트: dougfrazer/SDP
double AI::evaluateState(fizGTableState state, turn_T turn){
	set<shot> moves;

	generateMoves(state, moves, turn);

	double w[] = {1.0, .33, .15};

	double sum = 0;

	set<shot>::iterator iter = moves.begin();
	if(moves.empty()) return 1;

	for(int i = 0; iter != moves.end(); i++, iter++){
		sum += iter->probability * w[i];
	}

	return sum;
}
int _search(searchNode* thisNode, const int maxDepth, int depth, int parentHeuristic)
{
	thisNode->setNodeCount(nodeCounter++);
	if (thisNode->anyKingsMissing())
	{
		return simpleHeuristic(thisNode->getBoard());
	}
	int currentPlayer = (depth % 2);
	if (depth == maxDepth)
	{
		return simpleHeuristic(thisNode->getBoard());
	}
	Board currentBoard = thisNode->getBoard();
	std::vector<Board> possibles = generateMoves(currentBoard.getPieces(currentPlayer), currentBoard);
	if (possibles.size() == 0)
	{
		return simpleHeuristic(thisNode->getBoard());
	}
	int bestHeuristic = UNSET;
	for (int p = 0; p < possibles.size(); ++p)
	{
		//std::cout << "depth " << depth << " trying possibles[" << p << "] whose move is " << possibles[p].getMoveName() << "\n";
		searchNode* newNode = new searchNode(possibles[p]);
		thisNode->addChild(newNode);
		//std::cout << "newNode should match possibles[p] move name: " << newNode->getMoveName() << "\n";
		int childHeuristic = _search(newNode,maxDepth,depth+1,bestHeuristic);
		newNode->setHeuristic(childHeuristic);
		updateBestHeuristic(currentPlayer, bestHeuristic, childHeuristic);
		if (parentHeuristic != UNSET) 
		{
			if (
				(currentPlayer == 1 && bestHeuristic < parentHeuristic) ||
				(currentPlayer == 0 && bestHeuristic > parentHeuristic)
				)
			{
				thisNode->setCutoff(true);
				break;
			}
		}
	}
	thisNode->setHeuristic(bestHeuristic);
	return bestHeuristic;
}
예제 #18
0
bool ChessBoard::IsMate()
{   
    //qDebug()<<"check isMate side="<<m_sdPlayer;
    //int selfSide = m_sdPlayer;
    Moves mvs;
    generateMoves(mvs);
    for(int i=0; i<mvs.count(); i++)
    {
        //qDebug()<<"尝试解招:"<< mvString(mvs[i]);
        int pcCaptured = _movePiece(mvs[i]);
        if (!isChecked())
        {
            _undoMovePiece(mvs[i], pcCaptured);
            //qDebug()<<"!!!解招:"<< mvString(mvs[i]);
            return false;
        }
        else{
            _undoMovePiece(mvs[i], pcCaptured);
        }
    }
    return true;
}
예제 #19
0
int ChessBoard::negaMax(int depth, int& mv)
{
    if (depth==0)
    {
        return m_sdPlayer?m_vlBlack - m_vlRed:m_vlRed - m_vlBlack;
    }
    m_searchCallTimes++;
    int best = INT_MIN;
    Moves mvs;
    generateMoves(mvs);
    for(int i=0; i<mvs.count(); i++)
    {
        int oldVal = m_vlBlack - m_vlRed;
        int pcCapture;
        //qDebug()<<mvString(mvs[i]);
        if (makeMove(mvs[i], pcCapture))
        {
            int temp_mv;
            int val = -1 * negaMax(depth-1, temp_mv);

            if (temp_mv)
            {
                //qDebug()<<mvString(temp_mv)<<" 评分"<<val;
            }
            if (val>best)
            {
               best = val;
               mv = mvs[i];
            }
            undoMakeMove(mvs[i], pcCapture);
            //qDebug()<<"UndoMakeMove";
        }

        int newVal = m_vlBlack - m_vlRed;
        Q_ASSERT(oldVal==newVal);
    }
    return best;
}
예제 #20
0
파일: Search.cpp 프로젝트: niklasf/Cinnamon
int Search::printDtm() {
    int side = getSide();
    u64 friends = side == WHITE ? getBitmap<WHITE>() : getBitmap<BLACK>();
    u64 enemies = side == BLACK ? getBitmap<WHITE>() : getBitmap<BLACK>();
    display();
    int res = side ? getGtb().getDtm<WHITE, true>(chessboard, chessboard[RIGHT_CASTLE_IDX], 100) : getGtb().getDtm<BLACK, true>(chessboard, chessboard[RIGHT_CASTLE_IDX], 100);
    cout << " res: " << res;
    incListId();
    generateCaptures(side, enemies, friends);
    generateMoves(side, friends | enemies);
    _Tmove *move;
    u64 oldKey = 0;
    cout << "\n succ. \n";
    int best = -_INFINITE;
    for (int i = 0; i < getListSize(); i++) {
        move = &gen_list[listId].moveList[i];
        makemove(move, false, false);
        cout << "\n" << decodeBoardinv(move->type, move->from, getSide()) << decodeBoardinv(move->type, move->to, getSide()) << " ";
        res = side ? -getGtb().getDtm<BLACK, true>(chessboard, chessboard[RIGHT_CASTLE_IDX], 100) : getGtb().getDtm<WHITE, true>(chessboard, chessboard[RIGHT_CASTLE_IDX], 100);
        if (res != -INT_MAX) {
            cout << " res: " << res;
        }
        cout << "\n";
        takeback(move, oldKey, false);
        if (res > best) {
            best = res;
        }
    }
    if (best > 0) {
        best = _INFINITE - best;
    } else if (best < 0) {
        best = -(_INFINITE - best);
    }
    cout << endl;
    decListId();
    return best;
}
예제 #21
0
Move Board::randomMove()
{
	static int i = 999;
	unsigned int j,l;

	Move m;
	MoveList list;
	
	/* we prefer to use QT... */
	j = (QTime::currentTime()).msec();
	
	generateMoves(list);
	l = list.getLength();

	j = (j + i) % l +1;
	if ( (i+=7)>10000) i-=10000;
	
	while(j != 0) {
		list.getNext(m, Move::none);
		j--;
	}	
	
	return m;
}
예제 #22
0
void testGenerateMoves() {
  int _b[2][25] =   
  {
    {1, 1, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0}, 
    {0, 2, 2, 3, 0, 3, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} //PC
  };
  
  ConstTanBoard b=ms.anBoard;
  printf("\n\nTEST GENERATE MOVES...\n");
  printBoard((ConstTanBoard)b);
  int dices[2] = {4, 6};
  printDices(dices);
  
  int** moves; 
  int nMoves;

  moves = generateMoves((ConstTanBoard)b, dices[0], dices[1], &nMoves);
  int i=0;
  for (i=0;i<nMoves;i++) {
    printMove(moves[i]);
  }
  printf("MOVES: %d\n", nMoves);
  printf("AIlevel: %d\n\n", currentAILevel);
}
예제 #23
0
int MinimaxStrategy::minimax()
{
	Move m;
	MoveList list;
//	int maxEval, minEval;
	int bestEval;
	int eval;	
	int sign;

	if(current_depth == MAX_DEPTH)
		return evaluate();

	bestEval = -17000;
//	maxEval = -17000;
//	minEval = 17000;

	generateMoves(list);
	
	if(evaluate() == 16000)
	{
		if(current_depth == 0)
			finishedNode(0,0);
		pretty_print("current_depth", current_depth);
		return ((current_depth % 2) ==0) ? -16000 : 16000;
	}

	if((MAX_DEPTH-current_depth)%2 == 1)
		sign = 1;
	else
		sign = -1;

	while(list.getNext(m))	
	{
		if(current_depth < MAX_DEPTH)
		{
			current_depth++;
			playMove(m);
			eval=minimax();
			takeBack();
			current_depth--;
		}

		if(sign*eval > bestEval)
		{
			bestEval = sign*eval;
			if(unlikely(current_depth == 0)) {
				pretty_print("Eval", bestEval);
				foundBestMove(0, m, eval);
			}
		}

#if 0
		if((MAX_DEPTH - current_depth +1) % 2 == 0)
		{
			if(eval > maxEval)
			{
				maxEval=eval;
				if(current_depth == 0) {
					pretty_print("Eval", eval);
					foundBestMove(0, m, eval);
				}
			}
		}
		else
		{
			if(eval < minEval)
			{
				minEval=eval;                   
				if(current_depth == 0) {
					pretty_print("Eval2", eval);
					foundBestMove(0, m, eval);
				}

			}
		}
#endif
	}
	bestEval = sign*bestEval;

	if(current_depth == 0)
		finishedNode(0,0);
#if 0
	if((MAX_DEPTH - current_depth +1) % 2 == 0)
		return maxEval;
	else
                return minEval;
#endif

	return bestEval;
}
예제 #24
0
void t_chessCli::run()
{
   for (;;)
   {
      t_message message;

      {
         boost::unique_lock<boost::mutex> lock(sharedData.gameMutex);

         if (sharedData.gameBuffer.empty())
         {
            sharedData.gameCondition.wait(lock);
         }

         message = sharedData.gameBuffer.back();
         sharedData.gameBuffer.pop_back();

      }

      std::cout<<"I have recieved a message"<<std::endl;

      switch (message.id)
      {

      case BOARD_CLICKED:
      {
         t_myVector2 pos = message.boardClicked.pos;
         std::cout<<"It was clicked at "<<pos<<std::endl;

         t_message newMessage;
         newMessage.id = HIGHLIGHT_SPACE;


         if (selected)
         {
            if (pos == selectedPos)
            {
               selected = 0;
               newMessage.highlightSpace.pos = selectedPos;
               newMessage.highlightSpace.color = 0;
               {
                  boost::unique_lock<boost::mutex> lock(sharedData.clientMutex);

                  sharedData.clientBuffer.push_front(newMessage);

                  for (auto iter = move.begin(); iter != move.end(); iter++)
                  {
                     newMessage.highlightSpace.pos = *iter;
                     newMessage.highlightSpace.color = 0;

                     sharedData.clientBuffer.push_front(newMessage);
                  }

                  for (auto iter = hit.begin(); iter != hit.end(); iter++)
                  {
                     newMessage.highlightSpace.pos = *iter;
                     newMessage.highlightSpace.color = 0;

                     sharedData.clientBuffer.push_front(newMessage);
                  }

                  for (auto iter = castle.begin(); iter != castle.end(); iter++)
                  {
                     newMessage.highlightSpace.pos = *iter;
                     newMessage.highlightSpace.color = 0;

                     sharedData.clientBuffer.push_front(newMessage);
                  }
               }

               move.clear();
               hit.clear();
               castle.clear();
            }

            else if (std::find(move.begin(), move.end(), pos) != move.end())
            {
               if (checkCheck(pos,selectedPos))
               {
                  std::cout<<"I am in check"<<std::endl;
                  break;
               }

               if (turn == 0)
               {
                  whitePieces.erase(selectedPos);
                  whitePieces.insert(pos);
               }

               else
               {
                  blackPieces.erase(selectedPos);
                  blackPieces.insert(pos);
               }

               removeCastle(pos,selectedPos);

               selected = 0;
               newMessage.highlightSpace.pos = selectedPos;
               newMessage.highlightSpace.color = 0;
               
               {
                  boost::unique_lock<boost::mutex> lock(sharedData.clientMutex);

                  sharedData.clientBuffer.push_front(newMessage);

                  for (auto iter = move.begin(); iter != move.end(); iter++)
                  {
                     newMessage.highlightSpace.pos = *iter;
                     newMessage.highlightSpace.color = 0;

                     sharedData.clientBuffer.push_front(newMessage);
                  }

                  for (auto iter = hit.begin(); iter != hit.end(); iter++)
                  {
                     newMessage.highlightSpace.pos = *iter;
                     newMessage.highlightSpace.color = 0;

                     sharedData.clientBuffer.push_front(newMessage);
                  }

                  for (auto iter = castle.begin(); iter != castle.end(); iter++)
                  {
                     newMessage.highlightSpace.pos = *iter;
                     newMessage.highlightSpace.color = 0;

                     sharedData.clientBuffer.push_front(newMessage);
                  }

                  newMessage.id = MOVE_PIECE;
                  newMessage.movePiece.pos = pos;
                  newMessage.movePiece.oldPos = selectedPos;

                  sharedData.clientBuffer.push_front(newMessage);
               }

               move.clear();
               hit.clear();
               castle.clear();

               board[pos.y][pos.x] = board[selectedPos.y][selectedPos.x];
               board[selectedPos.y][selectedPos.x] = 0;

               turn = !turn;

               if (checkCheckmate())
               {
                  std::cout<<"I win"<<std::endl;
               }
            }

            else if (std::find(hit.begin(), hit.end(), pos) != hit.end())
            {
               if (checkCheck(pos,selectedPos))
               {
                  std::cout<<"I am in check"<<std::endl;
                  break;
               }

               if (turn == 0)
               {
                  whitePieces.erase(selectedPos);
                  whitePieces.insert(pos);

                  blackPieces.erase(pos);
               }

               else
               {
                  blackPieces.erase(selectedPos);
                  blackPieces.insert(pos);

                  whitePieces.erase(pos);
               }

               removeCastle(pos,selectedPos);

               selected = 0;
               newMessage.highlightSpace.pos = selectedPos;
               newMessage.highlightSpace.color = 0;
               
               {
                  boost::unique_lock<boost::mutex> lock(sharedData.clientMutex);

                  sharedData.clientBuffer.push_front(newMessage);

                  for (auto iter = move.begin(); iter != move.end(); iter++)
                  {
                     newMessage.highlightSpace.pos = *iter;
                     newMessage.highlightSpace.color = 0;

                     sharedData.clientBuffer.push_front(newMessage);
                  }

                  for (auto iter = hit.begin(); iter != hit.end(); iter++)
                  {
                     newMessage.highlightSpace.pos = *iter;
                     newMessage.highlightSpace.color = 0;

                     sharedData.clientBuffer.push_front(newMessage);
                  }

                  for (auto iter = castle.begin(); iter != castle.end(); iter++)
                  {
                     newMessage.highlightSpace.pos = *iter;
                     newMessage.highlightSpace.color = 0;

                     sharedData.clientBuffer.push_front(newMessage);
                  }

                  newMessage.id = CAPTURE_PIECE;
                  newMessage.movePiece.pos = pos;
                  newMessage.movePiece.oldPos = selectedPos;

                  sharedData.clientBuffer.push_front(newMessage);
               }

               move.clear();
               hit.clear();
               castle.clear();

               board[pos.y][pos.x] = board[selectedPos.y][selectedPos.x];
               board[selectedPos.y][selectedPos.x] = 0;

               turn = !turn;

               if (checkCheckmate())
               {
                  std::cout<<"I win"<<std::endl;
               }
            }

            else if (std::find(castle.begin(), castle.end(), pos) != castle.end())
            {
               if (checkCheck(pos,selectedPos))
               {
                  std::cout<<"I am in check"<<std::endl;
                  break;
               }

               if (turn == 0)
               {
                  whitePieces.erase(selectedPos);
                  whitePieces.insert(pos);
               }

               else
               {
                  blackPieces.erase(selectedPos);
                  blackPieces.insert(pos);
               }

               removeCastle(pos,selectedPos);

               selected = 0;
               newMessage.highlightSpace.pos = selectedPos;
               newMessage.highlightSpace.color = 0;
               
               {
                  boost::unique_lock<boost::mutex> lock(sharedData.clientMutex);

                  sharedData.clientBuffer.push_front(newMessage);

                  for (auto iter = move.begin(); iter != move.end(); iter++)
                  {
                     newMessage.highlightSpace.pos = *iter;
                     newMessage.highlightSpace.color = 0;

                     sharedData.clientBuffer.push_front(newMessage);
                  }

                  for (auto iter = hit.begin(); iter != hit.end(); iter++)
                  {
                     newMessage.highlightSpace.pos = *iter;
                     newMessage.highlightSpace.color = 0;

                     sharedData.clientBuffer.push_front(newMessage);
                  }

                  for (auto iter = castle.begin(); iter != castle.end(); iter++)
                  {
                     newMessage.highlightSpace.pos = *iter;
                     newMessage.highlightSpace.color = 0;

                     sharedData.clientBuffer.push_front(newMessage);
                  }

                  newMessage.id = MOVE_PIECE;
                  newMessage.movePiece.pos = pos;
                  newMessage.movePiece.oldPos = selectedPos;

                  sharedData.clientBuffer.push_front(newMessage);

                  if (pos.x == 2) //left castle
                  { 
                     newMessage.movePiece.pos.x = 3;
                     newMessage.movePiece.oldPos.x = 0;
                  }

                  else
                  {
                     newMessage.movePiece.pos.x = 5;
                     newMessage.movePiece.oldPos.x = 7;
                  }
                     sharedData.clientBuffer.push_front(newMessage);
               }

               move.clear();
               hit.clear();
               castle.clear();

               board[pos.y][pos.x] = board[selectedPos.y][selectedPos.x];
               board[selectedPos.y][selectedPos.x] = 0;

               if (pos.x == 2) //left
               {
                  pos.x = 3;
                  selectedPos.x = 0;

                  board[pos.y][3] = board[selectedPos.y][0];
                  board[selectedPos.y][0] = 0;
               }
               
               else 
               {
                  pos.x = 5;
                  selectedPos.x = 7;

                  board[pos.y][5] = board[selectedPos.y][7];
                  board[selectedPos.y][7] = 0;
               }

               if (turn == 0)
               {
                  whitePieces.erase(selectedPos);
                  whitePieces.insert(pos);
               }

               else
               {
                  blackPieces.erase(selectedPos);
                  blackPieces.insert(pos);
               }

               turn = !turn;


               if (checkCheckmate())
               {
                  std::cout<<"I win"<<std::endl;
               }
            }



         }

         else if (board[pos.y][pos.x] && board[pos.y][pos.x]/8 == turn)
         {
            selected = 1;
            selectedPos = pos;
            newMessage.highlightSpace.pos = pos;
            newMessage.highlightSpace.color = 1;

            generateMoves(pos);

            {
               boost::unique_lock<boost::mutex> lock(sharedData.clientMutex);

               sharedData.clientBuffer.push_front(newMessage);

               for (auto iter = move.begin(); iter != move.end(); iter++)
               {
                  newMessage.highlightSpace.pos = *iter;
                  newMessage.highlightSpace.color = 2;

                  sharedData.clientBuffer.push_front(newMessage);
               }

               for (auto iter = hit.begin(); iter != hit.end(); iter++)
               {
                  newMessage.highlightSpace.pos = *iter;
                  newMessage.highlightSpace.color = 3;

                  sharedData.clientBuffer.push_front(newMessage);
               }

               for (auto iter = castle.begin(); iter != castle.end(); iter++)
               {
                  newMessage.highlightSpace.pos = *iter;
                  newMessage.highlightSpace.color = 4;

                  sharedData.clientBuffer.push_front(newMessage);
               }

            }


         }



         break;
      }

      case QUIT_MESSAGE:
         std::cout<<"It told me to quit"<<std::endl;
         return;

      default:
         std::cout<<"And I do not know what it was"<<std::endl;

      }
   }
}
예제 #25
0
void findPerftBug(const std::string& validatorPath, const ChessPosition* pP, int depth)
{
	// allocate fen buffer;
	char fenBuffer[1024];
	std::string fenString;

	// generate Move List
	ChessMove MoveList[MOVELIST_SIZE];
	generateMoves(*pP, MoveList);
	
	PerftInfo T;

	if (depth <= 1) { // terminal node

		// generate FEN string
		memset(fenBuffer, 0, 1024);
		writeFen(fenBuffer, pP);
		fenString.assign(fenBuffer);

		std::cout << "Reached Single Position!\n";

		dumpChessPosition(*pP);
		dumpMoveList(MoveList);
		T.nMoves = T.nCapture = T.nEPCapture = T.nCastle = T.nCastleLong = T.nPromotion = 0LL;
		perftMT(*pP, 1, 1, &T);
		int nResult = perftValidateWithExternal(validatorPath, fenString, 1, T.nMoves);
		if (nResult == PERFTVALIDATE_FALSE) {
			std::cout << "Engines disagree on Number of moves from this position" << std::endl;
		} else {
			std::cout << "ok" << std::endl;
		}

		std::cout << "Hit enter to continue" << std::endl;
		getchar();

		return;
	}

	ChessMove* pM = MoveList;
	ChessPosition Q;

	while (pM->NoMoreMoves == 0)
	{
		// Set up position
		Q = *pP;
		Q.performMove(*pM);
		Q.switchSides();

		// generate FEN string
		memset(fenBuffer, 0, 1024);
		writeFen(fenBuffer, &Q);
		fenString.assign(fenBuffer);

		std::cout << "After Move: ";
		if (pP->BlackToMove)
			std::cout << "... ";
		dumpMove(*pM);
		std::cout << "Position: " << fenString << std::endl;

		T.nMoves = T.nCapture = T.nEPCapture = T.nCastle = T.nCastleLong = T.nPromotion = 0LL;
		perftMT(Q, depth - 1, 1, &T);

		std::cout << "\nValidating depth: " << depth - 1 << " perft: " << T.nMoves << std::endl;
		int nResult = perftValidateWithExternal(validatorPath, fenString, depth - 1, T.nMoves);
		if (nResult == PERFTVALIDATE_FALSE)
		{
			// Investigate further ...
			std::cout << "WRONG !! Taking a closer look ..." << std::endl;
			findPerftBug(validatorPath, &Q, depth - 1);
		}
		else
		{
			std::cout << "ok";
		}
		std::cout << "\n" << std::endl;

		pM++;
	}
	std::cout << "findPerftBug() finished\n\n";
}
예제 #26
0
파일: Board.cpp 프로젝트: weidendo/qenolaba
/*
 * We always try the maximize the board value
 */
int Board::search(int depth, int alpha, int beta)
{
    int actValue= -14999+depth, value;
    Move m;
    MoveList list;
    bool depthPhase, doDepthSearch;

    searchCalled++;

    /* We make a depth search for the following move types... */
    int maxType = (depth < maxDepth-1)  ? Move::maxMoveType() :
					  (depth < maxDepth)    ? Move::maxPushType() :
								  Move::maxOutType();

    generateMoves(list);

#ifdef MYTRACE

    int oldRatedPositions;
    int oldWonPositions;
    int oldSearchCalled;
    int oldMoveCount;
    int oldNormalCount;
    int oldPushCount;
    int oldOutCount;
    int oldCutoffCount;

    spyDepth = depth;

    moveCount += list.getLength();

    /*
	  if (spyLevel>1) {
	  indent(depth);
	  qDebug("%s (%6d .. %6d) MaxType %s\n", depth,
	  (color==color1)?"O":"X", alpha,beta,
		 (depth < maxDepth-1) ? "Moving" :
		 (depth < maxDepth)? "Pushing" : "PushOUT" );
	}
	*/
#endif

    /* check for a old best move in main combination */
    if (inPrincipalVariation) {
	m = pv[depth];

	if ((m.type != Move::none) &&
	    (!list.isElement(m, 0, true)))
	    m.type = Move::none;

	if (m.type == Move::none)
	    inPrincipalVariation = false;

#ifdef MYTRACE
	else {
	    if (spyLevel>1) {
		indent(spyDepth);
		qDebug("Got from pv !\n" );
	    }
	}
#endif
    }

    // first, play all moves with depth search
    depthPhase = true;

    while (1) {

	// get next move
	if (m.type == Move::none) {
	    if (depthPhase)
		depthPhase = list.getNext(m, maxType);
	    if (!depthPhase)
		if (!list.getNext(m, Move::none)) break;
	}
	// we could start with a non-depth move from principal variation
	doDepthSearch = depthPhase && (m.type <= maxType);

#ifdef MYTRACE

	if (m.isOutMove()) outCount++;
	else if (m.isPushMove()) pushCount++;
	else normalCount++;

	if (doDepthSearch) {
	    oldRatedPositions = ratedPositions;
	    oldWonPositions = wonPositions;
	    oldSearchCalled = searchCalled;
	    oldMoveCount = moveCount;
	    oldNormalCount = normalCount;
	    oldPushCount = pushCount;
	    oldOutCount = outCount;
	    oldCutoffCount = cutoffCount;

	    if (spyLevel>1) {
		indent(spyDepth);
		qDebug("%s [%6d .. %6d] ",
		       (color==color1)?"O":"X", alpha,beta);
		m.print();
		qDebug("\n");
	    }

#ifdef SPION
	    if (bUpdateSpy) emit update(depth, 0, m, false);
#endif
	}
#endif

	playMove(m);
	if (!isValid()) {
	    /* Possibility (1) to win: Piece Count <9 */
	    value = 14999-depth;
	    //  value = ((depth < maxDepth) ? 15999:14999) - depth;
#ifdef MYTRACE
	    wonPositions++;
#endif
	}
	else {

	    if (doDepthSearch) {
		/* opponent searches for his maximum; but we want the
	       * minimum: so change sign (for alpha/beta window too!)
	       */
		value = - search(depth+1,-beta,-alpha);
	    }
	    else {
		ratedPositions++;

		value = calcEvaluation();
	    }
	}
	takeBack();

	/* For GUI response */
	if (doDepthSearch && (maxDepth - depth >2))
	    emit searchBreak();

#ifdef MYTRACE

	if (doDepthSearch) {
	    spyDepth = depth;

	    if (spyLevel>1) {

		indent(spyDepth);
		if (oldSearchCalled < searchCalled) {
		    qDebug("  %d Calls", searchCalled-oldSearchCalled);
		    if (cutoffCount>oldCutoffCount)
			qDebug(" (%d Cutoffs)", cutoffCount-oldCutoffCount);
		    qDebug(", GenMoves %d (%d/%d/%d played)",
			   moveCount - oldMoveCount,
			   normalCount - oldNormalCount,
			   pushCount-oldPushCount,
			   outCount-oldOutCount);
		    qDebug(", Rate# %d",
			   ratedPositions+wonPositions
			   - oldRatedPositions - oldWonPositions);
		    if (wonPositions > oldWonPositions)
			qDebug(" (%d Won)", wonPositions- oldWonPositions);
		    qDebug("\n");
		    indent(spyDepth);
		}

		qDebug("  => Rated %d%s\n",
		       value,
		       (value>14900)  ? ", WON !":
					(value>=beta)  ? ", CUTOFF !":
							 (value>actValue)  ? ", Best !": "");
	    }
	}
	else {
	    if (spyLevel>2) {
		indent(spyDepth);
		qDebug("%s (%6d .. %6d) %-25s => Rating %6d%s\n",
		       (color==color1)?"O":"X", alpha,beta,
		       m.name().toLatin1(),
		       value,
		       (value>14900)  ? ", WON !":
					(value>=beta)  ? ", CUTOFF !":
							 (value>actValue)  ? ", Best !": "");
	    }
	}

	if (value>=beta) cutoffCount++;
#endif

#ifdef SPION
	if (bUpdateSpy) {
	    if (value > actValue)
		emit updateBest(depth, value, m, value >= beta);
	    emit update(depth, value, m, true);
	}
#endif
	if (value > actValue) {
	    actValue = value;
	    pv.update(depth, m);

	    // Only update best move if not stopping search
	    if (!breakOut && (depth == 0)) {
		_bestMove = m;

		if (bUpdateSpy) {
		    emit updateBestMove(m, actValue);
#ifdef MYTRACE
		    if (spyLevel>0) {
			int i;
			qDebug(">      New pv (Rating %d):", actValue);
			for(i=0;i<=maxDepth;i++) {
			    qDebug("\n>          D %d: %s",
				   i, pv[i].name().toLatin1() );
			}
			qDebug("\n>\n");
		    }
#endif
		}
	    }

	    if (actValue>14900 || actValue >= beta)
		return actValue;

	    /* maximize alpha */
	    if (actValue > alpha) alpha = actValue;
	}

	if (breakOut) depthPhase=false;
	m.type = Move::none;
    }

    return actValue;
}
예제 #27
0
void Board8x8::generateKnightMoves(uint row, uint col, MoveList & moveList)
{
  uint index = getIndex(row, col);
  generateMoves(mKnightMoves[index], row, col, moveList, false);
}
예제 #28
0
Move Board::moveToReach(Board* b, bool fuzzy)
{
    Move m;

    /* can not move from invalid position */
    int state = validState();
    if ((state != valid1) && (state != valid2))
        return m;

    if (!fuzzy) {
        if (b->moveNo() != _moveNo+1) {
            if (_verbose)
                printf("Board::moveToReach: moveNo %d => %d ?!\n",
                       _moveNo, b->moveNo());
            return m;
        }
        /* only time left for player can have decreased */
        int opponent = (color == color1) ? color2 : color1;
        if (_msecsToPlay[opponent] != b->msecsToPlay(opponent)) {
            if (_verbose)
                printf("Board::moveToReach: Opponent time changed ?!\n");
            return m;
        }
        if (_msecsToPlay[color] < b->msecsToPlay(color)) {
            if (_verbose)
                printf("Board::moveToReach: Player time increased ?!\n");
            return m;
        }
    }

    /* detect move drawn */
    MoveList l;
    generateMoves(l);

    if (_verbose) {
        printf("Board::moveToReach - %d allowed moves:\n",
               l.getLength());
        Move found;
        int type = Move::none;
        while(l.getNext(m, Move::maxMoveType)) {
            playMove(m);

            bool isSame = hasSameFields(b);
            takeBack();
            if (isSame) found = m;

            if (m.type != type) {
                type = m.type;
                printf(" %s:\n", m.typeName());
            }
            printf("  %s%s\n", m.name(), isSame ? " <== Choosen":"");
        }
        m = found;
    }
    else {
        while(l.getNext(m, Move::maxMoveType)) {
            playMove(m);

            bool isSame = hasSameFields(b);
            takeBack();
            if (isSame) break;
        }
    }

    return m;
}
int MinimaxStrategy::minimax()
{
	Move m;
	Move bestestMove; //;-p This is the cumulative best move among all threads.
	MoveList list;
	int bestEval;
	int eval;	
	int sign;
	int move_counter=0;
	int i=0;

	if(current_depth == MAX_DEPTH)
		return evaluate();

	bestEval = -17000;

	generateMoves(list);

	if(evaluate() == 16000)
	{
		if(current_depth == 0)
			finishedNode(0,0);
		pretty_print("current_depth", current_depth);
		return ((current_depth % 2) ==0) ? -16000 : 16000;
	}

	if(current_depth == 0)
	{
		for(i=0;i<thread_rank;i++)
			list.getNext(m);
	}

	if((MAX_DEPTH-current_depth)%2 == 1)
		sign = 1;
	else
		sign = -1;

	while(list.getNext(m))	
	{
		if(current_depth < MAX_DEPTH)
		{
			current_depth++;
			playMove(m);
			eval=minimax();
			takeBack();
			current_depth--;
		}

		if(sign*eval > bestEval)
		{
			bestEval = sign*eval;
			if(unlikely(current_depth == 0)) {
				pretty_print("Eval", bestEval);
				foundBestMove(0, m, eval);
			}
		}

		if(current_depth == 0)
		{	
			for(i=1;i<num_threads;i++)
				list.getNext(m);
		}
	}
	bestEval = sign*bestEval;

	if(current_depth == 0) 
	{
		if(thread_rank==0)
		{	
			Move *moves=NULL;
			int *eval_results;
			moves=(Move*)malloc((num_threads -1)*sizeof(Move));
			eval_results=(int*)malloc((num_threads - 1)*sizeof(int));

			//all threads send value to thread 0
			for(int i=1;i<num_threads;i++)
			{
				MPI_Status status;
				MPI_Recv((void*)&moves[i-1], sizeof(Move), MPI_BYTE, i, 10,
						MPI_COMM_WORLD, &status);
				MPI_Recv(&eval_results[i-1], 1, MPI_INT, i, 10, 
						MPI_COMM_WORLD, &status);
			}

			bestestMove=_bestMove;
			for(int i=0;i<num_threads-1;i++)
			{
				if(sign*eval_results[i] > sign*bestEval)
				{
					bestEval = eval_results[i];
					bestestMove=moves[i];
				}
			}

			for(int i=1;i<num_threads;i++) 
			{
				MPI_Send (&bestestMove, sizeof(Move), MPI_BYTE, i, 10,
						MPI_COMM_WORLD);
				MPI_Send (&bestEval, 1, MPI_INT, i, 10,
						MPI_COMM_WORLD);
			}

		}	
		else 
		{
			MPI_Send (&_bestMove, sizeof(Move), MPI_BYTE, 0, 10,
					MPI_COMM_WORLD);
			MPI_Send (&bestEval, 1, MPI_INT, 0, 10,
					MPI_COMM_WORLD);

			MPI_Status status;
			MPI_Recv(&bestestMove, sizeof(Move), MPI_BYTE, 0, 10,
					MPI_COMM_WORLD, &status);
			MPI_Recv(&bestEval, 1, MPI_INT, 0, 10,
					MPI_COMM_WORLD, &status);
		}
		foundBestMove(0, bestestMove, bestEval);
		finishedNode(0,0);
	}
	return bestEval;
}
예제 #30
0
int ChessBoard::alphaBetaSearch(int depth, int alpha, int beta)
{    
    //1.到达水平线返回
    if (depth==0)
    {
        return evaluate();
    }
    m_searchCallTimes++;

    //2.初使化最佳值,最佳走法    
    int vlBest = -MATE_VALUE;
    int mvBest = 0;

    //3.生成走法,根据历史表排序
    Moves mvs;
    generateMoves(mvs);
    //PrintMoves(mvs);
    qSort(mvs.begin(), mvs.end(), compareLessTan);
    //PrintMoves(mvs);
    //qDebug()<<"----------------------";

    // 4. 逐一走这些走法,并进行递归
    for(int i=0; i<mvs.count(); i++)
    {
        //列出走法
        int pcCaptured;
        if (makeMove(mvs[i], pcCaptured))
        {
            int vl = -alphaBetaSearch(depth - 1, -beta, -alpha);
            undoMakeMove(mvs[i], pcCaptured);
            //qDebug()<<mvString(mvs[i])<<" vl="<<vl;

            //进行Alpha-Beta大小判断和截断
            if (vl > vlBest)
            {
                // 找到最佳值(但不能确定是Alpha、PV还是Beta走法)
                vlBest = vl;        // "vlBest"就是目前要返回的最佳值,可能超出Alpha-Beta边界
                if (vl >= beta)
                {
                    // 找到一个Beta走法
                    mvBest = mvs[i];  // Beta走法要保存到历史表
                    break;            // Beta截断
                }
                if (vl > alpha)
                {
                    // 找到一个PV走法
                    mvBest = mvs[i];  // PV走法要保存到历史表
                    alpha = vl;     // 缩小Alpha-Beta边界
                }
            }
        }
    }

    // 5. 所有走法都搜索完了,把最佳走法(不能是Alpha走法)保存到历史表,返回最佳值
    if (vlBest == -MATE_VALUE)
    {
      // 如果是杀棋,就根据杀棋步数给出评价
      return m_distance - MATE_VALUE;
    }
    //qDebug()<<"mvBest="<<mvBest<<" distance="<<m_distance;
    if (mvBest != 0)
    {
      // 如果不是Alpha走法,就将最佳走法保存到历史表
      m_historyTable[mvBest] += depth * depth;
      if (m_distance==0)
      {
        // 搜索根节点时,总是有一个最佳走法(因为全窗口搜索不会超出边界),将这个走法保存下来
        m_mvComputer = mvBest;
      }
    }
    return vlBest;
}