#include <stdio.h> #include <stdlib.h> #define SCREEN_SIZE 25 #define MAX_LEN 15 #define STEP_CODE 2 #define CHEAT_CODE 1 /* Code of chessman. */ enum CM {NULL_CM, KING, QUEEN, PAWN, ROOK, ELEPHANT, HORSE}; /* Цвет фигуры. */ enum Color {BLACK_C = -1, NULL_C, WHITE_C}; /* 0 - Мат, 1 - Шах. */ enum Status {MATE_G, CHECK_G, GAME_G}; /* Странно, что в Си нет bool. -_- */ enum bool {FALSE, TRUE}; struct Game { struct Game_T { int cm [8] [8]; struct k {int x, y;} w, b; /* Белый король и черный. */ } n, /* Настоящее положение фигур. */ f; /* Промежуточное положение. Выполняется проверка. */ int status; /* (Status). */ int color; /* Цвет активного игрока (Color). */ } g; void startGame (void); void execLine (const char line[MAX_LEN]); void showBoard (void); void showMan (const int i); int checkValide (const char line[MAX_LEN]); void setCoordinates (char line [MAX_LEN]); void getCoordinates (char line [MAX_LEN]); int isPosible (int x1, int y1, int x2, int y2); inline void isPosibleKing (int x1, int y1, int x2, int y2, int *valide); inline void isPosibleRook (int x1, int y1, int x2, int y2, int *valide); inline void isPosibleElephant (int x1, int y1, int x2, int y2, int *valide); inline void isPosibleHorse (int x1, int y1, int x2, int y2, int *valide); inline void isPosiblePawn (int x1, int y1, int x2, int y2, int *valide); int isCheck (void); inline void isCheckFromElephant (int x, int y, int *valide); inline void isCheckFromRook (int x, int y, int *valide); inline void isCheckFromHorse (int x, int y, int *valide); inline void isCheckFromPawn (int x, int y, int *valide); /*////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////*/ int main(void) { char line [MAX_LEN]; int valide; scanf ("%s", line); /* Обработка настроек. */ execLine (line); while (g.status != MATE_G) { scanf ("%s", line); if ( (valide = checkValide (line)) == STEP_CODE) { setCoordinates (line); } else if ( valide == CHEAT_CODE) { execLine (line); } /* else doNothing(); */ } return 0; } void showBoard (void) { register int i, j; /* Оистка экрана. */ for (i = 0; i < SCREEN_SIZE; i++) printf ("\n"); printf ("\tA\tB\tC\tD\tE\tF\tG\tH"); for (i = 0; i < 8; i++) { printf ("%d\t", i); for (j = 0; j < 8; j++) { showMan (g.n.cm [i] [j]); } printf ("%d", i); } printf ("\tA\tB\tC\tD\tE\tF\tG\tH"); } /* Печатает букву с именем фигуры вместо ее номера. */ void showMan (const int i) { switch (i) { case KING : printf ("K"); break; case QUEEN : printf ("Q"); break; case ROOK : printf ("R"); break; case ELEPHANT : printf ("E"); break; case HORSE : printf ("H"); break; case PAWN : printf ("P"); break; case -KING : printf ("k"); break; case -QUEEN : printf ("q"); break; case -ROOK : printf ("r"); break; case -ELEPHANT : printf ("e"); break; case -HORSE : printf ("h"); break; case -PAWN : printf ("p"); break; } } void execLine (const char line[MAX_LEN]) { startGame (); /** Запуск чит-кода. */ } void startGame (void) { int i; /* Расстановка ладьей. */ g.n.cm [0] [0] = g.n.cm [0] [7] = ROOK + 10; g.n.cm [7] [0] = g.n.cm [7] [7] = -ROOK - 10; /* Расстановка коней. */ g.n.cm [0] [1] = g.n.cm [0] [6] = HORSE + 10; g.n.cm [7] [1] = g.n.cm [7] [6] = -HORSE - 10; /* Расстановка слонов. */ g.n.cm [0] [2] = g.n.cm [0] [5] = ELEPHANT + 10; g.n.cm [7] [2] = g.n.cm [7] [5] = -ELEPHANT - 10; /* Расстановка ферзей. */ g.n.cm [0] [3] = QUEEN + 10; g.n.cm [7] [3] = -QUEEN - 10; /* Установка королей. */ g.n.cm [0] [4] = KING + 10; g.n.cm [7] [4] = -KING - 10; g.n.w.x = g.n.b.x = 4; g.n.w.y = 0; g.n.b.y = 7; /* Пешки. */ for (i = 0; i < 7; i++) { g.n.cm [1] [i] = PAWN + 10; /* Белые. */ g.n.cm [6] [i] = -PAWN - 10; /* Черные. */ } g.status = GAME_G; g.color = WHITE_C; } int checkValide (const char line[MAX_LEN]) { int valide = TRUE; int i; /* Если элементы массива не содержат соответствующих символов, valide = 0. */ for (i = 0; i < 5; i += 3) { if ( !strcpm (line [i], "12345678")) { valide = FALSE; } } for (i = 1; i < 5; i += 3) { if ( !strcpm (line [i], "aAbBcCdDeEfFgGhH")) { valide = FALSE; } } if ( valide) { return STEP_CODE; } else { return CHEAT_CODE; } } void setCoordinates (char line [MAX_LEN]) { getCoordinates (line); const int x1 = line [0]; const int y1 = line [1] - 1; const int x2 = line [3]; const int y2 = line [4] - 1; /* Установка фигуры в промежуточное положение. */ g.f.cm [y2] [x2] = g.f.cm [y1] [x1]; g.f.cm [y1] [x1] = NULL_CM; if ( isPosible (x1, y1, x2, y2) && !isCheck()) { /* Запись положения короля. */ if ( abs (g.n.cm [y1] [x1] % 10) == KING) { if ( g.n.cm [y1] [x1] / 10 == WHITE_C) { g.n.w.x = x2; g.n.w.y = y2; } else { g.n.b.x = x2; g.n.b.y = y2; } } else { /* Установка фигуры. */ g.n.cm [y2] [x2] = g.n.cm [y1] [x1]; g.n.cm [y1] [x1] = NULL_CM; } } } /* Перевод координат из текста в цифры. */ void getCoordinates (char line [MAX_LEN]) { int i, j; char c, C; for (i = 0; i < 4; i += 3) { for (c = 'a', C = 'A', j = 1; c <= 'h' && C <= 'H' && j <= 8; c++, C++, j++) { if ( line [i] == c || line [i] == C) { line [i] = j; } } } line [1] = atoi (line [1]); line [4] = atoi (line [4]); } int isPosible (int x1, int y1, int x2, int y2) { int valide = FALSE; switch (abs (g.n.cm [y1] [x1] % 10)) { case KING : isPosibleKing(x1, y1, x2, y2, &valide); break; case QUEEN : isPosibleRook(x1, y1, x2, y2, &valide); isPosibleElephant(x1, y1, x2, y2, &valide); break; case PAWN : isPosiblePawn(x1, y1, x2, y2, &valide); break; case ROOK : isPosibleKing(x1, y1, x2, y2, &valide); break; case ELEPHANT : isPosibleElephant(x1, y1, x2, y2, &valide); break; case HORSE : isPosibleHorse(x1, y1, x2, y2, &valide); break; } return valide; } inline void isPosibleKing (int x1, int y1, int x2, int y2, int *valide) { valide = abs((x2 - x1) * (y2 - y1)) < 1 && g.n.cm [y2] [x2] / 10 != g.color; } inline void isPosibleRook (int x1, int y1, int x2, int y2, int *valide) { int i, j; for (i = y1 + 1, j = x2 + 1; i < 8 && j < 8 && !g.n.cm [y1] [i]; i++, j++) { if ( y1 == y2 && x2 - x1 && i == x2) { valide = 1; } } if ( i < 7 && j < 7 && g.n.cm [i + 1] [j + 1] == -g.color) { valide = 1; } for (i = y1 + 1, j = x2 - 1; i < 8 && j >= 0 && !g.n.cm [y1] [i]; i++, j--) { if ( y1 == y2 && x2 - x1 && i == x2) { valide = 1; } } if ( i < 7 && j > 0 && g.n.cm [i + 1] [j - 1] == -g.color) { valide = 1; } for (i = y1 - 1, j = x2 + 1; i >= 0 && j < 8 && !g.n.cm [y1] [i]; i--, j++) { if ( y1 == y2 && x2 - x1 && i == x2) { valide = 1; } } if ( i > 0 && j < 7 && g.n.cm [i - 1] [j + 1] == -g.color) { valide = 1; } for (i = y1 - 1, j = x2 - 1; i >= 0 && j >= 0 && !g.n.cm [y1] [i]; i--, j--) { if ( y1 == y2 && x2 - x1 && i == x2) { valide = 1; } } if ( i > 0 && j > 0 && g.n.cm [i - 1] [j - 1] == -g.color) { valide = 1; } } inline void isPosibleElephant (int x1, int y1, int x2, int y2, int *valide) { int i, j; for (i = y1 + 1, j = x1 + 1; i < 8 && j < 8 && !g.n.cm [i] [j]; i++, j++) { if ( i == y2 && j == x2) { valide = 1; } } if ( i < 7 && j < 7 && g.n.cm [i + 1] [j + 1] == -g.color) { valide = 1; } for (i = y1 + 1, j = x1 - 1; i < 8 && j >= 0 && !g.n.cm [i] [j]; i++, j--) { if ( i == y2 && j == x2) { valide = 1; } } if ( i < 7 && j > 0 && g.n.cm [i + 1] [j - 1] == -g.color) { valide = 1; } for (i = y1 - 1, j = x1 + 1; i >= 0 && j < 8 && !g.n.cm [i] [j]; i--, j++) { if ( i == y2 && j == x2) { valide = 1; } } if ( i > 0 && j < 7 && g.n.cm [i - 1] [j + 1] == -g.color) { valide = 1; } for (i = y1 - 1, j = x1 - 1; i >= 0 && j >= 0 && !g.n.cm [i] [j]; i--, j--) { if ( i == y2 && j == x2) { valide = 1; } } if ( i > 0 && j > 0 && g.n.cm [i - 1] [j - 1] == -g.color) { valide = 1; } } inline void isPosibleHorse (int x1, int y1, int x2, int y2, int *valide) { valide = (x2 == x1 + 2 && y2 == x1 + 3 || x2 == x1 + 3 && y2 == y1 + 2 || x2 == x1 - 2 && y2 == y1 - 3 || x2 == x1 - 3 && y2 == y1 - 2 || x2 == x1 + 2 && y2 == y1 - 3 || x2 == x1 + 3 && y2 == y1 - 2 || x2 == x1 - 2 && y2 == y1 + 3 || x2 == x1 - 3 && y2 == y1 + 2) && g.n.cm [y2] [x2] / 10 != g.color; } inline void isPosiblePawn (int x1, int y1, int x2, int y2, int *valide) { /* Если осуществляется попытка сделать ход на клетку вперед, ИЛИ если * осуществляется попытка сделать ход на клетку по диагонали, И если там есть * фигура противоположного цвета. */ valide = y2 - y1 == 1 && !(x2 - x1) && !g.n.cm [y2] [x2] || abs ((x2 - x1) * (y2 - y1)) == 1 && g.n.cm [y2] [x2] / 10 == -g.color; } int isCheck (void) { int x, y; int valide = FALSE; if ( g.color == WHITE_C) {x = g.f.w.x; y = g.f.w.y;} else {x = g.f.b.x; y = g.f.b.y;} /* Проверка битых полей от слона или ферзя. */ isCheckFromElephant (x, y, &valide); /* Проверка битых полей от ладьи или ферзя. */ isCheckFromRook (x, y, &valide); /* Проверка битых полей от коня. */ isCheckFromHorse (x, y, &valide); /* Проверка битых полей от пешки. */ isCheckFromPawn (x, y, &valide); return valide; } inline void isCheckFromElephant (int x, int y, int *valide) { int i, j; for (i = y + 1, j = x + 1; i < 7 && j < 7 && !g.n.cm [i] [j]; i++, j++); valide = g.n.cm [i] [j] == -g.color && (abs (g.f.cm [j] [i] % 10) == ELEPHANT || abs (g.f.cm [j] [i] % 10) == QUEEN); for (i = y + 1, j = x - 1; i < 7 && j > 0 && !g.n.cm [i] [j]; i++, j--); valide = g.n.cm [i] [j] == -g.color && (abs (g.f.cm [j] [i] % 10) == ELEPHANT || abs (g.f.cm [j] [i] % 10) == QUEEN); for (i = y - 1, j = x + 1; i > 0 && j < 7 && !g.n.cm [i] [j]; i--, j++); valide = g.n.cm [i] [j] == -g.color && (abs (g.f.cm [j] [i] % 10) == ELEPHANT || abs (g.f.cm [j] [i] % 10) == QUEEN); for (i = y - 1, j = x - 1; i > 0 && j > 0 && !g.n.cm [i] [j]; i--, j--); valide = g.n.cm [i] [j] == -g.color && (abs (g.f.cm [j] [i] % 10) == ELEPHANT || abs (g.f.cm [j] [i] % 10) == QUEEN); } inline void isCheckFromRook (int x, int y, int *valide) { int i; for (i = x + 1; && i < 7 && !g.n.cm [y] [i]; i++); valide = abs (g.f.cm [y] [i] % 10) == ROOK || abs (g.f.cm [y] [i] % 10) == QUEEN; for (i = x - 1; i > 0 && !g.n.cm [y] [i]; i--); valide = abs (g.f.cm [y] [i] % 10) == ROOK || abs (g.f.cm [y] [i] % 10) == QUEEN; for (i = y + 1; i < 7 && !g.n.cm [y] [i]; i++); valide = abs (g.f.cm [i] [x] % 10) == ROOK || abs (g.f.cm [i] [x] % 10) == QUEEN; for (i = y - 1; i > 0 && !g.n.cm [y] [i]; i--); valide = abs (g.f.cm [i] [x] % 10) == ROOK || abs (g.f.cm [i] [x] % 10) == QUEEN; } inline void isCheckFromHorse (int x, int y, int *valide) { valide = g.n.cm [y + 2] [x + 3] / 10 == -g.color && abs (g.n.cm [y + 2] [x + 3]) == HORSE || g.n.cm [y + 2] [x - 3] / 10 == -g.color && abs (g.n.cm [y + 2] [x - 3]) == HORSE || g.n.cm [y - 2] [x + 3] / 10 == -g.color && abs (g.n.cm [y - 2] [x + 3]) == HORSE || g.n.cm [y - 2] [x - 3] / 10 == -g.color && abs (g.n.cm [y - 2] [x - 3]) == HORSE || g.n.cm [y + 3] [x + 2] / 10 == -g.color && abs (g.n.cm [y + 3] [x + 2]) == HORSE || g.n.cm [y + 3] [x - 2] / 10 == -g.color && abs (g.n.cm [y + 3] [x - 2]) == HORSE || g.n.cm [y - 3] [x + 2] / 10 == -g.color && abs (g.n.cm [y - 3] [x + 2]) == HORSE || g.n.cm [y - 3] [x - 2] / 10 == -g.color && abs (g.n.cm [y - 3] [x - 2]) == HORSE; } inline void isCheckFromPawn (int x, int y, int *valide) { valide = abs (g.n.cm [y + g.color] [x + 1]) == PAWN || abs (g.n.cm [y + g.color] [x - 1]) == PAWN; }