* ----------------------------------------------------------------------
* Copyright (c) 1993, 1994, 1995 Matthias Mutz
* Copyright (c) 1999 Michael Vanier and the Free Software Foundation
+ * Copyright (c) 2008, 2013, 2014 Yann Dirson and the Free Software Foundation
*
* GNU SHOGI is based on GNU CHESS
*
* ----------------------------------------------------------------------
*/
+/* request *snprintf prototypes*/
+#define _POSIX_C_SOURCE 200112L
#include <ctype.h>
#include <signal.h>
#include <stdio.h>
+#include <stdarg.h>
#include <sys/param.h>
#include <sys/types.h>
#include <curses.h>
#include "gnushogi.h"
-#include "cursesdsp.h"
#if HAVE_UNISTD_H
#include <unistd.h>
#define FLUSH_SCANW fflush(stdout), scanw
-int mycnt1, mycnt2;
-
+#define MARGIN (5)
#define TAB (58)
#define VIR_C(s) ((flag.reverse) ? (NO_COLS - 1 - column(s)) : column(s))
#define VIR_R(s) ((flag.reverse) ? (NO_ROWS - 1 - row(s)) : row(s))
-unsigned short MV[MAXDEPTH];
-int MSCORE;
-char *DRAW;
+/****************************************
+ * forward declarations
+ ****************************************/
-/* Forward declarations. */
/* FIXME: change this name, puh-leeze! */
-
static void UpdateCatched(void);
static void DrawPiece(short sq);
static void ShowScore(short score);
+static void Curses_UpdateDisplay(short f, short t, short redraw, short isspec);
+static void Curses_Die(int sig);
+static void Curses_ShowSidetoMove(void);
/****************************************
* Trivial output functions.
}
-void
+static void
Curses_ClearScreen(void)
{
clear();
ClearEoln();
}
-
-void
+static void
Curses_ShowCurrentMove(short pnt, short f, short t)
{
algbr(f, t, false);
}
-void
+static void
Curses_ShowDepth(char ch)
{
gotoXY(TAB, 4);
}
-void
+static void
Curses_ShowGameType(void)
{
if (flag.post)
}
-void
+static void
ShowHeader(void)
{
gotoXY(TAB, 2);
- printw("GNU Shogi %s (pl %s)", version, patchlevel);
+ printw("GNU Shogi %s", PACKAGE_VERSION);
}
-void
+static void
Curses_ShowLine(unsigned short *bstline)
{
}
-void
-Curses_ShowMessage(char *s)
+static void
+_vprintw(const char *format, va_list ap)
+{
+ static char buffer[60];
+ vsnprintf(buffer, sizeof(buffer), format, ap);
+ printw("%s", buffer);
+}
+
+static void
+Curses_ShowMessage(char *format, ...)
{
+ va_list ap;
+ va_start(ap, format);
gotoXY(TAB, 6);
- printw("%s", s);
+ _vprintw(format, ap);
+ va_end(ap);
ClearEoln();
}
-
-void
-Curses_AlwaysShowMessage(const char *format, va_list ap)
+static void
+Curses_AlwaysShowMessage(const char *format, ...)
{
- static char buffer[60];
- vsnprintf(buffer, sizeof(buffer), format, ap);
- Curses_ShowMessage(buffer);
+ va_list ap;
+ va_start(ap, format);
+ gotoXY(TAB, 6);
+ _vprintw(format, ap);
+ va_end(ap);
+ ClearEoln();
}
-void
-Curses_Printf(const char *format, va_list ap)
+static void
+Curses_Printf(const char *format, ...)
{
- static char buffer[60];
- vsnprintf(buffer, sizeof(buffer), format, ap);
- printw("%s", buffer);
+ va_list ap;
+ va_start(ap, format);
+ _vprintw(format, ap);
+ va_end(ap);
}
-void
+static void
Curses_doRequestInputString(const char* fmt, char* buffer)
{
FLUSH_SCANW(fmt, buffer);
}
-int
+static int
Curses_GetString(char* sx)
{
fflush(stdout);
}
-void
+static void
Curses_ShowNodeCnt(long NodeCnt)
{
gotoXY(TAB, 22);
}
-void
+static void
Curses_ShowPatternCount(short side, short n)
{
if (flag.post)
}
-void
+static void
Curses_ShowPrompt(void)
{
Curses_ShowSidetoMove();
}
-void
+static void
Curses_ShowResponseTime(void)
{
if (flag.post)
}
-void
+static void
Curses_ShowResults(short score, unsigned short *bstline, char ch)
{
unsigned char d, ply;
}
-void
+static void
Curses_ShowSidetoMove(void)
{
gotoXY(TAB, 14);
}
-void
+static void
Curses_ShowStage(void)
{
gotoXY(TAB, 19);
* End of trivial output routines.
****************************************/
-void
+static void
Curses_Initialize(void)
{
signal(SIGINT, Curses_Die);
}
-void
+static void
Curses_ExitShogi(void)
{
if (!nolist)
}
-void
+static void
Curses_Die(int sig)
{
char s[80];
}
-void
+static void
Curses_TerminateSearch(int sig)
{
signal(SIGINT, SIG_IGN);
}
-void
+static void
Curses_help(void)
{
Curses_ClearScreen();
- printw("GNU Shogi %sp%s command summary\n", version, patchlevel);
+ printw("GNU Shogi %s command summary\n", PACKAGE_VERSION);
printw("-------------------------------"
"---------------------------------\n");
printw("7g7f move from 7g to 7f quit Exit Shogi\n");
}
-static const short x0[2] = { 54, 2 };
-static const short y0[2] = { 20, 4 };
+static const short x0[2] = { MARGIN + 5*NO_COLS + 4, 2 };
+static const short y0[2] = { 4 + 2 * (NO_ROWS - 1), 4 };
/*
* P* will put a pawn to the captured pieces.
*/
-void
+static void
Curses_EditBoard(void)
{
- short a, c, sq, i;
+ short a, c, sq, i, found;
short r = 0;
char s[80];
Book = BOOKFAIL;
Curses_ClearScreen();
Curses_UpdateDisplay(0, 0, 1, 0);
- gotoXY(TAB, 3);
+ gotoXY(TAB, 11);
printw(". Exit to main\n");
- gotoXY(TAB, 4);
+ gotoXY(TAB, 12);
printw("# Clear board\n");
- gotoXY(TAB, 5);
+ gotoXY(TAB, 13);
printw("c Change sides\n");
gotoXY(TAB, 7);
printw("Enter piece & location: ");
a = black;
- do
+ while(1)
{
- gotoXY(TAB, 6);
+ gotoXY(TAB, 4);
printw("Editing: %s", ColorStr[a]);
- gotoXY(TAB + 24, 7);
+ gotoXY(TAB + 2, 8);
ClearEoln();
FLUSH_SCANW("%s", s);
+ found = 0;
+ ClearMessage();
+
+ if (s[0] == '.')
+ break;
if (s[0] == '#')
{
ClearCaptured();
UpdateCatched();
+ continue;
}
- if (s[0] == 'c')
+ if (s[0] == 'c') {
a = otherside[a];
+ continue;
+ }
if (s[1] == '*')
{
for (i = NO_PIECES; i > no_piece; i--)
{
if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
+ {
+ Captured[a][unpromoted[i]]++;
+ UpdateCatched();
+ found = 1;
break;
+ }
}
-
- Captured[a][unpromoted[i]]++;
- UpdateCatched();
- c = -1;
+ if (!found)
+ dsp->AlwaysShowMessage("Invalid piece type '%c'", s[0]);
+ continue;
}
- else
- {
- c = COL_NAME(s[1]);
- r = ROW_NAME(s[2]);
+
+ c = COL_NUM(s[1]);
+ r = ROW_NUM(s[2]);
+
+ if ((c < 0) || (c >= NO_COLS) || (r < 0) || (r >= NO_ROWS)) {
+ dsp->AlwaysShowMessage("Out-of-board '%c%c'", s[1], s[2]);
+ continue;
}
- if ((c >= 0) && (c < NO_COLS) && (r >= 0) && (r < NO_ROWS))
- {
- sq = locn(r, c);
+ sq = locn(r, c);
- for (i = NO_PIECES; i > no_piece; i--)
+ for (i = NO_PIECES; i > no_piece; i--)
+ {
+ if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
{
- if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
- break;
+ color[sq] = a;
+ if (s[3] == '+')
+ board[sq] = promoted[i];
+ else
+ board[sq] = unpromoted[i];
+
+ found = 1;
+ break;
}
+ }
- if (s[3] == '+')
- i = promoted[i];
- else
- i = unpromoted[i];
+ if (!found)
+ dsp->AlwaysShowMessage("Invalid piece type '%c'", s[0]);
- board[sq] = i;
- color[sq] = ((board[sq] == no_piece) ? neutral : a);
- DrawPiece(sq);
- }
+ DrawPiece(sq);
}
- while (s[0] != '.');
for (sq = 0; sq < NO_SQUARES; sq++)
Mvboard[sq] = ((board[sq] != Stboard[sq]) ? 10 : 0);
}
-void
+static void
Curses_SearchStartStuff(short side)
{
short i;
}
-void
+static void
Curses_OutputMove(void)
{
t = (l + h) >> 1;
}
- ShowNodeCnt(NodeCnt);
+ Curses_ShowNodeCnt(NodeCnt);
gotoXY(TAB, 23);
printw("Max Tree = %5d", t);
ClearEoln();
}
-void
+static void
Curses_UpdateClocks(void)
{
short m, s;
s = 0;
if (player == black)
- gotoXY(20, (flag.reverse) ? 2 : 23);
+ gotoXY(20, (flag.reverse) ? 2 : (5 + 2*NO_ROWS));
else
- gotoXY(20, (flag.reverse) ? 23 : 2);
+ gotoXY(20, (flag.reverse) ? (5 + 2*NO_ROWS) : 2);
/* printw("%d:%02d %ld ", m, s, dt); */
printw("%d:%02d ", m, s);
if (flag.post)
- ShowNodeCnt(NodeCnt);
+ Curses_ShowNodeCnt(NodeCnt);
refresh();
}
y = pxx[(int)piece];
}
- gotoXY(8 + 5 * VIR_C(sq), 4 + 2 * ((NO_ROWS - 1) - VIR_R(sq)));
+ gotoXY(MARGIN + 3 + 5 * VIR_C(sq), 4 + 2 * ((NO_ROWS - 1) - VIR_R(sq)));
printw("%c%c%c%c", l, p, y, r);
}
/*
* Curses_ShowPostnValue(): must have called ExaminePosition() first
*/
-void
+static void
Curses_ShowPostnValue(short sq)
{
- short score;
-
gotoXY(4 + 5 * VIR_C(sq), 5 + 2 * (7 - VIR_R(sq))); /* CHECKME */
- score = ScorePosition(color[sq]);
+ (void) ScorePosition(color[sq]);
if (color[sq] != neutral)
#if defined SAVE_SVALUE
}
-void
+static void
Curses_ShowPostnValues(void)
{
short sq, score;
}
-void
+static void
Curses_UpdateDisplay(short f, short t, short redraw, short isspec)
{
short i, sq, z;
ShowPlayers();
i = 2;
- gotoXY(3, ++i);
+ gotoXY(MARGIN, ++i);
- printw(" +");
+ printw(" +");
for (j=0; j<NO_COLS; j++)
printw("----+");
while (i <= 1 + 2*NO_ROWS)
{
- gotoXY(1, ++i);
+ gotoXY(MARGIN, ++i);
if (flag.reverse)
z = (i / 2) - 1;
else
z = NO_ROWS + 2 - ((i + 1) / 2);
- printw(" %c |", ROW_NAME(z+1));
+ printw("%c |", ROW_NAME(z+1));
for (j=0; j<NO_COLS; j++)
printw(" |");
- gotoXY(3, ++i);
+ gotoXY(MARGIN, ++i);
if (i < 2 + 2*NO_ROWS)
{
- printw(" +");
+ printw(" +");
for (j=0; j<NO_COLS; j++)
printw("----+");
}
}
- printw(" +");
+ printw(" +");
for (j=0; j<NO_COLS; j++)
printw("----+");
- gotoXY(3, 4 + 2*NO_ROWS);
- printw(" ");
-
+ gotoXY(MARGIN, 4 + 2*NO_ROWS);
+ printw(" ");
+#ifndef MINISHOGI
if (flag.reverse)
printw(" 1 2 3 4 5 6 7 8 9");
else
printw(" 9 8 7 6 5 4 3 2 1");
+#else
+ if (flag.reverse)
+ printw(" 1 2 3 4 5");
+ else
+ printw(" 5 4 3 2 1");
+#endif
for (sq = 0; sq < NO_SQUARES; sq++)
DrawPiece(sq);
}
-void
+static void
Curses_ChangeAlphaWindow(void)
{
Curses_ShowMessage("WAwindow = ");
}
-void
+static void
Curses_ChangeBetaWindow(void)
{
Curses_ShowMessage("WBwindow = ");
}
-void
+static void
Curses_GiveHint(void)
{
char s[40];
}
-void
-Curses_ChangeSearchDepth(void)
+static void
+Curses_ChangeSearchDepth(char* sx)
{
Curses_ShowMessage("depth = ");
FLUSH_SCANW("%hd", &MaxSearchDepth);
}
-void
+static void
Curses_ChangeHashDepth(void)
{
Curses_ShowMessage("hashdepth = ");
}
-void
+static void
Curses_SetContempt(void)
{
Curses_ShowMessage("contempt = ");
}
-void
+static void
Curses_ChangeXwindow(void)
{
Curses_ShowMessage("xwndw= ");
}
-void
+static void
Curses_SelectLevel(char *sx)
{
int item;
Curses_ClearScreen();
gotoXY(32, 2);
- printw("GNU Shogi %sp%s", version, patchlevel);
+ printw("GNU Shogi %s", PACKAGE_VERSION);
gotoXY(20, 4);
printw(" 1. 40 moves in 5 minutes");
gotoXY(20, 5);
}
-void
+static void
Curses_DoDebug(void)
{
short c, p, sq, tp, tc, tsq, score;
}
-void
+static void
Curses_DoTable(short table[NO_SQUARES])
{
short sq;
}
-void
+static void
Curses_PollForInput(void)
{
int i;
}
-void
+static void
Curses_SetupBoard(void)
{
Curses_ShowMessage("'setup' command is not supported in Cursesmode");
}
+
+
+struct display curses_display =
+{
+ .ChangeAlphaWindow = Curses_ChangeAlphaWindow,
+ .ChangeBetaWindow = Curses_ChangeBetaWindow,
+ .ChangeHashDepth = Curses_ChangeHashDepth,
+ .ChangeSearchDepth = Curses_ChangeSearchDepth,
+ .ChangeXwindow = Curses_ChangeXwindow,
+ .ClearScreen = Curses_ClearScreen,
+ .DoDebug = Curses_DoDebug,
+ .DoTable = Curses_DoTable,
+ .EditBoard = Curses_EditBoard,
+ .ExitShogi = Curses_ExitShogi,
+ .GiveHint = Curses_GiveHint,
+ .Initialize = Curses_Initialize,
+ .ShowNodeCnt = Curses_ShowNodeCnt,
+ .OutputMove = Curses_OutputMove,
+ .PollForInput = Curses_PollForInput,
+ .SetContempt = Curses_SetContempt,
+ .SearchStartStuff = Curses_SearchStartStuff,
+ .SelectLevel = Curses_SelectLevel,
+ .ShowCurrentMove = Curses_ShowCurrentMove,
+ .ShowDepth = Curses_ShowDepth,
+ .ShowGameType = Curses_ShowGameType,
+ .ShowLine = Curses_ShowLine,
+ .ShowMessage = Curses_ShowMessage,
+ .AlwaysShowMessage = Curses_AlwaysShowMessage,
+ .Printf = Curses_Printf,
+ .doRequestInputString = Curses_doRequestInputString,
+ .GetString = Curses_GetString,
+ .SetupBoard = Curses_SetupBoard,
+ .ShowPatternCount = Curses_ShowPatternCount,
+ .ShowPostnValue = Curses_ShowPostnValue,
+ .ShowPostnValues = Curses_ShowPostnValues,
+ .ShowPrompt = Curses_ShowPrompt,
+ .ShowResponseTime = Curses_ShowResponseTime,
+ .ShowResults = Curses_ShowResults,
+ .ShowSidetoMove = Curses_ShowSidetoMove,
+ .ShowStage = Curses_ShowStage,
+ .TerminateSearch = Curses_TerminateSearch,
+ .UpdateClocks = Curses_UpdateClocks,
+ .UpdateDisplay = Curses_UpdateDisplay,
+ .help = Curses_help,
+};