เล่นหมากกระดานที่ถูกต้องให้บอร์ดกับ stdin


11

โปรแกรมเล่นเป็นสีขาว

ตัวอย่าง stdin:

8 ║♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜
7 ║♟ ♟ ♟ ♟ … ♟ ♟ ♟
6 ║… … … … … … … …
5 ║… … … … ♟ … … …
4 ║… … … … … … … …
3 ║… … ♘ … … … … …
2 ║♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙
1 ║♖ … ♗ ♕ ♔ ♗ ♘ ♖
——╚═══════════════
—— a b c d e f g h

ตัวอย่าง stdout:

8 ║♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜
7 ║♟ ♟ ♟ ♟ … ♟ ♟ ♟
6 ║… … … … … … … …
5 ║… … … … ♟ … … …
4 ║… … … … ♙ … … …
3 ║… … ♘ … … … … …
2 ║♙ ♙ ♙ ♙ … ♙ ♙ ♙
1 ║♖ … ♗ ♕ ♔ ♗ ♘ ♖
——╚═══════════════
—— a b c d e f g h

การเคลื่อนไหวที่ถูกต้องใด ๆ ก็โอเค "En passant" และ castling จะถูกละเว้น มันก็โอเคที่จะแสดงข้อความผิดพลาดหรือพิมพ์อะไรถ้าไม่มีการย้ายที่ถูกต้อง

คำตอบที่ได้คะแนนมากที่สุดจะเป็นฝ่ายชนะ


ฉันหมายถึงข้อความแสดงข้อผิดพลาดมาตรฐานที่เกิดจากความล้มเหลวของฟังก์ชั่นภาษาในตัว งั้นเหรอ? - มันเป็นข้อบังคับว่าโปรแกรมที่สามารถทำใด ๆย้ายกฎหมายหรือไม่ บางทีการเคลื่อนไหวแบบพิเศษและแบบจำนำควรมีทางเลือกด้วยโบนัสบ้างไหม?
หยุดหมุนทวนเข็มนาฬิกาเมื่อ

2
@leftaroundabout: เมื่อใดก็ตามที่คุณสามารถปราสาทคุณสามารถย้ายเกมโกงแทนดังนั้นคุณสามารถข้ามตรรกะสำหรับที่อย่างน้อย
hammar

2
... และเมื่อคิดถึงเรื่องนี้อีกแล้วการเคลื่อนไหว "en passant" ต้องการข้อมูลเกี่ยวกับการเคลื่อนไหวก่อนหน้านี้ซึ่งไม่สามารถอนุมานได้จากแค่ตำแหน่งของชิ้นส่วนดังนั้นฉันคิดว่ามันอาจจะปลอดภัยที่จะทิ้งสิ่งนั้นไว้ อย่างไรก็ตามไม่ว่าการย้ายครั้งแรกสองครั้งจะพร้อมใช้งานสามารถอนุมานได้จากอันดับของการจำนำดังนั้นคุณอาจต้องการรวมไว้
hammar

@hammar: ถูกต้องฉันไม่ได้คิดถึงเรื่องนั้น การย้ายสองครั้งก็ไม่สำคัญเช่นกันยกเว้นในกรณีเดียว: เมื่อคุณสามารถไปสองขั้นตอนคุณสามารถไปหนึ่งก้าวได้ดังนั้นจึงสำคัญเมื่อคุณอยู่ในการตรวจสอบและการย้ายซ้ำสองครั้งเป็นท่าเดียวที่ครอบคลุมกษัตริย์ นอกจากนี้แม้ว่าคุณไม่จำเป็นต้องใช้ทุกการเคลื่อนไหวคุณยังต้องพิจารณาว่าสีดำสามารถตอบได้ทุกโอกาส
หยุดที่จะเปลี่ยนรหัสลับเมื่อ

9
การลาออกนั้นนับว่าเป็นการเคลื่อนไหวทางกฎหมายหรือไม่? :)
gnibbler

คำตอบ:


16

