राजा + बदमाश बनाम राजा


16

यह एक और अच्छी तरह से खेला गया शतरंज का खेल है। आप श्वेत खिलाड़ी हैं, और आपके पास अभी भी एक बदमाश और आपका राजा है। आपके विरोधी के पास केवल अपना राजा बचा है।

जब से तुम गोरे हुए हो, तुम्हारी बारी है। इस शतरंज मैच को खेलने के लिए एक कार्यक्रम बनाएं। इसका आउटपुट चाल का एक अनुक्रम हो सकता है, एक GIF एनीमेशन, ASCII कला या जो भी आपको पसंद है।

यह काफी स्पष्ट लगता है, लेकिन मैं इसे स्पष्ट रूप से बताऊंगा: आपको गेम जीतना होगा (चालों की एक सीमित संख्या में)। इस पद से जीतना हमेशा संभव है। इस पुस्तक को न खोएं। स्थिति नहीं है।

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

स्कोर

आपका स्कोर आपके कोड + बोनस के बाइट में लंबाई होगा। किसी भी भाषा की अनुमति है, सबसे कम स्कोर जीतता है।

बक्शीश

-50 यदि आपका प्रोग्राम मानव परिभाषित प्रारंभिक स्थिति और एक यादृच्छिक दोनों की अनुमति देता है। मनुष्य इसे stdin, फ़ाइल, GUI के माध्यम से दर्ज कर सकता है ...

-100 यदि आपका कार्यक्रम एक मानव और एक यादृच्छिक खिलाड़ी दोनों को काले राजा को स्थानांतरित करने की अनुमति देता है

+12345 यदि आप बाहरी शतरंज सॉल्वर या एक अंतर्निहित शतरंज पुस्तकालय पर भरोसा करते हैं

सौभाग्य!

अपडेट करें!

अतिरिक्त नियम: चेकमेट तक मैच खेला जाना चाहिए। ब्लैक इस्तीफा नहीं देता, शतरंज की बिसात के बाहर नहीं कूदता और एलियंस द्वारा अपहरण नहीं किया जाता।

संकेत

आप शायद शतरंज पर इस सवाल से मदद ले सकते हैं ।


2
क्या 50 चाल ड्रॉ नियम लागू होता है?
कॉमिन्टेन

1
@ विक्टर मेरे पास एक दो जोड़े हैं, लेकिन इसने अभी तक काम नहीं किया है। ब्रूट बल स्पष्ट रूप से बहुत धीमा है, अल्फा-बीटा भी क्योंकि स्थिति रेटिंग का परिदृश्य काफी सपाट है; और एक पाश में फंस जाता है। प्रतिगामी विश्लेषण काम करेगा लेकिन बहुत धीमी गति से सामने। मेरा अगला प्रयास KRK के लिए ब्रात्को के एल्गोरिथ्म का उपयोग करेगा, जिसे मैंने बचा लिया है क्योंकि यह विशेष मामलों का ढेर है, गोल्फ के लिए महान नहीं है।
बाज़रघ

1
@victor मैं यह भी देख रहा हूँ। यह वास्तव में दिलचस्प है क्योंकि इसे परिभाषित करना आसान है और करना मुश्किल है। बदले में कार्यक्रम छोटा नहीं होगा, इसलिए कोड-गोल्फ टैग ने इसे दोगुना कठिन बना दिया। यदि मेरा कार्यक्रम काम करता है तो आप इसे जल्द ही देखेंगे।
लेवल रिवर सेंट

1
@ विक्टर समस्या इष्टतम होने की कोशिश करने के बारे में नहीं था, खेल के इतिहास पर विचार किए बिना किसी 'सर्वश्रेष्ठ' कदम को उठाने का कोई भी प्रयास लूप के लिए प्रेरित करता है। खेल को हर स्थिति से समाप्त करने की आवश्यकता है। Bratko + वेरिएंट इष्टतम हैं, लेकिन काफी हद तक समाप्त। अब केवल प्रतिगामी विश्लेषण की कोशिश करना (यानी एंडगेम टेबल का निर्माण), आशाजनक लगता है और वास्तव में इष्टतम है, जो अच्छा है। साथ ही यथोचित रूप से छोटा हो जाता है।

2
किसी को भी प्रेरणा की जरूरत है (या बस उत्सुक है), तो आप एक 1433 चरित्र पा सकते हैं पूरा शतरंज इंजन पर home.hccnet.nl/hgmuller/umax1_6.c
Comintern

जवाबों:


11

हास्केल 1463-100 = 1363

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

ghc -O2एंडगेम टेबल गणना के लिए स्वीकार्य प्रदर्शन के लिए संकलन करें ; पहला कदम के बाद खेल तुरंत है। श्वेत राजा, बदमाश, काले राजा को तर्क के रूप में आपूर्ति करें। एक चाल के लिए, यह सिर्फ एक वर्ग चाहता है, और यदि आप रिटर्न दबाते हैं तो आपके लिए एक चुन लेंगे। उदाहरण सत्र:

