home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 2 / FFMCD02.bin / new / game / think / ignuchess / source / intuidsp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-21  |  33.2 KB  |  1,443 lines

  1. /************************************************************************/
  2. /* IntuiDsp.c --- Intuition Interface for GNU Chess                        */
  3. /************************************************************************/
  4.  
  5. static const char *Version = "$VER: IGNUChess 1.51 (17.8.1993)";
  6.  
  7. #include <exec/types.h>
  8. #include <exec/memory.h>
  9.  
  10. #include <dos.h>
  11.  
  12. #include <libraries/diskfont.h>
  13. #include <libraries/gadtools.h>
  14. #include <libraries/asl.h>
  15.  
  16. #include <proto/exec.h>
  17. #include <proto/dos.h>
  18. #include <proto/diskfont.h>
  19. #include <proto/graphics.h>
  20. #include <proto/intuition.h>
  21. #include <proto/gadtools.h>
  22. #include <proto/asl.h>
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <signal.h>
  28. #include <time.h>
  29.  
  30. #include "Global.h"
  31. #include "gfx.h"
  32. #include "Proto.h"
  33. #include "Interface.h"
  34. #include "gnuchess.h"
  35.  
  36. /* -------------------------------------------------------------------- */
  37. /* Minimal library version for SAS/C auto open library feature            */
  38. /* -------------------------------------------------------------------- */
  39.  
  40. int    __oslibversion = 37;
  41.  
  42. /* -------------------------------------------------------------------- */
  43. /* static function prototypes                                            */
  44. /* -------------------------------------------------------------------- */
  45.  
  46. static void    Die(int);
  47. static void    TerminateSearch(int);
  48. static void    UpdateClocks(void);
  49. static int    parse(BPTR, unsigned short *, short);
  50. static void    GetGame(void);
  51. static void    SaveGame(void);
  52. static void ListGame(void);
  53. static void    Undo(void);
  54. static void    ChangeAlphaWindow(void);
  55. static void    ChangeBetaWindow(void);
  56. static void    GiveHint(void);
  57. static void ChangeSearchDepth(void);
  58. static void SetContempt(void);
  59. static void ChangeXwindow(void);
  60. static void    DoDebug(void);
  61. static void    ShowPostnValues(void);
  62.  
  63. /* -------------------------------------------------------------------- */
  64.  
  65. unsigned int            tmbuf1[2],
  66.                         tmbuf2[2];
  67. long                    time1,
  68.                         time2;
  69.  
  70. struct Screen            *s;
  71. struct ViewPort            *vp;
  72. APTR                    vi;
  73. struct Window            *w;
  74. struct RastPort            *rp;
  75. struct FileRequester    *freq;
  76. struct Remember            *rk;
  77.  
  78. static ULONG NewLook[] = { ~0 };
  79.  
  80. static struct ColorSpec ColorSpec[] = {
  81.     { COLOR_BCK    , 0x0B, 0x0B, 0x08 },
  82.     { COLOR_RAHMEN , 0x00, 0x00, 0x00 },
  83.     { COLOR_WFIG   , 0x0F, 0x0F, 0x0F },
  84.     { COLOR_REQBAR , 0x0C, 0x0C, 0x0A },
  85.     { COLOR_EMPTY  , 0x0C, 0x0B, 0x08 },
  86.     { COLOR_SFIG   , 0x06, 0x05, 0x02 },
  87.     { COLOR_WFELD  , 0x0A, 0x08, 0x01 },
  88.     { COLOR_SFELD  , 0x0E, 0x0D, 0x0A },
  89.     { COLOR_MENUBCK, 0x00, 0x05, 0x08 },
  90.     { COLOR_BLOCK  , 0x0D, 0x0D, 0x0B },
  91.     { COLOR_TXTBCK , 0x0E, 0x0E, 0x0C },
  92.     { COLOR_TXTFGR , 0x00, 0x00, 0x00 },
  93.     { COLOR_REQBCK , 0x08, 0x08, 0x01 },
  94.     { COLOR_MARK   , 0x0C, 0x04, 0x00 },
  95.     { COLOR_FMARK  , 0x0C, 0x04, 0x00 },
  96.     { -1, 0x00, 0x00, 0x00 }
  97. };
  98.  
  99. #define FONTFLAGS (FPF_ROMFONT | FPF_DISKFONT | FPF_DESIGNED)
  100.  
  101. static struct TextFont    *TF_Times15,
  102.                         *TF_Times18,
  103.                         *TF_Courier15;
  104.  
  105. struct TextAttr    TA_Times15        = { "times.font"  , 15, FS_NORMAL, FONTFLAGS },
  106.                 TA_Times18        = { "times.font"  , 18, FS_NORMAL, FONTFLAGS },
  107.                 TA_Courier15    = { "courier.font", 15, FSF_BOLD , FONTFLAGS };
  108.  
  109. // Graphic-offsets for texts
  110.  
  111. int    off_comp_left,        // "Computer"
  112.     off_comp_right,
  113.     off_human_left,        // "Human"
  114.     off_human_right,    //  *** smile ***
  115.     off_clock_left,        // clocks
  116.     off_clock_right,
  117.     off_algbr_left,        // notation
  118.     off_algbr_right;
  119.  
  120. /* -------------------------------------------------------------------- */
  121. /* Fit texts into text boxes, parameter `where` is for placement into    */
  122. /* left or right column                                                    */
  123. /* -------------------------------------------------------------------- */
  124.  
  125. #define LEFT    0
  126. #define RIGHT    1
  127.  
  128. static int CalcTextFit(char *s, int where)
  129. {
  130.     ULONG    enable;
  131.  
  132.     SetFont(rp, TF_Courier15);
  133.     enable = AskSoftStyle(rp);
  134.     SetSoftStyle(rp, FSF_BOLD, enable);
  135.  
  136.     if ( where == LEFT )
  137.         return       ( NX2 - NX1 )   / 4 - TextLength(rp, s, strlen(s)) / 2;
  138.     else
  139.         return ( 3 * ( NX2 - NX1 ) ) / 4 - TextLength(rp, s, strlen(s)) / 2;
  140. }
  141.  
  142. static void Fit_All_Text(void)
  143. {
  144.     off_comp_left        = CalcTextFit("Computer" , LEFT );
  145.     off_comp_right        = CalcTextFit("Computer" , RIGHT);
  146.     off_human_left        = CalcTextFit("  Human  ", LEFT );
  147.     off_human_right        = CalcTextFit("  Human  ", RIGHT);
  148.     off_clock_left        = CalcTextFit("000:00:00", LEFT );
  149.     off_clock_right        = CalcTextFit("000:00:00", RIGHT);
  150.     off_algbr_left        = CalcTextFit("a1h8"     , LEFT );
  151.     off_algbr_right        = CalcTextFit("a1h8"     , RIGHT);
  152. }
  153.  
  154. /* -------------------------------------------------------------------- */
  155. /* Print text string s at coordinates (x, y)                            */
  156. /* -------------------------------------------------------------------- */
  157.  
  158. static void MyText(char *s, int x, int y)
  159. {
  160.     ULONG    enable;
  161.  
  162.     SetAPen(rp, COLOR_TXTFGR);
  163.     SetBPen(rp, COLOR_TXTBCK);
  164.     SetDrMd(rp, JAM2);
  165.     SetFont(rp, TF_Courier15);
  166.     enable = AskSoftStyle(rp);
  167.     SetSoftStyle(rp, FSF_BOLD, enable);
  168.     Move(rp, x, y);
  169.     Text(rp, s, strlen(s));
  170. }
  171.  
  172. /* -------------------------------------------------------------------- */
  173. /* Reset game variables to their default values                            */
  174. /* -------------------------------------------------------------------- */
  175.  
  176. #ifndef true
  177. #    define true        1
  178. #endif
  179. #ifndef false
  180. #    define false    0
  181. #endif
  182.  
  183. static void ResetVars(void)
  184. {
  185.     beep                =
  186.     hashflag            = true;
  187.     reverse                =
  188.     bothsides            =
  189.     post                = false;
  190.     
  191.     Awindow                =
  192.     Bwindow                =
  193.     xwndw                = 90;
  194.     MaxSearchDepth        = 29;
  195.  
  196.     opponent            = white;
  197.     computer            = black;
  198.  
  199.     ResetGfx();
  200. }
  201.  
  202. /* -------------------------------------------------------------------- */
  203. /* This is called once at program start to initialize graphics            */
  204. /* -------------------------------------------------------------------- */
  205.  
  206. void Initialize(void)
  207. {
  208.     int x, y;
  209.  
  210.     /* ---------------------------------------------------------------- */
  211.     /* Open Fonts                                                        */
  212.     /* ---------------------------------------------------------------- */
  213.  
  214.     if ( ! (TF_Times15   = OpenDiskFont(&TA_Times15  )) ) ExitChess();
  215.     if ( ! (TF_Times18   = OpenDiskFont(&TA_Times18  )) ) ExitChess();
  216.     if ( ! (TF_Courier15 = OpenDiskFont(&TA_Courier15)) ) ExitChess();
  217.  
  218.     /* ---------------------------------------------------------------- */
  219.     /* Open custom screen, assign ViewPort and VisualInfo vars            */
  220.     /* ---------------------------------------------------------------- */
  221.  
  222.     s = OpenScreenTags(
  223.         NULL,
  224.         SA_Width,            STDSCREENWIDTH,
  225.         SA_Height,            STDSCREENHEIGHT,
  226.         SA_Depth,            4,
  227.         SA_Colors,            ColorSpec,
  228.         SA_DetailPen,        COLOR_TXTFGR,
  229.         SA_BlockPen,        COLOR_BLOCK,
  230.         SA_Font,            &TA_Courier15,
  231.         SA_Title,            "Intuition GNU Chess interface",
  232.         SA_Type,            CUSTOMSCREEN,
  233.         SA_DisplayID,        NTSC_MONITOR_ID | HIRESLACE_KEY,
  234.         SA_Overscan,        OSCAN_TEXT,
  235.         SA_Pens,            NewLook,
  236.         SA_FullPalette,        TRUE,
  237.         TAG_DONE
  238.     );
  239.     if ( ! s ) ExitChess();
  240.  
  241.     vp = &(s->ViewPort);
  242.     vi = GetVisualInfo(s, TAG_DONE);
  243.  
  244.     /* ---------------------------------------------------------------- */
  245.     /* Open main window                                                    */
  246.     /* ---------------------------------------------------------------- */
  247.  
  248.     w = OpenWindowTags(
  249.         NULL,
  250.         WA_Left,            0,
  251.         WA_Top,                0,
  252.         WA_IDCMP,            IDCMP_MOUSEBUTTONS    |
  253.                             IDCMP_GADGETUP        |
  254.                             IDCMP_MENUPICK        |
  255.                             IDCMP_REQVERIFY        |
  256.                             IDCMP_INTUITICKS    |
  257.                             IDCMP_REFRESHWINDOW,
  258.         WA_CustomScreen,    s,
  259.         WA_Flags,            WFLG_ACTIVATE        |
  260.                             WFLG_BORDERLESS        |
  261.                             WFLG_BACKDROP        |
  262.                             WFLG_SMART_REFRESH,
  263.         WA_AutoAdjust,        TRUE,
  264.         TAG_DONE
  265.     );
  266.     if ( ! w ) ExitChess();
  267.  
  268.     rp = w->RPort;
  269.  
  270.     /* ---------------------------------------------------------------- */
  271.     /* Allocate ASL file requester                                        */
  272.     /* ---------------------------------------------------------------- */
  273.  
  274.     freq = (struct FileRequester *) AllocAslRequestTags(
  275.         ASL_FileRequest,
  276.         ASLFR_Window,            w,
  277.         ASLFR_InitialLeftEdge,    0,
  278.         ASLFR_InitialTopEdge,    24,
  279.         ASLFR_InitialWidth,        421,
  280.         ASLFR_InitialHeight,    421,
  281.         ASLFR_SleepWindow,        TRUE,
  282.         ASLFR_TextAttr,            &TA_Courier15,
  283.         ASLFR_RejectIcons,        TRUE,
  284.         TAG_DONE
  285.     );
  286.     if ( ! freq ) ExitChess();
  287.  
  288.     /* ---------------------------------------------------------------- */
  289.     /* Create and install menus                                            */
  290.     /* ---------------------------------------------------------------- */
  291.  
  292.     Menu = CreateMenus(
  293.         NM,
  294.         GTMN_FrontPen,        COLOR_TXTFGR,
  295.         GTMN_FullMenu,        TRUE,
  296.         TAG_DONE
  297.     );
  298.     if ( ! Menu ) ExitChess();
  299.  
  300.     if ( ! LayoutMenus(Menu, vi, GTMN_TextAttr, &TA_Courier15, TAG_DONE ) )
  301.         ExitChess();
  302.  
  303.     if ( ! SetMenuStrip(w, Menu) ) ExitChess();
  304.  
  305.     /* ---------------------------------------------------------------- */
  306.     /* Initialize Gadgets                                                */
  307.     /* ---------------------------------------------------------------- */
  308.  
  309.     InitGads();
  310.  
  311.     /* ---------------------------------------------------------------- */
  312.     /* Render basic graphics                                            */
  313.     /* ---------------------------------------------------------------- */
  314.  
  315.     SetRast(rp, COLOR_BCK);
  316.  
  317.     DrawBevelBox(
  318.         rp,
  319.         NX1 - 2,            NY1 - 2,
  320.         NX2 - NX1 + 5,        NY2 - NY1 + 5,
  321.         GT_VisualInfo,        vi,
  322.         TAG_DONE
  323.     );
  324.     DrawBevelBox(
  325.         rp,
  326.         NX1 - 1,            NY1 - 1,
  327.         NX2 - NX1 + 3,        NY2 - NY1 + 3,
  328.         GT_VisualInfo,        vi,
  329.         TAG_DONE
  330.     );
  331.     DrawBevelBox(
  332.         rp,
  333.         TX1 - 2,            TY1 - 2,
  334.         TX2 - TX1 + 5,        TY2 - TY1 + 5,
  335.         GT_VisualInfo,        vi,
  336.         TAG_DONE
  337.     );
  338.     DrawBevelBox(
  339.         rp,
  340.         TX1 - 1,            TY1 - 1,
  341.         TX2 - TX1 + 3,        TY2 - TY1 + 3,
  342.         GT_VisualInfo,        vi,
  343.         TAG_DONE
  344.     );
  345.  
  346.     SetAPen(rp, COLOR_TXTBCK);
  347.     RectFill(rp, NX1, NY1, NX2, NY2);
  348.     RectFill(rp, TX1, TY1, TX2, TY2);
  349.  
  350.     SetAPen(rp, COLOR_RAHMEN);
  351.     for ( y = -1; y <= 7; y++ ) {
  352.         Move(rp, XPOS(0)-2, YPOS(y)-1);
  353.         Draw(rp, XPOS(8)-1, YPOS(y)-1);
  354.         Move(rp, XPOS(0)-2, YPOS(y)-2);
  355.         Draw(rp, XPOS(8)-1, YPOS(y)-2);
  356.     }
  357.     for ( x = 0; x <= 8; x++ ) {
  358.         Move(rp, XPOS(x)-2, YPOS(-1)-1);
  359.         Draw(rp, XPOS(x)-2, YPOS( 7)-1);
  360.         Move(rp, XPOS(x)-1, YPOS(-1)-1);
  361.         Draw(rp, XPOS(x)-1, YPOS( 7)-1);
  362.     }
  363.  
  364.     Fit_All_Text();
  365.     ResetVars();
  366. }
  367.  
  368. /* -------------------------------------------------------------------- */
  369. /* Clean up, de-allocate everything opened at runtime, exit gracefully    */
  370. /* -------------------------------------------------------------------- */
  371.  
  372. void ExitChess(void)
  373. {
  374.     if ( w                ) { ClearMenuStrip(w); CloseWindow(w); }
  375.     if ( Menu            )     FreeMenus(Menu);
  376.                               FreeGads();
  377.     if ( vi                )    FreeVisualInfo(vi);
  378.     if ( s                )    CloseScreen(s);
  379.     if ( freq            )    FreeAslRequest((APTR) freq);
  380.     if ( TF_Courier15    )    CloseFont(TF_Courier15);
  381.     if ( TF_Times15        )    CloseFont(TF_Times15);
  382.     if ( TF_Times18        )    CloseFont(TF_Times18);
  383.     if ( rk                )    FreeRemember(&rk, TRUE);
  384.     exit(0);
  385. }
  386.  
  387. /* -------------------------------------------------------------------- */
  388. /* This function is called every time the user is prompted for a move.    */
  389. /* -------------------------------------------------------------------- */
  390.  
  391. void InputCommand(void)
  392. {
  393.     short                ok,
  394.                         i;
  395.     long                cnt,
  396.                         rate,
  397.                         t1,
  398.                         t2;
  399.     unsigned short        mv;
  400.     char                s[5]        = "a1a1",
  401.                         line[40];
  402.     struct IntuiMessage    *msg;
  403.     int                    selected    = FALSE,
  404.                         toggle        = TRUE,
  405.                         sq1            = 0,
  406.                         sq2,
  407.                         mustredraw    = FALSE;
  408.  
  409.     ok        =
  410.     quit    = false;
  411.     player    = opponent;
  412.     ft        = 0;
  413.  
  414.     /* ---------------------------------------------------------------- */
  415.     /* Main input event selector loop                                    */
  416.     /* ---------------------------------------------------------------- */
  417.  
  418.     while ( ! ( ok || quit ) ) {
  419.         WaitPort(IDCMPORT);
  420.         msg = GT_GetIMsg(IDCMPORT);
  421.         switch ( CLASS(msg) ) {
  422.  
  423.             /* -------------------------------------------------------- */
  424.             /* Refresh window event, required for GadTools                */
  425.             /* -------------------------------------------------------- */
  426.  
  427.             case IDCMP_REFRESHWINDOW:
  428.                 GT_BeginRefresh(w);
  429.                 GT_EndRefresh(w, TRUE);
  430.                 break;
  431.  
  432.             /* -------------------------------------------------------- */
  433.             /* Intuiticks, used for blinking selected square            */
  434.             /* -------------------------------------------------------- */
  435.  
  436.             case IDCMP_INTUITICKS:
  437.                 if ( selected ) {
  438.                     if ( toggle )
  439.                         SetRGB4(
  440.                             vp,
  441.                             COLOR_FMARK,
  442.                             ColorSpec[COLOR_RAHMEN].Red,
  443.                             ColorSpec[COLOR_RAHMEN].Green,
  444.                             ColorSpec[COLOR_RAHMEN].Blue
  445.                         );
  446.                     else
  447.                         SetRGB4(
  448.                             vp,
  449.                             COLOR_FMARK,
  450.                             ColorSpec[COLOR_FMARK].Red,
  451.                             ColorSpec[COLOR_FMARK].Green,
  452.                             ColorSpec[COLOR_FMARK].Blue
  453.                         );
  454.                     toggle = ! toggle;
  455.                 }
  456.                 chkabort();
  457.                 break;
  458.  
  459.             /* -------------------------------------------------------- */
  460.             /* Mousebuttons, select start and end square for moves        */
  461.             /* -------------------------------------------------------- */
  462.  
  463.             case IDCMP_MOUSEBUTTONS:
  464.                 if ( mustredraw ) {
  465.                     UpdateDisplay(0, 0, 1, 0);
  466.                     mustredraw = FALSE;
  467.                 }
  468.                 if ( ! selected ) {
  469.                     if ( ( CODE(msg) & IECODE_UP_PREFIX ) && MFeld(msg, &sq1) ) {
  470.                         if ( color[sq1] == opponent ) {
  471.                             selected = TRUE;
  472.                             MarkField(sq1);
  473.                         }
  474.                     }
  475.                 }
  476.                 else {
  477.                     if ( ( CODE(msg) & IECODE_UP_PREFIX ) && MFeld(msg, &sq2) ) {
  478.                         if ( color[sq2] != opponent ) {
  479.                             s[0] = 'a' + (sq1 & 7);
  480.                             s[1] = '1' + (sq1 / 8);
  481.                             s[2] = 'a' + (sq2 & 7);
  482.                             s[3] = '1' + (sq2 / 8);
  483.                             player = opponent;
  484.                             ok = VerifyMove(s, 0, &mv);
  485.                             if ( ok && mv != hint )
  486.                                 Sdepth    =
  487.                                 ft        = 0;
  488.                             UnMarkField(sq1);
  489.                             selected = FALSE;
  490.                         }
  491.                     }
  492.                 }
  493.                 break;
  494.  
  495.             /* -------------------------------------------------------- */
  496.             /* Gadget selection, currently none defined                    */
  497.             /* -------------------------------------------------------- */
  498.  
  499.             case IDCMP_GADGETUP:
  500.                 break;
  501.  
  502.             /* -------------------------------------------------------- */
  503.             /* Menu selection                                            */
  504.             /* -------------------------------------------------------- */
  505.  
  506.             case IDCMP_MENUPICK:
  507.                 if ( mustredraw ) {
  508.                     UpdateDisplay(0, 0, 1, 0);
  509.                     mustredraw = FALSE;
  510.                 }
  511.                 if ( selected ) {
  512.                     UnMarkField(sq1);
  513.                     selected = FALSE;
  514.                 }
  515.                 switch( CODE(msg) ) {
  516.                     case PROJECT_ABOUT:
  517.                         About();
  518.                         break;
  519.                     case PROJECT_NEWGAME:
  520.                         NewGame();
  521.                         break;
  522.                     case PROJECT_GETGAME:
  523.                         GetGame();
  524.                         break;
  525.                     case PROJECT_SAVEGAME:
  526.                         SaveGame();
  527.                         break;
  528.                     case PROJECT_SAVEEXT:
  529.                         SaveGame();
  530.                         break;
  531.                     case PROJECT_LISTGAME:
  532.                         ListGame();
  533.                         break;
  534.                     case PROJECT_QUIT:
  535.                         quit = true;
  536.                         break;
  537.                     case EDIT_EDITBOARD:
  538.                         EditBoard();
  539.                         break;
  540.                     case EDIT_GAMEDATA:
  541.                         PartieData();
  542.                         break;
  543.                     case EDIT_FORCE:
  544.                         force = ! force;
  545.                         break;
  546.                     case GAME_UNDO:
  547.                         if ( GameCnt >= 0 )
  548.                             Undo();
  549.                         break;
  550.                     case GAME_REMOVE:
  551.                         if ( GameCnt >= 1 ) {
  552.                             Undo();
  553.                             Undo();
  554.                         }
  555.                         break;
  556.                     case GAME_HINT:
  557.                         GiveHint();
  558.                         break;
  559.                     case GAME_SWITCHSIDES:
  560.                         computer    = otherside[computer];
  561.                         opponent    = otherside[opponent];
  562.                         force        = false;
  563.                         Sdepth        = 0;
  564.                         ok            = true;
  565.                         break;
  566.                     case GAME_COMPUTERWHITE:
  567.                         computer    = white;
  568.                         opponent    = black;
  569.                         ok            = true;
  570.                         force        = false;
  571.                         Sdepth        = 0;
  572.                         UpdateDisplay(0, 0, 1, 0);
  573.                         break;
  574.                     case GAME_COMPUTERBLACK:
  575.                         computer    = black;
  576.                         opponent    = white;
  577.                         ok            = true;
  578.                         force        = false;
  579.                         Sdepth        = 0;
  580.                         UpdateDisplay(0, 0, 1, 0);
  581.                         break;
  582.                     case GAME_COMPUTERBOTH:
  583.                         bothsides    = !bothsides;
  584.                         Sdepth        = 0;
  585.                         SelectMove(opponent, 1);
  586.                         ok            = true;
  587.                         UpdateDisplay(0, 0, 1, 0);
  588.                         break;
  589.                     case GAME_RESETVARS:
  590.                         ResetVars();
  591.                         break;
  592.                     case LEVEL_60_IN_005:
  593.                         TCmoves        = 60;
  594.                         TCminutes    = 5;
  595.                         TCflag        = true;
  596.                         SetTimeControl();
  597.                         UpdateDisplay(0, 0, 1, 0);
  598.                         break;
  599.                     case LEVEL_60_IN_015:
  600.                         TCmoves        = 60;
  601.                         TCminutes    = 15;
  602.                         TCflag        = true;
  603.                         SetTimeControl();
  604.                         UpdateDisplay(0, 0, 1, 0);
  605.                         break;
  606.                     case LEVEL_60_IN_030:
  607.                         TCmoves        = 60;
  608.                         TCminutes    = 30;
  609.                         TCflag        = true;
  610.                         SetTimeControl();
  611.                         UpdateDisplay(0, 0, 1, 0);
  612.                         break;
  613.                     case LEVEL_40_IN_030:
  614.                         TCmoves        = 40;
  615.                         TCminutes    = 30;
  616.                         TCflag        = true;
  617.                         SetTimeControl();
  618.                         UpdateDisplay(0, 0, 1, 0);
  619.                         break;
  620.                     case LEVEL_40_IN_060:
  621.                         TCmoves        = 40;
  622.                         TCminutes    = 60;
  623.                         TCflag        = true;
  624.                         SetTimeControl();
  625.                         UpdateDisplay(0, 0, 1, 0);
  626.                         break;
  627.                     case LEVEL_40_IN_120:
  628.                         TCmoves        = 40;
  629.                         TCminutes    = 120;
  630.                         TCflag        = true;
  631.                         SetTimeControl();
  632.                         UpdateDisplay(0, 0, 1, 0);
  633.                         break;
  634.                     case LEVEL_40_IN_240:
  635.                         TCmoves        = 40;
  636.                         TCminutes    = 240;
  637.                         TCflag        = true;
  638.                         SetTimeControl();
  639.                         UpdateDisplay(0, 0, 1, 0);
  640.                         break;
  641.                     case LEVEL_01_IN_015:
  642.                         TCmoves        = 1;
  643.                         TCminutes    = 15;
  644.                         TCflag        = false;
  645.                         SetTimeControl();
  646.                         UpdateDisplay(0, 0, 1, 0);
  647.                         break;
  648.                     case LEVEL_01_IN_060:
  649.                         TCmoves        = 1;
  650.                         TCminutes    = 60;
  651.                         TCflag        = false;
  652.                         SetTimeControl();
  653.                         UpdateDisplay(0, 0, 1, 0);
  654.                         break;
  655.                     case LEVEL_01_IN_600:
  656.                         TCmoves        = 1;
  657.                         TCminutes    = 600;
  658.                         TCflag        = false;
  659.                         SetTimeControl();
  660.                         UpdateDisplay(0, 0, 1, 0);
  661.                         break;
  662.                     case PROPERTIES_HASH:
  663.                         hashflag    = ! hashflag;
  664.                         break;
  665.                     case PROPERTIES_BOOK:
  666.                         Book        = NULL;
  667.                         break;
  668.                     case PROPERTIES_BEEP:
  669.                         beep        = ! beep;
  670.                         break;
  671.                     case PROPERTIES_POST:
  672.                         post        = ! post;
  673.                         break;
  674.                     case PROPERTIES_REVERSE:
  675.                         reverse        = ! reverse;
  676.                         UpdateDisplay(0, 0, 1, 0);
  677.                         break;
  678.                     case PROPERTIES_RANDOM:
  679.                         dither        = 6;
  680.                         break;
  681.                     case DEBUG_AWINDOW:
  682.                         ChangeAlphaWindow();
  683.                         break;
  684.                     case DEBUG_BWINDOW:
  685.                         ChangeBetaWindow();
  686.                         break;
  687.                     case DEBUG_DEPTH:
  688.                         ChangeSearchDepth();
  689.                         break;
  690.                     case DEBUG_CONTEMPT:
  691.                         SetContempt();
  692.                         break;
  693.                     case DEBUG_XWINDOW:
  694.                         ChangeXwindow();
  695.                         break;
  696.                     case DEBUG_TEST:
  697.                         t1            = time(0);
  698.                         cnt            = 0;
  699.                         for ( i = 0; i < 10000; i++ ) {
  700.                             MoveList(opponent, 2);
  701.                             cnt += TrPnt[3] - TrPnt[2];
  702.                         }
  703.                         t2            = time(0);
  704.                         rate        = cnt / (t2-t1);
  705.                         sprintf(line, "cnt = %ld  rate = %ld", cnt, rate);
  706.                         ShowMessage(line);
  707.                         break;
  708.                     case DEBUG_SHOWPOSTNVAL:
  709.                         ShowPostnValues();
  710.                         mustredraw = TRUE;
  711.                         break;
  712.                     case DEBUG_DEBUG:
  713.                         DoDebug();
  714.                         mustredraw = TRUE;
  715.                         break;
  716.                 }
  717.                 break;
  718.         }
  719.         GT_ReplyIMsg(msg);
  720.     }
  721.     
  722.     ClearMessage();
  723.     ElapsedTime(1);
  724.     if ( force ) {
  725.         computer = opponent;
  726.         opponent = otherside[computer];
  727.     }
  728.     timer(tmbuf1);
  729.     time1 = 60 * tmbuf1[0] + tmbuf1[1] / 16667;
  730.     signal(SIGINT, TerminateSearch);
  731. }
  732.  
  733. /* -------------------------------------------------------------------- */
  734. /* This is called if two successive breaks (CTRL-C) are sent             */
  735. /* -------------------------------------------------------------------- */
  736.  
  737. static void Die(int dummy)
  738. {
  739.     static struct EasyStruct es = {
  740.         sizeof(struct EasyStruct),
  741.         0,
  742.         "Please select",
  743.         "Abort?",
  744.         "Yes|No"
  745.     };
  746.  
  747.     signal(SIGINT, SIG_IGN);
  748.     if ( EasyRequestArgs(w, &es, NULL, NULL) == 1 ) ExitChess();
  749.     signal(SIGINT, Die);
  750. }
  751.  
  752. /* -------------------------------------------------------------------- */
  753. /* This is called if a break (CTRL-C) is sent while GNUChess thinks        */
  754. /* -------------------------------------------------------------------- */
  755.  
  756. static void TerminateSearch(int dummy)
  757. {
  758.     signal(SIGINT, SIG_IGN);
  759.     timeout        = true;
  760.     bothsides    = false;
  761.     signal(SIGINT, Die);
  762. }
  763.  
  764. /* -------------------------------------------------------------------- */
  765. /* Display current search depth                                            */
  766. /* -------------------------------------------------------------------- */
  767.  
  768. void ShowDepth(char ch)
  769. {
  770.     char buf[40];
  771.  
  772.     sprintf(buf, "Depth = %2ld%lc", Sdepth, ch);
  773.     MyText(buf, NX1 + 6, NY1 + 13);
  774. }
  775.  
  776. /* -------------------------------------------------------------------- */
  777. /* Display evaluated position score and best line found                    */
  778. /* -------------------------------------------------------------------- */
  779.  
  780. void ShowResults(short score, unsigned short *bstline, char ch)
  781. {
  782.     short    ply;
  783.     char    buf[40];
  784.     int        x, y;
  785.  
  786.     if ( post && player == computer ) {
  787.         sprintf(buf, "Score = %5ld", score);
  788.         MyText(buf, NX1 + 125, NY1 + 13);
  789.         SetAPen(rp, COLOR_TXTBCK);
  790.         RectFill(rp,
  791.             NX1 +   6, NY1 +  20,
  792.             NX1 + 231, NY1 + 100
  793.         );
  794.         for ( ply = 0; bstline[ply+1] > 0; ply++ ) {
  795.             x = NX1 + 45 * ( ply % 5 ) +  6;
  796.             y = NY1 + 17 * ( ply / 5 ) + 33;
  797.             algbr(bstline[ply+1] >> 8, bstline[ply+1] & 0xFF, false);
  798.             MyText(mvstr1, x, y);
  799.         }
  800.     }
  801. }
  802.  
  803. /* -------------------------------------------------------------------- */
  804. /* This is called every time GNUChess calculation is started            */
  805. /* -------------------------------------------------------------------- */
  806.  
  807. void SearchStartStuff(short side)
  808. {
  809.     signal(SIGINT, TerminateSearch);
  810.     if ( player == computer ) {
  811.         SetAPen(rp, COLOR_TXTBCK);
  812.         RectFill(rp, NX1, NY1, NX2, NY2);
  813.     }
  814. }
  815.  
  816. /* -------------------------------------------------------------------- */
  817. /* Display move GNUChess did                                            */
  818. /* -------------------------------------------------------------------- */
  819.  
  820. void OutputMove(void)
  821. {
  822.     char buf[40];
  823.  
  824.     if ( root->flags & epmask )
  825.         UpdateDisplay(0, 0, 1, 0);
  826.     else
  827.         UpdateDisplay(root->f, root->t, 0, root->flags & cstlmask);
  828.  
  829.     strcpy(buf, "My move is: ");
  830.     strcat(buf, mvstr1);
  831.  
  832.     MyText("                           ", TX1 + 6, TY2 - 27);
  833.     MyText(buf, TX1 + 6, TY2 - 27);
  834.  
  835.     if ( beep ) DisplayBeep(NULL);
  836.  
  837.     if ( root->flags & draw )        MyText("Draw game!              ", TX1 + 6, TY2 - 26);
  838.     else if ( root->score == -9999 ) MyText("opponent mates!         ", TX1 + 6, TY2 - 26);
  839.     else if ( root->score ==  9998 ) MyText("computer mates!         ", TX1 + 6, TY2 - 26);
  840.     else if ( root->score <  -9000 ) MyText("opponent will soon mate!", TX1 + 6, TY2 - 26);
  841.     else if ( root->score >   9000 ) MyText("computer will soon mate!", TX1 + 6, TY2 - 26);
  842.   
  843.     if ( post ) {
  844.         sprintf(buf, "Nodes     = %8ld", NodeCnt);
  845.         MyText(buf, NX1 + 6, NY1 + 132);
  846.         sprintf(buf, "Nodes/Sec = %8ld", evrate);
  847.         MyText(buf, NX1 + 6, NY1 + 144);
  848.     }
  849. }
  850.  
  851. /* -------------------------------------------------------------------- */
  852. /* Determine the time that has passed since the search was started.  If    */
  853. /* the  elapsed  time  exceeds the target (ResponseTime+ExtraTime) then    */
  854. /* set timeout to true which will terminate the search.                    */
  855. /* -------------------------------------------------------------------- */
  856.  
  857. void ElapsedTime(short iop)
  858. {
  859.     et = time(NULL) - time0;
  860.     if ( et < 0 )
  861.         et = 0;
  862.     ETnodes += 50;
  863.     if ( et > et0 || iop == 1 ) {
  864.         if ( et > ResponseTime + ExtraTime && Sdepth > 1 )
  865.             timeout = true;
  866.         et0 = et;
  867.         if ( iop == 1 ) {
  868.             time0    = time(NULL);
  869.             et0        = 0;
  870.         }
  871.         timer(tmbuf2);
  872.         time2        = 60 * tmbuf2[0] + tmbuf1[1] / 16667;
  873.         cputimer    = 100 * (time2 - time1) / HZ;
  874.         evrate        = ( cputimer > 0 ) ? (100 * NodeCnt) / (cputimer + 100 * ft) : 0;
  875.         ETnodes        = NodeCnt + 50;
  876.         UpdateClocks();
  877.     }
  878. }
  879.  
  880. static void UpdateClocks(void)
  881. {
  882.     int        m, s;
  883.     char    buf[40];
  884.  
  885.     chkabort();
  886.  
  887.     m = et / 60;
  888.     s = et % 60;
  889.     if ( TCflag ) {
  890.         m = (TimeControl.clock[player] - et) / 60;
  891.         s = (TimeControl.clock[player] - et) % 60;
  892.     }
  893.     if ( m < 0 )
  894.         m = 0;
  895.     if ( s < 0 )
  896.         s = 0;
  897.  
  898.     sprintf(buf, "%03ld:%02ld:%02ld", m / 60, m % 60, s);
  899.  
  900.     if ( player == white )
  901.         MyText(buf, TX1 + off_clock_left , TY1 + 30);
  902.     else
  903.         MyText(buf, TX1 + off_clock_right, TY1 + 30);
  904.  
  905.     if ( post ) {
  906.         sprintf(buf, "Nodes     = %8ld", NodeCnt);
  907.         MyText(buf, NX1 + 6, NY1 + 132);
  908.         sprintf(buf, "Nodes/Sec = %8ld", evrate);
  909.         MyText(buf, NX1 + 6, NY1 + 144);
  910.     }
  911. }
  912.  
  913. void SetTimeControl(void)
  914. {
  915.     if ( TCflag ) {
  916.         TimeControl.moves[white] =
  917.         TimeControl.moves[black] = TCmoves;
  918.         TimeControl.clock[white] =
  919.         TimeControl.clock[black] = 60 * TCminutes;
  920.     }
  921.     else {
  922.         TimeControl.moves[white] =
  923.         TimeControl.moves[black] =
  924.         TimeControl.clock[white] =
  925.         TimeControl.clock[black] = 0;
  926.         Level = 60 * TCminutes;
  927.     }
  928.     et = 0;
  929.     ElapsedTime(1);
  930. }
  931.  
  932. void DrawPiece(short sq)
  933. {
  934.     int piece;
  935.  
  936.     piece = ( color[sq] == black ) ? qxx[board[sq]] : pxx[board[sq]];
  937.     if ( reverse )
  938.         DrawFeld(piece, 7 - column[sq], 7 - row[sq]);
  939.     else
  940.         DrawFeld(piece, column[sq], row[sq]);
  941. }
  942.  
  943. void UpdateDisplay(short f, short t, short flag, short iscastle)
  944. {
  945.     short l; 
  946.  
  947.     if ( flag ) {
  948.         ResetGfx();
  949.         if ( bothsides ) {
  950.             MyText("Computer" , TX1 + off_comp_left  , TY1 + 13);
  951.             MyText("Computer" , TX1 + off_comp_right , TY1 + 13);
  952.         }
  953.         else
  954.             if ( computer == white ) {
  955.                 MyText("Computer" , TX1 + off_comp_left  , TY1 + 13);
  956.                 MyText("  Human  ", TX1 + off_human_right, TY1 + 13);
  957.             }
  958.             else {
  959.                 MyText("  Human  ", TX1 + off_human_left , TY1 + 13);
  960.                 MyText("Computer" , TX1 + off_comp_right , TY1 + 13);
  961.             }
  962.  
  963.         for (l = 0; l < 64; l++)
  964.             DrawPiece(l);
  965.     }
  966.     else {
  967.         DrawPiece(f);
  968.         DrawPiece(t);
  969.         if ( iscastle )
  970.             if (t > f) {
  971.                 DrawPiece(f+3);
  972.                 DrawPiece(t-1);
  973.             }
  974.             else {
  975.                 DrawPiece(f-4);
  976.                 DrawPiece(t+1);
  977.             }
  978.     }
  979. }
  980.  
  981. /* -------------------------------------------------------------------- */
  982. /* Read in the Opening Book file and parse the algebraic notation for a    */
  983. /* move  into  an  unsigned  integer  format indicating the from and to    */
  984. /* square.   Create  a  linked  list  of  opening  lines  of play, with    */
  985. /* entry->next  pointing to the next line and entry->move pointing to a    */
  986. /* chunk  of  memory containing the moves.  More Opening lines of up to    */
  987. /* 256 half moves may be added to gnuchess.book.                        */
  988. /* -------------------------------------------------------------------- */
  989.  
  990. void GetOpenings(void)
  991. {
  992.     BPTR                fd;
  993.     int                    c, i, j, side;
  994.     struct BookEntry    *entry;
  995.     unsigned short        mv, *mp, tmp[100];
  996.  
  997.     if ( fd = Open("gnuchess.book", MODE_OLDFILE) ) {
  998.         Book    = NULL;
  999.         i        = 0;
  1000.         side    = white;
  1001.         while ( (c = parse(fd, &mv, side)) >= 0 )
  1002.             if ( c == 1 ) {
  1003.                 tmp[++i]    = mv;
  1004.                 side        = otherside[side];
  1005.             }
  1006.             else
  1007.                 if ( c == 0 && i > 0 ) {
  1008.                     entry = (struct BookEntry *)
  1009.                         AllocRemember(&rk, sizeof(struct BookEntry), MEMF_PUBLIC);
  1010.                     mp = (unsigned short *)
  1011.                         AllocRemember(&rk, (i+1) * sizeof(unsigned short), MEMF_PUBLIC);
  1012.                     entry->mv    = mp;
  1013.                     entry->next    = Book;
  1014.                     Book        = entry; 
  1015.                     for ( j = 1; j <= i; j++ )
  1016.                         *(mp++) = tmp[j];
  1017.                     *mp        =
  1018.                     i        = 0;
  1019.                     side    = white;
  1020.                 }
  1021.         Close(fd);
  1022.     }
  1023. }
  1024.  
  1025.  
  1026. static int parse(BPTR fd, unsigned short *mv, short side)
  1027. {
  1028.     int        c, i, r1, r2, c1, c2;
  1029.     char    s[100];
  1030.  
  1031.     while ( ( c = FGetC(fd) ) == ' ' ) { ; }
  1032.     i        = 0;
  1033.     s[0]    = c;
  1034.     while ( c != ' ' && c != '\n' && c != EOF )
  1035.         s[++i]    =
  1036.         c        = FGetC(fd);
  1037.     s[++i] = '\0';
  1038.     if ( c == EOF )
  1039.         return -1;
  1040.     if ( s[0] == '!' || i < 3 ) {
  1041.         while ( c != '\n' && c != EOF )
  1042.             c = FGetC(fd);
  1043.         return 0;
  1044.     }
  1045.     if ( s[4] == 'o' )
  1046.         *mv = ( side == black ) ? 0x3C3A : 0x0402;
  1047.     else
  1048.         if ( s[0] == 'o' )
  1049.             *mv = ( side == black ) ? 0x3C3E : 0x0406;
  1050.         else {
  1051.             c1    = s[0] - 'a';
  1052.             r1    = s[1] - '1';
  1053.             c2    = s[2] - 'a';
  1054.             r2    = s[3] - '1';
  1055.             *mv    = ( locn[r1][c1] << 8 ) + locn[r2][c2];
  1056.         }
  1057.     return 1;
  1058. }
  1059.  
  1060. static void GetGame(void)
  1061. {
  1062.     FILE            *fd;
  1063.     char            fname[FMSIZE];
  1064.     int                c;
  1065.     BOOL            success;
  1066.     short            sq;
  1067.     unsigned short    m;
  1068.  
  1069.     success = AslRequestTags(
  1070.         freq,
  1071.         ASLFR_TitleText,    "Load Game File",
  1072.         ASLFR_InitialFile,    "chess.000",
  1073.         TAG_DONE
  1074.     );
  1075.     if ( success ) {
  1076.         strmfp(fname, freq->rf_Dir, freq->rf_File);
  1077.         if ( fd = fopen(fname, "r") ) {
  1078.             fscanf(
  1079.                 fd,
  1080.                 "%hd%hd%hd" "%hd%hd%hd%hd" "%hd%hd" "%ld%ld%hd%hd",
  1081.                 &computer,
  1082.                 &opponent,
  1083.                 &Game50,
  1084.  
  1085.                 &castld[white],
  1086.                 &castld[black],
  1087.                 &kingmoved[white],
  1088.                 &kingmoved[black],
  1089.  
  1090.                 &TCflag,
  1091.                 &OperatorTime,
  1092.  
  1093.                 &TimeControl.clock[white],
  1094.                 &TimeControl.clock[black],
  1095.                 &TimeControl.moves[white],
  1096.                 &TimeControl.moves[black]
  1097.             );
  1098.             for ( sq = 0; sq < 64; sq++ ) {
  1099.                 fscanf(fd, "%hd", &m);
  1100.                 board[sq] = (m >> 8);
  1101.                 color[sq] = (m & 0xFF);
  1102.                 if ( color[sq] == 0 )
  1103.                     color[sq] = neutral;
  1104.                 else
  1105.                     --color[sq];
  1106.             }
  1107.             GameCnt = -1;
  1108.             c = '?';
  1109.             while ( c != EOF ) {
  1110.                 ++GameCnt;
  1111.                 c = fscanf(fd, "%hd%hd%hd%ld%hd%hd%hd",
  1112.                         &GameList[GameCnt].gmove,
  1113.                         &GameList[GameCnt].score,
  1114.                         &GameList[GameCnt].depth,
  1115.                         &GameList[GameCnt].nodes,
  1116.                         &GameList[GameCnt].time,
  1117.                         &GameList[GameCnt].piece,
  1118.                         &GameList[GameCnt].color
  1119.                 );
  1120.                 if ( GameList[GameCnt].color == 0 )
  1121.                     GameList[GameCnt].color = neutral;
  1122.                 else
  1123.                     --GameList[GameCnt].color;
  1124.             }
  1125.             GameCnt--;
  1126.             if ( TimeControl.clock[white] > 0 )
  1127.                 TCflag = true;
  1128.             computer--;
  1129.             opponent--;
  1130.         }
  1131.         fclose(fd);
  1132.         InitializeStats();
  1133.         UpdateDisplay(0, 0, 1, 0);
  1134.         Sdepth = 0;
  1135.     }
  1136. }
  1137.  
  1138.  
  1139. static void SaveGame(void)
  1140. {
  1141.     BPTR    fd;
  1142.     char    fname[FMSIZE];
  1143.     short    sq, i, c;
  1144.     BOOL    success;
  1145.  
  1146.     success = AslRequestTags(
  1147.         freq,
  1148.         ASLFR_TitleText,    "Save Game File",
  1149.         ASLFR_InitialFile,    "chess.000",
  1150.         ASLFR_DoSaveMode,    TRUE,
  1151.         TAG_DONE
  1152.     );
  1153.     if ( success ) {
  1154.         strmfp(fname, freq->rf_Dir, freq->rf_File);
  1155.         if ( fd = Open(fname, MODE_NEWFILE) ) {
  1156.             fprintf(
  1157.                 (FILE *) fd,
  1158.                 "%ld %ld %ld\n" "%ld %ld %ld %ld\n" "%ld %ld\n" "%ld %ld %ld %ld\n",
  1159.                 computer+1,
  1160.                 opponent+1,
  1161.                 Game50,
  1162.  
  1163.                 castld[white],
  1164.                 castld[black],
  1165.                 kingmoved[white],
  1166.                 kingmoved[black],
  1167.  
  1168.                 TCflag,
  1169.                 OperatorTime,
  1170.  
  1171.                 TimeControl.clock[white],
  1172.                 TimeControl.clock[black],
  1173.                 TimeControl.moves[white],
  1174.                 TimeControl.moves[black]
  1175.             );
  1176.             for ( sq = 0; sq < 64; sq++ ) {
  1177.                 c = (color[sq] == neutral) ? 0 : color[sq]+1;
  1178.                 fprintf((FILE *) fd,"%ld\n",256*board[sq] + c);
  1179.             }
  1180.             for ( i = 0; i <= GameCnt; i++ ) {
  1181.                 c = (GameList[i].color == neutral) ? 0 : GameList[i].color + 1;
  1182.                 fprintf(
  1183.                     (FILE *) fd,
  1184.                     "%ld %ld %ld %ld %ld %ld %ld\n",
  1185.                     GameList[i].gmove,
  1186.                     GameList[i].score,
  1187.                     GameList[i].depth,
  1188.                     GameList[i].nodes,
  1189.                     GameList[i].time,
  1190.                     GameList[i].piece,
  1191.                     c
  1192.                 );
  1193.             }
  1194.             Close(fd);
  1195.         }
  1196.     }
  1197. }
  1198.  
  1199.  
  1200. static void ListGame(void)
  1201. {
  1202.     BPTR    fd;
  1203.     short    i, f, t;
  1204.     BOOL    success;
  1205.     char    name[FMSIZE];
  1206.  
  1207.     success = AslRequestTags(
  1208.         freq,
  1209.         ASLFR_TitleText,    "List Game",
  1210.         ASLFR_InitialFile,    "chess.lst",
  1211.         ASLFR_DoSaveMode,    TRUE,
  1212.         TAG_DONE
  1213.     );
  1214.     if ( success ) {
  1215.         strmfp(name, freq->rf_Dir, freq->rf_File);
  1216.         if ( fd = Open(name, MODE_NEWFILE) ) {
  1217.             fprintf(
  1218.                 (FILE *) fd,
  1219.                 "\n"
  1220.                 "       score  depth  nodes  time         "
  1221.                 "       score  depth  nodes  time\n"
  1222.             );
  1223.             for ( i = 0; i <= GameCnt; i++ ) {
  1224.                 f = GameList[i].gmove >> 8;
  1225.                 t = (GameList[i].gmove & 0xFF);
  1226.                 algbr(f, t, false);
  1227.                 fprintf(
  1228.                     (FILE *) fd,
  1229.                     (i % 2) ? "         " : "\n"
  1230.                 );
  1231.                 fprintf(
  1232.                     (FILE *) fd,
  1233.                     "%5s  %5ld     %2ld %6ld %5ld",
  1234.                     mvstr1,
  1235.                     GameList[i].score,
  1236.                     GameList[i].depth,
  1237.                     GameList[i].nodes,
  1238.                     GameList[i].time
  1239.                 );
  1240.             }
  1241.             fprintf(
  1242.                 (FILE *) fd,
  1243.                 "\n\n"
  1244.             );
  1245.             Close(fd);
  1246.         }
  1247.     }
  1248.  
  1249. /* -------------------------------------------------------------------- */
  1250. /* Undo the most recent half-move.                                        */
  1251. /* -------------------------------------------------------------------- */
  1252.  
  1253. static void Undo(void)
  1254. {
  1255.     short f, t;
  1256.  
  1257.     f = GameList[GameCnt].gmove >> 8;
  1258.     t = GameList[GameCnt].gmove & 0xFF;
  1259.     if ( board[t] == king && distance(t, f) > 1 )
  1260.         castle(GameList[GameCnt].color, f, t, 2);
  1261.     else {
  1262.         board[f] = board[t];
  1263.         color[f] = color[t];
  1264.         board[t] = GameList[GameCnt].piece;
  1265.         color[t] = GameList[GameCnt].color;
  1266.         if ( board[f] == king )
  1267.             --kingmoved[color[f]];
  1268.     }
  1269.     if ( TCflag )
  1270.         ++TimeControl.moves[color[f]];
  1271.     GameCnt--;
  1272.     mate    = false;
  1273.     Sdepth    = 0;
  1274.     UpdateDisplay(0, 0, 1, 0);
  1275.     InitializeStats();
  1276. }
  1277.  
  1278. void ShowMessage(char *s)
  1279. {
  1280.     ClearMessage();
  1281.     MyText(s, TX1 + 6, TY2 - 10);
  1282. }
  1283.  
  1284. void ClearMessage(void)
  1285. {
  1286.     MyText("                           ", TX1 + 6, TY2 - 10);
  1287. }
  1288.  
  1289. void ClrScreen(void)
  1290. {
  1291.     ClearMessage();
  1292. }
  1293.  
  1294. void ShowCurrentMove(short pnt, short f, short t)
  1295. {
  1296.     char buf[40];
  1297.  
  1298.     algbr(f, t, false);
  1299.     sprintf(buf, "(%2ld) %4s", pnt, mvstr1);
  1300.     MyText(buf, NX1 + 6, NY1 + 114);
  1301. }
  1302.  
  1303. void ShowSidetomove(void)
  1304. {
  1305. }
  1306.  
  1307. static void ChangeAlphaWindow(void)
  1308. {
  1309.     Awindow = NumberRequest("Alpha window size:", Awindow);
  1310. }
  1311.  
  1312. static void ChangeBetaWindow(void)
  1313. {
  1314.     Bwindow = NumberRequest("Beta window size:", Bwindow);
  1315. }
  1316.  
  1317. static void GiveHint(void)
  1318. {
  1319.     char s[40];
  1320.  
  1321.     algbr((short) (hint >> 8), (short) (hint & 0xFF), false);
  1322.     strcpy(s, "try ");
  1323.     strcat(s, mvstr1);
  1324.     ShowMessage(s);
  1325. }
  1326.  
  1327. static void ChangeSearchDepth(void)
  1328. {
  1329.     MaxSearchDepth = NumberRequest("Search depth:", MaxSearchDepth);
  1330. }
  1331.  
  1332. static void SetContempt(void)
  1333. {
  1334.     contempt = NumberRequest("Contempt value:", contempt);
  1335. }
  1336.  
  1337. static void ChangeXwindow(void)
  1338. {
  1339.     xwndw = NumberRequest("X window size:", xwndw);
  1340. }
  1341.  
  1342. void SelectLevel(void)
  1343. {
  1344.     OperatorTime    = 0;
  1345.     TCmoves            = 60;
  1346.     TCminutes        = 30;
  1347.     TCflag            = true;
  1348.     SetTimeControl();
  1349.     UpdateDisplay(0, 0, 1, 0);
  1350. }
  1351.  
  1352. static void ShowPostnValues(void)
  1353. {
  1354.     short i, r, c;
  1355.     char line[40];
  1356.  
  1357.     ExaminePosition();
  1358.     for ( i = 0; i < 64; i++ ) {
  1359.         if ( reverse ) {
  1360.             r = 7-row[i];
  1361.             c = 7-column[i];
  1362.         }
  1363.         else {
  1364.             r = row[i];
  1365.             c = column[i];
  1366.         }
  1367.         c1        = color[i];
  1368.         c2        = otherside[c1];
  1369.         PC1        = PawnCnt[c1];
  1370.         PC2        = PawnCnt[c2];
  1371.         atk1    = atak[c1];
  1372.         atk2    = atak[c2];
  1373.         if ( color[i] != neutral ) {
  1374.             sprintf(line, "%3ld", SqValue(i,opponent));
  1375.             MyText(line, XPOS(c)+FELDBREITE/2-15, YPOS(r)+FELDHOEHE/2+10);
  1376.         }
  1377.     }
  1378.     ScorePosition(opponent, &i);
  1379.     sprintf(line, "Score = %ld", i);
  1380.     ShowMessage(line);
  1381. }
  1382.  
  1383. static void DoDebug(void)
  1384. {
  1385.     short k, p, i, r, c, tp, tc;
  1386.     char s[40];
  1387.  
  1388.     ExaminePosition();
  1389.     strcpy(s, StringRequest("Enter piece:", ""));
  1390.     k = (s[0] == 'w') ? white : black;
  1391.     switch ( s[1] ) {
  1392.         case 'p':
  1393.             p = pawn;
  1394.             break;
  1395.         case 'n':
  1396.             p = knight;
  1397.             break;
  1398.         case 'b':
  1399.             p = bishop;
  1400.             break;
  1401.         case 'r':
  1402.             p = rook;
  1403.             break;
  1404.         case 'q':
  1405.             p = queen;
  1406.             break;
  1407.         case 'k':
  1408.             p = king;
  1409.             break;
  1410.         default:
  1411.             p = no_piece;
  1412.             break;
  1413.     }
  1414.     for ( i = 0; i < 64; i++ ) {
  1415.         if ( reverse ) {
  1416.             r = 7-row[i];
  1417.             c = 7-column[i];
  1418.         }
  1419.         else {
  1420.             r = row[i];
  1421.             c = column[i];
  1422.         }
  1423.         tp            = board[i];
  1424.         tc            = color[i];
  1425.         board[i]    = p;
  1426.         color[i]    = k;
  1427.         c1            = k;
  1428.         c2            = otherside[c1];
  1429.         PC1            = PawnCnt[c1];
  1430.         PC2            = PawnCnt[c2];
  1431.         atk1        = atak[c1];
  1432.         atk2        = atak[c2];
  1433.         sprintf(s, "%3ld", SqValue(i,opponent));
  1434.         MyText(s, XPOS(c)+FELDBREITE/2-15, YPOS(r)+FELDHOEHE/2+10);
  1435.         board[i]    = tp;
  1436.         color[i]    = tc;
  1437.     }
  1438.     ScorePosition(opponent, &i);
  1439.     sprintf(s, "Score = %ld", i);
  1440.     ShowMessage(s);
  1441. }
  1442.