commit 3bc33d613e5898f992e13a8a1a9f1801a7b3b87e
parent 2fc01f0a8ff7da1fafbcf537702e54c2cf94711e
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Wed, 14 Sep 2022 16:14:45 +0200
Remove move.c and general improvements
Diffstat:
10 files changed, 180 insertions(+), 175 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,57 +1,44 @@
# GNU Makefile for Chess Anki Trainer
#
-# Usage: make [-f path\Makefile] [DEBUG=Y] [NO_UNICODE=Y] [NO_MOUSE=Y] target
+# Usage: make [-f path\Makefile] [DEBUG=Y] [NO_UNICODE=Y] target
NAME = chess
CC = gcc
CFLAGS = -I include
-LDFLAGS =-lcurl -ljson-c -lncursesw -lm
+LDFLAGS =-lcurl -ljson-c -lm
SRC = src
OBJ = obj
-BINDIR = bin
+BIN = bin
-BIN = bin/$(NAME)
SRCS=$(wildcard $(SRC)/*.c)
OBJS=$(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SRCS))
+TRGT=$(BIN)/$(NAME)
-ifeq ($(OS),Windows_NT)
- RM = del
- NAME := $(NAME).exe
- DEL_CLEAN = $(subst /,\,$(BIN)) $(subst /,\,$(OBJS))
-else
- RM = rm -f
- DEL_CLEAN = $(BIN) $(OBJS)
-endif
-
ifeq ($(DEBUG),Y)
- CFLAGS += -lciid -ldisplayd
- CFLAGS += -Wall -Wextra -Werror -Wpedantic -fsanitize=address -ggdb
+ LDFLAGS += -lciid -lpaned
+ CFLAGS += -ggdb -Wall -Wextra -Werror -Wpedantic
else
- CFLAGS += -lcii -ldisplay
+ LDFLAGS += -lcii -lpane
endif
ifeq ($(NO_UNICODE),Y)
CFLAGS += -D NO_UNICODE
endif
-ifeq ($(NO_MOUSE),Y)
- CFLAGS += -D NO_MOUSE
-endif
-
-all: $(BIN)
+all: $(TRGT)
-$(BIN): $(OBJS)
+$(TRGT): $(OBJS)
$(CC) $^ $(CFLAGS) $(LDFLAGS) -o $@
$(OBJ)/%.o: $(SRC)/%.c
$(CC) -c $< -o $@ $(CFLAGS) $(LDFLAGS)
clean:
- -$(RM) $(DEL_CLEAN)
+ -$(RM) $(BIN)/* $(OBJ)/*
help:
- @echo "Game of Life Simulation"
+ @echo "Chess Anki Trainer"
@echo
@echo "Usage: make [-f path\Makefile] [DEBUG=Y] [NO_UNICODE=Y] target"
@echo
@@ -63,7 +50,6 @@ help:
@echo "Optional parameters:"
@echo " DEBUG - Compile binary file with debug flags enabled"
@echo " NO_UNICODE - Compile binary file that does not use Unicode characters"
- @echo " NO_MOUSE - Compile binary file that does not have mouse support even if terminal supports it"
@echo
.PHONY: all clean help docs
diff --git a/include/anki.h b/include/anki.h
@@ -1,7 +1,7 @@
#ifndef ANKI_H
#define ANKI_H
-#include <except.h>
+#include <cii/except.h>
#include <stddef.h>
#define Move_T card_T
diff --git a/include/board.h b/include/board.h
@@ -2,13 +2,12 @@
#define BOARD_H
#include "anki.h"
-#include "move.h"
-#define Move_T Board_T
-#define G Grave_T
+#define T Board_T
+#define G Grave_T
-typedef struct Move_T *Move_T;
-typedef struct G *G;
+typedef struct G *G;
+typedef struct T *T;
enum AC { AC_QUIT = -3, AC_SUSPEND, AC_INDEX };
@@ -18,7 +17,7 @@ typedef void (*review_f)(void);
typedef struct game_T *game_T;
struct game_T {
card_T card;
- move_T *moves;
+ char **moves;
review_f review_next;
int pass;
@@ -33,29 +32,31 @@ struct game_T {
char buffer[BUFF_SIZE + 1];
int buffer_crnt;
- size_t moves_size;
- size_t boards_size;
- Move_T boards[];
+ size_t moves_num;
+ T boards[];
};
-Move_T Board_new(void);
-Move_T Board_from_FEN(char *fen);
-void Board_free(Move_T *self);
+T Board_new(void);
+T Board_from_FEN(char *fen);
+void Board_free(T *self);
-Move_T Board_play(Move_T self, char *m);
-void Board_print(Move_T self);
+T Board_play(T self, char *m);
+void Board_print(T self);
-char Board_atIndex(Move_T self, int i, int j);
+char Board_atIndex(T self, int i, int j);
int piece_get_index(char l);
-G Board_grave(Move_T self, char player);
+G Board_grave(T self, char player);
char Grave_atIndex(G self, int index);
int Grave_size(G self);
/* GAME */
game_T game_new(size_t moves);
-#undef Move_T
+/* MOVE */
+char ** Move_list(char *pgn, size_t *size);
+
+#undef T
#undef G
#endif
diff --git a/include/display.h b/include/display.h
@@ -1,11 +1,10 @@
#ifndef DISPAY_H
#define DISPAY_H
-#include <pane.h>
-#include <widgetList.h>
+#include <pane/pane.h>
+#include <pane/widgets.h>
#include "board.h"
-#include "except.h"
#define MAX_READ 5
@@ -38,6 +37,8 @@ struct boardStyle_T {
int border;
int piece;
int annotation;
+ int pass;
+ int fail;
};
typedef struct movesInfo_T *movesInfo_T;
diff --git a/include/move.h b/include/move.h
@@ -1,17 +0,0 @@
-#ifndef MOVE_H
-#define MOVE_H
-
-#include <stddef.h>
-
-typedef struct move_T *move_T;
-struct move_T {
- char turn[10];
- char white[10];
- char black[10];
-};
-
-move_T *Move_list(char *pgn, size_t *size);
-char *Move_halfmove(move_T *moves, int halfturn);
-
-#undef Board_T
-#endif
diff --git a/src/anki.c b/src/anki.c
@@ -2,14 +2,14 @@
#include <stdlib.h>
#include <string.h>
+#include <cii/assert.h>
+#include <cii/except.h>
+#include <cii/mem.h>
#include <curl/curl.h>
#include <json-c/json.h>
#include "anki.h"
-#include "assert.h"
#include "display.h"
-#include "except.h"
-#include "mem.h"
#define Move_T card_T
diff --git a/src/board.c b/src/board.c
@@ -1,18 +1,18 @@
-#include "board.h"
-#include "assert.h"
-#include "mem.h"
-
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include "move.h"
+#include <cii/assert.h>
+#include <cii/mem.h>
+
+#include "board.h"
#define T Board_T
#define G Grave_T
-typedef struct G *G;
+#define MAX_MOVE 10
#define MAX_PLAY 1024
const char def_board[8][8] = {"rnbqkbnr", "pppppppp", " ", " ",
@@ -294,9 +294,9 @@ char Board_atIndex(T self, int i, int j) {
/* GAME */
-game_T game_new(size_t moves_size) {
- game_T game = ALLOC(sizeof(*game) + moves_size * sizeof(struct move_T));
- game->moves_size = moves_size;
+game_T game_new(size_t moves_num) {
+ game_T game = ALLOC(sizeof(*game) + moves_num * sizeof(struct Board_T));
+ game->moves_num = moves_num;
game->display_current = 0;
game->buffer_crnt = 0;
game->pass = 0;
@@ -307,4 +307,36 @@ game_T game_new(size_t moves_size) {
return game;
}
+/* MOVE */
+
+char **Move_list(char *pgn, size_t *size) {
+ char *crnt;
+ size_t moves_size = 1, cnt = 0;
+
+ char **moves = malloc(MAX_PLAY * sizeof(*moves));
+ char *buffer = malloc(1000 * sizeof(char));
+ strcpy(buffer, pgn);
+
+ moves[0] = "Starting move, empty board!";
+ for (crnt = strtok(buffer, " "); crnt;
+ crnt = strtok(NULL, " "), cnt = (cnt + 1) % 3) {
+ switch (cnt) {
+ case 0:
+ continue;
+ case 1:
+ case 2:
+ if (strcmp(crnt, "*") != 0) {
+ moves[moves_size] = malloc(MAX_MOVE * sizeof(char));
+ strcpy(moves[moves_size], crnt);
+ moves_size++;
+ }
+ }
+ }
+
+ if (size)
+ *size = moves_size - 1;
+
+ return moves;
+}
+
#undef G
diff --git a/src/display.c b/src/display.c
@@ -2,12 +2,11 @@
#include <stddef.h>
#include <string.h>
-#include <pane.h>
-#include <utils.h>
+#include <pane/pane.h>
+#include <pane/utils.h>
#include "anki.h"
#include "display.h"
-#include "move.h"
#define USTART L'\u2654'
@@ -28,15 +27,25 @@ void board_display(widget_T widget) {
UNUSED(info);
- int bg_color, fg_color;
+ int bg_color, fg_color, dark;
size_t x_start = centerHorisontal(pane, 16);
size_t y_start = centerVertical(pane, 8);
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
- bg_color = ((i + j) % 2) ? style->square_dark : style->square_light;
+ dark = style->square_dark;
+ if (game->pass)
+ dark = style->pass;
+ else if (game->fail)
+ dark = style->fail;
+ bg_color = ((i + j) % 2) ? dark : style->square_light;
fg_color = style->piece;
+#ifndef NO_UNICODE
tb_set_cell(x_start + 2 * i, y_start + j,
convert(Board_atIndex(board, j, i)), fg_color, bg_color);
+#else
+ tb_set_cell(x_start + 2 * i, y_start + j, Board_atIndex(board, j, i),
+ fg_color, bg_color);
+#endif
tb_set_cell(x_start + 2 * i + 1, y_start + j, ' ', fg_color, bg_color);
}
}
@@ -104,22 +113,21 @@ int game_handleInput(data_T data, struct tb_event ev) {
game->display_current = game->move_current;
return 1;
case TB_KEY_ENTER:
- if (game->move_current == game->boards_size) {
+ if (game->move_current == game->moves_num) {
anki_grade(game->pass);
game->review_next();
- return 1;
+ return INPUT_REFORM;
}
if (game->buffer_crnt) {
- if (strcmp(game->buffer,
- Move_halfmove(game->moves, game->move_current)) != 0) {
+ if (strcmp(game->buffer, game->moves[game->move_current + 1]) != 0) {
game->move_fail = game->move_current + 1;
- game->move_current = game->boards_size;
+ game->move_current = game->moves_num;
game->fail = 1;
} else {
game->display_current = ++game->move_current;
- if (game->move_current == game->boards_size)
+ if (game->move_current == game->moves_num)
game->pass = 1;
memset(game->buffer, '\0', BUFF_SIZE);
@@ -134,7 +142,8 @@ int game_handleInput(data_T data, struct tb_event ev) {
game->buffer[--game->buffer_crnt] = '\0';
return 1;
default:
- if (!isalnum(ev.ch) && ev.ch != '+' && ev.ch != '#' && ev.ch != '-')
+ if (!isalnum(ev.ch) && ev.ch != '+' && ev.ch != '#' && ev.ch != '-' &&
+ ev.ch != '=')
break;
if (game->buffer_crnt >= BUFF_SIZE)
@@ -166,12 +175,12 @@ void moves_display(widget_T widget) {
if (!widget->inited) {
widget->inited = 1;
- info->list = widgetList_new(widget->pane, game->moves_size);
+ info->list = widgetList_new(widget->pane, game->moves_num / 2 + 1);
}
widgetList_T list = info->list;
- int display_row =
- ACLAMP(((int)game->display_current - 1) / 2, 0, ((int)game->moves_size));
+ int display_row = ACLAMP(((int)game->display_current - 1) / 2, 0,
+ ((int)game->moves_num / 2));
widgetList_cacl(list, display_row);
pane_clear(pane, 0);
@@ -179,11 +188,12 @@ void moves_display(widget_T widget) {
size_t index_end =
MIN(list->index_start + list->display_num, (game->move_current + 1) / 2);
for (i = list->index_start; i < index_end; i++, y++) {
- move_T move = game->moves[i];
- move_display(game, style, -1, move->turn, x, y);
- move_display(game, style, i * 2 + 1, move->white, x + style->padding, y);
+ tb_printf(x, y, style->foreground, style->background, "%*d.",
+ style->padding - 1, i + 1);
+ move_display(game, style, i * 2 + 1, game->moves[i * 2 + 1],
+ x + style->padding, y);
if (i * 2 + 2 <= game->move_current)
- move_display(game, style, i * 2 + 2, move->black, x + 2 * style->padding,
- y);
+ move_display(game, style, i * 2 + 2, game->moves[i * 2 + 2],
+ x + 2 * style->padding, y);
}
}
diff --git a/src/main.c b/src/main.c
@@ -6,24 +6,33 @@
#define TB_IMPL
#define TB_OPT_TRUECOLOR
-#include <except.h>
-#include <mem.h>
-#include <menu.h>
-#include <pane.h>
-#include <utils.h>
-#include <widgetList.h>
+#include <cii/except.h>
+#include <cii/mem.h>
+#include <pane/menu.h>
+#include <pane/pane.h>
+#include <pane/utils.h>
+#include <pane/widgets.h>
#include "anki.h"
#include "board.h"
#include "display.h"
-#include "move.h"
+
+/* static char *profile = NULL; */
void set_selectDeck(void);
void set_selectProfile(void);
+void profile_selected(char *name, int ignore);
+void deck_selected(char *name, int ignore);
void start(void);
void stop(void);
+struct widget_T error_widget = {
+ .pane = NULL,
+ .callback = widgetCenter_print,
+ .title = "Error",
+};
+
struct menuInfo_T mainMenuInfo;
struct menuStyle_T mainMenuStyle = {
.separator = "<------------->",
@@ -57,6 +66,8 @@ struct boardStyle_T boardStyle = {
.square_dark = TB_GREEN,
.square_light = TB_WHITE,
.piece = TB_BLACK,
+ .pass = TB_BLUE,
+ .fail = TB_RED,
.border = 0,
.annotation = 3,
};
@@ -118,23 +129,47 @@ struct widget_T title_widget = {
.info = &titleInfo,
};
-void review_card() {
+void done_review(void) {
+ char message[] =
+ "You have finished all of the reviews for this deck. Please "
+ "check back later!";
+ struct tb_event ev;
+ data_T data = data_new(message, NULL);
+ widget_setData(&error_widget, data);
+ widget_activate(&error_widget, MAIN);
+ error_widget.callback(&error_widget);
+ tb_poll_event(&ev);
+ if (ev.ch == 'q' || ev.key == TB_KEY_ESC)
+ stop();
+}
+
+void review_finished(void) {
+
+ pane_unsplit(MAIN);
+ pane_clear(MAIN, 0);
+
+ done_review();
+ set_selectDeck();
+ widget_activate(&mainMenu_widget, MAIN);
+}
+
+void review_card(void) {
char *fen;
- size_t moves_size, i;
+ size_t moves_num, i;
- card_T card = anki_current_card();
- move_T *moves = Move_list(card_pgn(card), &moves_size);
- game_T game = game_new(moves_size);
+ card_T card = anki_current_card();
- game->boards[0] = (fen = card_fen(card)) ? Board_from_FEN(fen) : Board_new();
- for (i = 0; i < moves_size; i++) {
- int base = i * 2;
- game->boards[base + 1] = Board_play(game->boards[base], moves[i]->white);
- game->boards[base + 2] =
- Board_play(game->boards[base + 1], moves[i]->black);
+ if (card == NULL) {
+ review_finished();
+ return;
}
- game->boards_size =
- moves_size * 2 - (strcmp(moves[moves_size - 1]->black, "*") == 0);
+
+ char **moves = Move_list(card_pgn(card), &moves_num);
+ game_T game = game_new(moves_num);
+
+ game->boards[0] = (fen = card_fen(card)) ? Board_from_FEN(fen) : Board_new();
+ for (i = 1; i <= moves_num; i++)
+ game->boards[i] = Board_play(game->boards[i - 1], moves[i]);
game->card = card;
game->review_next = review_card;
@@ -157,18 +192,28 @@ void deck_selected(char *name, int ignore) {
anki_load_deck(name);
- pane_clear(MAIN, 1);
- children1 = pane_vsplit(MAIN, 2, -5, 1);
- children2 = pane_split(children1[1], 2, -(MOVE_PADDING * 3 + 4), 2);
+ if (anki_current_card()) {
+ pane_clear(MAIN, 1);
+ children1 = pane_vsplit(MAIN, 2, -5, 1);
+ children2 = pane_split(children1[1], 2, -(MOVE_PADDING * 3 + 4), 2);
- review_card();
- widget_activate(&title_widget, children1[0]);
- widget_activate(&moves_widget, children2[0]);
- widget_activate(&board_widget, children2[1]);
+ review_card();
+
+ widget_activate(&title_widget, children1[0]);
+ widget_activate(&moves_widget, children2[0]);
+ widget_activate(&board_widget, children2[1]);
+ } else {
+ done_review();
+ set_selectDeck();
+ widget_activate(&mainMenu_widget, MAIN);
+ }
}
void profile_selected(char *name, int ignore) {
UNUSED(ignore);
+ /* if (!profile) */
+ /* profile = malloc(100 * sizeof(char)); */
+ /* strcpy(profile, name); */
anki_load_profile(name);
set_selectDeck();
}
@@ -203,12 +248,6 @@ void stop(void) {
exit(1);
}
-struct widget_T error_widget = {
- .pane = NULL,
- .callback = widgetCenter_print,
- .title = "Error",
-};
-
void start(void) {
struct tb_event ev;
char message[] = "Can't start anki, make sure it's running and try again";
diff --git a/src/move.c b/src/move.c
@@ -1,47 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "mem.h"
-#include "move.h"
-
-#define MAX_PLAY 1024
-
-move_T Move_new(char *turn, char *white, char *black) {
- move_T m;
- NEW0(m);
-
- strcpy(m->turn, turn);
- strcpy(m->white, white);
- strcpy(m->black, black);
- return m;
-}
-
-move_T *Move_list(char *pgn, size_t *size) {
- char *turn, *white, *black, *crnt;
- char **test[] = {&turn, &white, &black};
- size_t moves_size = 0, cnt = 0;
-
- move_T *moves = malloc(MAX_PLAY * sizeof(*moves));
- for (crnt = strtok(pgn, " "); crnt; crnt = strtok(NULL, " ")) {
- *test[cnt++] = crnt;
- if (cnt == 3) {
- moves[moves_size++] = Move_new(turn, white, black);
- *test[1] = NULL;
- cnt = 0;
- }
- }
-
- if (*test[1])
- moves[moves_size++] = Move_new(turn, white, "");
-
- if (size)
- *size = moves_size;
-
- return moves;
-}
-
-char *Move_halfmove(move_T *moves, int halfturn) {
- return (halfturn % 2) ? moves[halfturn / 2]->black
- : moves[halfturn / 2]->white;
-}