टिक-टैक-टो खेलें और कभी न हारें


14

(कुछ चुनौतियों का सामना करना पड़ता है जिनमें सबसे अच्छी रणनीति का उपयोग करने की आवश्यकता होती है, लेकिन यहां हम नहीं हैं। भले ही आप जीतने में सक्षम हों, आपको एक टाई बनाने की अनुमति है)

चुनौती

एक कार्यक्रम लिखें जो गेम टिक-टैक-टो खेलता है। इसे खोना नहीं चाहिए (इसलिए, इसे खेल को या तो टाई के साथ समाप्त करना चाहिए या जीतना चाहिए)।

अनुमत I / O विधियाँ

  1. इनपुट वर्तमान बोर्ड हो सकता है। आप मान सकते हैं कि दूसरे खिलाड़ी के सभी पिछले चाल आपके इंजन द्वारा खेले गए थे।
  2. इनपुट पहले खिलाड़ी की चाल हो सकती है, और आपके फ़ंक्शन स्टोर जो अतीत में हुए थे। इस मामले में फ़ंक्शन को कई बार कहा जाता है, प्रत्येक चाल के लिए एक बार; या कई बार के लिए फ़ंक्शन / प्रोग्राम प्रॉम्प्ट इनपुट।
  3. आपको यह कहते हुए एक अतिरिक्त इनपुट लेने की अनुमति दी जाती है कि क्या आप पहले खिलाड़ी हैं, या पहले खिलाड़ी की समस्या को हल करने के लिए दो (संभवतः संबंधित) कार्य लिखते हैं और दूसरा-खिलाड़ी एक। यदि आपके प्रोग्राम को इनपुट मेथड 2 (मल्टीपल कॉल) का उपयोग करने की आवश्यकता है, तो आप यह निर्णय ले सकते हैं कि पहली कॉल में क्या पास हुआ है।
  4. आपकी बारी के बाद आउटपुट बोर्ड हो सकता है।
  5. आउटपुट आपकी चाल हो सकती है।
  6. एक चाल को संख्याओं की एक जोड़ी के रूप में दर्शाया जा सकता है (0-अनुक्रमण या 1-अनुक्रमण हो सकता है), संख्या 0 ~ 8 में एक संख्या, या श्रेणी 1 ~ 9 में एक संख्या।
  7. बोर्ड को 3 × 3 सरणी या लंबाई के एक सरणी के रूप में दर्शाया जा सकता है। 9. भले ही भाषा में 0-इंडेक्सिंग सरणी हो, आप 1-इंडेक्सिंग का उपयोग कर सकते हैं।
  8. ग्रिड पर कोशिकाएँ इंगित करने के लिए किसी भी 3 भिन्न मानों का उपयोग कर सकती हैं X, Oऔर खाली करने के लिए।

मानदंड जीतना

प्रत्येक भाषा की जीत में सबसे छोटा कोड।


यदि कोई हार आपको दिया जाता है तो आपका समाधान अमान्य है। आप दूसरे के साथ खेल रहे हैं, इसलिए शतरंज की बिसात तुरंत नहीं बदलेगी, इसलिएwe can assume that all previous moves of the 2nd player were also played by our engine
l4m2


1
@ l4m2 इंटरप्रेटर को पुनः आरंभ करें। किया हुआ। इससे परेशान क्यों? यह अनावश्यक रूप से कुछ भी नहीं के लिए बाइट काउंट बढ़ाता है।
user202729


4
बोनस मत करो। या तो इसकी आवश्यकता है या इसे हटा दें, इसे वैकल्पिक न बनाएं। बोनस चुनौती को बर्बाद करता है ..
Rɪᴋᴇʀ

जवाबों:


4

बेफुंज, 181 168 बाइट्स

>>4&5pp20555>>03>16p\::5g8%6p5v
 ^p5.:g605$_ #!<^_|#:-1g61+%8g<
543217539511|:_^#->#g0<>8+00p3+5%09638527419876
v<304p$_v#:->#$$:2`#3_:^
>#\3#13#<111v124236478689189378

