बहुत ही रोचक सवाल। +1 :) यहां मेरा लेना है।
पूर्ण समाधान के लिए मेरी पहेली http://jsfiddle.net/BuddhiP/J9bLC/ देखें। मैं यहां मुख्य बिंदुओं को समझाने की कोशिश करूंगा।
मैं इस तरह के बोर्ड से शुरू करता हूं। मैंने -1 के बजाय 0 का उपयोग किया है क्योंकि यह आसान है।
var a = 'a', b = 'b';
var board = [
[a, 0, a],
[b, b, b],
[a, 0, a]
];
मेरी रणनीति सरल है।
- जांचें कि पंक्तियों में से कोई भी एक ही खिलाड़ी (ए या बी) है, यदि हमारे पास विजेता है।
- वरना, देखें कि क्या किसी भी कॉलम को ही खिलाड़ी
- वरना है, की जाँच करें जो तीन जीत मामलों रहे हैं, तो विकर्ण एक खिलाड़ी
है।
सबसे पहले मैंने एक फ़ंक्शन बनाया जो पंक्तियों का सेट ले सकता है (पूर्व: [ए, 0, बी]), और जांचें कि क्या संपूर्ण पंक्ति में एक ही मान है, और यदि वह मान शून्य नहीं है (या -1 मामला)।
checkForWinner = function() {
lines = Array.prototype.slice.call(arguments);
// Find compact all rows to unique values.
var x = _.map(lines, function (l) {
return _.uniq(l);
});
// Find the rows where all threee fields contained the same value.
var y = _.filter(x, function (cl) {
return (cl.length == 1 && cl[0] !== 0);
});
var w = (y.length > 0) ? y[0] : null;
return w;
};
यहाँ मैं एक पंक्ति में अद्वितीय मान लेते हैं, और अगर मैं केवल एक अनूठा मूल्य जो शून्य नहीं है पा सकते हैं, वह विजेता है।
यदि पंक्तियों में कोई विजेता नहीं है, तो मैं कॉलम की जांच करता हूं। मेरे कोड का पुन: उपयोग करने के लिए, मैं कॉलम को पंक्तियों में बदलने के लिए _.zip() विधि का उपयोग करता हूं और उसके बाद उपरोक्त एक ही फ़ंक्शन का उपयोग यह जांचने के लिए करता हूं कि हमारे पास विजेता है या नहीं।
var board2 = _.zip.apply(this, board);
winner = checkForWinner.apply(this, board2);
यदि मुझे अभी भी एक विजेता नहीं मिला है, तो विकर्णों की जांच करने का समय। मैंने बोर्ड से दो विकर्णों को दो पंक्तियों के रूप में निकालने के लिए यह फ़ंक्शन लिखा है, और यह देखने के लिए कि क्या किसी भी खिलाड़ी द्वारा विकर्णों का प्रभुत्व है या नहीं, उसी चेकफॉरविनर फ़ंक्शन का उपयोग करें।
extractDiagonals = function (b) {
var d1 = _.map(b, function (line, index) {
return line[index];
});
var d2 = _.map(b, function (line, index) {
return line[line.length - index - 1];
});
return [d1, d2];
};
अंत में यह वह जगह है जहाँ मैं वास्तव में एक विजेता के लिए बोर्ड की जाँच करें:
// Check rows
winner = checkForWinner.apply(this, board);
if (!winner) {
var board2 = _.zip.apply(this, board);
// Check columns, now in rows
winner = checkForWinner.apply(this, board2);
if (!winner) {
var diags = extractDiagonals(board);
// Check for the diagonals now in two rows.
winner = checkForWinner.apply(this, diags);
}
}
अगर आप में से किसी क्यों मैं के बजाय लागू() विधि का उपयोग सीधे फ़ंक्शन कॉल, कारण लागू है () आपको किसी फ़ंक्शन में तर्कों की सूची के रूप में सरणी तत्वों को पारित करने की अनुमति देता है।
मेरा मानना है कि यह 4x4 या उच्चतर मैट्रिक्स के लिए भी काम करना चाहिए, हालांकि मैंने उनका परीक्षण नहीं किया था।
मेरे पास समाधान का परीक्षण करने के लिए बहुत कम समय था, इसलिए अगर आपको कोई त्रुटि मिलती है तो कृपया मुझे बताएं।
मुझे लगता है कि, 'समाधान' पैटर्न में एक टिक-टैक-टो के लिए, आप शून्य से मेल नहीं खाते बल्कि खाली कोशिकाओं को मेल नहीं करना चाहते हैं। – akuhn
तुलनात्मकता को आसान बनाने के लिए आप सरणी को 1 स्तर गहराई में बदलने की कोशिश कर सकते हैं। लेकिन मुझे कोई सरणी उथल-पुथल स्निपेट नहीं पता ... :( – ajax333221