चैंपियन बनें


11

टिक-टैक-लैटिन!

यह एक सच्ची कहानी है, इसलिए नामों में फेरबदल किया गया है।

मेरे लैटिन शिक्षक, श्री लैटिन ने अपना स्वयं का मालिकाना (कोई मजाक नहीं) टिक टीएसी पैर की अंगुली संस्करण बनाया। चलो इसे टिक-टैक-लैटिन कहते हैं। खेल सरल है, यह अनिवार्य रूप से टिक टीएसी को पैर की अंगुली पर चार ग्रिड द्वारा खेला जाता है।

औपचारिक नियम की घोषणा

एक पंक्ति या तो एक पंक्ति, स्तंभ या एक विकर्ण है। दो प्रतीक हैं, 'X' और 'O', लेकिन एक या दोनों को अलग प्रतीक के लिए प्रतिस्थापित किया जा सकता है।
जब आप अपने प्रतीक के तीन और दूसरे वर्ण में से एक होते हैं तो आप एक अंक प्राप्त करते हैं।

ये व्यवस्था स्कोर:

--- हे
-O--
XXXO
XOOX

O -XX
-  -
- एक्स -
--- हे

ये स्कोर नहीं करते हैं:

----
XXXX
----
OOOO

----
XXX-
----
OOO-

खेल तब भी जीता जाता है जब एक खिलाड़ी के पास अधिक अंक होते हैं। खेल तभी ड्रा होता है जब बोर्ड भर जाता है।

चुनौती

इस खेल को हल करें। आपका काम एक जीत या टाई की गारंटी देने का एक तरीका है, जो भी इष्टतम परिणाम है।

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


चाल के किसी भी क्रम के खिलाफ अपने खिलाड़ी को खेलना इष्टतम परिणाम देना चाहिए। इसका मतलब है कि आप मान सकते हैं कि इनपुट स्थिति वह है जो आपके खिलाड़ी के साथ खेलने से पहुंच योग्य है। सबमिशन को नियतात्मक होना चाहिए, और जरूरी नहीं कि इसे इष्टतमता के प्रमाण की आपूर्ति करने की आवश्यकता है, लेकिन यदि वे क्रैक हो जाते हैं (पीटा जा रहा है) तो आपके सबमिशन को अमान्य माना जाएगा (आप इसे छोड़ सकते हैं, लेकिन हेडलाइन में जोड़ सकते हैं)।
यह एक गैर-तुच्छ कार्य है, इसलिए कोई भी मान्य प्रस्तुत प्रभावशाली है और एक स्वीकृत टिक के योग्य है, लेकिन मैं कोड गोल्फ को प्राथमिक जीतने की कसौटी बनाऊंगा।

एक विजेता चुने जाने तक इस सूची में नीचे जाकर विजेता चुना जाता है।

  • सबसे कम हल किया हुआ अनुकरण जो हमेशा जीतता है
  • सबसे कम कार्यान्वयन

1
"पहले खेलने की गुणवत्ता देखी जाती है" क्या आपको नहीं लगता कि यह व्यक्तिपरक है?
user48538

खेलने के लिए एक इंटरफ़ेस प्रदान करने का कार्य एक आदर्श खिलाड़ी को लिखने का परिधीय लगता है। मेरा सुझाव है कि इनपुट के रूप में वर्तमान गेम स्थिति को पास करने और कोड को एक विजयी चाल का उत्पादन करने की आवश्यकता होती है, या यहां तक ​​कि केवल सही खेल (जीत, ड्रा, हार) के तहत एक मूल्यांकन।
xnor

1
अकुशल ब्रूट फोर्स सर्च करने से एक समाधान गोल्फ हो सकता है। क्या आप ठीक हैं यदि कोड बहुत धीमी गति से चलता है?
xnor