ฉันไม่ได้บ่นเกี่ยวกับ upvotes แต่เพื่อความเป็นธรรม ... วิธีแก้ปัญหาของฉันที่นี่ไม่ใช่สิ่งที่ยอดเยี่ยมจริงๆ Ugoren's ดีกว่านอกจากขาดการสนับสนุน Unicode อย่าลืมดูคำตอบทั้งหมดก่อนที่จะลงคะแนนถ้าคุณเจอคำถามนี้แล้วตอนนี้!
อย่างไรก็ตาม.

Haskell, 893 888 904 952 (ไม่รวมปราสาท)

862 (โดยไม่จำนำสองเท่า)

(คุณไม่ได้ระบุว่าควรจะเป็นโค้ดกอล์ฟหรือไม่ แต่ดูเหมือนว่าฉันควรจะเป็น)

χ=w⋈b;w="♙♢♤♔♕♖♗♘";b="♟♦♠♚♛♜♝♞"
μ=t⤀ζ++((\(x,y)->(x,-y))⤀)⤀μ;q c|((_,m):_)<-((==c).fst)☂(χ⋎μ)=m
t(x:y:l)=(d x,d y):t l;t _=[];d c=fromEnum c-78
ζ=["NM","NL","MMOM","MMMNMONMNOOMONOO",σ⋈δ,σ,δ,"MLOLPMPOOPMPLOLM"]
σ=l>>=(\c->'N':c:c:"N");δ=[l⋎l,reverse l⋎l]>>=(>>=(\(l,r)->[l,r]))
l="GHIJKLMOPQRSTU"
α c|c∊"♢♤"='♙'|c∊"♦♠"='♟'|c∊χ=c;π('♙':_)=6;π _=1
(⋎)=zip;(⤀)=map;(∊)=elem;(✄)=splitAt;(☂)=filter;(⋈)=(++)
φ r@(x,y)p a
 |x>7=φ(0,y+1)p a
 |y>7=[]
 |c<-a✠r=(c⌥r)p a y⋈φ(x+1,y)p a
(c⌥r)p a y
 |c==p!!0=(a☈r)c χ++const(y==π p)☂(a☈r)(p!!1)χ++(a☈r)(p!!2)('…':w)
 |c∊p=(a☈r)c χ
 |True=[]
a✠(x,y)=a!!y!!(x*2);o(x,y)=x>=0&&x<8&&y>=0&&y<8
(n➴a)(x,y)|(u,m:d)<-y✄a,(l,_:r)<-(x*2)✄m=u⋈(l⋈(n:r):d)
(a☈r@(x,y))c b=(α c➴('…'➴a)r)⤀((\r->o r&&not((a✠r)∊b))☂((\(ξ,υ)->(x+ξ,y+υ))⤀q c))
main=interact$unlines.uncurry((⋈).zipWith((⋈).(:" ║"))['8','7'..]
 .head.((all(any('♔'∊)).φ(0,0)b)☂).φ(0,0)w.(drop 3⤀)).(8✄).lines

เมื่อคุณติดตั้งGHC (เช่นเป็นส่วนหนึ่งของแพลตฟอร์ม Haskell ) คุณสามารถทำได้

$ runhaskell def0.hs < examplechessboard.txt
8 ║♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜
7 ║♟ ♟ ♟ ♟ … ♟ ♟ ♟
6 ║… … … … … … … …
5 ║… ♘ … … ♟ … … …
4 ║… … … … … … … …
3 ║… … … … … … … …
2 ║♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙
1 ║♖ … ♗ ♕ ♔ ♗ ♘ ♖
——╚═══════════════
—— a b c d e f g h

ตอนนี้มันบ้าแล้ว :) ฉันจะลองดู :)
Hristo Hristov

มีความคิดวิธีทดสอบความสุดยอดนี้ไหม? Ideone.com ไม่สามารถจัดการได้ ...
Hristo Hristov

@HristoHristov: แปลกไม่ทำงานกับ Ideone อาจเกี่ยวข้องกับอักขระที่ไม่ใช่ ASCII
หยุดที่จะเปลี่ยนรหัสลับเมื่อ

ใช่นี่เป็นปัญหาของ ideone
Hristo Hristov

14
ขอแสดงความยินดีคุณได้ทำให้ Haskell ดูเหมือน APL แล้ว :-)
Ilmari Karonen

11

C, 734 672 640 ตัวอักษร

