Stdin'de bir tahta verilen geçerli bir satranç hamlesini oynayın


11

Program beyaz oynar.

Örnek stdin:

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

Örnek stdout:

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

Geçerli herhangi bir hareket tamam. "En yolcu" ve yayın yoksayılır. Geçerli bir hareket yoksa hata mesajlarını göstermek veya hiçbir şey yazdırmamakta fayda vardır.

En çok oy alan cevap kazanır.


Dilde bazı yerleşik işlevlerin başarısızlığından kaynaklanan standart bir hata mesajı demek istiyorum. Yani sorun değil mi? - Programın herhangi bir yasal hamle yapabilmesi zorunlu mu? Belki de rıhtım ve piyon özel hamle bazı bonus ile isteğe bağlı yapılmalıdır?
ters saat çevirmeyi bıraktı

2
@ leftaroundabout: Ne zaman kale yapabiliyorsanız, bunun yerine kaleyi hareket ettirebilirsiniz, böylece bunun için mantığı en azından atlayabilirsiniz.
Hamar

2
... ve biraz daha düşündüğümüzde, "en passant" hamle, daha önceki hamlelerin yapıldığı hakkında bilgi gerektirir, bu da sadece parçaların konumlarından çıkarılamaz, bu yüzden bunu bırakmak güvenli olabilir. Bununla birlikte, çift ilk hamlenin mevcut olup olmadığı piyonun sırasından çıkarılabilir, bu yüzden bunu dahil etmek isteyebilirsiniz.
Hamar

@hammar: Haklısın, bunu düşünmemiştim. Çift hamle de önemli değil, bir durum hariç : iki adım atabildiğinizde bir hamle de yapabilirsiniz, bu yüzden sadece kontrol ettiğinizde önemli hale gelir ve çift hamle kralı kapsayan tek hamledir. Ayrıca bile size her hareketini kullanabilmek için gerekmez, yine herhangi imkanı ile o siyah kutu cevabı dikkate almak gerekir.
saat yönünün tersine çevirmeyi bıraktı

9
İstifa yasal bir hamle olarak sayılıyor mu? :)
gnibbler

Yanıtlar:


16

Upvotes hakkında şikayetçi değilim, ama adil olmak gerekirse ... buradaki çözümüm aslında o kadar da iyi değil. Ugoren'in unicode desteğinden yoksun olması daha iyidir. Bu soruya yalnızca şimdi rastladıysanız, oylamadan önce tüm cevaplara baktığınızdan emin olun!
Neyse.

Haskell'in 893 888 904 952 (rok olmadan)

862 (piyon çift hareketsiz)

(Bunun kod golfü olup olmadığını belirtmediniz, ancak bana öyle geliyor ki)

χ=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

Eğer varsa GHC (bir parçası olarak örneğin yüklü Haskell platformu ) sadece yapabileceği

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

Şimdi bu deli :) Ben kontrol edeceğim :)
Hristo Hristov

Bu mükemmelliği nasıl test edeceğiniz hakkında bir fikriniz var mı? Ideone.com idare edemez ...
Hristo Hristov

@HristoHristov: Garip Ideone üzerinde çalışmıyor. Muhtemelen ASCII olmayan karakterlerle ilgilidir.
ters saat çevirmeyi bıraktı

evet, bu ideone ile ilgili sorun
Hristo Hristov

14
Tebrikler, Haskell'i APL gibi göstermeyi başardınız. :-)
Ilmari Karonen

11

C 734 672 640 karakter

Karakterler, çıkarılabilir boşluk olmadan sayılır.
Kullandığım dosya biçimi istendiği gibi değil, basitleştirilmiş ASCII.
Unicode karakter desteği eklemem gerekiyor, bazı karakterlere mal olacak.

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]]);
}

Giriş / çıkış dosya formatı:
Tam olarak 8 karakterden oluşan 8 satır olmalıdır. pnbrqkbeyaz parçalar, PNBRQKsiyah parçalar, boşluklar için kullanılır:

RNBQKBNR
PPPP PPP

 n  P


pppppppp
r bqkbnr

Mantık oldukça basittir:
Her beyaz parçanın olası her hareketi için, her siyah parçanın olası her hareketini deneyin.
Beyaz kralı hiçbir siyah hamle yakalamazsa, beyaz hamle geçerlidir.