बोर्ड पर पदों की संख्या 1 से 9. होती है। डिफ़ॉल्ट रूप से आपको पहला कदम मिलता है, लेकिन अगर आप कंप्यूटर को पहले जाने देना चाहते हैं, तो आप अपने पहले कदम के लिए 0 दर्ज कर सकते हैं। जब आप एक चाल बनाते हैं, तो कंप्यूटर एक संख्या के साथ प्रतिक्रिया करेगा जो उनकी चाल को दर्शाता है।

यह सुनिश्चित करने के लिए कोई चेक नहीं है कि आप एक वैध कदम दर्ज नहीं करते हैं, और यह देखने के लिए भी कोई चेक नहीं है कि क्या कोई जीता या हारा है। एक बार जब उनकी कोई और चाल नहीं होती है, तो कार्यक्रम सिर्फ एक अनंत लूप में चला जाता है।

यह ऑनलाइन परीक्षण करना थोड़ा मुश्किल है, क्योंकि इंटरएक्टिव इनपुट के साथ कोई ऑनलाइन दुभाषिया नहीं हैं। हालाँकि, यदि आप जानते हैं कि आप कौन-सी चालें बनाने जा रहे हैं (जो आपको पता है कि कंप्यूटर कैसे जवाब देने वाला है), तो आप उन चालों के साथ TIO पर परीक्षण कर सकते हैं।

उपयोगकर्ता पहले खेलता है: इसे ऑनलाइन आज़माएं!
कंप्यूटर पहले खेलता है: इसे ऑनलाइन आज़माएं!

यह देखना आसान बनाता है कि क्या चल रहा है, मुझे एक संस्करण भी मिला है जो चालों के बीच बोर्ड को आउटपुट करता है।

उपयोगकर्ता पहले खेलता है: इसे ऑनलाइन आज़माएं!
कंप्यूटर पहले खेलता है: इसे ऑनलाइन आज़माएं!

ध्यान दें कि परिणाम देखने से पहले आपको TIO का समय समाप्त होने तक इंतजार करना होगा।

व्याख्या

बोर्ड को 1 से 9 तक अनुक्रमित 9 मानों के एक फ्लैट सरणी के रूप में बेफुंज मेमोरी क्षेत्र में संग्रहीत किया गया है, यह हमें शून्य ऑफसेट का उपयोग एक विशेष मामले "नो मूव" के रूप में करता है जब हम कंप्यूटर को पहले खेलने देना चाहते हैं। खिलाड़ी चाल 4 के रूप में संग्रहीत की जाती हैं, और कंप्यूटर 5 के रूप में चलता है। सभी पदों के साथ शुरू करने के लिए 32 (Befunge मेमोरी डिफ़ॉल्ट) के लिए प्रारंभ किया जाता है, इसलिए जब भी हम बोर्ड पर पहुंचते हैं हम 8 के साथ मॉड करते हैं, इसलिए हम 0, 4 या तो वापस प्राप्त करेंगे। या ५।

उस व्यवस्था को देखते हुए, यदि हम बोर्ड में किन्हीं तीन पदों के मानों को जोड़ते हैं, तो हम जानते हैं कि कंप्यूटर एक जीत से दूर है यदि कुल 10 है, तो खिलाड़ी एक जीत से दूर है यदि कुल 8 है, और कंप्यूटर और खिलाड़ी के बीच स्थितियां साझा की जाती हैं (लेकिन अभी भी एक स्थिति मुक्त है) यदि कुल 9 है।

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

ट्रायल्स की मुख्य सूची जो हम परीक्षण करते हैं वे विजेता संयोजन (1/2/3, 1/5/9, 1/4/7, आदि) हैं। हम पहली बार कुल 10 (कंप्यूटर जीतने के बारे में) की तलाश करते हैं, और फिर कुल 8 (खिलाड़ी जीतने वाला है और हमें उस कदम को ब्लॉक करने की आवश्यकता है)। स्पष्ट रूप से, हम कुल 9 के लिए भी जांच करते हैं (यदि खिलाड़ी और कंप्यूटर में से प्रत्येक के पास एक स्थिति है, तो यह कंप्यूटर के लिए तीसरी रणनीति है)।

