Визуализация - fica99/Corewar GitHub Wiki

Визуализация является бонусной частью проекта «Corewar», поэтому вариантов её реализации существует великое множество.

В данном разделе будет разобран подход к визуализации, который был предоставлен нам в качестве примера.

Визуализатор

Он основывается на наличии у каждого из игроков, которые участвуют в сражении, своего цвета.

Этим цветом будет закрашен исполняемый код чемпиона при инициализации арены, а также те участки памяти, которые будут записаны принадлежащими ему каретками с помощью операций st и sti.

В список принадлежащих игроку входит каретка, которая размещается на начале его исходного кода перед сражением, а также все каретки, которые она затем породит с помощью операций fork и lfork.

Участки памяти, которые не раскрашены в цвета одного из игроков будут иметь цвет по умолчанию — серый.

Каретка

Также особым образом на арене выделяются каретки. Ячейка, на которой каретка находится в данный момент, подсвечивается следующим образом: фон — цвет, в который окрашен код в ячейке; содержимое — черный цвет.

Важно, что на фоне отображается цвет кода самой ячейки, а не каретки. То есть каретка порожденная «зеленым» игроком попав на синее поле будет светиться синим цветом.

План написания визуализатора

Визуализатор будет написан с помошью графической библиотеки ncurses на C++. Данные будут передаваться с помощью сокетов (TCP протокол). Визуализатор будет выступать сервером, который будет постоянно ждать данные, при получении данных будет отрисовываться новая картинка. Виртуальная машина будет клиентом, она будет отправлять данные (при наличии специального флага).

  1. Изучить сокеты (Сетевое программирование).
  2. Изучить работу виртуальной машины.
  3. Продумать структуру с отправляемой информацией.
  4. Изучить библиотеки для сериализации и десериализации, если не получится использовать, то написать свой сериализатор (tpl).
  5. Написать библиотеку для отправки и получения данных в нужном формате.
  6. Изучить ncurses.
  7. Продумать стиль визуализации.
  8. Написать класс для отрисовки нужных объектов.

Libserver

Структура для с отправляемой информацией для визуализатора

Виртуальная машина при наличии специального флага будет отправлять визуализатору следующую структуру:

typedef struct	   s_vis_arena
{
    int            cycle;
    int            cycle_to_die;
    int            cycle_delta;
    int            nbr_live;
    int            max_checks;
    uint8_t        winner_id;
    t_vis_player   players[MAX_PLAYERS];
    t_vis_cell     arena[MEM_SIZE];

}                  t_vis_arena;

В поле winner_id сохранятся id чемпиона, в случае его отсутствия 0. В структуре t_vis_player находится необходимая информация о игроках.

typedef struct	   s_vis_player
{
    uint8_t        id;
    char           name[PROG_NAME_LENGT];
    int            last_live;
    int            lives_in_cur_period;

}                  t_vis_player;

В структуре t_cell будет храниться следующая информация о ячейке арены

typedef struct	    s_vis_cell
{
    uint8_t         code;
    uint8_t         player_id;
    t_bool          is_carriage;
}                   t_vis_cell;

В поле code хранится информация о исполняемом коде ячейки. В поле player_id хранится id игрока, которому принадлежит эта ячейка (если она никому не принадлежит, то player_id = 0). В поле is_carriage говорится, есть ли каретка на данной ячейке или нет. Ячейка раскрашивается в соответствующий цвет только при наличии player_id != 0. Каретка выделяется фоновым цветом при наличии is_carriage == false (В случае если, player_id == 0, то ячейка становится на белом фоне).

Функции для отправки и получения t_vis_arena

Перед отправкой структуры необходимо установить соединение с сервером.

int				connect_server(const char *host_name);

host_name - IP адрес сервера. В случае успеха, функция возвращает listenfd - переменная через которую будет происходить взаимодействие (файловый дескриптор сокета).

После работы с сервером необходимо разорвать соединение с помощью функции:

void		    disconnect_server(int listenfd);

Для отправки самой структуры необходимо использовать функцию:

void			send_arena(const t_vis_arena *arena, int listenfd);