2012-04-29 22 views
6

Tôi có vấn đề với Chess Engine của riêng tôi sử dụng thuật toán minimax để tìm kiếm di chuyển cờ vua Tôi sử dụng tìm kiếm độ sâu 5 plies và chỉ với đánh giá vật liệu/tiền thưởng/di động, nhưng nó cũng làm cho di chuyển câm và hy sinh các phần có giá trị ngay cả khi tôi cung cấp cho họ vô cùng (chắc chắn là một vấn đề tìm kiếm), tôi không sử dụng bất kỳ loại cắt xén nào và đưa ra kết quả tìm kiếm sâu 5 giây sau vài giây.Minimax đơn giản

Tôi bị kẹt trong vấn đề này trong một tuần, tôi chắc chắn vấn đề với Backtracking không phải là Chess Logic (vì vậy bất kỳ ai không có nền cờ sẽ giải quyết điều này :)) và tôi đã tìm kiếm rất nhiều đây là lần đầu tiên của tôi Câu hỏi trong stack Overflow và tôi hy vọng các bạn sẽ không thất vọng tôi :)

đây là mã tìm kiếm đơn giản

int GameControl::Evaluate(ChessBoard _B) 
{ 

    int material=0,bonus=0,mobility=0; 
    for(int i=0;i<8;i++) 
     for(int j=0;j<8;j++) 
     { 

      if(_B.Board[i][j]!=EMPTY) 
      { 
       if(_B.Board[i][j]->pieceColor==WHITE){ 
        material+=-_B.Board[i][j]->Weight; 
        bonus+=-_B.Board[i][j]->bonusPosition[i][j]; 
        mobility+=-_B.Board[i][j]->getPossibleMovesList(i,j,B).size(); 
       } 
       else { 
        material+=_B.Board[i][j]->Weight; 
        bonus+=_B.Board[i][j]->bonusPosition[i][j];    
       mobility+=_B.Board[i][j]->getPossibleMovesList(i,j,B).size(); 
       } 
      } 
     } 
     return material+bonus/10+mobility/20; 
} 


pair<pair<int,int>,pair<int,int>> GameControl::minimax(int depth , ChessBoard _B) 
{ 
    short int i,j; 

    int bestValue = -INFINITY; 

    pair<pair<int,int>,pair<int,int>> bestMove; 

    vector< pair<int,int> > ::iterator it; 

    vector< pair<int,int> > Z; 

    for(i = 0; i < 8; i++) 

     for(j = 0; j < 8; j++) 
     { 
      if(_B.Board[i][j]!=EMPTY && _B.Board[i][j]->pieceColor==BLACK) 
      { 
       Z=_B.Board[i][j]->getPossibleMovesList(i,j,_B); 
       for(it=Z.begin();it!=Z.end();it++) 
       { 
        pair<int,int> temp; 
        temp.first=i,temp.second=j; 
        ChessPieces* DestinationPiece; 
        DestinationPiece=_B.Board[(*it).first][(*it).second]; 
        //Moving 
        _B.Board[(*it).first][(*it).second]=_B.Board[i][j]; 
        _B.Board[i][j]=EMPTY; 
        // 
        int value = minSearch(depth-1 , _B); 
        if(value > bestValue) 
        { 
         bestValue = value; 
         bestMove.first.first = i; 
         bestMove.first.second = j; 
         bestMove.second.first = (*it).first; 
         bestMove.second.second = (*it).second; 

        } 
        //Undo Move 
        _B.Board[i][j]=_B.Board[((*it).first)][(*it).second]; 
        _B.Board[(*it).first][(*it).second]=DestinationPiece; 
       } 

      } 
     } 

     return bestMove; 
} 


int GameControl::minSearch(int depth , ChessBoard _B) 
{ 

    short int i; 
    short int j; 
    if(depth==0) 
     return Evaluate(_B); 

    int bestValue = INFINITY; 
    for(i = 0; i < 8; i++) 
     for(j = 0; j < 8; j++) 
     { 
      vector< pair<int,int> > ::iterator it; 
      vector< pair<int,int> > Z; 
      if(_B.Board[i][j]!=EMPTY && _B.Board[i][j]->pieceColor==WHITE && !_B.Board[i][j]->V.empty()) 
      { 

       Z=_B.Board[i][j]->getPossibleMovesList(i,j,_B); 
       for(it=Z.begin();it!=Z.end();it++) 
       { 

        pair<int,int> temp; 
        temp.first=i; 
        temp.second=j; 
        ChessPieces* DestinationPiece; 
        DestinationPiece=_B.Board[(*it).first][(*it).second]; 
        // Moving 
        _B.Board[(*it).first][(*it).second]=_B.Board[i][j]; 
        _B.Board[i][j]=EMPTY; 
        // 
        int value = maxSearch(depth-1 , _B); 
        if(value < bestValue) 
         bestValue = value; 
        //Undo Move 
        _B.Board[i][j]=_B.Board[(*it).first][(*it).second];  
        _B.Board[(*it).first][(*it).second]=DestinationPiece; 
        // 
       } 

      } 
     } 
     return bestValue; 
} 


