Added ANSI mode with separate flags for `ansi` and `strictansi`.
authorAaron Taylor <ataylor@subgeniuskitty.com>
Mon, 24 May 2021 08:19:57 +0000 (01:19 -0700)
committerAaron Taylor <ataylor@subgeniuskitty.com>
Mon, 24 May 2021 08:19:57 +0000 (01:19 -0700)
interface/play_ansi.c

index c93b6e5..f81a134 100644 (file)
@@ -50,7 +50,15 @@ showmoyo         display moyo\n\
 showterri        display territory\n\
 "
 
 showterri        display territory\n\
 "
 
-/* some options for the ascii interface */
+/* ANSI color codes */
+#define RESETCOLOR "\x1B[0m"
+#define WHITECOLOR "\x1B[41m"
+#define BLACKCOLOR "\x1B[44m"
+#define TILE1COLOR "\x1B[47m"
+#define TILE2COLOR "\x1B[107m"
+#define TILE3COLOR "\x1B[43m"
+
+/* some options for the ansi interface */
 static int opt_showboard = 1;
 static int showdead = 0;
 static SGFTree sgftree;
 static int opt_showboard = 1;
 static int showdead = 0;
 static SGFTree sgftree;
@@ -64,18 +72,18 @@ static int clock_on = 0;
 static int current_score_estimate = NO_SCORE;
 
 static void do_play_ansi(Gameinfo* gameinfo, bool strict);
 static int current_score_estimate = NO_SCORE;
 
 static void do_play_ansi(Gameinfo* gameinfo, bool strict);
-static int ascii_endgame(Gameinfo* gameinfo, int reason);
-static void ascii_count(Gameinfo* gameinfo);
+static int ansi_endgame(Gameinfo* gameinfo, int reason, bool strict);
+static void ansi_count(Gameinfo* gameinfo, bool strict);
 static void showcapture(char* line);
 static void showdefense(char* line);
 static void showcapture(char* line);
 static void showdefense(char* line);
-static void ascii_goto(Gameinfo* gameinfo, char* line);
-static void ascii_free_handicap(Gameinfo* gameinfo, char* handicap_string);
+static void ansi_goto(Gameinfo* gameinfo, char* line);
+static void ansi_free_handicap(Gameinfo* gameinfo, char* handicap_string, bool strict);
 
 /* If sgf game info is written can't reset parameters like handicap, etc. */
 static int sgf_initialized;
 
 /*
 
 /* If sgf game info is written can't reset parameters like handicap, etc. */
 static int sgf_initialized;
 
 /*
- * Create letterbar for the top and bottom of the ASCII board.
+ * Create letterbar for the top and bottom of the ANSI board.
  */
 
 static void
  */
 
 static void
@@ -179,19 +187,12 @@ set_handicap_spots(int boardsize)
     return;
 }
 
     return;
 }
 
-#define WHITECOLOR "\x1B[41m"
-#define BLACKCOLOR "\x1B[44m"
-#define RESETCOLOR "\x1B[0m"
-
-#define BACK1COLOR "\x1B[43m"
-#define BACK2COLOR "\x1B[47m"
-
 /*
 /*
- * Display the board position when playing in ASCII.
+ * Display the board position when playing in ANSI.
  */
 
 static void
  */
 
 static void
