четверг, 17 марта 2011 г.

Game

Тема нашей курсовой по Операционным системам — создание клиент-серверного приложения игры «Крестики-нолики». Первую часть, практически готовый клиент, мы должны показать в ближайшее время. У меня получилось нечто такое:

Составил ТЗ:
Типовое задание.

В данном курсовом проекте мы разрабатываем клиент-серверную модель игры «крестики-нолики». Далее будут описаны правила игры и алгоритм проведения игровой ситуации.

К серверу подсоединяется один из клиентов, ему предлагается ожидать подключения оппонента. Если в течение 3 минут очередной клиент не подсоединяется к серверу, начинается игра с сервером в качестве оппонента. Случайным образом выбирается сторона, за которую играет первый из подключившихся игроков. Второй автоматически относится к противоположной стороне. Первыми всегда ходят «крестики». В терминалах клиентов распложено игровое поле, ниже располагается чат, перейти в который можно, нажав клавишу Tab. Передвижение по полю осуществляется «стрелками», выставление очередного символа — клавишей Enter. Клиент контролирует правильность очередного хода: нельзя ставить символ на уже занятое место, либо если в данный момент ходит другой игрок. Сервер контролирует очередность хода с помощью счётчика. В начале игры счётчик устанавливается в ноль. Если он чётен, ходит первый игрок, если нечётен — второй. При достижении счётчика значения 8 или более, игра заканчивается. Величина счётчика автоматически присваивается восьми при выставлении трёх одинаковых символов в ряд.
При выставлении очередного символа серверу посылается сообщение о том, что игрок сделал свой ход, и отправляется порядковый номер ячейки, в которой был выставлен символ. Сервер синхронно отображает символ в данной ячейке на всех клиентах (в том числе у spectators).
Существует возможность наблюдать за игрой. При запуске клиента у пользователя спрашивается, желает он участвовать в игре или только смотреть. Также в стартовом окошке отображается список текущих игр или ожидающих пользователей. Выбрать пункт «наблюдать» при отсутствии текущей игры нельзя.

Протокол

1. запрос и выдача существущих игр
2. подключение к игре
3. чат
4. пинг
5. передача id клиента, счётчика ходов и номеров ячеек поля


Кода довольно-таки немного, всё находится в библиотеках. Чат пока не работает, нужно писать сервер. Вот файл клиента:
#include "lib.c"

int main (int argc, char *argv[]) {
    enum keys key;
    int rkey;
    int x = SXDIV2,
        y = SYDIV2;
    int i, j;
    int counter = 0;
    char str[128];
    int inchat = 0;
    
    InitBoard(&gboard);
    rk_mytermregime(0, 0, 0, 0, 1);    
    mt_clrscr();
    
    PrintBoard(gboard);
    PrintChat();
    mt_gotoXY(x, y);
    
    rkey = rk_readkey(&key);
    while (key != K_L) {
        if ((i = IsEnd()) != 0) {
            printf("Player %d wins!", i);
            printf(" (%s)\n", i == 1 ? "CROSS" : "CRISS");
            break;
        }
        
        if (counter == FIELDSIZE * FIELDSIZE) {
            printf("Nobody wins.\n");
            break;
        }
        
        rkey = rk_readkey(&key);
        if (!rkey) {
            switch (key) {
            case K_DOWN:
                y = y <= FIELDSIZE * SYDIV2 ? y + (CELLSIZEY + 1) : SYDIV2;
                mt_gotoXY(x, y);
            break;
            case K_UP:
                y = y - SYDIV2 > 0 ? y - (CELLSIZEY + 1) : SYDIV2 + (FIELDSIZE - 1) * (CELLSIZEY + 1);
                mt_gotoXY(x, y);
            break;
            case K_LEFT:
                x = x - SXDIV2 > 0 ? x - (CELLSIZEX + 1) : SXDIV2 + (FIELDSIZE - 1) * (CELLSIZEX + 1);
                mt_gotoXY(x, y);
            break;
            case K_RIGHT:
                x = x <= FIELDSIZE * SXDIV2 ? x + (CELLSIZEX + 1) : SXDIV2;
                mt_gotoXY(x, y);
            break;
            case K_TAB:
                if (inchat) {
                    rk_mytermregime(0, 0, 0, 0, 1);
                    inchat = 0;
                    mt_gotoXY(x, y);
                } else {
                    if (inchat == 0) {
                        rk_mytermregime(0, 0, 0, 1, 1);
                    }
                    inchat++;
                    mt_gotoXY(35, 2);
                    /*StartChat...*/
                    scanf("%s", str);
                    printf("%s", str);
                }
            break;
            case K_ENTER:
                i = (x - SXDIV2) / (CELLSIZEX + 1);
                j = (y - SYDIV2) / (CELLSIZEY + 1);
                
                if (gboard.cell[i][j] == NONE) {
                    gboard.cell[i][j] = counter % 2 ? CRISS : CROSS;
                    counter++;
                }
                PrintBoard(gboard);
                mt_gotoXY(x, y);
            break;
            default:
            break;
            }
        }
    }
    rk_mytermrestore();
    return 0;
}

Продолжаем работать..

UPD. Разместил проект на googlecode: http://code.google.com/p/criss-n-cross/
Думаю, обновления ещё будут.

3 комментария:

JIghtuse комментирует...

Сегодня сдал обе части, теперь это полноценные клиент и сервер. Доступны по той же ссылке.

Анонимный комментирует...

Уточните пожалуйста, по какой именно ссылке. С Вашего позволения хотелось бы скачать поразбираться как написано.

JIghtuse комментирует...

О, извиняюсь. Считал что выкладывал уже.
http://code.google.com/p/criss-n-cross/
Ссылка из Featured Download.

С недавних пор читаю howto по ncurses, планирую перенести игрушку на эту библиотеку — проще будет разбираться в коде.