$ time  printf "\n\n\n\n\n\n\n\n"|./rook8 e1 a1 e8
("e1","a7","e8")[d8]?
("d2","a7","d8")[c8]?
("d2","h7","c8")[b8]?
("c3","h7","b8")[a8]?
("b4","h7","a8")[b8]?
("c5","h7","b8")[a8]?
("b6","h7","a8")[b8]?
("b6","h8","b8") mate

real    0m8.885s
user    0m8.817s
sys 0m0.067s

कोड:

import System.Environment
import qualified Data.Set as S
sp=S.partition
sf=S.fromList
fl=['a'..'h']
rk=[0..7]
lf=filter
m=map
ln=notElem
lh=head
pl=putStrLn
pa[a,b]=(lh[i|(i,x)<-zip[0..]fl,a==x],read[b]-1)
pr(r,c)=fl!!r:show(c+1)
t f(w,r,b)=(f w,f r,f b)
km(a,b)=[(c,d)|c<-[a-1..a+1],d<-[b-1..b+1],0<=c,c<=7,0<=d,d<=7]
vd (w,r,b)=b`ln`km w&&w/=r&&b/=w&&b/=r
vw p@(_,r,b)=vd p&&r`ln`km b&&(ck p||[]/=bm p)
vb p=vd p&&(not.ck)p
rm (w@(c,d),(j,k),b@(u,x))=[(w,(j,z),b)|z<-rk,z/=k,j/=c||(k<d&&z<d)||(d<k&&d<z),j/=u||(k<x&&z<x)||(x<k&&x<z)]
kw(w,r,b)=m(\q->(q,r,b))$km w
xb(w,r,_)b=(w,r,b)
wm p=lf(\q->q/=p&&vw q)$rm p++(m(t f)$rm$t f p)++kw p
bm p@(_,_,b)=lf(\q->q/=p&&vb q)$m(xb p)$km b
c1((c,d),(j,k),(u,x))=j==u&&(c/=j||(k<x&&d<k)||(k>x&&d>k))
ck p=c1 p||(c1$t f p)
mt p=ck p&&[]==bm p
h(x,y)=(7-x,y)
v=f.h.f
f(x,y)=(y,x)
n p@((c,d),_,_)|c>3=n$t h p|d>3=n$t v p|c>d=n$t f p|True=p
ap=[((c,d),(j,k),(u,x))|c<-[0..3],d<-[c..3],j<-rk,k<-rk,u<-rk,x<-rk]
fr s p=S.member(n p)s
eg p=ef(sp mt$sf$lf vw ap)(sf$lf vb ap)
ps w mv b0=sp(\r->any(fr b0)$mv r)w
ef(b0,b1)w=let(w1,w2)=ps w wm b0 in(w1,b0):(if S.null w2 then[]else ef(f$ps b1 bm w2)w2)
lu((w1,b0):xs)p=if fr w1 p then lh$lf(fr b0)$wm p else lu xs p
th(_,_,b)=b
cd tb q=do{let{p=lu tb q};putStr$show$t pr p;if mt p then do{pl" mate";return()}else do{let{b1=pr$th$lh$bm p};pl("["++b1++"]?");mv<-getLine;cd tb$xb p (pa$if""==mv then b1 else mv)}}
main=do{p1<-getArgs;let{p2=m pa p1;p=(p2!!0,p2!!1,p2!!2)};cd(eg p)p}

संपादित: एंडगेम टेबल को याद रखने और तर्कों का उपयोग करने के लिए निश्चित कोड, इतना कम दर्दनाक बार-बार परीक्षण करने के लिए।


2
साइड इफेक्ट के साथ हैसेल कोड? तुम, विधर्मी कैसे हो सकता है! : पी
आइनेकियो

अंत में एक गंभीर!
.जाबरे

वह पहेली बुरी थी @izabera!
१०:१६ पर बजरघ

अच्छा! मैं जिस प्रयास पर काम कर रहा था, उससे बहुत बेहतर। मैं सिर्फ 50 चाल साथियों को सुनिश्चित करने के लिए पर्याप्त रूप से एल अजेड्रेसीस्टा में सुधार करने की कोशिश कर रहा था, लेकिन जहां तक ​​एक एल्गोरिथ्म चला जाता है यह वास्तव में बहुत बुरा है।
कोमिन्टर्न

एंडी टेबल ( y) को याद नहीं करने से मेरे पास बहुत सारे बेकार प्रदर्शन आए । यह वास्तव में स्पष्ट है कि जब हम पहले ही पूरे एंडगेम पर विचार कर चुके होते हैं तो दूसरा कदम तेज नहीं होता। मैं आज शाम पब से जा रहा हूं लेकिन अगर मुझे कल मौका मिला तो मैं इसे कम भयानक बना दूंगा।
bazzargh