Kart, char[256]sadece sol üst 8x8'in kullanıldığı 16x16 matris olarak kabul edilir. Konumlar ve hareket vektörleri 8 bit tamsayılarda ( x:4,y:4) tutulur . Ekstra bit new_pos = old_pos + steps*direction, tahta kenarının kolayca algılanması ile basit aritmetik ( ) kullanımına izin verir ( &0x88sihri yapar). r[]üç şeyi kodlar:

  1. İlk 15 bayt dahili parça kodlarını (K = 1, P = 2, N = 3, B = 4, R = 5, Q = 6) harflerle eşleştirir.
  2. Sonraki 6 bayt dahili parça kodlarını son kısımdaki ofsetlere eşler (K ​​ve Q aynıdır, B onların kuyruğudur).
  3. Son 16 bayt, tüm parçaların hareketini kodlar '('+vector.

Fonksiyonlar:

  1. mainanakartı okur, harfleri iç koda dönüştürür, abeyaz hamle bulmak için arama yapar, tahtayı yazdırır.
  2. a64 karenin üzerinde tekrarlayan döngüler. Doğru rengin her parçası için (parametre c), parça ve aramalar için hareket kuralını bulur d.
  3. dvektörlerin bir listesi olan eve her birini çağıran kodlanmış hareket kuralı üzerinde özyinelemeli olarak döngüler . Bu verir eorijinal konumuna, vektör ve aralık sınırı (ikinci seviye piyon için B, 2, yukarıda parçalar için 7, 1 başka bir şekilde).
  4. ebir vektör boyunca tüm hareketleri test eder. Hareket mümkünse (yani piyonlar ileriye doğru hareket eder, tahta içinde engellenmez, piyon yakalama çapraz olarak), iki şeyden birini kontrol eder. Beyaz hareketlerde, vhareketi doğrulamak için çalışır . Siyah hareketler için beyaz kralın yakalanıp yakalanmadığını kontrol eder. Doğruysa, hareket tahtada oynanır.
  5. vbeyaz bir hareketi doğrular. Tahtayı bir kenara kopyalar, test etmek için hareketi yürütür ve asiyah hareketleri aramak için tekrar arar .

Sonunda , olası hareketleri uygun şekilde sıkıştırılmış kodlamaya sahip bir çözüm ! Ve oldukça hızlı. Unicode sarıcı ekleyebileceğinizi ve kodumdan daha kısa olabileceğini düşünmüyor musunuz?
counterclockwis

@ leftaroundabout, sanırım yapabilirim. Asıl sorun, Unicode'u göremediğiniz bir Linux komut satırında çalışıyorum, bu yüzden hata ayıklamak can sıkıcı olurdu. Ayrıca yaklaşık 40 bayt tasarruf eden bir sürümüm var (yakında güncelleyeceğim), bu yüzden çalışmak için çok sayıda karakterim var.
ugoren

@ugoren: Kesinlikle herhangi bir yarım yollu modern Linux dağıtımı UTF-8'i kutudan çıkarıyor mu?
han

@han, Windows üzerinde çalışıyorum ve SSH tarafından Linux'a bağlanıyorum ve Unicode çalışmıyor. Bir dosyaya yazıp Windows'ta açabiliyorum, ama artık ilginç değil.
ugoren

Bu gcc ile derlenecek mi? MinGW ile Windows için Geany kullanıyorum ve bir sürü hata ve uyarı ile derlenecek, ancak / run.eg oluşturmayacak: C: \ Kullanıcılar \ xxx \ AppData \ Local \ Temp \ ccpBG9zy.o: codegolfchess.c :(. text + 0x2d8): `` bcopy '' için tanımlanmamış referans2: ld 1 çıkış durumu döndürdü
rpd

5

Python 2.6, 886 - 1425 karakter

İlk versiyonum (revizyonlarda) 886 karakterde geldi, ancak spesifikasyonu tam olarak tatmin etmedi (mat arkadaştan kaçınmayı kontrol etmedi; siyah parçaların olası hareketlerini bile düşünmedi).

Şimdi öyle (ve orijinalindeki birkaç hatayı düzelttim). Ne yazık ki bu karakterlerde bir maliyetle geliyor: şimdilik 1425, ancak hala iyileştirilmesi için çok az yer olmalı. Bu sürüm, kenar kasaları ele alırken öncekinden çok daha sağlam olmalıdır.

#-*-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"

Örnek giriş ve çıkış:

# INPUT

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

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

886 bayt, ancak sadece 854 karakter. (Birçok ASCII dışı operatör sayesinde programım 1 kb'nin üzerinde!) - Henüz kralı ele geçirmek için kontrol ekleyecek misin?
counterclockwis dönüşü kesildi

@ leftaroundabout: Kral kontrollerini ekledim (bu beni siyahın olası hareketlerini de hesaba katmaya zorlar ve çok fazla karakter ekler ...). Oh, bu sürüm kenar durumlarda daha sağlam olmalı (test ettiğim kadarıyla).
ChristopheD
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.