C#

chess.c

#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;
}

Теги:
Шахматы без ИИ
Добавлено: 01 Декабря 2013 09:57:15 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...