उस अंतिम परिदृश्य से पहले, हम जो अन्य रणनीतिक कदम उठाते हैं, वह सभी कोने सेट (1/2/4, 2/3/6, आदि) के साथ-साथ दो विरोधी कोने संयोजनों (1/8/9 और 3) की जांच करना है। / 7/8)। यदि इनमें से कोई भी संयोजन 8 तक है, यानी खिलाड़ी ने दो स्थान लिए हैं, तो कंप्यूटर के लिए शेष मुक्त स्थिति लेना एक अच्छी रणनीति है।

अंत में, दो विशेष मामले हैं। सबसे पहले, हम हमेशा कोशिश करते हैं और किसी अन्य कदम से पहले केंद्र की स्थिति लेते हैं। यह हमारे सभी अन्य चालों के समान दिनचर्या के साथ हासिल किया जाता है, बस एक एकल ट्रिपल, 5/5/5 में गुजर रहा है, और 0. का लक्ष्य योग है। इसके अलावा, यदि अन्य सभी परीक्षण एक कदम खोजने में विफल रहे हैं, तो हम लेने की कोशिश करते हैं अंतिम उपाय के रूप में शीर्ष कोनों में से एक। फिर से यह केवल 0 के लक्ष्य योग के साथ, 1/1/1 और 3/3/3 तीनों का परीक्षण करके प्राप्त किया जाता है।

मुझे नहीं लगता कि यह आवश्यक रूप से एक सही रणनीति है - ऐसे गेम हो सकते हैं जो कंप्यूटर ड्रॉ करता है जो संभावित रूप से जीता जा सकता है - लेकिन यह एक मैच नहीं हारने के लिए पर्याप्त है। मैंने एक परीक्षण स्क्रिप्ट चलाई है जिसमें कंप्यूटर के खिलाफ हर संभव कदम उठाने की कोशिश की गई है, और चाल के हर वैध अनुक्रम के लिए, कंप्यूटर ने गेम जीता या ड्रॉ किया।


मुझे काफी जानकारी नहीं है, लेकिन हो सकता है कि आप सभी संभावित इनपुट ( नमूना )
l4m2

@ l4m2 FYI करें, मैंने अब एक परीक्षण स्क्रिप्ट चलाई है जो कंप्यूटर के खिलाफ हर संभव कदम उठाती है और यह पुष्टि कर सकती है कि यह कभी भी नहीं खोता है।
जेम्स होल्डरनेस

2

पायथन 2: 399 401 349 333 317 370 बाइट्स

2x बग फिक्स: l4m2 को क्रेडिट

-52 चार्ट: अंडरग्राउंडोरेल को श्रेय

-16 चार्ट: जोनाथन फ्रेच को श्रेय

-26 वर्ण: श्रेय user202729 को

def f(b):
 t=4,9,2,3,5,7,8,1,6;n=lambda k:[t[i]for i,j in enumerate(b)if j==k];p,o,a,I=n(2),n(1),n(0),t.index
 for i in p:
    for j in p:
     for k in a:
        if i+j+k==15and-j+i:return I(k)
 for i in o:
    for j in o:
     for k in a:
        if i+j+k==15and-j+i:return I(k)
 for i in 9,3,7,1:
    if i in a and 5 in p:return I(i)
 for i in 5,4,2,8,6:
    if i in a:return I(i)
 return I(a[0])

इसे ऑनलाइन आज़माएं!

एक लीनियर बीजगणित पाठ्यक्रम के पहले दिन मैंने अंतिम सेमेस्टर में प्रवेश लिया, मेरे अस्सिटेंट ग्रेजुएट छात्र प्रशिक्षक ने प्रस्ताव रखा कि यदि आप मैट्रिक्स के रूप में टिक-टैक-टो बोर्ड का प्रतिनिधित्व करते हैं:

4 | 9 | 2
--+---+--
3 | 5 | 7
--+---+--
8 | 1 | 6