7

सी, वर्तमान में 2552 नॉनवेज नॉनवॉइटस्पेस कैरेक्टर

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

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

स्टार्ट पोजिशन्स को ऊपर दाईं ओर से रो (1-8) कॉलम (1-8) के रूप में दर्ज किया जाता है और प्रोग्राम उसी स्कीम पर काम करता है। इसलिए यदि आपने अपनी स्क्रीन को 90 डिग्री एंटीकॉकवाइज कर दिया है, तो यह मानक पत्राचार शतरंज संख्यात्मक वर्ग संकेतन का पालन करेगा। ऐसी स्थितियाँ जहाँ काला राजा पहले से ही जाँच में है, को अवैध माना जाता है।

काली चाल को 0 से 7 तक एक संख्या के रूप में दर्ज किया जाता है, जिसमें 0 उत्तर की ओर, 1 से उत्तर-पूर्व की ओर एक चाल है और एक घड़ी की सूझबूझ से।

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

मुझे लगता है कि अधिकांश कीड़े और संभव अनंत छोरों को इस्त्री किया गया है, यह अब बहुत अच्छा चल रहा है। मैं कल फिर से इसके साथ खेलूंगा और देखूंगा कि क्या कुछ और है जिसे ठीक करने की जरूरत है।

#include "stdafx.h"
#include "stdlib.h"
#include "string.h"

int b[2], w[2], r[2], n[2],s,t,i,nomate;
int v[2][8] = { {-1,-1,0,1,1,1,0,-1}, {0,1,1,1,0,-1,-1,-1} };
int u[5] = { 0, 1, -1, 2, -2 };
char empty[82] = "        \n--------\n--------\n--------\n--------\n--------\n--------\n--------\n--------\n";
char board[82];

int distance(int p[2], int q[2]){
    return __max(abs(p[0]-q[0]),abs(p[1]-q[1]));
}

int sign(int n){
    return (n>0)-(0>n); 
}

// from parameters p for white king and q for rook, determines if rook is/will be safe
int rsafe(int p[2],int q[2]){
    return  distance(p, q)<2 | distance(q,b)>1;
}

void umove(){
    t=0;
    while (t != 100){
        printf("Enter number 0 to 7 \n");
        scanf_s("%d", &t); t %= 8;
        n[0] = b[0] + v[0][t];
        n[1] = b[1] + v[1][t];
        if (distance(w, n) < 2 | (n[0] == r[0] & (n[1]-w[1])*(r[1]-w[1])>0) 
            | ((n[1] == r[1]) & (n[0]-w[0])*(r[0]-w[0])>0) | n[0] % 9 == 0 | n[1] % 9 == 0)
            printf("illegal move");
        else{ b[0] = n[0]; b[1] = n[1]; t = 100; };
    }
}

void imove(){
    t=0;
    // mate if possible
    if (distance(b, w) == 2 & b[0] == w[0] & (b[1] == 1 | b[1] == 8) & r[0]!=w[0]){
        n[0] = r[0]; n[1] = b[1];
        if (rsafe(w, n)){
            r[1] = n[1]; 
            printf("R to %d %d mate!\n", r[0], r[1]);
            nomate=0;
            return;
        }
    }

    //avoid stalemate
    if ((b[0] == 1 | b[0] == 8) & (b[1] == 1 | b[1] == 8) & abs(b[0] - r[0]) < 2 & abs(b[0]-w[0])<2){
        r[0] = b[0]==1? 3:6;
        printf("R to %d %d \n", r[0], r[1]);
        return;
    }

    // dont let the rook be captured. 
    if(!rsafe(w,r)) 
    {
        if (w[0] == r[0]) r[1] = w[1] + sign(r[1]-w[1]);
        else r[1] = r[1]>3? 2:7;
        printf("R to %d %d \n", r[0], r[1]);
        return;
    }

    // if there's a gap between the kings and the rook, move rook towards them. we only want to do this when kings on same side of rook, and not if the black king is already on last row.
    if (abs(w[0]-r[0])>1 & abs(b[0] - r[0]) > 1 & (b[0]-r[0])*(w[0]-r[0])>0 & b[0]!=1 & b[0]!=8){
        n[0] = r[0] + sign(b[0] - r[0]); n[1] = r[1];
        if (rsafe(w, n)) r[0] = n[0]; 
        else r[1] = r[1]>3? 2:7;
        printf("R to %d %d \n", r[0], r[1]);
        return;

    }
    // if kings are far apart, or if they not on the same row (except if b 1 row from r and w 2 rows from r), move king
    if ((w[0]-r[0])!=2*(b[0]-r[0]) | abs(b[0]-w[0])>1 | distance(w,b)>2){
        for (i = 0; i<8; i++) if (v[0][i] == sign(b[0] - w[0]) & v[1][i] == sign(b[1] - w[1])) t = i;
        s = 1 - 2 * (w[0]>3 ^ w[1] > 3);
        for (i = 0; i < 5; i++){
            n[0] = w[0] + v[0][(t + s*u[i] + 8) % 8];
            n[1] = w[1] + v[1][(t + s*u[i] + 8) % 8] *(1-2*(abs(w[0]-b[0])==2));
            if (distance (n,b)>1 & distance(n, r)>0 & rsafe(n,r) & n[0]%9!=0 & n[1]%9!=0
                & !(n[0]==r[0] & (w[0]-r[0])*(b[0]-r[0])>0)) i = 5;
        }
        if (i == 6) {
            w[0] = n[0]; w[1] = n[1]; printf("K to %d %d \n", w[0], w[1]); return;
        }
    }

    //if nothing else to do, perform a waiting move with the rook. Black is forced to move his king.
    t = r[1]>3? -1:1;
    for (i = 1; i < 5; i++){
        n[0] = r[0]; n[1] = r[1] + t*i;
        if (rsafe(w, n)){ r[1] = n[1]; i=5; }
    }
    printf("R to %d %d \n", r[0], r[1]);
}