-ascii_showboard(void)
+ansi_showboard(bool strict)
 {
     int i, j;
     char letterbar[64];
 {
     int i, j;
     char letterbar[64];
@@ -243,28 +244,13 @@ ascii_showboard(void)
                 pos_is_move = 0;
             dead = (dragon_status(POS(i, j)) == DEAD) && showdead;
             switch (BOARD(i, j) + pos_is_move + last_pos_was_move) {
                 pos_is_move = 0;
             dead = (dragon_status(POS(i, j)) == DEAD) && showdead;
             switch (BOARD(i, j) + pos_is_move + last_pos_was_move) {
-            case EMPTY + 128:
-            case EMPTY:
-                if (i % 2 == 0) {
-                    if (j % 2 == 0) {
-                        printf(BACK1COLOR "  " RESETCOLOR);
-                    } else {
-                        printf(BACK2COLOR "  " RESETCOLOR);
-                    }
-                } else {
-                    if (j % 2 == 0) {
-                        printf(BACK2COLOR "  " RESETCOLOR);
-                    } else {
-                        printf(BACK1COLOR "  " RESETCOLOR);
-                    }
-                }
-                last_pos_was_move = 0;
-                break;
             case BLACK:
             case BLACK:
+            case BLACK + 256:
                 printf(BLACKCOLOR "  " RESETCOLOR);
                 last_pos_was_move = 0;
                 break;
             case WHITE:
                 printf(BLACKCOLOR "  " RESETCOLOR);
                 last_pos_was_move = 0;
                 break;
             case WHITE:
+            case WHITE + 256:
                 printf(WHITECOLOR "  " RESETCOLOR);
                 last_pos_was_move = 0;
                 break;
                 printf(WHITECOLOR "  " RESETCOLOR);
                 last_pos_was_move = 0;
                 break;
@@ -276,30 +262,32 @@ ascii_showboard(void)
                 printf(WHITECOLOR "()" RESETCOLOR);
                 last_pos_was_move = 0;
                 break;
                 printf(WHITECOLOR "()" RESETCOLOR);
                 last_pos_was_move = 0;
                 break;
+            case EMPTY:
+            case EMPTY + 128:
             case EMPTY + 256:
                 if (i % 2 == 0) {
                     if (j % 2 == 0) {
             case EMPTY + 256:
                 if (i % 2 == 0) {
                     if (j % 2 == 0) {
-                        printf(BACK1COLOR "  " RESETCOLOR);
+                        printf(TILE1COLOR "  " RESETCOLOR);
                     } else {
                     } else {
-                        printf(BACK2COLOR "  " RESETCOLOR);
+                        if (strict) {
+                            printf(TILE3COLOR "  " RESETCOLOR);
+                        } else {
+                            printf(TILE2COLOR "  " RESETCOLOR);
+                        }
                     }
                 } else {
                     if (j % 2 == 0) {
                     }
                 } else {
                     if (j % 2 == 0) {
-                        printf(BACK2COLOR "  " RESETCOLOR);
+                        if (strict) {
+                            printf(TILE3COLOR "  " RESETCOLOR);
+                        } else {
+                            printf(TILE2COLOR "  " RESETCOLOR);
+                        }
                     } else {
                     } else {
-                        printf(BACK1COLOR "  " RESETCOLOR);
+                        printf(TILE1COLOR "  " RESETCOLOR);
                     }
                 }
                 last_pos_was_move = 0;
                 break;
                     }
                 }
                 last_pos_was_move = 0;
                 break;
-            case BLACK + 256:
-                printf(BLACKCOLOR "  " RESETCOLOR);
-                last_pos_was_move = 0;
-                break;
-            case WHITE + 256:
-                printf(WHITECOLOR "  " RESETCOLOR);
-                last_pos_was_move = 0;
-                break;
             default:
                 fprintf(stderr, "Illegal board value %d\n", (int)BOARD(i, j));
                 exit(EXIT_FAILURE);
             default:
                 fprintf(stderr, "Illegal board value %d\n", (int)BOARD(i, j));
                 exit(EXIT_FAILURE);
@@ -330,7 +318,7 @@ ascii_showboard(void)
         clock_print(BLACK);
     }
 
         clock_print(BLACK);
     }
 
-} /* end ascii_showboard */
+} /* end ansi_showboard */
 
 /*
  * command help
 
 /*
  * command help
@@ -555,7 +543,7 @@ init_sgf(Gameinfo* ginfo)
  */
 
 static int
  */
 
 static int
