stdinのボードを指定して、有効なチェスの動きをする


11

プログラムは白で再生されます。

標準入力の例:

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

標準出力の例:

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

有効な移動は問題ありません。「パッサン」とキャスリングは無視されます。有効な移動がない場合は、エラーメッセージを表示したり、何も印刷しないでかまいません。

投票数が最も多い答えが勝ちです。


私は、言語のいくつかの組み込み関数の失敗によって引き起こされる標準エラーメッセージを意味します。大丈夫?-それは必須のプログラムが行うことができるということです任意の法的な動きを?おそらく、キャスリングとポーンの特別な動きは、いくつかのボーナスでオプションにするべきですか?
反時計回り

2
@leftaroundabout:キャッスルできるときはいつでも、代わりにルークを動かすことができるので、少なくともそのロジックをスキップできます。
ハンマー

2
...さらに考えてみると、「en passant」ムーブには、以前のムーブが行われたことに関する情報が必要です。これは、ピースの位置だけから推測することはできません。ただし、ダブルファーストムーブが使用可能かどうかはポーンのランクから推測できるため、これを含めることができます。
ハンマー

@hammar:あなたは正しい、私はそれについて考えていなかった。ダブルムーブも重要ではありませんが、1つの場合を除きます:2ステップ移動できる場合は1ステップも移動できるため、チェック中にのみ重要になり、ダブルムーブはキングをカバーする唯一の移動です。また、場合でも、あなたはすべての動きを使用することができるようにする必要はありません、あなたはまだすべての可能性とその黒缶の答えを考慮する必要があります。
counterclockwis回すのをやめ

9
辞任は合法的な動きとしてカウントされますか?:)
ニブラー

回答:


16

私は賛成票について文句を言っているわけではありませんが、公平を期すために...ここでの私の解決策は実際にはそれほど素晴らしいものではありません。Ugorenの方が優れていますが、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

今、これはクレイジーです:)私はそれをチェックします:)
フリストフリスト

この素晴らしさをテストする方法はありますか?Ideone.comそれを扱うことができない...
フリスト・フリストフ

@HristoHristov:奇妙なことに、Ideoneでは動作しません。おそらく非ASCII文字に関係しています。
反時計回りを回すのをやめた

はい、これはイデオンの問題です
フリストフリスト

14
おめでとうございます、HaskellをAPLのように見せることができました。:-)
イルマリカロネン

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]、左上8x8のみが使用される16x16マトリックスとして扱われます。位置と移動ベクトルは、8ビット整数(x:4,y:4)で保持されます。余分なビットにより、単純な算術演算(new_pos = old_pos + steps*direction)を使用でき、ボードエッジを簡単に検出できます(&0x88マジックを実行します)。 r[]3つのことをエンコードします。

  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. a64個の正方形を再帰的にループします。正しい色の各ピース(パラメーターc)について、ピースの移動ルールを見つけ、を呼び出しますd
  3. dベクトルのリストであるエンコードされた移動ルールを再帰的にループし、各ルールを呼び出しeます。これは、得られるe(特にB、第二ランクポーン2、1個以上の7)元の位置、ベクトル及び範囲制限を。
  4. eベクトルに沿ったすべての動きをテストします。移動が可能な場合(つまり、ポーンがボード内で前方に移動し、ブロックされず、ポーンが斜めにキャプチャする)、次の2つのいずれかをチェックします。ホワイトムーブの場合v、ムーブを検証するために実行されます。黒の動きについては、白の王が捕まっているかどうかを確認します。trueの場合、移動はボード上で再生されます。
  5. v白い動きを検証します。ボードを脇にコピーし、テストのためにムーブを実行し、a再度コールして、ブラックムーブを探します。

最後に、可能な動きの適切な圧縮エンコードを使用したソリューション!そして、それは非常に高速です。Unicodeラッパーを追加しても、コードよりも短くなると思いませんか?
counterclockwis回すのをやめ

@leftaroundabout、私はできると思います。主な問題は、Unicodeが表示されないLinuxコマンドラインで作業しているため、デバッグが煩わしいことです。また、約40バイトを節約するバージョンもあります(すぐに更新します)ので、使用する文字がたくさんあります。
-ugoren

@ugoren:確かに、現代のLinuxディストリビューションの中には、すぐにUTF-8をサポートするものがありますか?
ハン

@han、私はWindowsで作業していて、SSHでLinuxに接続していますが、Unicodeは動作しません。ファイルに書き込み、Windowsで開くことができますが、それはもう面白くありません。
ウゴレン

これはgccでコンパイルできますか?私はMinGWでGeany for Windowsを使用していますが、多数のエラーと警告を伴ってコンパイルされますが、ビルド/実行されません。例:C:\ Users \ xxx \ AppData \ Local \ Temp \ ccpBG9zy.o:codegolfchess.c 。:(テキスト+ 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"

入力と出力の例:

#入力

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

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

886バイトですが、たった854文字です。(私のプログラムは、多くの非ASCII演算子のおかげで1kBを超えています!)—あなたはまだ王を取得するためのチェックを追加するつもりですか?
反時計回りを回すのをやめた

@leftaroundabout:キングチェックを追加しました(これにより、黒の動きの可能性も考慮しなければならず、多くのキャラクターが追加されます...)。まあ、このバージョンは、(私がテストした限りでは)エッジケースの周りでより強固なはずです。
クリストフ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.