C, Derzeit 2552 noncomment nonwhitespace Zeichen
Die Zählung zeigt mir, dass ich unter 2552 Zeichen Golf spielen könnte, aber da es bereits eine kleinere Antwort gibt (die schwer zu schlagen sein wird), werde ich dies sorgfältig prüfen, bevor ich mir die Mühe mache, es zu tun. Es ist wahr, es gibt ungefähr 200 Zeichen für die Anzeige der Tafel und jeweils weitere 200 für die Überprüfung der Benutzereingaben von Startposition und Bewegung (was ich zum Testen brauche, aber beseitigen könnte.)
Hier gibt es keinen Spielbaum, nur einen fest codierten Algorithmus, sodass er sich sofort bewegt.
Startpositionen werden als Reihe (1-8), Spalte (1-8) von rechts oben nummeriert eingegeben und das Programm arbeitet nach demselben Schema. Wenn Sie Ihren Bildschirm also um 90 Grad gegen den Uhrzeigersinn drehen, folgt er der standardmäßigen numerischen Quadratnotation für Korrespondenzschach. Positionen, bei denen der schwarze König bereits in Schach ist, werden als illegal zurückgewiesen.
Schwarze Züge werden als Zahl von 0 bis 7 eingegeben, wobei 0 ein Zug nach Norden, 1 nach Nordosten usw. im Uhrzeigersinn ist.
Es folgt nicht dem allgemein bekannten Algorithmus, der ausschließlich den Turm unter dem Schutz des weißen Königs verwendet, um den schwarzen König einzuschränken. Der Turm schränkt den schwarzen König nur in vertikaler Richtung ein (und rennt horizontal davon, wenn er verfolgt wird). Der weiße König schränkt den schwarzen König in horizontaler Richtung ein. Dies bedeutet, dass sich die beiden weißen Teile nicht gegenseitig behindern.
Ich habe die meisten Bugs und möglichen Endlosschleifen ausgebügelt, es läuft jetzt ziemlich gut. Ich werde morgen wieder damit spielen und sehen, ob es noch etwas gibt, das repariert werden muss.
#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();
}
Hier ist ein typisches Finish (Mate kann manchmal irgendwo am rechten oder linken Rand des Bretts auftreten.)