2015-07-24 5 views
5

के लिए मेरे मिनीमैक्स एल्गोरिदम के साथ क्या गलत है मैं एक मजेदार सीखने के अनुभव के लिए एक टिक टैक पैर खेल बना रहा हूं। मैं कंप्यूटर के लिए इष्टतम कदम वापस जाने के लिए एक अल्पमहिष्ठ एल्गोरिथ्म का निर्माण किया है, लेकिन किसी भी तरह मैं गलत जा रहा हूँ और इसtictactoe

TIC TAC TOE V1.0 
--- 
--- 
--- 
Enter row, column of your move 
1,1 
--- 
-X- 
--- 
... 
0, 0: -1038 
0, 1: -1470 
0, 2: -1038 
1, 0: -1470 
1, 2: -1470 
2, 0: -1038 
2, 1: -1470 
2, 2: -1038 
O-- 
-X- 
--- 
Enter row, column of your move 
1,2 
O-- 
-XX 
--- 
... 
0, 1: -15 
0, 2: -9 
1, 0: -10 
2, 0: -1 
2, 1: -29 
2, 2: -41 
O-- 
-XX 
O-- 
Enter row, column of your move 
1,0 
O-- 
XXX 
O-- 
WINNER: PLAYER 

की तरह अजीब उत्पादन आप देख सकते हैं कि कंप्यूटर को काटने से निचले बाएँ कोने बल्कि चुना है मिल खिलाड़ी। मेरा कोड सभी संभव gamestates के माध्यम से मोड़ के बीच फ्लॉप फ्लिप करने का प्रयास करता है, प्रत्येक जीत या नुकसान के लिए स्कोर को संक्षेप में जोड़ता है, फिर अधिकतम स्कोर के साथ कदम देता है। प्रिंटआउट प्रत्येक मोड़ का स्कोर होने से पहले होता है (आप देख सकते हैं कि यह उच्चतम चुनता है), तो मैं खिलाड़ी को क्यों नहीं हटा रहा हूं? मैं इसे कैसे ठीक करूं? मेरा कोड यहाँ है।

int compMoveScoreRecursive(state_t **board, int dimension, int row, int col, state_t turn) { 
    board[row][col] = turn; 
    state_t winner = checkWinner(board, dimension); 
    if (winner == COMPUTER) { 
     return 1; 
    } else if (winner == PLAYER) { 
     return -1; 
    } else { 
     int score = 0; 
     state_t nextTurn = turn == COMPUTER ? PLAYER : COMPUTER; 
     for (int i = 0; i < dimension; i++) { 
      for (int j = 0; j < dimension; j++) { 
       if (board[i][j] == NIL) { 
        state_t **boardCopy = copyBoard(board, dimension); 
        score += compMoveScoreRecursive(boardCopy, dimension, i, j, nextTurn); 
        destroyBoard(boardCopy, dimension); 
       } 
      } 
     } 
     return score; 
    } 
} 

move_t optimalCompMove(state_t **board, int dimension) { 
    move_t optMove; 
    int optScore = INT_MIN; 
    for (int row = 0; row < dimension; row++) { 
     for (int col = 0; col < dimension; col++) { 
      if (board[row][col] == NIL) { 
       state_t **boardCopy = copyBoard(board, dimension); 
       int score = compMoveScoreRecursive(boardCopy, dimension, row, col, COMPUTER); 
       printf("%d, %d: %d\n", row, col, score); 
       if (score > optScore) { 
        optMove.row = row; 
        optMove.col = col; 
        optScore = score; 
       } 
       destroyBoard(boardCopy, dimension); 
      } 
     } 
    } 
    return optMove; 
} 
+0

प्रत्येक रिकर्सन के दौरान संभावित बोर्ड प्रिंट करें। परिणाम आपको चौंका सकते हैं। – WhozCraig

उत्तर

4

minmax एल्गोरिदम की अवधारणा «अधिकतम हानि को कम करें» (Wikipedia) है, इसलिए आपके एल्गोरिदम के साथ पहली चीज़ गलत है।

खेल के किसी भी राज्य S के लिए, और किसी भी कदम M मौजूदा खिलाड़ी के लिए avaialble के लिए, minmax (S + M, P2) का मूल्य P2P1 अगर नाटकों M के लिए अधिकतम संभव उत्पादन होता है (मान लीजिए कि खिलाड़ी 1 P1 हैं)। इसलिए यदि P1 जीतने का अपना मौका अधिकतम करना चाहता है, तो उसे P2 के लिए अधिकतम आउटपुट जितना संभव हो उतना कम करना चाहिए, यानी उसे आउटपुट के न्यूनतम मिलना चाहिए।

