HTMLify
ui.c
Views: 16 | Author: abh
#include <ncurses.h>
#include <locale.h>
#include <string.h>
#include "ttt.h"
#include "ui.h"
enum {
WHITE,
BLACK,
RED,
BLUE,
};
void draw_mark(int pos, char mark) {
char *o[5] = {
"▄▀▀▀▄",
"█ █",
" ▀▀▀ "
};
char *x[5] = {
"▀▄ ▄▀",
" ▄▀▄ ",
"▀ ▀"
};
int markx, marky, x_offset, y_offset, i;
marky = (LINES - 13) / 2;
markx = (COLS - 25) / 2;
// y offset
switch (pos) {
case 1: case 2: case 3:
y_offset = 1; break;
case 4: case 5: case 6:
y_offset = 5; break;
case 7: case 8: case 9:
y_offset = 9; break;
}
// x offset
switch (pos) {
case 1: case 4: case 7:
x_offset = 2; break;
case 2: case 5: case 8:
x_offset = 10; break;
case 3: case 6: case 9:
x_offset = 18; break;
}
attron(COLOR_PAIR(mark == 'o' ? BLUE : RED));
for (i=0; i<3; i++) {
move(marky+y_offset+i, markx+x_offset);
addstr((mark == 'o' ? o : x)[i]);
}
attroff(COLOR_PAIR(mark == 'o' ? BLUE : RED));
}
void draw_game(TTT *game) {
// height = 13
// width = 25
int
tly = (LINES - 13) / 2,
tlx = (COLS - 25) / 2,
i
;
// board
char *lines[25] = {
"█▀▀▀▀▀▀▀█▀▀▀▀▀▀▀█▀▀▀▀▀▀▀█",
"█ █ █ █",
"█ █ █ █",
"█ █ █ █",
"█▀▀▀▀▀▀▀█▀▀▀▀▀▀▀█▀▀▀▀▀▀▀█",
"█ █ █ █",
"█ █ █ █",
"█ █ █ █",
"█▀▀▀▀▀▀▀█▀▀▀▀▀▀▀█▀▀▀▀▀▀▀█",
"█ █ █ █",
"█ █ █ █",
"█ █ █ █",
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀",
};
for (i=0; i<13; i++) {
move(tly+i, tlx);
addstr(lines[i]);
}
// marks
for (i=0; i<9; i++) {
char m = game->state[i];
if (m == ' ')
continue;
draw_mark(i+1, m);
}
// player names
if (game->turn == 1)
attron(COLOR_PAIR(game->symbols[0] == 'o' ? BLUE : RED));
mvaddstr(tly-2, tlx, game->player1);
attroff(COLOR_PAIR(RED));
attroff(COLOR_PAIR(BLUE));
if (game->turn == 2)
attron(COLOR_PAIR(game->symbols[1] == 'o' ? BLUE : RED));
mvaddstr(tly-2, tlx-strlen(game->player2)+25, game->player2);
attroff(COLOR_PAIR(RED));
attroff(COLOR_PAIR(BLUE));
}
int detect_pos(int x, int y) {
int
tly = (LINES - 13) / 2,
tlx = (COLS - 25) / 2,
gx, gy, pos
;
if (tly+0 <= y && y <= tly+3)
gy = 1;
if (tly+4 <= y && y <= tly+7)
gy = 2;
if (tly+8 <= y && y <= tly+11)
gy = 3;
if (tlx+1 <= x && x <= tlx+7)
gx = 1;
if (tlx+9 <= x && x <= tlx+15)
gx = 2;
if (tlx+17 <= x && x <= tlx+23)
gx = 3;
pos = (gy-1) * 3 + gx;
if (0 < pos && pos < 10)
return pos;
return 0;
}
void draw_winner_screen(TTT *game) {
for (int i=0; i<LINES; i++) {
for (int j=0; j<COLS; j++) {
if (i>3 && i<LINES-3 && j>3 && j<COLS-3)
continue;
attron(COLOR_PAIR((i+j)%2==1?RED:BLUE));
mvaddstr(i, j, "█");
attroff(COLOR_PAIR((i+j)%2==1?RED:BLUE));
}
}
int w = TTT_check_win(game), offset;
char winner_line[32];
switch (w) {
case 0:
sprintf(winner_line, "Game is Draw [-]");
break;
case 1:
sprintf(winner_line, "Winner is: %s [%c]", game->player1, game->symbols[0]);
break;
case 2:
sprintf(winner_line, "Winner is: %s [%c]", game->player2, game->symbols[1]);
break;
}
offset = (COLS - strlen(winner_line))/2;
mvaddstr(8, offset, winner_line);
}
void ui(TTT *game) {
MEVENT event;
int key, mark_pos;
bool _exit = false;
setlocale(LC_ALL, "");
initscr();
keypad(stdscr, true);
noecho();
cbreak();
curs_set(0);
mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL);
start_color();
// init_pair(0, COLOR_WHITE, COLOR_BLACK);
init_pair(WHITE, COLOR_WHITE, COLOR_BLACK);
init_pair(BLACK, COLOR_BLACK, COLOR_WHITE);
init_pair(RED, COLOR_RED, COLOR_BLACK);
init_pair(BLUE, COLOR_BLUE, COLOR_BLACK);
draw_game(game);
while (game->running || _exit) {
key = getch();
switch (key) {
case 'q':
_exit = true;
break;
case KEY_MOUSE:
if (getmouse(&event) == OK) {
if (event.bstate & BUTTON1_CLICKED) {
mark_pos = detect_pos(event.x, event.y);
if (mark_pos != 0)
TTT_mark(game, mark_pos);
}
}
}
erase();
draw_game(game);
if (strcmp((game->turn == 1 ? game->player1 : game->player2), "-<BOT>-")==0) {
TTT_bot_turn(game);
erase();
draw_game(game);
}
}
draw_winner_screen(game);
getch();
endwin();
}