1
" यदि आप स्कोर करते हैं तो आप गेम जीतते हैं और इस प्रक्रिया में अपने प्रतिद्वंद्वी के लिए स्कोर नहीं करते हैं। " इसका मतलब यह है कि मैं केवल तभी जीत सकता हूं जब मैं एक टुकड़ा रखता हूं, न कि जब मेरा प्रतिद्वंद्वी करता है? यदि कोई चाल दोनों खिलाड़ियों के लिए जीत की रेखा बनाती है तो क्या होता है: खेल तैयार किया गया या खेला गया?
पीटर टेलर

1
@RohanJhunjhunwala आपको खेल राज्य के अनुमत इनपुट को स्पष्ट करना चाहिए, अन्यथा यह संभव है कि लोग वर्तमान में अपरिभाषित इनपुट प्रारूप का लाभ उठा सकते हैं और एक प्रारूप चुन सकते हैं जो उनके समाधान में बहुत मदद करता है।
केवल

जवाबों:


6

पर्ल, 147 बाइट्स (गैर प्रतिस्पर्धा, प्रति सेकंड 10 सेकंड से अधिक समय लगता है)

के लिए +4 शामिल है -0p

कार्यक्रम खेलता है X। यह एक आदर्श खेल खेलेंगे।

STDIN पर बोर्ड इनपुट करें, उदाहरण के लिए:

tictaclatin.pl
-X-O
-X--
X-X-
O--O
^D

Ouptut एक ही बोर्ड होगा, जिसकी Xजगह सभी Oऔर इसके विपरीत होंगे। खाली स्थान एक संख्या से भरा होगा जो परिणाम का संकेत देगा यदि X वहां खेलता है, 1जिसका अर्थ है कि परिणाम एक जीत, 2एक ड्रॉ और 3एक नुकसान होगा। एक समाप्त खेल उलटे रंगों के साथ एक ही स्थिति देता है।

इस उदाहरण में आउटपुट होगा:

1O1X
1O33
O3O3
X33X

Xयदि वह शीर्ष और बाईं ओर 3 स्थानों में खेलता है तो स्थिति उसके लिए एक जीत है । अन्य सभी चालें हार जाती हैं।

यह भ्रामक आउटपुट वास्तव में सुविधाजनक है यदि आप जानना चाहते हैं कि एक कदम के बाद खेल कैसे जारी है। चूंकि कार्यक्रम हमेशा खेलता है, Xआपको स्वैप करना है Xऔर Oइसके लिए चालें देखना है O। उदाहरण के लिए यह बहुत स्पष्ट है कि Xशीर्ष बाएं में खेलकर जीतता है, लेकिन Xशीर्ष के साथ तीसरे स्थान पर खेलने पर क्या होगा ? बस आउटपुट को कॉपी करें, Oआपके द्वारा चुनी गई चाल के स्थान पर और -फिर से सभी अन्य नंबरों को प्रतिस्थापित करें, इसलिए यहां:

-OOX
-O--
O-O-
X--X

जिसके परिणामस्वरूप:

3XXO
3X33
X3X3
O33O

जाहिर है कि हर कदम Oको हारना चाहिए, इसलिए अगर वह शीर्ष पर रहे तो वह कैसे हारेंगे? फिर Oसे ऊपर बाईं ओर रखकर और अंकों को बदलकर ऐसा करें -:

OXXO
-X--
X-X-
O--O

देते हुए:

XOOX
1O33
O3O3
X33X

तो X के पास अपनी जीत के लिए जाने का एक ही तरीका है:

XOOX
OO--
O-O-
X--X

देते हुए

OXXO
XX33
X3X3
O33O

के लिए स्थिति Oनिराशाजनक बनी हुई है। अब यह देखना आसान है कि हर कदम Xतुरंत जीतने की अनुमति देता है। चलो कम से कम एक पंक्ति में 3 हे के लिए जाने की कोशिश करें:

OXXO
XX--
X-X-
O-OO

देते हुए:

XOOX
OO13
O3O3
X3XX