จำนวนตัวอักษรโดยไม่ต้องมีช่องว่างที่ถอดออกได้
รูปแบบไฟล์ที่ฉันใช้ไม่ได้รับการร้องขอ แต่ทำให้ ASCII ง่ายขึ้น
ฉันต้องการเพิ่มการรองรับอักขระ Unicode มันจะมีราคาแพง

char*r=" kpnbrq  KPNBRQ $ ,&)$wxy()879()8(6:GI(",B[256],*b=B,i;
e(x,d,m,V,c,r,n,p){
    for(r=0,p=b[x];m/++r;){
        n=x+d*r;
        if(p==2+8*(d<0)||n&136||!(b[n]?r=8,8^p^b[n]^8&&c&65^64:c&65^65)
            ? r=m,0
            : V?v(n,x):b[n]==1)
            return b[x]=0,b[n]=p%8-2||n/16%7?p:p+4;
    }
    return d>0&&e(x,-d,m,V,c);
}
d(x,v,m,i)char*m;{
    return(i=*m-40)?e(x,i%64,b[x]%8-2?b[x]&4?7:1:(x/16-1)%5|i%2?1:2,v,i)||d(x,v,m+1):0;
}
v(t,f){
    bcopy(B,b+=128,128);
    b[t]=b[f];b[f]=0;
    i=a(1,63);
    b=B;
    return!i;
}
a(c,n){
    return b[i=n*2-n%8]&&b[i]/8==c&&d(i,!c,r+r[b[i]%8+15]-10)||n--&&a(c,n);
}
main(){
    for(;gets(b);b+=8)for(;*b;b++)*b=strchr(r,*b)-r;b=B;
    for(i=64*!a(0,63);i<64;i++%8-7||puts(""))putchar(r[b[i*2-i%8]]);
}

รูปแบบไฟล์อินพุต / เอาท์พุต:
ต้องมีความยาว 8 บรรทัดอย่างแท้จริง 8 ตัวอักษร pnbrqkใช้สำหรับชิ้นส่วนสีขาวPNBRQKสำหรับชิ้นส่วนสีดำช่องว่างสำหรับช่องว่าง:

RNBQKBNR
PPPP PPP

 n  P


pppppppp
r bqkbnr

ตรรกะค่อนข้างง่าย:
สำหรับการเคลื่อนไหวที่เป็นไปได้ของชิ้นส่วนสีขาวแต่ละชิ้นให้ลองเคลื่อนชิ้นส่วนสีดำแต่ละอันที่เป็นไปได้
หากไม่มีการเคลื่อนไหวสีดำจับกษัตริย์สีขาวย้ายสีขาวที่ถูกต้อง

บอร์ดนี้ได้รับการบำรุงchar[256]รักษาโดยใช้เป็นเมทริกซ์ขนาด 16x16 ซึ่งใช้ 8x8 บนซ้ายเท่านั้น ตำแหน่งและเวกเตอร์การเคลื่อนไหวจะถูกเก็บไว้ในจำนวนเต็ม 8 บิต ( x:4,y:4) บิตพิเศษช่วยให้การใช้เลขคณิตอย่างง่าย ( new_pos = old_pos + steps*direction) พร้อมการตรวจจับขอบบอร์ด&0x88อย่างง่ายดาย r[]เข้ารหัสสามสิ่ง:

  1. 15 ไบต์แรกแม็พโค้ดชิ้นส่วนภายใน (K = 1, P = 2, N = 3, B = 4, R = 5, Q = 6) กับตัวอักษร
  2. 6 ไบต์ถัดไปทำการแมปรหัสชิ้นส่วนภายในเพื่อออฟเซ็ตในส่วนสุดท้าย (K และ Q เหมือนกัน B คือส่วนท้ายของมัน)
  3. 16 '('+vectorคนสุดท้ายไบต์เข้ารหัสการเคลื่อนไหวของทุกชิ้นเป็น