int _tmain(){

    do{ 
        t=0;
        printf("enter the row and col of the black king ");
        scanf_s("%d%d", &b[0], &b[1]);
        printf("enter the row and col of the white king ");
        scanf_s("%d%d", &w[0], &w[1]);
        printf("enter the row and col of the rook");
        scanf_s("%d%d", &r[0], &r[1]);
        for (i = 0; i < 2; i++) if (b[i]<1 | b[i]>8 | w[i]<1 | w[i]>8 | w[i]<1 | w[i]>8)t=1;
        if (distance(b,w)<2)t+=2;
        if ((b[0] == r[0] & (b[1]-w[1])*(r[1]-w[1])>0) | ((b[1] == r[1]) & (b[0]-w[0])*(r[0]-w[0])>0)) t+=4;
        printf("error code (0 if OK) %d \n",t);
    } while(t);

    nomate=1;
    while (nomate){
        imove();
        strncpy_s(board, empty, 82);
        board[b[0] * 9 + b[1] - 1] = 'B'; board[w[0] * 9 + w[1] - 1] = 'W'; board[r[0] * 9 + r[1] - 1] = 'R'; printf("%s", board);      
        if(nomate)umove();
    }
    getchar(); getchar();

}

यहां एक विशिष्ट फिनिश (दोस्त कभी-कभी बोर्ड के दाएं या बाएं किनारे पर कहीं भी हो सकता है।)

यहाँ छवि विवरण दर्ज करें


6

बैश, 18 (या -32?)

ठीक है, यह एक मजाक का जवाब है। चूंकि ब्लैक एक अच्छा शतरंज खिलाड़ी है, और ब्लैक जानता है कि व्हाइट भी एक अच्छा शतरंज खिलाड़ी है, वह तय करता है कि करने के लिए एकमात्र समझदार चीज़ है:

echo Black resigns

इससे श्वेत विजय प्राप्त होती है, जो विनिर्देशन को पूरा करती है।

तकनीकी रूप से आप वर्तमान स्थिति को तर्क के रूप में भी दर्ज कर सकते हैं, कार्यक्रम सिर्फ उन्हें अनदेखा करता है, इसलिए यकीनन यह -50 बोनस के लिए अर्हता प्राप्त कर सकता है।


मजेदार, लेकिन मैंने नियमों को अपडेट किया। चेकमेट तक खेलना अब अनिवार्य है।
izabera

1
Btw मूल प्रश्न में स्पष्ट रूप से कहा गया है कि आपका कार्यक्रम काले रंग के लिए एक मानव या एक यादृच्छिक खिलाड़ी की अनुमति दे सकता है, और आपका यादृच्छिक नहीं है।
इजाबेरा

2
मानक संकेतन का उपयोग करते हुए, आप आउटपुट 1-0को थोड़ा छोटा कर सकते हैं।
डानिएरो

1
@Comintern अच्छी तरह से वास्तविक जब इष्टतम खोने आमतौर पर सबसे लंबे समय तक चलने का मतलब है।
PyRulez

@PyRulez विकिपीडिया के अनुसार , "किसी भी खिलाड़ी किसी भी समय इस्तीफा दे सकता है और उनका प्रतिद्वंद्वी खेल जीतता है।" इसके अलावा, यह सिर्फ एक मजाक का जवाब है, इसे इतनी गंभीरता से न लें।
user12205
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.