Xकेवल जीतने वाला कदम निभाता है (ध्यान दें कि यह XXXOतीसरे स्तंभ के साथ आता है :

XOOX
OOO-
O-O-
X-XX

यहाँ उत्पादन है:

OXXO
XXX-
X-X-
O-OO

क्योंकि खेल पहले ही समाप्त हो चुका था। आप तीसरे कॉलम पर जीत देख सकते हैं।

वास्तविक कार्यक्रम tictaclatin.pl:

#!/usr/bin/perl -0p
y/XO/OX/,$@=-$@while$|-=/(@{[map{(O.".{$_}O"x3)=~s%O%Z|$`X$'|Z%gr}0,3..5]})(?{$@++})^|$/sx;$@<=>0||s%-%$_="$`O$'";$$_||=2+do$0%eg&&(/1/||/2/-1)

रिक्त बोर्ड पर लागू यह 9506699 पदों का मूल्यांकन करता है जो मेरे कंप्यूटर पर 30 जीबी और 41 मिनट लगते हैं। परिणाम है:

2222
2222
2222
2222

इसलिए हर शुरुआती कदम ड्रॉ होता है। तो खेल एक ड्रा है।

चरम मेमोरी उपयोग ज्यादातर रिकर्सियन का उपयोग करने के कारण होता है do$0। एक सादे फ़ंक्शन का उपयोग करके इस 154 बाइट संस्करण का उपयोग करने के लिए 3Gb और 11 मिनट की आवश्यकता होती है:

#!/usr/bin/perl -0p
sub f{y/XO/OX/,$@=-$@while$|-=/(@{[map{(O.".{$_}O"x3)=~s%O%Z|$`X$'|Z%gr}0,3..5]})(?{$@++})^|$/sx;$@<=>0||s%-%$_="$`O$'";$$_||=2+&f%eeg&&(/1/||/2/-1)}f

जो अधिक मुस्कराता है (लेकिन अभी भी बहुत कुछ है, कुछ अभी भी स्मृति लीक होना चाहिए)।

कई स्पीडअप के संयोजन से यह 160 बाइट संस्करण (5028168 स्थिति, 4 मिनट और खाली बोर्ड के लिए 800M) हो जाता है:

#!/usr/bin/perl -0p
sub f{y/XO/OX/,$@=-$@while$|-=/(@{[map{(O.".{$_}O"x3)=~s%O%Z|$`X$'|Z%gr}0,3..5]})(?{$@++})^|$/osx;$@<=>0||s%-%$_="$`O$'";$a{$_}//=&f+1or return 1%eeg&&/1/-1}f

कि 0एक जीत के लिए पिछले एक का उपयोग करता है (एक साथ भ्रमित नहीं O), 1एक ड्रॉ के लिए और 2एक नुकसान के लिए। इस एक का उत्पादन भी अधिक भ्रामक है। यह रंग स्वैप के बिना एक जीत के मामले में एक्स के लिए जीतने की चाल में भरता है, लेकिन अगर इनपुट गेम पहले ही जीता गया था, तब भी रंग स्वैप नहीं करता है और किसी भी चाल में नहीं भरता है।

बेशक सभी संस्करण तेज़ हो जाते हैं और कम मेमोरी का उपयोग करते हैं क्योंकि बोर्ड भरता है। जैसे ही 2 या 3 मूव किए गए, तेज़ संस्करणों को 10 सेकंड से कम समय में एक चाल उत्पन्न करनी चाहिए।

सिद्धांत रूप में यह 146 बाइट संस्करण भी काम करना चाहिए:

#!/usr/bin/perl -0p
y/XO/OX/,$@=-$@while/(@{[map{(O.".{$_}O"x3)=~s%O%Z|$`X$'|Z%gr}0,3..5]})(?{$@++})^/sx,--$|;$@<=>0||s%-%$_="$`O$'";$$_||=2+do$0%eg&&(/1/||/2/-1)

लेकिन मेरी मशीन पर यह एक पर्ल बग को ट्रिगर करता है और कोर को डंप करता है।

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

आप डाल दिया $\=बस से पहले: (3 बाइट्स लागत) $@<=>0: उसके बाद प्रत्येक उत्पादन बोर्ड पूरे बोर्ड की स्थिति के बाद किया जाएगा 1के लिए Xजीत, 0ड्रॉ के लिए और -1कम करने के लिए।

यहाँ एक इंटरेक्टिव ड्राइवर है जो ऊपर बताए गए सबसे तेज़ संस्करण पर आधारित है। गेम खत्म होने पर ड्राइवर के पास कोई तर्क नहीं है इसलिए आपको खुद को रोकना होगा। गोल्फ कोड हालांकि जानता है। अगर सुझाए गए कदम के साथ -कुछ भी नहीं बदला है तो खेल खत्म हो जाता है।

#!/usr/bin/perl
sub f{
    if ($p++ % 100000 == 0) {
        local $| = 1;
        print ".";
    }
y/XO/OX/,$@=-$@while$|-=/(@{[map{(O.".{$_}O"x3)=~s%O%Z|$`X$'|Z%gr}0,3..5]})(?{$@++})^|$/osx;$@<=>0||s%-%$_="$`O$'";$a{$_}//=&f+1or return 1%eeg&&/1/-1}

# Driver
my $tomove = "X";
my $move = 0;
@board = ("----\n") x 4;
while (1) {
    print "Current board after move $move ($tomove to move):\n  ABCD\n";
    for my $i (1..4) {
        print "$i $board[$i-1]";
    }
    print "Enter a move like B4, PASS (not a valid move, just for setup) or just press enter to let the program make suggestions\n";
    my $input = <> // exit;
    if ($input eq "\n") {
        $_ = join "", @board;
        tr/OX/XO/ if $tomove eq "O";
        $p = 0;
        $@="";
        %a = ();
        my $start = time();
        my $result = f;
        if ($result == 1) {
            tr/OX/XO/ if $tomove eq "O";
            tr/012/-/;
        } else {
            tr/OX/XO/ if $tomove eq "X";
            tr/012/123/;
        }
        $result = -$result if $tomove eq "O";
        my $period = time() - $start;
        print "\nSuggested moves (evaluated $p positions in $period seconds, predicted result for X: $result):\n$_";
        redo;
    } elsif ($input =~ /^pass$/i) {
        # Do nothing
    } elsif (my ($x, $y) = $input =~ /^([A-D])([1-4])$/) {
        $x = ord($x) - ord("A");
        --$y;
        my $ch = substr($board[$y],$x, 1);
        if ($ch ne "-") {
            print "Position already has $ch. Try again\n";
            redo;
        }
        substr($board[$y],$x, 1) = $tomove;
    } else {
        print "Cannot parse move. Try again\n";
        redo;
    }
    $tomove =~ tr/OX/XO/;
    ++$move;
}

अच्छा उत्तर। क्या आप मुझे इसका परीक्षण करने के लिए कुछ आसान तरीके प्रदान कर सकते हैं? आदर्श रूप से यह एक इंटरैक्टिव संस्करण देखना पसंद करेंगे ... (यह मेरी अपनी जिज्ञासा के लिए जूट है)।
रोहन झुनझुनवाला

@ रोहन झुनझुनवाला ओके ने
टन हास्पेल

परिवर्तनीय '$ चाल' को prog.pl:2 पर घोषित नहीं किया गया है
रोहन झुनझुनवाला

क्या कोई मानव समाधान लागू कर सकता है?
रोहन झुनझुनवाला

@ रोहन झुनझुनवाला ने बस ड्राइवर प्रोग्राम को रीचेक किया। रन ठीक है, $moveलाइन 11 पर घोषित किया गया है। मुझे कोई अनुमान नहीं है कि कोई मानव उत्तराधिकारी है या नहीं। यह कार्यक्रम सिर्फ गेम ट्री पर मिनिमैक्स करता है, इसमें कोई रणनीतिक ज्ञान नहीं है ।
टन हास्पेल

2

जावास्क्रिप्ट (ईएस 6) 392 बाइट्स

a=>b=>(c="0ed3b56879a4c21f",r=[],k=f=>r.push([a.filter(f),b.filter(f)]),[0,1,2,3].map(i=>k(n=>n%4==i)+k(n=>(n/4|0)==i)),k(n=>n%5==0),k(n=>n&&n-15&&!(n%3)),g=r.find(o=>(o[0].length==1&&o[1].length==2)||(o[0].length==2&&o[1].length==1)),g?parseInt(c[30-[...g[0],...g[1]].map(i=>parseInt(c[i],16)).reduce((p,c)=>p+c)],16):[...a,...b].indexOf(15-a[0])+1?15-a.find(i=>b.indexOf(15-i)==-1):15-a[0])

प्रयोग

"बॉट" दूसरा बजाएगा।

एक 4x4 ग्रिड बनाएं जो इस तरह से गिना जाता है:

+----+----+----+----+
|  0 |  1 |  2 |  3 |
+----+----+----+----+
|  4 |  5 |  6 |  7 |
+----+----+----+----+
|  8 |  9 | 10 | 11 |
+----+----+----+----+
| 12 | 13 | 14 | 15 |
+----+----+----+----+

इसे ब्राउजर कंसोल में चलाते हैं: f=कोड के सामने रखें

तो, अगर मैं में शुरू करना चाहते हैं 1, मैं चल पाएंगे f([1])([])और यह मेरे दे देंगे 14

अच्छी चाल ... क्या होगा अगर मैं 2बाद में खेलूं? f([2,1])([14])। यह वापस आ जाएगी 13

लेमेक आत्मसमर्पण का प्रयास करें। खेलते हैं 3f([3,2,1])([14,13])। ओह 0! आप समझ गए!

खेलते हैं 0? f([0,2,1])([14,13])15ठीक है चलो खेलते रहो ...

ध्यान दें

  1. अंतःक्रियात्मक रूप से खेलें। से शुरू करें f([your-step])([])

  2. अपना अगला कदम बढ़ाएँ। (ऊपर डेमो देखें)

  3. "बॉट" इनपुट को उसके चरणों में मदद करें। यदि आप इसे यादृच्छिक सेटिंग देते हैं तो यह आपको अच्छे परिणाम नहीं देगा। (जैसे f([1,2,4])([14,12])देंगे 14- अरे बॉट 13अपनी दूसरी चाल पर खेलना चाहता था !

संक्षिप्त सारांश

जब तक आप आत्मसमर्पण नहीं कर रहे हैं, बॉट एक दर्पण चाल चलेगा।

धन्यवाद @EHTproductions मुझे यह बताने के लिए कि मैं खेल के नियमों और गोल्फ सुझावों को गलत बताता हूं: पी

अब यह भी पता लगाएगा कि उसे चेकमेट मिला या नहीं। यदि हाँ, तो इसे ब्लॉक करें!

इसकी प्राथमिकताएं: ब्लॉक> मिरर> (फॉलबैक) एक दर्पण को पुन: पेश करने के तरीकों की तलाश करें


मुझे वास्तव में "मिरर मूव" रणनीति पसंद है :) मुझे गलतफहमी हो सकती है, लेकिन 3,2,1आपके 0लिए और बॉट आपके लिए जीत नहीं है?
ETHproductions

उफ़, मुझे गलत समझा गया "जो एक तरह के 3 और दूसरे के 1 के पैटर्न को पकड़ता है"। Lemme ने समाधान को थोड़ा ट्विक किया .. धन्यवाद @ETHproductions।
सनी पुन

गोल्फ युक्तियाँ के एक जोड़े: करने के लिए गोल्फ [0,1,2,3].map(i=>{k(n=>n%4==i);k(n=>Math.floor(n/4)==i);})हो सकता है [0,1,2,3].map(i=>k(n=>n%4==i)+k(n=>(n/4|0)==i))
18

मुझे नहीं लगता कि यह साबित करने योग्य है
रोहन झुनझुनवाला

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