C, В даний час 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();
}
Ось типова обробка (парення іноді можуть виникати в будь-якому місці правого або лівого краю дошки.)