फिर एक पंक्ति में तीन प्राप्त करना रेंज में तीन संख्याओं को चुनने के बराबर है [1,9] जो 15 तक जोड़ता है। यह उत्तर इस विचार का फायदा उठाता है। फ़ंक्शन एक सूची लेता है जिसमें बोर्ड का प्रतिनिधित्व करने वाले नौ नंबर होते हैं। 0 एक खाली स्थान को इंगित करता है, 1 प्रतिद्वंद्वी द्वारा कब्जा कर लिया जाता है, और 2 कार्यक्रम द्वारा बनाए गए पिछले नाटक का प्रतिनिधित्व करता है। पहले 3 लाइनों में यह पता चलता है कि प्रोग्राम ने क्या नंबर उठाए हैं (पी), विपक्ष ने (ओ) उठाया है, और अभी भी उपलब्ध हैं (ए)। यह तब उपलब्ध नंबरों के माध्यम से देखता है और देखता है कि उनमें से कोई भी, दो नंबरों के साथ मिलकर इसे पहले से ही पंद्रह में जोड़ दिया है। यदि ऐसा होता है, तो वह उस वर्ग को चुन लेगा और जीत जाएगा। यदि कोई तत्काल विजेता चाल नहीं है, तो यह देखने के लिए जांच करेगा कि क्या प्रतिद्वंद्वी उसी पद्धति का उपयोग करके जीत सकता है। यदि वे कर सकते हैं, तो यह उनके जीतने वाले वर्ग को ले जाएगा। यदि न तो कोई जीत है और न ही अवरुद्ध कदम उपलब्ध है, यह एक कोने में चला जाएगा। यह एक मूर्ख साथी को रोकता है:

- - - 
- X -
- - -

- O -             # Bad Move
- X -
- - -

- O X
- X -
- - -

- O X
- X -
O - -

- O X
- X -
O - X

यदि इनमें से कोई भी स्थिति नहीं होती है, तो यह मनमाने ढंग से एक वर्ग का चयन करेगा। फ़ंक्शन एल्गोरिथ्म द्वारा चुने गए 0 अनुक्रमित वर्ग का प्रतिनिधित्व करते हुए एक नंबर [0,8] आउटपुट करता है।

संपादित करें: एल्गोरिथ्म अब विकर्ण पर केंद्र को प्राथमिकता देता है, जो l4m2 और संबंधित रणनीतियों द्वारा इंगित किए गए एक अन्य मूर्ख साथी की संभावना को रोक देगा।

संपादित करें: स्पष्ट करने के लिए, फ़ंक्शन एक सरणी के रूप में एक बोर्ड में ले जाता है और एक कदम के रूप में एक कदम को आउटपुट करता है [0,8]। क्योंकि यह I / O रणनीति इतनी क्लिंकी है, यहां एक रैपर स्क्रिप्ट है जो इसे अधिक इंटरैक्टिव बनाती है। यह एक एकल कमांड लाइन तर्क लेता है, जो 1 होना चाहिए अगर खिलाड़ी पहले जाता है, और 0 यदि कार्यक्रम पहले जाता है।

import sys

def f(b):
 t=4,9,2,3,5,7,8,1,6;n=lambda k:[t[i]for i,j in enumerate(b)if j==k];p,o,a,I=n(2),n(1),n(0),t.index
 for i in p:
    for j in p:
     for k in a:
        if i+j+k==15and-j+i:return I(k)
 for i in o:
    for j in o:
     for k in a:
        if i+j+k==15and-j+i:return I(k)
 for i in 9,3,7,1:
    if i in a and 5 in p:return I(i)
     for i in 5,4,2,8,6:
        if i in a:return I(i)
 return I(a[0])

board = [0,0,0,0,0,0,0,0,0]
rep = {0:"-",1:"X",2:"O"}

turn = int(sys.argv[1])
while True:
    for i in range(3):
        print rep[board[i*3]]+" "+rep[board[i*3+1]]+" "+rep[board[i*3+2]]
        print
    if turn:
        move = int(raw_input("Enter Move [0-8]: "))
    else:
        move = f(board)
    board[move] = turn+1
    turn = (turn+1)%2 


1
सभी अपने returnपिछले एक को छोड़कर लाइनों उनके सामने लाइन पर रखा जा सकता है, खाली स्थान के बचत
undergroundmonorail

1
इसके अलावा, मैं मदद नहीं कर सकता, लेकिन अगर यह बाइट को बचाने e=enumerate, करने f=lambda n:[t[i]for i,j in enumerate(b)if j==n]और असाइन करने p, oऔर aफ़ंक्शन का उपयोग करने के बजाय, मदद करेगा । हालांकि इसे गिना नहीं गया
भूमिगत

3
फिर भी हैक कर लियाxkcd.com/832 वास्तव में मदद करता है
l4m2

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.