home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 3.ddi / CHESS.ZIP / SMALL.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  9.5 KB  |  456 lines

  1. // ObjectWindows - (C) Copyright 1992 by Borland International
  2.  
  3. #include <windows.h>
  4. #include <time.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include "wcdefs.h"
  8. #include "wchess.h"
  9. #include "externs.h"
  10.  
  11. /*
  12.  *  Global Variables
  13.  */
  14.  
  15.  
  16. MOVETYPE ZeroMove = { 8, 8, 0, empty, empty };
  17. CLOCKTYPE ChessTime[2];
  18. MOVETYPE KeyMove;
  19. BOOL Running;
  20. COLORTYPE RunColor;
  21. BOOL Analysis, Opan;
  22. double WantedTime;
  23. extern double AverageTime;
  24. BOOL GameOver = FALSE;
  25. char EndGameMessage[80];
  26.  
  27.  
  28. void EndMessage(char *);
  29.  
  30. /*
  31.  *  Initialize the chess clocks
  32.  */
  33.  
  34. void InitChessTime()
  35. {
  36.    InitTime(&ChessTime[white]);
  37.    InitTime(&ChessTime[black]);
  38. }
  39.  
  40. void StopChessTime()
  41. {
  42.     if (Running)
  43.     {
  44.         StopTime(&ChessTime[RunColor]);
  45.         KillTimer(hWndMain, TIMEID);
  46.         Running = FALSE;
  47.     }
  48. }
  49.  
  50. /*
  51.  *  Stop the running chess clock and start the clock for color
  52.  */
  53.  
  54. void StartChessTime(COLORTYPE color)
  55. {
  56.     RunColor = color;
  57.     Running = TRUE;
  58.     StartTime(&ChessTime[RunColor]);
  59.     SetTimer(hWndMain, TIMEID, 1000, NULL);
  60. }
  61.  
  62. /*
  63.  *  reset MovTab
  64.  */
  65.  
  66. void ResetMoves()
  67. {
  68.    Depth = -1;
  69.    MovTab[-1] = ZeroMove;
  70. }
  71.  
  72.  
  73. /*
  74.  *  Clear HintLine
  75.  */
  76.  
  77. void ClearHint()
  78. {
  79.    HintLine[0] = ZeroMove;
  80.    HintEvalu = 0;
  81. }
  82.  
  83. void InitNode(NODEVAL *nodes)
  84. {
  85.    nodes->nodebase = 0;
  86.    nodes->nodeoffset = 0;
  87. }
  88.  
  89. /*
  90.  *  Test if the move is legal for Programcolor == player in the
  91.  *  given position
  92.  */
  93.  
  94. BOOL IllegalMove(MOVETYPE *move)
  95. {
  96.    BOOL illegal;
  97.  
  98.    Perform(move, 0);
  99.    illegal = Attacks(Opponent, PieceTab[Player][0].isquare);
  100.    Perform(move, 1);
  101.    return illegal;
  102. }
  103.  
  104.  
  105.  
  106. /*
  107.  *  Make move for programcolor = player and updates variables
  108.  */
  109.  
  110. void MakeMove(MOVETYPE *move)
  111. {
  112.     Depth++;
  113.     MoveNo++;
  114.     Perform(move, 0);
  115.     ProgramColor = Opponent;
  116.     Opponent = Player;
  117.     Player = ProgramColor;
  118. }
  119.  
  120.  
  121. /*
  122.  *  Prints comment to the game (check, mate, draw, resign)
  123.  */
  124.  
  125. void PrintComment(void)
  126. {
  127.    extern char buf[];
  128.     short check, possiblemove, checkmate;
  129.     int nummoves;
  130.  
  131.     Message("");
  132.     checkmate = 0;
  133.     Depth++;
  134.     possiblemove = 0;
  135.     InitMovGen();
  136.     do
  137.     {
  138.         MovGen();
  139.         if (Next.movpiece != empty)
  140.             if (!IllegalMove(&Next))
  141.                 possiblemove = 1;
  142.     } while (Next.movpiece != empty && !possiblemove);
  143.  
  144.     Depth--;
  145.     check = Attacks(Opponent, PieceTab[Player][0].isquare); /* calculate check */
  146.     /*  No possible move means checkmate or stalemate  */
  147.     if (!possiblemove)
  148.     {
  149.         if (check)
  150.         {
  151.             checkmate = 1;
  152.             EndMessage("CheckMate");
  153.         }
  154.         else
  155.             EndMessage("Stalemate!");
  156.     }
  157.     else
  158.         if (HintEvalu >= MATEVALUE - DEPTHFACTOR * 16)
  159.         {
  160.             nummoves = (MATEVALUE - HintEvalu + 0x40) / (DEPTHFACTOR * 2);
  161.             sprintf(buf, "Mate in %d Move%c", nummoves, (nummoves > 1) ? 's!':'!');
  162.             Message(buf);
  163.         }
  164.     if (check && !checkmate)
  165.         Message("Check!");
  166.     else  /*  test 50 move rule and repetition of moves  */
  167.       {
  168.       if (FiftyMoveCnt() >= 100)
  169.          {
  170.          EndMessage("50 Move rule");
  171.          }
  172.       else
  173.          if (Repetition(0) >= 3)
  174.          {
  175.             EndMessage("3 fold Repetition");
  176.          }
  177.          else                /*  Resign if the position is hopeless  */
  178.             if (-25500 < HintEvalu && HintEvalu < -0x880)
  179.                {
  180.                switch (Opponent)
  181.                   {
  182.                   case white :
  183.                      EndMessage(" White resigns");
  184.                      break;
  185.                   case black :
  186.                      EndMessage(" Black resigns");
  187.                   }
  188.                }
  189.       }
  190. }
  191.  
  192. void EnterMove(MOVETYPE *move)
  193. {
  194.    StopChessTime();
  195.    PrintMove(MoveNo, ProgramColor, move, ChessTime[RunColor].totaltime);
  196.    MakeMove(move);
  197.    UpdateBoard();
  198.    PrintComment();
  199.    StartChessTime(ProgramColor);
  200. }
  201.  
  202. void RemoveMove(MOVETYPE *move)
  203. {
  204.    StopChessTime();
  205.    PrintMove(MoveNo, ProgramColor, move, ChessTime[RunColor].totaltime);
  206.    TakeBackMove(move);
  207.    UpdateBoard();
  208.    PrintComment();
  209.    StartChessTime(ProgramColor);
  210. }
  211.  
  212. /*
  213.  *  perform the move entered by the user 
  214.  */
  215.  
  216. void EnterKeyMove(void)
  217. {
  218.     MovTab[Depth+1] = KeyMove;
  219.     PlayerMove = KeyMove;
  220.     ClearHint();
  221.     DragEnd(TRUE);
  222.     EnterMove(&MovTab[Depth+1]);
  223. }
  224.  
  225.  
  226. /*
  227.  *  move movtab to depth = -1
  228.  */
  229.  
  230. void AdjustMoves()
  231. {
  232.     int i;
  233.  
  234.     for (i = Depth; i>= BACK; i--)
  235.         MovTab[i - (Depth+1)] = MovTab[i];
  236.     Depth = -1;
  237. }
  238.  
  239.  
  240. /*
  241.  *  Move movtab one move BACK
  242.  */
  243.  
  244.  
  245. void StoreMoves(void)
  246. {
  247.     int i;
  248.     Depth--;
  249.     for (i = BACK; i <= Depth; i++)
  250.         MovTab[i] = MovTab[i+1];
  251.     MovTab[BACK] = ZeroMove;
  252. }
  253.     
  254.  
  255. /*
  256.  *  Check to see if the input move is legal
  257.  */
  258.                
  259. BOOL MoveCheck(SQUARETYPE startsq, SQUARETYPE endsq)
  260. {
  261.    Depth++;
  262.    KeyMove = ZeroMove;
  263.    InitMovGen();
  264.    do
  265.       {
  266.       MovGen();
  267.       if (Next.new1 == endsq && Next.old == startsq)
  268.          {
  269.          KeyMove = Next;
  270.          break;
  271.          }
  272.       } while (Next.movpiece != empty);
  273.    if (KeyMove.movpiece == empty)
  274.       {
  275.       Warning("Impossible move");
  276.       Depth--;
  277.       return FALSE;
  278.       }
  279.    if (IllegalMove(&KeyMove))
  280.       {
  281.       Warning("Illegal move. Check!");
  282.       Depth--;
  283.       return FALSE;
  284.       }
  285.    Depth--;
  286.    if (!ComputerThinking)
  287.       {
  288.       AdjustMoves();
  289.       EnterKeyMove();
  290.       StoreMoves();
  291.       }
  292.    return TRUE;
  293. }
  294.  
  295.  
  296. /*
  297.  *  calculate the WANTED response time
  298.  */
  299.  
  300. void StartAnalysis()
  301. {
  302.     int timecontrol;
  303.    extern HWND hWndMain;
  304.    extern HCURSOR hWaitCursor;
  305.  
  306.     Analysis = 1;
  307.     Opan = 0;
  308.     SetClassWord(hWndMain, GCW_HCURSOR, WORD(hWaitCursor));
  309.     SetCursor(hWaitCursor);   
  310.     switch (Level)
  311.     {
  312.         case easygame :
  313.         case normal :
  314.             /*  Divides the Time left till nest time control
  315.                 between moves left.  There is a margin of
  316.                 4 moves to make sure that the program does
  317.                 not lose on time  */
  318.             timecontrol = (((MoveNo >> 1) + 20) / 20) * 20;
  319.             if (timecontrol <= 40) timecontrol = 40;
  320.             WantedTime = (AverageTime * timecontrol -
  321.                     ChessTime[ProgramColor].totaltime) /
  322.                         (timecontrol + 4 - (MoveNo >> 1));
  323.  
  324.             /*  In the begining of the game the program thinks
  325.                 around twice as long, since the early middle
  326.                 game is normally the most crucial part of
  327.                 a game  */
  328.  
  329.             if ((MoveNo >> 1) <= 40)
  330.                 WantedTime = 5.0 + (WantedTime - 5.0) *
  331.                         ((80 - (MoveNo >> 1)) /40);
  332.             break;
  333.         case fullgametime :
  334.             /*  Assumes that the game will last for around 40 moves and
  335.                 divides the time left accordingly  */
  336.              WantedTime = (AverageTime * 60.0 -
  337.                     ChessTime[ProgramColor].totaltime) / 44;
  338.  
  339.             /*  In the begining of the game the program thinks
  340.                 around twice as long, since the early middle
  341.                 game is normally the most crucial part of
  342.                 a game  */
  343.             if ((MoveNo >> 1) <= 40)
  344.                 WantedTime = 5.0 + (WantedTime - 5.0) *
  345.                         ((80 - (MoveNo >> 1)) /40);
  346.             break;
  347.         case matching :
  348.             /*  Spend as much time as the Opponent does  */
  349.             if (MoveNo >= 2)
  350.                 WantedTime = ChessTime[Opponent].totaltime / (MoveNo >> 1);
  351.             else
  352.                 WantedTime = 5.0;
  353.             WantedTime += (ChessTime[Opponent].totaltime -
  354.                         ChessTime[ProgramColor].totaltime) * 0.25;
  355.         default :
  356.             WantedTime = 1000000.0;
  357.     }
  358. }
  359.  
  360.  
  361. /*
  362.  *  take BACK move and update variables
  363.  */
  364.  
  365. void TakeBackMove(MOVETYPE *move)
  366. {
  367.     ProgramColor = Opponent;
  368.     Opponent = Player;
  369.     Player = ProgramColor;
  370.     Perform(move, 1);
  371.     MoveNo--;
  372.     Depth--;
  373. }
  374.  
  375.  
  376. void IncNode(NODEVAL *nodes)
  377. {
  378.     if (nodes->nodeoffset >= MAXINT)
  379.     {
  380.         nodes->nodebase++;
  381.         nodes->nodeoffset = 0;
  382.     }
  383.     else
  384.         nodes->nodeoffset++;
  385. }
  386.  
  387.  
  388. void Wait(int tenths)
  389. {
  390.     clock_t NumTicksToWait;
  391.  
  392.     /* two ticks == approx. 1/10 second, since 18.2 clocks is approx a
  393.        second */
  394.     NumTicksToWait = (tenths * 2) + clock();
  395.     while (NumTicksToWait > clock()) ;
  396. }
  397.  
  398.  
  399. /*
  400.  *  Flash a move once on the screen
  401.  */
  402.  
  403. void FlashMove(MOVETYPE *move)
  404. {
  405.     MakeMove(move);
  406.     UpdateBoard();
  407.     Wait(4);
  408.     TakeBackMove(move);
  409.     UpdateBoard();
  410.     Wait(4);
  411. }
  412.  
  413. void DoSlideMove(MOVETYPE &move)
  414. {
  415.    SQUARETYPE castsquare, cornersquare;
  416.    SlidePiece(move.new1, move.old);
  417.    if (move.spe)
  418.    {
  419.        if (move.movpiece == king)
  420.        {
  421.            GenCastSquare(move.new1, &castsquare, &cornersquare);
  422.            SlidePiece(castsquare, cornersquare);
  423.        }
  424.    }
  425. }
  426.  
  427. void EndMessage(char *message)
  428. {
  429.    strcpy(EndGameMessage, message);
  430.    GameOver = TRUE;
  431. }
  432.  
  433.  
  434. void ShowHint()
  435. {
  436.     DEPTHTYPE dep = 0;
  437.     buf[0] = '\0';
  438.     Message(buf);
  439.     while (HintLine[dep].movpiece != empty)
  440.     {
  441.         strcat(buf, MoveStr(&HintLine[dep]));
  442.         strcat(buf, " ");
  443.         Message(buf);
  444.         MakeMove(&HintLine[dep]);
  445.         UpdateBoard();
  446.         Wait(6);
  447.         dep++;
  448.     }
  449.     while (dep > 0)
  450.     {
  451.         dep--;
  452.         TakeBackMove(&HintLine[dep]);
  453.     }
  454.     UpdateBoard();
  455. }
  456.