ฟังก์ชั่น:

  1. mainอ่านบอร์ดแปลงตัวอักษรเป็นรหัสภายในโทรaหาการเคลื่อนไหวสีขาวพิมพ์กระดาน
  2. aวนซ้ำ 64 ช่อง สำหรับชิ้นส่วนของสีที่เหมาะสม (แต่ละพารามิเตอร์c) dก็พบกฎการเคลื่อนไหวสำหรับชิ้นส่วนและบริการโทร
  3. dวนซ้ำวนซ้ำในกฎการเคลื่อนที่ที่เข้ารหัสซึ่งเป็นรายการของเวกเตอร์ที่เรียกeใช้แต่ละอัน มันให้eตำแหน่งเริ่มต้นเวกเตอร์และขีด จำกัด ของช่วง (7 สำหรับชิ้นส่วนเหนือ B, 2 สำหรับเบี้ยอันดับสองหรือ 1 อย่างอื่น)
  4. eทดสอบการเคลื่อนไหวทั้งหมดพร้อมเวกเตอร์ หากการย้ายเป็นไปได้ (เช่นเบี้ยไปข้างหน้าภายในคณะกรรมการไม่ถูกบล็อกจับจำนำเป็นแนวทแยงมุม) ตรวจสอบหนึ่งในสองสิ่ง สำหรับการเคลื่อนไหวสีขาววิ่งvเพื่อตรวจสอบการย้าย สำหรับท่าดำตรวจสอบว่าจับราชาขาวได้ไหม ถ้าเป็นจริงการเคลื่อนไหวจะเล่นบนกระดาน
  5. vตรวจสอบการย้ายสีขาว มันคัดลอกกระดานกันดำเนินการย้ายเพื่อทดสอบและโทรaอีกครั้งเพื่อค้นหาการเคลื่อนไหวสีดำ

ในที่สุดวิธีการแก้ปัญหาด้วยการเข้ารหัสบีบอัดที่เหมาะสมของการเคลื่อนไหวที่เป็นไปได้! และมันก็เร็วมาก คุณไม่คิดว่าคุณสามารถเพิ่มเครื่องห่อ Unicode และยังคงสั้นกว่ารหัสของฉันได้หรือไม่
หยุดหมุนทวนเข็มนาฬิกาเมื่อ

@leftaroundabout ฉันเดาว่าฉันทำได้ ปัญหาหลักคือฉันทำงานในบรรทัดคำสั่ง Linux ที่คุณไม่เห็น Unicode ดังนั้นการดีบักมันจะน่ารำคาญ ฉันยังมีรุ่นที่ช่วยประหยัดอีก 40 ไบต์ (ฉันจะอัปเดตเร็ว ๆ นี้) ดังนั้นฉันจึงมีตัวอักษรมากมายให้ใช้งาน
ugoren

@ugoren: การกระจาย Linux ที่ทันสมัยแบบครึ่งทางรองรับ UTF-8 ได้หรือไม่
ฮัน

@han ฉันกำลังทำงานบน Windows และเชื่อมต่อกับ Linux โดย SSH และ Unicode ไม่ทำงาน ฉันสามารถเขียนไปยังไฟล์และเปิดใน Windows แต่มันก็ไม่น่าสนใจอีกต่อไป
ugoren

