2012-11-20 8 views
9

मैं जावा में एक गेम के लिए एक मिनीमैक्स एल्गोरिदम लिख रहा हूं, और, गति के उद्देश्यों के लिए, खेल स्थिति को बदल रहा हूं क्योंकि मैं निर्णय पेड़ के माध्यम से बार-बार काम करता हूं। हालांकि, इसमें उन चालों की सूची को संशोधित करना शामिल है जो मैं कर रहा हूं।क्या मैं एक सरणी को सुरक्षित रूप से बदल सकता हूं, अगर मैं प्रत्येक पुनरावृत्ति के बाद अपने मूल स्थिति में वापस आ जाता हूं?

public int minimax(int currentDepth) { 
    if (currentDepth == depth || board.legalMoves.isEmpty()) { 
     int eval = board.eval(); 
     board.takeBack(1); 
     return eval; 
    } 
    int x = Integer.MIN_VALUE; 
    for (Tuple move : board.legalMoves) { 
     board.move(move); 
     x = max(x, -1*minimax(currentDepth+1)); 
     board.takeBack(1); 
    } 
    return x 
} 

board.move() विधि ArrayList legalMoves mutates, लेकिन takeBack(1) इसे वापस उसकी मूल स्थिति में लाता है। क्या इससे कोई समस्या हो सकती है?

+0

बस आशा है कि आपके पास पेड़ तक पहुंचने वाले एक से अधिक धागे नहीं हैं ... – Reactormonk

+1

आप यहां एक लूप का उपयोग क्यों कर रहे हैं? यह शुरुआती तत्व से परे कभी नहीं * फिर से शुरू होगा क्योंकि आप विधि से वापस आते हैं। – Vulcan

+1

उपर्युक्त 'रिटर्न' भी 'कोड.takeBack (1)' को कॉल कोड के रूप में कॉल करता है, जो कुछ हद तक प्रश्न के उद्देश्य को मारता है। – Vulcan

उत्तर

5

एक शब्द में, हाँ।

आप board.legalMoves के प्रकार निर्दिष्ट नहीं करते हैं। आप कहते हैं कि यह सरणी है, लेकिन यह नहीं हो सकता है, क्योंकि आप isEmpty() पर कॉल कर रहे हैं। इसलिए मुझे संदेह है कि आपका मतलब ArrayList है। अगर ऐसी बात है, documentation बहुत स्पष्ट है:

iterators इस वर्ग के iterator और listIterator विधियों द्वारा लौटाए गए असफल फास्ट: यदि सूची संरचना की दृष्टि से किसी भी समय संशोधित किया गया है के बाद इटरेटर किसी भी तरह से बनाया जाता है, इटेटरेटर के remove या add विधियों को छोड़कर, इटेटरेटर ConcurrentModificationException फेंक देगा। इस प्रकार, समवर्ती संशोधन के चेहरे में, पुनरावृत्त भविष्य में अनिश्चित समय पर मनमाने ढंग से, गैर-निर्धारक व्यवहार को खतरे में डालकर, जल्दी और साफ-सफाई में विफल रहता है।

1) संरचनात्मक संशोधनों से बचें:

मैं इस के आसपास दो तरीके से देखते हैं। दूसरे शब्दों में, तत्वों के मान मानना ​​ठीक है, लेकिन तत्वों को जोड़ने/निकालना ठीक नहीं है।

2) दोहराएं ArrayList से अधिक सूचकांक का उपयोग कर:

for (int i = 0; i < board.legalMoves.size(); i++) { 
    Tuple move = board.get(i); 
    ... 
} 
+0

ठीक कर दूंगा, मैं इससे डरता था। क्या इसके चारों ओर एक रास्ता है? मैं एल्गोरिदम के प्रत्येक पुनरावृत्ति के लिए सरणी सूची को क्लोन करना नहीं चाहूंगा; मुझे लगता है कि यह काफी धीमा हो जाएगा ... – mavix

+0

यह आपको सटीक संशोधनों पर निर्भर करता है जो आपको करने की ज़रूरत है।यदि आप सूची * संरचनात्मक रूप से * संशोधित नहीं करते हैं, तो आपको ठीक होना चाहिए (संरचनात्मक संशोधन का गठन करने के स्पष्टीकरण के लिए जावाडोक देखें)। – NPE

+1

हम्म, शायद मैं एक लिंक्डलिस्ट का उपयोग कर सकता हूं और (currentNode.hasNext) ... – mavix

0

हाँ, आप कर सकते हैं, लेकिन यह खतरनाक है। मैं सुझाव देता हूं कि मिनीमैक्स एल्गोरिदम को एक नई कक्षा में ले जाएं और डेटा को कन्स्ट्रक्टर में विश्लेषण करने के लिए पास करें।

अब, आप सामग्री को पर एक बार प्रतिलिपि बना सकते हैं और विधियां प्रतिलिपि पर काम कर सकती हैं। एल्गोरिदम अब डेटा को किसी भी तरह से संशोधित कर सकता है, यह गेम या अन्य धागे के अन्य हिस्सों को प्रभावित नहीं करेगा। इसके अलावा, अगर आपको कोई समस्या है, तो उन्हें एक कक्षा में कोड से आना चाहिए।

सामान्य लक्ष्य कोड के प्रत्येक संशोधित भाग को डेटा की प्रतिलिपि देना है जो इसे निर्भरताओं में कटौती करने के लिए आवश्यक है जो परेशानी का कारण बन सकता है।