tictactoe में minmax, यह पूरे खेल (अधिकतम 9 चाल) का परीक्षण करने के लिए संभव है, आप अर्थ हमेशा अब अगर PX जीत (1), खो देते हैं (-1) या (0) ड्रा बनाते हैं। तो minmax (state, PX) इन तीनों में से केवल एक मूल्य लौटाएगा।

कई खेल में, आप नहीं पूरे खेल (उदाहरण के लिए ड्राफ्ट) यदि आप जीत, खेल सकते हैं, इसलिए दिए गए मान अगर तुम हार उदाहरण -oo के लिए, राज्य के एक संकेत है, +oo के बीच का अंतर otherwize अपने ड्राफ्ट्स और आपके प्रतिद्वंद्वी की संख्या।

+0

क्या इसका मतलब यह है कि मुझे किसी भी समय एक ही मिनीमैक्स मूल्य से चुनने के लिए कई कदम हो सकते हैं? यानी संभावित चालें +1, +1, -1, 0, +1 उत्पन्न करती हैं। मैं इनके बीच कैसे चुनाव करूंगा? या यह कोई महत्त्व नहीं रखता? – shane

+0

हां आपको एक ही मूल्य के साथ कई कदम मिलेगा, विकल्प मिनीमैक्स एल्गोरिदम के लिए कोई फर्क नहीं पड़ता। – Holt

0

यह अपने एल्गोरिथ्म के पीछे की अवधारणा की तरह लगता है दोषपूर्ण है। जिस तरह से आपने इसका वर्णन किया है, उसके आधार पर, आप इस खेल के हर पंक्ति पर विचार कर रहे हैं, क्योंकि यह मानने के विरोध में कि प्रतिद्वंद्वी सही कदम उठाएगा। इस वजह से, प्रतिद्वंद्वी अगले कदम के साथ जीत सकता है, बहुत कम वजन है, क्योंकि आप उन सभी विकल्पों पर भी विचार करते हैं जो अन्य 4 चालें प्रदान करते हैं (इस तथ्य के बावजूद कि वे स्पष्ट रूप से कभी नहीं बनाए जाएंगे)। आप ठीक ढंग से न्यूनतम-अधिकतम के रूप में compMoveScoreRecursive के कार्यान्वयन में बोर्ड राज्यों

2
मेरी समझ के लिए

के पूरे सेट की खोज कर रही है, का विरोध किया, रिकर्सिवली गणना स्कोर

के माध्यम से जोड़ा जाता है करने के लिए अपने एल्गोरिथ्म को परिष्कृत करना होगा मूल्य को अधिकतम या कम करने के बजाय
score += compMoveScoreRecursive(boardCopy, dimension, i, j, nextTurn); 

। हालांकि, turn तर्क के आधार पर, कम से कम लौटने का मूल्य कम से कम किया जा सकता है, यही कारण है कि दृष्टिकोण को मिनमैक्स कहा जाता है।

+0

आपकी समझ सही है, राज्य 'राज्य' में, 'पी 1' के लिए उपलब्ध किसी भी 'चाल' के लिए, 'मिनीमैक्स (राज्य + चाल, पी 2)' 'पी 2' के लिए अधिकतम ** संभव आउटपुट होना चाहिए यदि' पी 1 'नाटकों' चाल ', ताकि जीतने का मौका अधिकतम करने के लिए,' पी 1 'को' चाल 'खेलना चाहिए जो 'p2' के अधिकतम आउटपुट को कम करता है। – Holt

+0

इसलिए प्रत्येक संभावित चाल के स्कोर जोड़ने के बजाय, मुझे केवल एक +1 या -1 वापस करने की आवश्यकता है, इस पर निर्भर करता है कि प्रतिद्वंद्वी उस बिंदु से जीतने वाले राज्य तक पहुंच सकता है या नहीं? – shane

+0

बिल्कुल; एक चाल का मूल्य {0, -1,1} होना चाहिए जिसमें यह व्यक्त किया जाता है कि कौन सा खिलाड़ी पूरी तरह से खेला जाता है, जिसका अर्थ यह है कि प्रत्येक बाद की चाल भी इष्टतम है, जिसका अर्थ है कि कौन सा खिलाड़ी गेम (या ड्रॉ गेम के लिए 0) जीतता है। – Codor