Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
6.0 kB
3
Indexable
Never
#include <stdio.h>
#include <stdlib.h>

#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>

#define SERVER_PORT_S "15000"
#define SERVER_PORT 15000

void host_room();
void start_game();
void connect_to();

// Создаём комнату
void host_room()
{
    // Надо ввести айпи текущего компьютера (можно было бы без этого, но пока так)
    char ip[16];
    scanf("%s", ip);

    struct sockaddr_in sin;

    sin.sin_family = AF_INET;
    inet_pton(AF_INET, ip, &sin.sin_addr);
    sin.sin_port = SERVER_PORT;

    // Создаем сокет
    SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(server == INVALID_SOCKET)
    {
        printf("Error at socket(): %d\n", WSAGetLastError());
        return;
    }

    // Привязываем его к айпи и порту
    if(bind(server, (struct sockaddr*)&sin, sizeof(struct sockaddr_in)) == SOCKET_ERROR)
    {
        printf("bind failed with error: %d\n", WSAGetLastError());
        closesocket(server);
        return;
    }

    // Слушаем
    if(listen(server, 1) == SOCKET_ERROR)
    {
        printf("Listen failed with error: %d\n", WSAGetLastError() );
        closesocket(server);
        return;
    }

    // Принимаем клиента
    SOCKET client = accept(server, NULL, NULL);
    if(client == INVALID_SOCKET)
    {
        printf("accept failed: %d\n", WSAGetLastError());
        closesocket(server);
        return;
    }

    start_game(client, 0);
}

///////////////////////////////////////
// Подсоединяемся по айпи
///////////////////////////////////////
void connect_to()
{
    // Вводим айпи противника (айпи компьютера где комната создана)
    char ip[16];
    scanf("%s", ip);

    // Заполняем айпи и порт в структуре
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    inet_pton(AF_INET, ip, (void*)&sin.sin_addr);
    sin.sin_port = SERVER_PORT;

    // Сокет и соединение
    SOCKET client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(client != INVALID_SOCKET)
    {
        int r = connect(client, (struct sockaddr*)&sin, sizeof(sin));
        if(r != SOCKET_ERROR)
        {
            start_game(client, 1);
        }
        else
        {
            printf("Connection failed: %d\n", WSAGetLastError());
            // Неверный айпи!
        }
    }
}

void start_game(int enemy, int order)
{
    // Вводим своё число число
    char num[4];
    fread(num, sizeof(char), 4, stdin);

    // Если 1 - то наш ход первый
    // Если 0 - то ход противника
    // Тот кто подключается ходит первым (для определенности)
    // Поэтому изначально order у одного 1 а у другого 0, и он меняется

    while(1)
    {
        if(order == 1)
        {
            //////////////////////////////////////////////////////////
            // Шлём число противнику и получаем сколько быков и коров
            //////////////////////////////////////////////////////////

            char guess[4];
            fread(guess, sizeof(char), 4, stdin);

            if(send(enemy, guess, 4, 0) > 0)
            {
                char reply[2];
                if(recv(enemy, reply, 2, 0) > 0)
                {
                    // reply[0] - кол-во быков
                    // reply[1] - кол-во коров

                    if(reply[0] == 4)
                    {
                        // Мы выиграли
                        closesocket(enemy);
                        break;
                    }
                }
                else
                {
                    // Соединение закрыто или ошибка
                    break;
                }
            }
            else
            {
                // Соединение закрыто или ошибка
                break;
            }
        }
        else
        {
            //////////////////////////////////////////////////////////
            // Получаем число противника и шлём сколько быков и коров
            //////////////////////////////////////////////////////////

            char guess[4];

            if(recv(enemy, guess, 4, 0) > 0)
            {
                // Проверяем сколько угадал противник

                char reply[2];
                reply[0] = 0; // Быков
                reply[1] = 0; // Коров

                // Отправить кол-во быков и коров
                if(send(enemy, reply, 2, 0) <= 0)
                {
                    // Соединение закрыто или ошибка
                    break;
                }

                // Если кол-во быков - 4, то все позиции угаданы и противник угадал число
                if(reply[0] == 4)
                {
                    // Мы проиграли
                    closesocket(enemy);
                    break;
                }
            }
            else
            {
                // Соединение закрыто или ошибка
                break;
            }
        }

        order = 1 - order;
    }
}

int main()
{
    // Инициализация
    WSADATA wsaData;
    int r = 0;

    r = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (r != 0)
    {
        printf("WSAStartup failed: %d\n", r);
        return 1;
    }

    // Выбрать режим (это уже в меню)
    host_room(); // - создать комнату
    connect_to() // - подсоединится к уже созданной

    WSACleanup();
    return 0;
}