-computer_move(Gameinfo* gameinfo, int* passes)
+computer_move(Gameinfo* gameinfo, int* passes, bool strict)
 {
     int move;
     float move_value;
 {
     int move;
     float move_value;
@@ -570,7 +558,7 @@ computer_move(Gameinfo* gameinfo, int* passes)
         adjust_level_offset(gameinfo->to_move);
     move = genmove(gameinfo->to_move, &move_value, &resign);
     if (resignation_allowed && resign) {
         adjust_level_offset(gameinfo->to_move);
     move = genmove(gameinfo->to_move, &move_value, &resign);
     if (resignation_allowed && resign) {
-        int state = ascii_endgame(gameinfo, 2);
+        int state = ansi_endgame(gameinfo, 2, strict);
         if (state != -1)
             return state;
 
         if (state != -1)
             return state;
 
@@ -607,7 +595,7 @@ computer_move(Gameinfo* gameinfo, int* passes)
  */
 
 static int
  */
 
 static int
-do_move(Gameinfo* gameinfo, char* command, int* passes, int force)
+do_move(Gameinfo* gameinfo, char* command, int* passes, int force, bool strict)
 {
     int move = string_to_location(board_size, command);
 
 {
     int move = string_to_location(board_size, command);
 
@@ -630,7 +618,7 @@ do_move(Gameinfo* gameinfo, char* command, int* passes, int force)
     sgffile_output(&sgftree);
 
     if (opt_showboard) {
     sgffile_output(&sgftree);
 
     if (opt_showboard) {
-        ascii_showboard();
+        ansi_showboard(strict);
         printf("GNU Go is thinking...\n");
     }
 
         printf("GNU Go is thinking...\n");
     }
 
@@ -642,7 +630,7 @@ do_move(Gameinfo* gameinfo, char* command, int* passes, int force)
     }
 
     gameinfo->to_move = OTHER_COLOR(gameinfo->to_move);
     }
 
     gameinfo->to_move = OTHER_COLOR(gameinfo->to_move);
-    return computer_move(gameinfo, passes);
+    return computer_move(gameinfo, passes, strict);
 }
 
 /*
 }
 
 /*
@@ -650,7 +638,7 @@ do_move(Gameinfo* gameinfo, char* command, int* passes, int force)
  */
 
 static int
  */
 
 static int
-do_pass(Gameinfo* gameinfo, int* passes, int force)
+do_pass(Gameinfo* gameinfo, int* passes, int force, bool strict)
 {
     (*passes)++;
     init_sgf(gameinfo);
 {
     (*passes)++;
     init_sgf(gameinfo);
@@ -666,7 +654,7 @@ do_pass(Gameinfo* gameinfo, int* passes, int force)
         return 0;
     }
 
         return 0;
     }
 
-    return computer_move(gameinfo, passes);
+    return computer_move(gameinfo, passes, strict);
 }
 
 /*
 }
 
 /*
@@ -743,13 +731,13 @@ void do_play_ansi(Gameinfo* gameinfo, bool strict)
 
         /* Does the computer play first?  If so, make a move. */
         if (gameinfo->computer_player == gameinfo->to_move)
 
         /* Does the computer play first?  If so, make a move. */
         if (gameinfo->computer_player == gameinfo->to_move)
-            state = computer_move(gameinfo, &passes);
+            state = computer_move(gameinfo, &passes, strict);
 
 
-        /* main ASCII Play loop */
+        /* main ANSI Play loop */
         while (state == 0) {
             /* Display game board. */
             if (opt_showboard)
         while (state == 0) {
             /* Display game board. */
             if (opt_showboard)
-                ascii_showboard();
+                ansi_showboard(strict);
 
 #if !READLINE
             /* Print the prompt */
 
 #if !READLINE
             /* Print the prompt */
@@ -773,7 +761,7 @@ void do_play_ansi(Gameinfo* gameinfo, bool strict)
                 /* Get the command or move. */
                 switch (get_command(command)) {
                 case RESIGN:
                 /* Get the command or move. */
                 switch (get_command(command)) {
                 case RESIGN:
-                    state = ascii_endgame(gameinfo, 1);
+                    state = ansi_endgame(gameinfo, 1, strict);
                     break;
 
                 case END:
                     break;
 
                 case END:
@@ -849,7 +837,7 @@ void do_play_ansi(Gameinfo* gameinfo, bool strict)
                     }
                     while (*command && *command != ' ')
                         command++;
                     }
                     while (*command && *command != ' ')
                         command++;
-                    ascii_free_handicap(gameinfo, command);
+                    ansi_free_handicap(gameinfo, command, strict);
                     break;
 
                 case SETKOMI:
                     break;
 
                 case SETKOMI:
@@ -888,17 +876,17 @@ void do_play_ansi(Gameinfo* gameinfo, bool strict)
 
                 case DISPLAY:
                     if (!opt_showboard)
 
                 case DISPLAY:
                     if (!opt_showboard)
-                        ascii_showboard();
+                        ansi_showboard(strict);
                     break;
 
                 case FORCE:
                     command += 6; /* skip the force part... */
                     switch (get_command(command)) {
                     case MOVE:
                     break;
 
                 case FORCE:
                     command += 6; /* skip the force part... */
                     switch (get_command(command)) {
                     case MOVE:
-                        state = do_move(gameinfo, command, &passes, 1);
+                        state = do_move(gameinfo, command, &passes, 1, strict);
                         break;
                     case PASS:
                         break;
                     case PASS:
-                        state = do_pass(gameinfo, &passes, 1);
+                        state = do_pass(gameinfo, &passes, 1, strict);
                         break;
                     default:
                         printf("Illegal forced move: %s %d\n", command,
                         break;
                     default:
                         printf("Illegal forced move: %s %d\n", command,
@@ -908,11 +896,11 @@ void do_play_ansi(Gameinfo* gameinfo, bool strict)
                     break;
 
                 case MOVE:
                     break;
 
                 case MOVE:
-                    state = do_move(gameinfo, command, &passes, 0);
+                    state = do_move(gameinfo, command, &passes, 0, strict);
                     break;
 
                 case PASS:
                     break;
 
                 case PASS:
-                    state = do_pass(gameinfo, &passes, 0);
+                    state = do_pass(gameinfo, &passes, 0, strict);
                     break;
 
                 case PLAY:
                     break;
 
                 case PLAY:
@@ -925,7 +913,7 @@ void do_play_ansi(Gameinfo* gameinfo, bool strict)
                         for (m = 0; m < num; m++) {
                             gameinfo->computer_player
                                 = OTHER_COLOR(gameinfo->computer_player);
                         for (m = 0; m < num; m++) {
                             gameinfo->computer_player
                                 = OTHER_COLOR(gameinfo->computer_player);
-                            state = computer_move(gameinfo, &passes);
+                            state = computer_move(gameinfo, &passes, strict);
                             if (state)
                                 break;
                             if (passes >= 2)
                             if (state)
                                 break;
                             if (passes >= 2)
@@ -941,19 +929,19 @@ void do_play_ansi(Gameinfo* gameinfo, bool strict)
                     if (gameinfo->computer_player == WHITE)
                         gameinfo->computer_player = BLACK;
                     if (gameinfo->computer_player == gameinfo->to_move)
                     if (gameinfo->computer_player == WHITE)
                         gameinfo->computer_player = BLACK;
                     if (gameinfo->computer_player == gameinfo->to_move)
-                        state = computer_move(gameinfo, &passes);
+                        state = computer_move(gameinfo, &passes, strict);
                     break;
 
                 case PLAYWHITE:
                     if (gameinfo->computer_player == BLACK)
                         gameinfo->computer_player = WHITE;
                     if (gameinfo->computer_player == gameinfo->to_move)
                     break;
 
                 case PLAYWHITE:
                     if (gameinfo->computer_player == BLACK)
                         gameinfo->computer_player = WHITE;
                     if (gameinfo->computer_player == gameinfo->to_move)
-                        state = computer_move(gameinfo, &passes);
+                        state = computer_move(gameinfo, &passes, strict);
                     break;
 
                 case SWITCH:
                     gameinfo->computer_player = OTHER_COLOR(gameinfo->computer_player);
                     break;
 
                 case SWITCH:
                     gameinfo->computer_player = OTHER_COLOR(gameinfo->computer_player);
-                    state = computer_move(gameinfo, &passes);
+                    state = computer_move(gameinfo, &passes, strict);
                     break;
 
                 case UNDO:
                     break;
 
                 case UNDO:
@@ -1035,7 +1023,7 @@ void do_play_ansi(Gameinfo* gameinfo, bool strict)
 
                 case CMD_GOTO:
                     strtok(command, " ");
 
                 case CMD_GOTO:
                     strtok(command, " ");
-                    ascii_goto(gameinfo, strtok(NULL, " "));
+                    ansi_goto(gameinfo, strtok(NULL, " "));
                     break;
 
                 case CMD_SAVE:
                     break;
 
                 case CMD_SAVE:
@@ -1048,7 +1036,7 @@ void do_play_ansi(Gameinfo* gameinfo, bool strict)
                         init_sgf(gameinfo);
                         writesgf(sgftree.root, tmpstring);
                         printf("You may resume the game");
                         init_sgf(gameinfo);
                         writesgf(sgftree.root, tmpstring);
                         printf("You may resume the game");
-                        printf(" with -l %s --mode ascii\n", tmpstring);
+                        printf(" with -l %s --mode ansi\n", tmpstring);
                         printf("or load %s\n", tmpstring);
                     } else
                         printf("Please specify filename\n");
                         printf("or load %s\n", tmpstring);
                     } else
                         printf("Please specify filename\n");
@@ -1086,7 +1074,7 @@ void do_play_ansi(Gameinfo* gameinfo, bool strict)
                 }
 
                 if (passes >= 2)
                 }
 
                 if (passes >= 2)
-                    state = ascii_endgame(gameinfo, 0);
+                    state = ansi_endgame(gameinfo, 0, strict);
             }
 #if READLINE
             free(line_ptr);
             }
 #if READLINE
             free(line_ptr);
@@ -1111,7 +1099,7 @@ void do_play_ansi(Gameinfo* gameinfo, bool strict)
 
 /* Communicates with user after a game has ended. */
 static int
 
 /* Communicates with user after a game has ended. */
 static int
-ascii_endgame(Gameinfo* gameinfo, int reason)
+ansi_endgame(Gameinfo* gameinfo, int reason, bool strict)
 {
     char line[80];
     char* line_ptr;
 {
     char line[80];
     char* line_ptr;
@@ -1166,7 +1154,7 @@ ascii_endgame(Gameinfo* gameinfo, int reason)
 
         case COUNT:
             if (reason == 0)
 
         case COUNT:
             if (reason == 0)
-                ascii_count(gameinfo);
+                ansi_count(gameinfo, strict);
             break;
 
         case CONTINUE:
             break;
 
         case CONTINUE:
@@ -1189,10 +1177,10 @@ ascii_endgame(Gameinfo* gameinfo, int reason)
     return state;
 }
 
     return state;
 }
 
-/* ascii_count() scores the game.
+/* ansi_count() scores the game.
  */
 static void
  */
 static void
-ascii_count(Gameinfo* gameinfo)
+ansi_count(Gameinfo* gameinfo, bool strict)
 {
     char line[12];
     int done = 0;
 {
     char line[12];
     int done = 0;
@@ -1201,7 +1189,7 @@ ascii_count(Gameinfo* gameinfo)
 
     printf("\nGame over. Let's count!.\n");
     showdead = 1;
 
     printf("\nGame over. Let's count!.\n");
     showdead = 1;
-    ascii_showboard();
+    ansi_showboard(strict);
     while (!done) {
         printf("Dead stones are marked with small letters (x,o).\n");
         printf("\nIf you don't agree, enter the location of a group\n");
     while (!done) {
         printf("Dead stones are marked with small letters (x,o).\n");
         printf("\nIf you don't agree, enter the location of a group\n");
@@ -1235,7 +1223,7 @@ ascii_count(Gameinfo* gameinfo)
         } else if (!strncmp(line, "undo", 4)) {
             printf("UNDO not allowed anymore. The status of the stones now\n");
             printf("toggles after entering the location of it.\n");
         } else if (!strncmp(line, "undo", 4)) {
             printf("UNDO not allowed anymore. The status of the stones now\n");
             printf("toggles after entering the location of it.\n");
-            ascii_showboard();
+            ansi_showboard(strict);
         } else {
             int pos = string_to_location(board_size, line);
             if (pos == NO_MOVE || board[pos] == EMPTY)
         } else {
             int pos = string_to_location(board_size, line);
             if (pos == NO_MOVE || board[pos] == EMPTY)
@@ -1244,7 +1232,7 @@ ascii_count(Gameinfo* gameinfo)
                 enum dragon_status status = dragon_status(pos);
                 status = (status == DEAD) ? ALIVE : DEAD;
                 change_dragon_status(pos, status);
                 enum dragon_status status = dragon_status(pos);
                 status = (status == DEAD) ? ALIVE : DEAD;
                 change_dragon_status(pos, status);
-                ascii_showboard();
+                ansi_showboard(strict);
             }
         }
     }
             }
         }
     }
@@ -1293,7 +1281,7 @@ showdefense(char* line)
 }
 
 static void
 }
 
 static void
-ascii_goto(Gameinfo* gameinfo, char* line)
+ansi_goto(Gameinfo* gameinfo, char* line)
 {
     const char* movenumber = line;
 
 {
     const char* movenumber = line;
 
@@ -1310,7 +1298,7 @@ ascii_goto(Gameinfo* gameinfo, char* line)
 }
 
 static void
 }
 
 static void
-ascii_free_handicap(Gameinfo* gameinfo, char* handicap_string)
+ansi_free_handicap(Gameinfo* gameinfo, char* handicap_string, bool strict)
 {
     int handi;
     int i;
 {
     int handi;
     int i;
@@ -1332,7 +1320,7 @@ ascii_free_handicap(Gameinfo* gameinfo, char* handicap_string)
         handi = 0;
 
         while (1) {
         handi = 0;
 
         while (1) {
-            ascii_showboard();
+            ansi_showboard(strict);
             printf("\nType in coordinates of next handicap stone, or one of the following commands:\n");
             printf("  undo        take back the last stone placed\n");
             printf("  clear       remove all the stones placed so far\n");
             printf("\nType in coordinates of next handicap stone, or one of the following commands:\n");
             printf("  undo        take back the last stone placed\n");
             printf("  clear       remove all the stones placed so far\n");