จะรวบรวมกับ gcc นี้หรือไม่ ฉันใช้ Geany สำหรับ Windows กับ MinGW และมันจะรวบรวมข้อผิดพลาดและคำเตือนมากมาย แต่จะไม่สร้าง / run.eg: C: \ Users \ xxx \ AppData \ Local \ Temp \ ccpBG9zy.o: codegolfchess.c :(. text + 0x2d8): การอ้างอิงที่ไม่ได้กำหนดไปยัง `bcopy 'collect2: ld ส่งคืนสถานะทางออก 1 รายการ
rpd

5

Python 2.6, 886 - 1425 ตัวอักษร

เวอร์ชั่นเริ่มต้นของฉัน (ในการแก้ไข) มีตัวอักษร 886 ตัว แต่ไม่ตอบสนองสเป็คอย่างสมบูรณ์ (ไม่ได้ตรวจสอบเพื่อหลีกเลี่ยงการรุกฆาต; มันไม่ได้พิจารณาการเคลื่อนไหวที่เป็นไปได้ของชิ้นส่วนสีดำ)

ตอนนี้มันจะ (และฉันได้แก้ไขข้อบกพร่องหลายอย่างในต้นฉบับ) อนิจจาเรื่องนี้มาพร้อมกับค่าใช้จ่ายในตัวละคร: 1425 สำหรับตอนนี้ แต่ยังคงมีพื้นที่เล็ก ๆ สำหรับการปรับปรุง รุ่นนี้ควรมีความแข็งแกร่งมากกว่าในการจัดการเคสแบบขอบและรุ่นก่อนหน้า

#-*-coding:utf8-*-
import sys;e=enumerate
B,W=["♟","♜","♞","♝","♛","♚"],["♙","♖","♘","♗","♕","♔"]
R={"♙":[11,42],"♖":[28],"♘":[31],"♗":[8],"♕":[8,28],"♔":[1,21]}
def F(w):return sum([[(i,j)for j,p in e(o)if p==w]for i,o in e(Z)],[])
def G(x,y):
 P=Z[x][y];D=P in W;L=[]
 for o in R[P]if D else R[unichr(ord(P.decode('utf8'))-6).encode('utf8')]:
  r,k="%02d"%o        
  for g,h in[[(-1,-1),(1,1),(-1,1),(1,-1)],[[(1,-1),(1,1)],[(-1,-1),(-1,1)]][D],[(-1,0),(1,0),(0,-1),(0,1)],[(-2,-1),(-2,1),(-1,-2),(-1,2),(1,-2),(1,2),(2,-1),(2,1)],[(-1,0)]][int(r)]:
   J=0
   for i in range(int(k)):
    T=x+(i+1)*g;U=y+(i+1)*h
    if T<0 or T>7 or U<0 or U>7:break
    M=Z[T][U]
    if not J:L.append((T,U,P,M))
    else:break
    if r in"02"and(M in W+B):
     J=1
     if not((D and M in B)or(not D and M in W)):L.pop()
    elif(r=="1"and not((D and M in B)or(not D and M in W)))or(r=="4"and((i==1 and x!=6)or M!="…")):L.pop()
 return L  
Z=[[y for y in l[5:].split()]for l in sys.stdin.readlines()[:-2]]
Q=[]
for p in R:
 for i,j in F(p):
  for M,L,c,_ in G(i,j):
   O=Z[M][L];Z[i][j]="…";Z[M][L]=c;E=[];map(E.extend,map(F,B))
   if not any(any(1 for _,_,_,I in G(v,h)if I==["♔","♚"][c in B])for v,h in E):Q.append((i,j,M,L,c))
   Z[i][j]=c;Z[M][L]=O
(x,y,X,Y,p)=Q[0];Z[x][y]="…";Z[X][Y]=p
for i,h in e(Z):print`8-i`+' ║'+' '.join(h)
print"——╚"+"═"*16+"\n—— a b c d e f g h"

ตัวอย่างอินพุตและเอาต์พุต:

# INPUT

8 ║♜♞♝…♚♝♞♜
7 ║♟♟♟♟…♟♟♟
6 ║………………………
5 ║……………♟………
4 ║……………………♙♛
3 ║………………♙……
2 ║♙♙♙♙♙…♙…
1 ║♖♘♗♕♔♗♘♖
--╚═══════════════
—— abcdefgh
# เอาท์พุท

8 ║♜♞♝…♚♝♞♜
7 ║♟♟♟♟…♟♟♟
6 ║………………………
5 ║……………♟………
4 ║……………………♙♛
3 ║………………♙♙…
2 ║♙♙♙♙♙………
1 ║♖♘♗♕♔♗♘♖
--╚════════════════
—— abcdefgh

มันคือ 886 ไบต์ แต่มีเพียง 854 ตัวอักษร (โปรแกรมของฉันมีมากกว่า 1kB ขอบคุณผู้ประกอบการที่ไม่ใช่ ASCII!) - คุณจะเพิ่มการตรวจสอบเพื่อรับตำแหน่งราชาหรือยัง?
หยุดหมุนทวนเข็มนาฬิกาเมื่อ

@leftaroundabout: ฉันได้เพิ่มการตรวจสอบของกษัตริย์ (ซึ่งบังคับให้ฉันต้องคำนึงถึงการเคลื่อนไหวที่เป็นไปได้ของสีดำและเพิ่มอักขระจำนวนมาก ... ) โอ้รุ่นนี้ควรจะแข็งกว่าเคสแบบขอบ (เท่าที่ผมทดสอบ)
ChristopheD
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.