int GameControl::maxSearch(int depth , ChessBoard _B) 
{ 


    short int i; 
    short int j; 
    if(depth==0) 
     return Evaluate(_B); 
    vector< pair<int,int> > ::iterator it; 
    vector< pair<int,int> > Z; 
    int bestValue = -INFINITY; 
    for(i = 0; i < 8; i++) 
     for(j = 0; j < 8; j++) 
     { 

      if(_B.Board[i][j]!=EMPTY && _B.Board[i][j]->pieceColor==BLACK) 
      { 
       Z=_B.Board[i][j]->getPossibleMovesList(i,j,_B); 
       for(it=Z.begin();it!=Z.end();it++) 
       { 
        pair<int,int> temp; 

        temp.first=i,temp.second=j; 
        ChessPieces* DestinationPiece; 
        DestinationPiece=_B.Board[(*it).first][(*it).second]; 
        //Moving 
        _B.Board[(*it).first][(*it).second]=_B.Board[i][j]; 
        _B.Board[i][j]=EMPTY; 
        // 
        int value = minSearch(depth-1 , _B); 
        if(value > bestValue)  
         bestValue = value; 

        //Undo Move 
        _B.Board[i][j]=_B.Board[((*it).first)][(*it).second]; 
        _B.Board[(*it).first][(*it).second]=DestinationPiece; 
       } 

      } 
     } 
     return bestValue; 
} 
+0

Đã thêm thẻ 'C++'. Đây là 'C++' phải không? – Cratylus

+2

Nếu bạn thực hiện tìm kiếm 5 lớp, chương trình sẽ "khắc phục" bất kỳ vấn đề nào bằng cách đẩy 6 lỗ mất về phía trước. Chương trình là "thông minh"! Bạn không thể để nó dừng tìm kiếm khi một số phần sắp bị bắt. –

Trả lời

6

bạn đang không làm quiescence search, do đó di chuyển câm có nhiều khả năng do giếng được biết đến là horizon effect mà các tìm kiếm tối thiểu cố định có thể dễ bị tổn thương. Ở mức tối thiểu bạn nên mở rộng tìm kiếm cho bất kỳ di chuyển bắt buộc, kiểm tra hoặc chụp nơi một mảnh chụp một trong những giá trị bằng hoặc lớn hơn.

+0

Và tôi đã học được điều gì đó mới mẻ hôm nay, cảm ơn bạn! –

+0

Thực ra khi tôi nói những động tác ngớ ngẩn, tôi có nghĩa là di chuyển câm như hy sinh những mảnh có giá trị cho một số ít nên tránh ngay cả trong tìm kiếm 2 ply – Osama

1

Có một vài điều mà có thể được cải thiện với mã của bạn:

  1. Sử dụng các công thức negamax. Điều này sẽ loại bỏ sự sao chép mã của minsearchmaxsearch của bạn.
  2. Sử dụng cắt tỉa alpha-beta. Điều này sẽ tăng gấp đôi độ sâu tìm kiếm của bạn cho một lượng thời gian tìm kiếm nhất định.
  3. Sử dụng iterative deepening kết hợp với hash table. Độ sâu lặp đi lặp lại sẽ dần dần tinh chỉnh kết quả tìm kiếm của bạn (để bạn có thể ngừng tìm kiếm và di chuyển bất kỳ lúc nào) và bảng băm sẽ cho phép bạn tránh trùng lặp nếu bạn gặp phải sự chuyển đổi trong cây trò chơi.
0

Không nên chức năng tìm kiếm trong hàm minimax ban đầu tối đa hóa và không giảm thiểu?

+0

Nó thực sự không quan trọng tùy thuộc vào người chơi nào là maximizer và trình phát nào là trình tối ưu hóa . – Osama