adds unicode support

Tue, 18 Sep 2018 15:02:08 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 18 Sep 2018 15:02:08 +0200
changeset 69
c8f2c280cff7
parent 68
b34de5ce7d0e
child 70
5427beba96d1

adds unicode support

conf.mk file | annotate | diff | comparison | revisions
src/chess/rules.c file | annotate | diff | comparison | revisions
src/chess/rules.h file | annotate | diff | comparison | revisions
src/game.c file | annotate | diff | comparison | revisions
src/main.c file | annotate | diff | comparison | revisions
src/terminal-chess.h file | annotate | diff | comparison | revisions
     1.1 --- a/conf.mk	Wed Aug 29 17:31:36 2018 +0200
     1.2 +++ b/conf.mk	Tue Sep 18 15:02:08 2018 +0200
     1.3 @@ -32,10 +32,10 @@
     1.4  
     1.5  BIN        = terminal-chess
     1.6  CC         = gcc
     1.7 -CFLAGS     = -O2 -std=gnu99 `pkg-config --cflags ncurses`
     1.8 -CFLAGS_D   = -g -std=gnu99 -Wall -pedantic `pkg-config --cflags ncurses`
     1.9 +CFLAGS     = -O2 -std=gnu99 `pkg-config --cflags ncursesw`
    1.10 +CFLAGS_D   = -g -std=gnu99 -Wall -pedantic `pkg-config --cflags ncursesw`
    1.11  LD         = gcc
    1.12 -LDFLAGS    = `pkg-config --libs ncurses`
    1.13 +LDFLAGS    = `pkg-config --libs ncursesw`
    1.14  ARFLAGS    = -r
    1.15  MKDIRFLAGS = -p
    1.16  RMFLAGS    = -f -R
     2.1 --- a/src/chess/rules.c	Wed Aug 29 17:31:36 2018 +0200
     2.2 +++ b/src/chess/rules.c	Tue Sep 18 15:02:08 2018 +0200
     2.3 @@ -204,6 +204,18 @@
     2.4      }
     2.5  }
     2.6  
     2.7 +unsigned char* getpieceunicode(uint8_t piece) {
     2.8 +    switch (piece & PIECE_MASK) {
     2.9 +    case PAWN: return "\u265f";
    2.10 +    case ROOK: return "\u265c";
    2.11 +    case KNIGHT: return "\u265e";
    2.12 +    case BISHOP: return "\u265d";
    2.13 +    case QUEEN: return "\u265b";
    2.14 +    case KING: return "\u265a";
    2.15 +    default: return "";
    2.16 +    }
    2.17 +}
    2.18 +
    2.19  uint8_t getpiece(char c) {
    2.20      switch (c) {
    2.21          case 'R': return ROOK;
     3.1 --- a/src/chess/rules.h	Wed Aug 29 17:31:36 2018 +0200
     3.2 +++ b/src/chess/rules.h	Tue Sep 18 15:02:08 2018 +0200
     3.3 @@ -174,12 +174,23 @@
     3.4   * 
     3.5   * Does not work for pawns, scince they don't have a character.
     3.6   * 
     3.7 - * @param piece one of ROOK, KNIGHT, BISHOP, QUEEN, KING
     3.8 + * @param piece may have color or additional flags
     3.9   * @return character value for the specified piece
    3.10   */
    3.11  char getpiecechr(uint8_t piece);
    3.12  
    3.13  /**
    3.14 + * Maps a piece to a unicode character sequence.
    3.15 + * 
    3.16 + * The returned unicode is for black pieces.
    3.17 + * You may colorize the output by setting the terminal foreground color.
    3.18 + * 
    3.19 + * @param piece the piece to dispaly
    3.20 + * @return unicode character sequence for the specified piece
    3.21 + */
    3.22 +unsigned char* getpieceunicode(uint8_t piece);
    3.23 +
    3.24 +/**
    3.25   * Checks, if a specified field is covered by a piece of a certain color.
    3.26   * 
    3.27   * The out-parameters may both be NULL, but if any of them is set, the other
     4.1 --- a/src/game.c	Wed Aug 29 17:31:36 2018 +0200
     4.2 +++ b/src/game.c	Tue Sep 18 15:02:08 2018 +0200
     4.3 @@ -71,7 +71,9 @@
     4.4      return 0;
     4.5  }
     4.6  
     4.7 -static void draw_board(GameState *gamestate, uint8_t perspective) {
     4.8 +static void draw_board(GameState *gamestate,
     4.9 +		       uint8_t perspective,
    4.10 +		       _Bool unicode) {
    4.11      char fen[90];
    4.12      compute_fen(fen, gamestate);
    4.13      mvaddstr(0, 0, fen);
    4.14 @@ -80,11 +82,18 @@
    4.15          for (uint8_t x = 0 ; x < 8 ; x++) {
    4.16              uint8_t col = gamestate->board[y][x] & COLOR_MASK;
    4.17              uint8_t piece = gamestate->board[y][x] & PIECE_MASK;
    4.18 -            char piecec;
    4.19 +            unsigned char piecestr[5];
    4.20              if (piece) {
    4.21 -                piecec = piece == PAWN ? 'P' : getpiecechr(piece);
    4.22 +                if (unicode) {
    4.23 +                    unsigned char* uc = getpieceunicode(piece);
    4.24 +                    strncpy(piecestr, uc, 5);
    4.25 +                } else {
    4.26 +                    piecestr[0] = piece == PAWN ? 'P' : getpiecechr(piece);
    4.27 +                    piecestr[1] = '\0';
    4.28 +                }
    4.29              } else {
    4.30 -                piecec = ' ';
    4.31 +                piecestr[0] = ' ';
    4.32 +                piecestr[1] = '\0';
    4.33              }
    4.34              
    4.35              _Bool boardblack = (y&1)==(x&1);
    4.36 @@ -97,9 +106,7 @@
    4.37              
    4.38              int cy = perspective == WHITE ? boardy-y : boardy-7+y;
    4.39              int cx = perspective == WHITE ? boardx+x*3 : boardx+21-x*3;
    4.40 -            mvaddch(cy, cx, ' ');
    4.41 -            mvaddch(cy, cx+1, piecec);
    4.42 -            mvaddch(cy, cx+2, ' ');
    4.43 +            mvprintw(cy, cx, " %s ", piecestr);
    4.44          }
    4.45      }
    4.46      
    4.47 @@ -460,9 +467,11 @@
    4.48      }
    4.49  }
    4.50  
    4.51 -static void post_game(GameState *gamestate, GameInfo *gameinfo) {
    4.52 +static void post_game(Settings* settings, GameState *gamestate) {
    4.53 +    GameInfo *gameinfo = &(settings->gameinfo);
    4.54 +
    4.55      move(0,0);
    4.56 -    draw_board(gamestate, WHITE);
    4.57 +    draw_board(gamestate, WHITE, settings->unicode);
    4.58      
    4.59      // TODO: network connection is still open here - think about it!
    4.60      
    4.61 @@ -520,13 +529,13 @@
    4.62      _Bool running;
    4.63      do {
    4.64          clear();
    4.65 -        draw_board(&gamestate, curcol);
    4.66 +        draw_board(&gamestate, curcol, settings->unicode);
    4.67          running = !domove_singlemachine(&gamestate,
    4.68              &(settings->gameinfo), curcol);
    4.69          curcol = opponent_color(curcol);
    4.70      }  while (running);
    4.71      
    4.72 -    post_game(&gamestate, &(settings->gameinfo));
    4.73 +    post_game(settings, &gamestate);
    4.74  }
    4.75  
    4.76  void game_continue(Settings *settings, int opponent, GameState *gamestate) {
    4.77 @@ -541,7 +550,7 @@
    4.78      _Bool running;
    4.79      do {
    4.80          clear();
    4.81 -        draw_board(gamestate, mycolor);
    4.82 +        draw_board(gamestate, mycolor, settings->unicode);
    4.83          if (myturn) {
    4.84              running = !sendmove(gamestate, &(settings->gameinfo),
    4.85                  opponent, mycolor);
    4.86 @@ -551,7 +560,7 @@
    4.87          myturn ^= TRUE;
    4.88      }  while (running);
    4.89      
    4.90 -    post_game(gamestate, &(settings->gameinfo));
    4.91 +    post_game(settings, gamestate);
    4.92  }
    4.93  
    4.94  void game_start(Settings *settings, int opponent) {
     5.1 --- a/src/main.c	Wed Aug 29 17:31:36 2018 +0200
     5.2 +++ b/src/main.c	Tue Sep 18 15:02:08 2018 +0200
     5.3 @@ -34,6 +34,7 @@
     5.4  #include <string.h>
     5.5  #include <time.h>
     5.6  #include <getopt.h>
     5.7 +#include <locale.h>
     5.8  
     5.9  int get_settings(int argc, char **argv, Settings *settings) {
    5.10      char *valid;
    5.11 @@ -41,7 +42,7 @@
    5.12      uint8_t timeunit = 60;
    5.13      size_t len;
    5.14      
    5.15 -    for (int opt ; (opt = getopt(argc, argv, "a:bc:hp:rsS:t:v")) != -1 ;) {
    5.16 +    for (int opt ; (opt = getopt(argc, argv, "a:bc:hp:rsS:t:Uv")) != -1 ;) {
    5.17          switch (opt) {
    5.18          case 'c':
    5.19              settings->continuepgn = optarg;
    5.20 @@ -58,6 +59,9 @@
    5.21          case 'S':
    5.22              settings->analyzepgn = optarg;
    5.23              break;
    5.24 +        case 'U':
    5.25 +            settings->unicode = 0;
    5.26 +            break;
    5.27          case 't':
    5.28          case 'a':
    5.29              len = strlen(optarg);
    5.30 @@ -114,6 +118,7 @@
    5.31  "  -r            Distribute color randomly\n"
    5.32  "  -s            Single machine mode\n"
    5.33  "  -t <time>     Specifies time limit (default: no limit)\n"
    5.34 +"  -U            Disables unicode pieces\n"
    5.35  "\nNotes\n"
    5.36  "The time unit for -a is seconds and for -t minutes by default. To "
    5.37  "specify\nseconds for the -t option, use the s suffix.\n"
    5.38 @@ -151,6 +156,7 @@
    5.39      memset(&settings, 0, sizeof(Settings));
    5.40      settings.gameinfo.servercolor = WHITE;
    5.41      settings.port = "27015";
    5.42 +    settings.unicode = !!setlocale(LC_CTYPE, "C.UTF-8");
    5.43      return settings;
    5.44  }
    5.45  
     6.1 --- a/src/terminal-chess.h	Wed Aug 29 17:31:36 2018 +0200
     6.2 +++ b/src/terminal-chess.h	Tue Sep 18 15:02:08 2018 +0200
     6.3 @@ -36,7 +36,7 @@
     6.4  #ifndef TERMINAL_CHESS_H
     6.5  #define	TERMINAL_CHESS_H
     6.6  
     6.7 -#define PROGRAM_VERSION "0.9-r68"
     6.8 +#define PROGRAM_VERSION "0.9-r69"
     6.9  
    6.10  #ifdef	__cplusplus
    6.11  extern "C" {
    6.12 @@ -49,6 +49,7 @@
    6.13      char* continuepgn;
    6.14      char* analyzepgn;
    6.15      _Bool singlemachine;
    6.16 +    _Bool unicode;
    6.17  } Settings;
    6.18  
    6.19  #define is_server(settings) !((settings)->serverhost)

mercurial