home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume10 / xboard / part03 < prev    next >
Internet Message Format  |  1990-12-17  |  40KB

  1. Path: uunet!lll-winken!sun-barr!newstop!exodus!decwrl.dec.com
  2. From: sears@decwrl.dec.com (Chris Sears)
  3. Newsgroups: comp.sources.x
  4. Subject: v10i063: xboard, Part03/03
  5. Message-ID: <4697@exodus.Eng.Sun.COM>
  6. Date: 18 Dec 90 02:06:51 GMT
  7. References: <csx-10i061:xboard@uunet.UU.NET>
  8. Sender: news@exodus.Eng.Sun.COM
  9. Lines: 1463
  10. Approved: argv@sun.com
  11.  
  12. Submitted-by: sears@decwrl.dec.com (Chris Sears)
  13. Posting-number: Volume 10, Issue 63
  14. Archive-name: xboard/part03
  15.  
  16. X    }
  17. X}
  18. X
  19. X/*
  20. X * MakeMove() executes moves after they have been checked by GNU Chess.
  21. X */
  22. Xvoid
  23. XMakeMove(move_type, from_x, from_y, to_x, to_y)
  24. X    int *move_type, from_x, from_y, to_x, to_y;
  25. X{
  26. X    if (gameMode != PlayFromGameFile)
  27. X        DisplayTimers(SwitchTimers);
  28. X    CopyBoard(boards[currentMove + 1], boards[currentMove]);
  29. X    forwardMostMove = ++currentMove;
  30. X
  31. X    if (from_y == 0 && from_x == 4                /* white king-side castle */
  32. X            && boards[currentMove][from_y][from_x] == WhiteKing
  33. X            && to_y == 0 && to_x == 6) {
  34. X        *move_type = WhiteKingSideCastle;
  35. X        boards[currentMove][0][7] = EmptySquare;
  36. X        boards[currentMove][0][6] = WhiteKing;
  37. X        boards[currentMove][0][5] = WhiteRook;
  38. X        boards[currentMove][0][4] = EmptySquare;
  39. X        DrawSquare(0, 7, boards[currentMove][0][7]);
  40. X        DrawSquare(0, 6, boards[currentMove][0][6]);
  41. X        DrawSquare(0, 5, boards[currentMove][0][5]);
  42. X        DrawSquare(0, 4, boards[currentMove][0][4]);
  43. X    } else if (from_y == 0 && from_x == 4        /* white queen-side castle */
  44. X            && boards[currentMove][from_y][from_x] == WhiteKing
  45. X            && to_y == 0 && to_x == 2) {
  46. X        *move_type = WhiteQueenSideCastle;
  47. X        boards[currentMove][0][0] = EmptySquare;
  48. X        boards[currentMove][0][2] = WhiteKing;
  49. X        boards[currentMove][0][3] = WhiteRook;
  50. X        boards[currentMove][0][4] = EmptySquare;
  51. X        DrawSquare(0, 0, boards[currentMove][0][0]);
  52. X        DrawSquare(0, 2, boards[currentMove][0][2]);
  53. X        DrawSquare(0, 3, boards[currentMove][0][3]);
  54. X        DrawSquare(0, 4, boards[currentMove][0][4]);
  55. X    } else if (from_y == 6                        /* white pawn promotion */
  56. X            && boards[currentMove][from_y][from_x] == WhitePawn && to_y == 7) {
  57. X        *move_type = WhitePromotion;
  58. X        boards[currentMove][6][from_x] = EmptySquare;
  59. X        boards[currentMove][7][to_x] = WhiteQueen;
  60. X        DrawSquare(6, from_x, boards[currentMove][6][from_x]);
  61. X        DrawSquare(7, to_x, boards[currentMove][7][to_x]);
  62. X    } else if ((from_y == 4)                    /* white captures en passant */
  63. X            && (to_x != from_x)
  64. X            && (boards[currentMove][from_y][from_x] == WhitePawn)
  65. X            && (boards[currentMove][to_y][to_x] == EmptySquare)) {
  66. X        *move_type = WhiteCapturesEnPassant;
  67. X        boards[currentMove][from_y][from_x] = EmptySquare;
  68. X        boards[currentMove][to_y][to_x] = WhitePawn;
  69. X        boards[currentMove][to_y - 1][to_x] = EmptySquare;
  70. X        DrawSquare(from_y, from_x, boards[currentMove][from_y][from_x]);
  71. X        DrawSquare(to_y, to_x, boards[currentMove][to_y][to_x]);
  72. X        DrawSquare(to_y - 1, to_x, boards[currentMove][to_y - 1][to_x]);
  73. X    } else if (from_y == 7 && from_x == 4        /* black king-side castle */
  74. X            && boards[currentMove][from_y][from_x] == BlackKing
  75. X            && to_y == 7 && to_x == 6) {
  76. X        *move_type = BlackKingSideCastle;
  77. X        boards[currentMove][7][4] = EmptySquare;
  78. X        boards[currentMove][7][5] = BlackRook;
  79. X        boards[currentMove][7][6] = BlackKing;
  80. X        boards[currentMove][7][7] = EmptySquare;
  81. X        DrawSquare(7, 7, boards[currentMove][7][7]);
  82. X        DrawSquare(7, 6, boards[currentMove][7][6]);
  83. X        DrawSquare(7, 5, boards[currentMove][7][5]);
  84. X        DrawSquare(7, 4, boards[currentMove][7][4]);
  85. X    } else if (from_y == 7 && from_x == 4        /* black queen-side castle */
  86. X            && boards[currentMove][from_y][from_x] == BlackKing
  87. X            && to_y == 7 && to_x == 2) {
  88. X        *move_type = BlackQueenSideCastle;
  89. X        boards[currentMove][7][0] = EmptySquare;
  90. X        boards[currentMove][7][2] = BlackKing;
  91. X        boards[currentMove][7][3] = BlackRook;
  92. X        boards[currentMove][7][4] = EmptySquare;
  93. X        DrawSquare(7, 0, boards[currentMove][7][0]);
  94. X        DrawSquare(7, 2, boards[currentMove][7][2]);
  95. X        DrawSquare(7, 3, boards[currentMove][7][3]);
  96. X        DrawSquare(7, 4, boards[currentMove][7][4]);
  97. X    } else if (from_y == 1                        /* black pawn promotion */
  98. X            && boards[currentMove][from_y][from_x] == BlackPawn && to_y == 0) {
  99. X        *move_type = BlackPromotion;
  100. X        boards[currentMove][1][from_x] = EmptySquare;
  101. X        boards[currentMove][0][to_x] = BlackQueen;
  102. X        DrawSquare(1, from_x, boards[currentMove][1][from_x]);
  103. X        DrawSquare(0, to_x, boards[currentMove][0][to_x]);
  104. X    } else if ((from_y == 3)                    /* black captures en passant */
  105. X            && (to_x != from_x)
  106. X            && (boards[currentMove][from_y][from_x] == BlackPawn)
  107. X            && (boards[currentMove][to_y][to_x] == EmptySquare)) {
  108. X        *move_type = BlackCapturesEnPassant;
  109. X        boards[currentMove][from_y][from_x] = EmptySquare;
  110. X        boards[currentMove][to_y][to_x] = BlackPawn;
  111. X        boards[currentMove][to_y + 1][to_x] = EmptySquare;
  112. X        DrawSquare(from_y, from_x, boards[currentMove][from_y][from_x]);
  113. X        DrawSquare(to_y, to_x, boards[currentMove][to_y][to_x]);
  114. X        DrawSquare(to_y + 1, to_x, boards[currentMove][to_y + 1][to_x]);
  115. X    } else {
  116. X        *move_type = NormalMove;
  117. X        boards[currentMove][to_y][to_x] = boards[currentMove][from_y][from_x];
  118. X        boards[currentMove][from_y][from_x] = EmptySquare;
  119. X        DrawSquare(to_y, to_x, boards[currentMove][to_y][to_x]);
  120. X        DrawSquare(from_y, from_x, boards[currentMove][from_y][from_x]);
  121. X    }
  122. X
  123. X    XSync(xDisplay, False);
  124. X}
  125. X
  126. Xvoid
  127. XInitPosition()
  128. X{
  129. X    currentMove = forwardMostMove = 0;
  130. X    CopyBoard(boards[0], initialPosition);
  131. X    DrawPosition(boardWidget, NULL);
  132. X}
  133. X
  134. Xvoid
  135. XCopyBoard(to, from)
  136. X    Board to, from;
  137. X{
  138. X    int i, j;
  139. X
  140. X    for (i = 0; i < BOARD_SIZE; i++)
  141. X        for (j = 0; j < BOARD_SIZE; j++)
  142. X            to[i][j] = from[i][j];
  143. X}
  144. X
  145. X/*
  146. X * event handler for updating board state
  147. X */
  148. Xvoid
  149. XDrawPosition(w, event)
  150. X    Widget w;
  151. X    XExposeEvent *event;
  152. X{
  153. X    int i, j;
  154. X
  155. X    /*
  156. X     * It would be simpler to clear the window or fill a rectangle,
  157. X     * but that causes a very distracting flicker.
  158. X     */
  159. X    XDrawSegments(xDisplay, xBoardWindow, lineGC,
  160. X        gridSegments, (BOARD_SIZE + 1) * 2);
  161. X
  162. X    for (i = 0; i < BOARD_SIZE; i++)
  163. X        for (j = 0; j < BOARD_SIZE; j++)
  164. X            DrawSquare(i, j, boards[currentMove][i][j]);
  165. X
  166. X    XSync(xDisplay, False);
  167. X}
  168. X
  169. X/*
  170. X * event handler for parsing user moves
  171. X * TODO: ignore a ButtonRelease without a valid corresponding ButtonPress.
  172. X */
  173. Xvoid
  174. XHandleUserMove(w, event)
  175. X    Widget w;
  176. X    XEvent *event;
  177. X{
  178. X    static int from_x, from_y;
  179. X    int move_type, to_x, to_y;
  180. X    char user_move[MSG_SIZ];
  181. X
  182. X    if ((gameMode == PlayFromGameFile) || (gameMode == PauseGame))
  183. X        return;
  184. X
  185. X    DisplayMessage("");
  186. X
  187. X    switch (event->type) {
  188. X    case ButtonPress:
  189. X        if ((from_x = EventToOrdinal(event->xbutton.x)) < 0)
  190. X            break;
  191. X        if ((from_y = EventToOrdinal(event->xbutton.y)) < 0)
  192. X            break;
  193. X        if (flipView)
  194. X            from_x = BOARD_SIZE - 1 - from_x;
  195. X        else
  196. X            from_y = BOARD_SIZE - 1 - from_y;
  197. X        break;
  198. X    case ButtonRelease:
  199. X        if ((to_x = EventToOrdinal(event->xbutton.x)) < 0)
  200. X            break;
  201. X        if ((to_y = EventToOrdinal(event->xbutton.y)) < 0)
  202. X            break;
  203. X        if (flipView)
  204. X            to_x = BOARD_SIZE - 1 - to_x;
  205. X        else
  206. X            to_y = BOARD_SIZE - 1 - to_y;
  207. X
  208. X        MakeMove(&move_type, from_x, from_y, to_x, to_y);
  209. X
  210. X        switch (move_type) {
  211. X        case WhitePromotion:
  212. X        case BlackPromotion:    /* GNU Chess limitation of only Q promotion */
  213. X            sprintf(user_move, "%c%c%c%c(Q)\n", /* GNU Chess limitation */
  214. X                'a' + from_x, '1' + from_y, 'a' + to_x, '1' + to_y);
  215. X            break;
  216. X        case NormalMove:
  217. X        case WhiteKingSideCastle:
  218. X        case WhiteQueenSideCastle:
  219. X        case WhiteCapturesEnPassant:
  220. X        case BlackKingSideCastle:
  221. X        case BlackQueenSideCastle:
  222. X        case BlackCapturesEnPassant:
  223. X            sprintf(user_move, "%c%c%c%c\n",
  224. X                'a' + from_x, '1' + from_y, 'a' + to_x, '1' + to_y);
  225. X            break;
  226. X        }
  227. X
  228. X        SendToProgram(user_move, toFirstProgFP);
  229. X        strcpy(moveList[currentMove - 1], user_move);
  230. X
  231. X        switch (gameMode) {
  232. X        case ForceMoves:
  233. X            forwardForce = False;
  234. X            break;
  235. X        case PlayFromGameFile:
  236. X            SendToProgram("black\n", toFirstProgFP);
  237. X        case BeginningOfGame:
  238. X        case SetupPosition:
  239. X            gameMode = MachinePlaysBlack;
  240. X        default:
  241. X            break;
  242. X        }
  243. X        break;
  244. X    }
  245. X}
  246. X
  247. Xvoid
  248. XHandleMachineMove(message)
  249. X    char *message;
  250. X{
  251. X    int i, j, move_type, from_x, from_y, to_x, to_y;
  252. X    char machine_move[MSG_SIZ], tmp_move[MSG_SIZ], buf1[MSG_SIZ], buf2[MSG_SIZ];
  253. X
  254. X    /*
  255. X     * If the move is illegal, cancel it and redraw the board.
  256. X     */
  257. X    if (strstr(message, "Illegal move") != NULL) {
  258. X        if (gameMode == PlayFromGameFile)
  259. X            gameMode = BeginningOfGame;
  260. X        else {
  261. X            currentMove--;
  262. X            DisplayTimers(SwitchTimers);
  263. X        }
  264. X        DisplayMessage(message);
  265. X
  266. X        for (i = 0; i < BOARD_SIZE; i++)
  267. X            for (j = 0; j < BOARD_SIZE; j++)
  268. X                if (boards[currentMove][i][j] != boards[currentMove + 1][i][j])
  269. X                    DrawSquare(i, j, boards[currentMove][i][j]);
  270. X
  271. X        XSync(xDisplay, False);
  272. X        return;
  273. X    }
  274. X
  275. X    if (strstr(message, "Hint:") != NULL) {
  276. X        DisplayMessage(message);
  277. X        return;
  278. X    }
  279. X
  280. X    /*
  281. X     * win, lose or draw
  282. X     */
  283. X    if (strstr(message, "White") != NULL)
  284. X        EndOfGameProc("White wins");
  285. X    else if (strstr(message, "Black") != NULL)
  286. X        EndOfGameProc("Black wins");
  287. X    else if (strstr(message, "Draw") != NULL)
  288. X        EndOfGameProc("Draw");
  289. X
  290. X    /*
  291. X     * normal move
  292. X     */
  293. X    if (strstr(message, "...") != NULL) {
  294. X        bzero(machine_move, MSG_SIZ);
  295. X        sscanf(message, "%s %s %s", buf1, buf2, machine_move);
  296. X        if (strlen(machine_move) == 0)
  297. X            return;
  298. X    } else
  299. X        return; /* ignore noise */
  300. X
  301. X    strcpy(moveList[currentMove], machine_move);
  302. X
  303. X    from_x = machine_move[0] - 'a';
  304. X    from_y = machine_move[1] - '1';
  305. X    to_x = machine_move[2] - 'a';
  306. X    to_y = machine_move[3] - '1';
  307. X
  308. X    MakeMove(&move_type, from_x, from_y, to_x, to_y);
  309. X
  310. X    switch (gameMode) {
  311. X    case EndOfGame:
  312. X    case SetupPosition:
  313. X        break;
  314. X    case ForceMoves:
  315. X    case PlayFromGameFile:
  316. X        strcpy(tmp_move, machine_move);
  317. X        strcat(tmp_move, "\n");
  318. X        SendToProgram(tmp_move, toFirstProgFP);
  319. X        break;
  320. X    case TwoMachinesPlay:
  321. X        strcpy(tmp_move, machine_move);
  322. X        strcat(tmp_move, "\n");
  323. X
  324. X        if (currentMove % 2)
  325. X            SendToProgram(tmp_move, toFirstProgFP);
  326. X        else
  327. X            SendToProgram(tmp_move, toSecondProgFP);
  328. X
  329. X        /*
  330. X         * need white's move before sending "black" to first program
  331. X         */
  332. X        if (firstMove) {
  333. X            firstMove = False;
  334. X            SendToProgram("black\n", toFirstProgFP);
  335. X        }
  336. X        break;
  337. X    }
  338. X}
  339. X
  340. XXtCallbackProc
  341. XSelectCommand(w, client_data, call_data)
  342. X    Widget w;
  343. X    XtPointer client_data;
  344. X    XtPointer call_data;
  345. X{
  346. X    XawListReturnStruct *list_return;
  347. X
  348. X    list_return = XawListShowCurrent(w);
  349. X
  350. X    switch (list_return->list_index) {
  351. X    case ButtonQuit:
  352. X        EndOfGameProc("Quitting");
  353. X        QuitProc();
  354. X        break;
  355. X    case ButtonBackward:
  356. X        BackwardProc();
  357. X        break;
  358. X    case ButtonForward:
  359. X        ForwardProc();
  360. X        break;
  361. X    case ButtonFlip:
  362. X        FlipProc();
  363. X        break;
  364. X    case ButtonReset:
  365. X        ResetProc();
  366. X        break;
  367. X    case ButtonSaveGame:
  368. X        SaveGameProc();
  369. X        break;
  370. X    case ButtonSavePosition:
  371. X        SavePositionProc();
  372. X        break;
  373. X    case ButtonHint:
  374. X        HintProc();
  375. X        break;
  376. X    case ButtonSwitch:
  377. X        SwitchProc();
  378. X        break;
  379. X    case ButtonSetupFromFile:
  380. X        SetupPositionFromFileProc();
  381. X        break;
  382. X    case ButtonPlayFromFile:
  383. X        PlayFromGameFileProc();
  384. X        break;
  385. X    case ButtonMachinePlaysBlack:
  386. X        MachinePlaysBlackProc();
  387. X        break;
  388. X    case ButtonMachinePlaysWhite:
  389. X        MachinePlaysWhiteProc();
  390. X        break;
  391. X    case ButtonTwoMachinesPlay:
  392. X        TwoMachinesPlayProc();
  393. X        break;
  394. X    case ButtonForce:
  395. X        ForceProc();
  396. X        break;
  397. X    case ButtonPause:
  398. X        PauseProc();
  399. X        break;
  400. X    }
  401. X
  402. X    XawListUnhighlight(w);
  403. X}
  404. X
  405. Xvoid
  406. XEndOfGameProc(message)
  407. X    char *message;
  408. X{
  409. X    DisplayMessage(message);
  410. X
  411. X    if (firstProgPID != 0) {
  412. X        fclose(fromFirstProgFP);
  413. X        fclose(toFirstProgFP);
  414. X        fromFirstProgFP = toFirstProgFP = NULL;
  415. X        kill(firstProgPID, SIGTERM);
  416. X    }
  417. X    if (secondProgPID != 0) {
  418. X        fclose(fromSecondProgFP);
  419. X        fclose(toSecondProgFP);
  420. X        fromSecondProgFP = toSecondProgFP = NULL;
  421. X        kill(secondProgPID, SIGTERM);
  422. X    }
  423. X    if (firstProgXID != 0)
  424. X        XtRemoveInput(firstProgXID);
  425. X    if (secondProgXID != 0)
  426. X        XtRemoveInput(secondProgXID);
  427. X    firstProgXID = secondProgXID = NULL;
  428. X
  429. X    if (appData.matchMode != MatchFalse) {
  430. X        SaveGameProc();
  431. X        SavePositionProc();
  432. X        QuitProc();
  433. X    } else
  434. X        DisplayTimers(StopTimers);
  435. X}
  436. X
  437. Xvoid
  438. XQuitProc()
  439. X{
  440. X    XFreePixmap(xDisplay, solidRookBitmap);
  441. X    XFreePixmap(xDisplay, solidKnightBitmap);
  442. X    XFreePixmap(xDisplay, solidBishopBitmap);
  443. X    XFreePixmap(xDisplay, solidQueenBitmap);
  444. X    XFreePixmap(xDisplay, solidKingBitmap);
  445. X    XFreePixmap(xDisplay, solidPawnBitmap);
  446. X
  447. X    XFreeGC(xDisplay, lightSquareGC);
  448. X    XFreeGC(xDisplay, darkSquareGC);
  449. X    XFreeGC(xDisplay, lineGC);
  450. X
  451. X    if (appData.monoMode) {
  452. X        XFreePixmap(xDisplay, outlinePawnBitmap);
  453. X        XFreePixmap(xDisplay, outlineRookBitmap);
  454. X        XFreePixmap(xDisplay, outlineKnightBitmap);
  455. X        XFreePixmap(xDisplay, outlineBishopBitmap);
  456. X        XFreePixmap(xDisplay, outlineQueenBitmap);
  457. X        XFreePixmap(xDisplay, outlineKingBitmap);
  458. X
  459. X        XFreeGC(xDisplay, wbPieceGC);
  460. X        XFreeGC(xDisplay, wwPieceGC);
  461. X        XFreeGC(xDisplay, bbPieceGC);
  462. X        XFreeGC(xDisplay, bwPieceGC);
  463. X    } else {
  464. X        XFreeGC(xDisplay, wdPieceGC);
  465. X        XFreeGC(xDisplay, wlPieceGC);
  466. X        XFreeGC(xDisplay, bdPieceGC);
  467. X        XFreeGC(xDisplay, blPieceGC);
  468. X    }
  469. X
  470. X    XtDestroyApplicationContext(XtWidgetToApplicationContext(shellWidget));
  471. X    exit(0);
  472. X}
  473. X
  474. Xvoid
  475. XBackwardProc()
  476. X{
  477. X    int i, j;
  478. X
  479. X    if ((gameMode == PlayFromGameFile) || (currentMove <= 0))
  480. X        return;
  481. X
  482. X    SendToProgram("undo\n", toFirstProgFP);
  483. X    currentMove--;
  484. X
  485. X    for (i = 0; i < BOARD_SIZE; i++)
  486. X        for (j = 0; j < BOARD_SIZE; j++)
  487. X            if (boards[currentMove][i][j] != boards[currentMove + 1][i][j])
  488. X                DrawSquare(i, j, boards[currentMove][i][j]);
  489. X}
  490. X
  491. Xvoid
  492. XForwardProc()
  493. X{
  494. X    char buf[MSG_SIZ];
  495. X    int i, j;
  496. X
  497. X    if ((gameMode == PlayFromGameFile)
  498. X            || ((currentMove == 0) && (forwardMostMove == 0))
  499. X            || (currentMove >= forwardMostMove))
  500. X        return;
  501. X
  502. X    if (forwardForce == False) {
  503. X        forwardForce = True;
  504. X        SendToProgram("force\n", toFirstProgFP);
  505. X    }
  506. X
  507. X    if (currentMove <= forwardMostMove)
  508. X        for (i = 0; i < BOARD_SIZE; i++)
  509. X            for (j = 0; j < BOARD_SIZE; j++)
  510. X                if (boards[currentMove + 1][i][j] != boards[currentMove][i][j])
  511. X                    DrawSquare(i, j, boards[currentMove + 1][i][j]);
  512. X
  513. X    strcpy(moveList[currentMove++], buf);
  514. X    strcat(buf, "\n");
  515. X    SendToProgram(buf, toFirstProgFP);
  516. X}
  517. X
  518. Xvoid
  519. XFlipProc()
  520. X{
  521. X    flipView = !flipView;
  522. X    DrawPosition(boardWidget, NULL);
  523. X}
  524. X
  525. Xvoid
  526. XResetProc()
  527. X{
  528. X    gameMode = BeginningOfGame;
  529. X    flipView = forwardForce = False;
  530. X    wCount = bCount = currentMove = forwardMostMove = 0;
  531. X    firstMove = True;
  532. X
  533. X    EndOfGameProc("Resetting");
  534. X    InitPosition();
  535. X    InitChessProgram();
  536. X    DisplayMessage("");
  537. X    DisplayTimers(ResetTimers);
  538. X    if (readGameXID != NULL) {
  539. X        XtRemoveTimeOut(readGameXID);
  540. X        readGameXID = NULL;
  541. X    }
  542. X
  543. X    /*
  544. X     * Initialize GNU Chess.
  545. X     * "beep" prevents GNU Chess from sending a ^G.
  546. X     *
  547. X     * ResetProc() only resets toFirstProgFP
  548. X     * since toSecondProgFP is reset in TwoMachinesProc()
  549. X     */
  550. X    SendToProgram(appData.initString, toFirstProgFP);
  551. X}
  552. X
  553. Xvoid
  554. XSaveGameProc()
  555. X{
  556. X    time_t tm;
  557. X    int i = 0, move = 1;
  558. X    char buf[MSG_SIZ], host_name[MSG_SIZ],
  559. X        white_move[MSG_SIZ], black_move[MSG_SIZ];
  560. X    FILE *game_file_fp;
  561. X
  562. X    if (!(game_file_fp = fopen(appData.saveGameFile, "w"))) {
  563. X        sprintf(buf, "Can't open %s", appData.saveGameFile);
  564. X        DisplayMessage(buf);
  565. X        return;
  566. X    }
  567. X
  568. X    tm = time((time_t *) NULL);
  569. X    gethostname(host_name, MSG_SIZ);
  570. X
  571. X    fprintf(game_file_fp, "xboard game file -- %s", ctime(&tm));
  572. X    switch (gameMode) {
  573. X    case MachinePlaysWhite:
  574. X        fprintf(game_file_fp, "\t%s@%s vs. %s@%s\n",
  575. X            appData.firstChessProgram, appData.firstHost,
  576. X            getlogin(), host_name);
  577. X        break;
  578. X    case MachinePlaysBlack:
  579. X        fprintf(game_file_fp, "\t%s@%s vs. %s@%s\n",
  580. X            getlogin(), host_name,
  581. X            appData.firstChessProgram, appData.firstHost);
  582. X        break;
  583. X    case TwoMachinesPlay:
  584. X        fprintf(game_file_fp, "\t%s@%s vs. %s@%s\n",
  585. X            appData.secondChessProgram, appData.secondHost,
  586. X            appData.firstChessProgram, appData.firstHost);
  587. X        break;
  588. X    default:
  589. X        fprintf(game_file_fp, "\n");
  590. X        break;
  591. X    }
  592. X    fprintf(game_file_fp, "\talgebraic\n");
  593. X
  594. X    while (True) {
  595. X        if (strlen(moveList[i]) == 0)
  596. X            break;
  597. X        /*
  598. X         * get rid of '\n' added to send the move to GNU Chess
  599. X         */
  600. X        strcpy(white_move, moveList[i++]);
  601. X        if (white_move[strlen(white_move) - 1] == '\n')
  602. X            white_move[strlen(white_move) - 1] = NULL;
  603. X        fprintf(game_file_fp, "%d. %s ", move++, white_move);
  604. X
  605. X        if (strlen(moveList[i]) == 0) {
  606. X            fprintf(game_file_fp, "\n");
  607. X            break;
  608. X        }
  609. X        strcpy(black_move, moveList[i++]);
  610. X        if (black_move[strlen(black_move) - 1] == '\n')
  611. X            black_move[strlen(black_move) - 1] = NULL;
  612. X        fprintf(game_file_fp, "%s\n", black_move);
  613. X    }
  614. X    fclose(game_file_fp);
  615. X}
  616. X
  617. Xvoid
  618. XSavePositionProc()
  619. X{
  620. X    time_t tm;
  621. X    int i, j;
  622. X    char buf[MSG_SIZ], host_name[MSG_SIZ];
  623. X    FILE *position_file_fp;
  624. X
  625. X    if (!(position_file_fp = fopen(appData.savePositionFile, "w"))) {
  626. X        sprintf(buf, "Can't open %s", appData.savePositionFile);
  627. X        DisplayMessage(buf);
  628. X        return;
  629. X    }
  630. X
  631. X    tm = time((time_t *) NULL);
  632. X    gethostname(host_name, MSG_SIZ);
  633. X
  634. X    fprintf(position_file_fp, "xboard position file -- %s", ctime(&tm));
  635. X    switch (gameMode) {
  636. X    case MachinePlaysWhite:
  637. X        fprintf(position_file_fp, "\t%s@%s vs. %s@%s\n",
  638. X            appData.firstChessProgram, appData.firstHost,
  639. X            getlogin(), host_name);
  640. X        break;
  641. X    case MachinePlaysBlack:
  642. X        fprintf(position_file_fp, "\t%s@%s vs. %s@%s\n",
  643. X            getlogin(), host_name,
  644. X            appData.firstChessProgram, appData.firstHost);
  645. X        break;
  646. X    case TwoMachinesPlay:
  647. X        fprintf(position_file_fp, "\t%s@%s vs. %s@%s\n",
  648. X            appData.secondChessProgram, appData.secondHost,
  649. X            appData.firstChessProgram, appData.firstHost);
  650. X        break;
  651. X    default:
  652. X        fprintf(position_file_fp, "\n");
  653. X        break;
  654. X    }
  655. X    fprintf(position_file_fp, "\n");
  656. X
  657. X    for (i = BOARD_SIZE - 1; i >= 0; i--) {
  658. X        for (j = 0; j < BOARD_SIZE; j++) {
  659. X            fprintf(position_file_fp, "%s",
  660. X                pieceToString[boards[currentMove][i][j]]);
  661. X            if (j == BOARD_SIZE - 1)
  662. X                fprintf(position_file_fp, "\n");
  663. X            else
  664. X                fprintf(position_file_fp, " ");
  665. X        }
  666. X    }
  667. X
  668. X    fclose(position_file_fp);
  669. X}
  670. X
  671. Xvoid
  672. XHintProc()
  673. X{
  674. X    if (gameMode == PlayFromGameFile)
  675. X        return;
  676. X    SendToProgram("hint\n", toFirstProgFP);
  677. X}
  678. X
  679. Xvoid
  680. XSwitchProc()
  681. X{
  682. X    switch (gameMode) {
  683. X    default:
  684. X        return;
  685. X    case MachinePlaysWhite:
  686. X        gameMode = MachinePlaysBlack;
  687. X        break;
  688. X    case MachinePlaysBlack:
  689. X        gameMode = MachinePlaysWhite;
  690. X        break;
  691. X    }
  692. X
  693. X    SendToProgram("switch\n", toFirstProgFP);
  694. X}
  695. X
  696. Xvoid
  697. XSetupPositionFromFileProc()
  698. X{
  699. X    int i, j;
  700. X    char c, *p, line[MSG_SIZ], buf[MSG_SIZ];
  701. X    Board initial_position;
  702. X    FILE *position_file_fp;
  703. X
  704. X    if (gameMode == PlayFromGameFile)
  705. X        return;
  706. X
  707. X    gameMode = SetupPosition;
  708. X    currentMove = forwardMostMove = 0;
  709. X
  710. X    if (!(position_file_fp = fopen(appData.readPositionFile, "r"))) {
  711. X        sprintf(buf, "Can't open %s", appData.readPositionFile);
  712. X        DisplayMessage(buf);
  713. X        return;
  714. X    }
  715. X
  716. X    /*
  717. X     * skip header information in position file
  718. X     */
  719. X    fgets(line, MSG_SIZ, position_file_fp);
  720. X    fgets(line, MSG_SIZ, position_file_fp);
  721. X    fgets(line, MSG_SIZ, position_file_fp);
  722. X
  723. X    for (i = BOARD_SIZE - 1; i >= 0; i--) {
  724. X        fgets(line, MSG_SIZ, position_file_fp);
  725. X        p = line;
  726. X        for (j = 0; j < BOARD_SIZE; p++) {
  727. X            if ((c = *p) == ' ')
  728. X                continue;
  729. X            switch (c) {
  730. X            case 'p':
  731. X                sprintf(blackPieces[bCount++],
  732. X                    "P%c%c", 'a' + j, '1' + i);
  733. X                initial_position[i][j] = BlackPawn;
  734. X                break;
  735. X            case 'r':
  736. X                sprintf(blackPieces[bCount++],
  737. X                    "R%c%c", 'a' + j, '1' + i);
  738. X                initial_position[i][j] = BlackRook;
  739. X                break;
  740. X            case 'n':
  741. X                sprintf(blackPieces[bCount++],
  742. X                    "N%c%c", 'a' + j, '1' + i);
  743. X                initial_position[i][j] = BlackKnight;
  744. X                break;
  745. X            case 'b':
  746. X                sprintf(blackPieces[bCount++],
  747. X                    "B%c%c", 'a' + j, '1' + i);
  748. X                initial_position[i][j] = BlackBishop;
  749. X                break;
  750. X            case 'q':
  751. X                sprintf(blackPieces[bCount++],
  752. X                    "Q%c%c", 'a' + j, '1' + i);
  753. X                initial_position[i][j] = BlackQueen;
  754. X                break;
  755. X            case 'k':
  756. X                sprintf(blackPieces[bCount++],
  757. X                    "K%c%c", 'a' + j, '1' + i);
  758. X                initial_position[i][j] = BlackKing;
  759. X                break;
  760. X            case 'P':
  761. X                sprintf(whitePieces[wCount++],
  762. X                    "P%c%c", 'a' + j, '1' + i);
  763. X                initial_position[i][j] = WhitePawn;
  764. X                break;
  765. X            case 'R':
  766. X                sprintf(whitePieces[wCount++],
  767. X                    "R%c%c", 'a' + j, '1' + i);
  768. X                initial_position[i][j] = WhiteRook;
  769. X                break;
  770. X            case 'N':
  771. X                sprintf(whitePieces[wCount++],
  772. X                    "N%c%c", 'a' + j, '1' + i);
  773. X                initial_position[i][j] = WhiteKnight;
  774. X                break;
  775. X            case 'B':
  776. X                sprintf(whitePieces[wCount++],
  777. X                    "B%c%c", 'a' + j, '1' + i);
  778. X                initial_position[i][j] = WhiteBishop;
  779. X                break;
  780. X            case 'Q':
  781. X                sprintf(whitePieces[wCount++],
  782. X                    "Q%c%c", 'a' + j, '1' + i);
  783. X                initial_position[i][j] = WhiteQueen;
  784. X                break;
  785. X            case 'K':
  786. X                sprintf(whitePieces[wCount++],
  787. X                    "K%c%c", 'a' + j, '1' + i);
  788. X                initial_position[i][j] = WhiteKing;
  789. X                break;
  790. X            case '.':
  791. X                initial_position[i][j] = EmptySquare;
  792. X                break;
  793. X            }
  794. X
  795. X            j++;
  796. X        }
  797. X    }
  798. X
  799. X    SendPosition(toFirstProgFP);
  800. X    CopyBoard(boards[0], initial_position);
  801. X    DrawPosition(boardWidget, NULL);
  802. X    fclose(position_file_fp);
  803. X}
  804. X
  805. Xvoid
  806. XSendPosition(fp)
  807. X    FILE *fp;
  808. X{
  809. X    int i;
  810. X    char message[MSG_SIZ];
  811. X
  812. X    DisplayTimers(StopTimers);
  813. X    SendToProgram("edit\n", fp);
  814. X
  815. X    SendToProgram("#\n", fp);
  816. X    for (i = 0; i < wCount; i++) {
  817. X        sprintf(message, "%s\n", whitePieces[i]);
  818. X        SendToProgram(message, fp);
  819. X        bzero(message, MSG_SIZ);
  820. X    }
  821. X
  822. X    SendToProgram("c\n", fp);
  823. X    for (i = 0; i < bCount; i++) {
  824. X        sprintf(message, "%s\n", blackPieces[i]);
  825. X        SendToProgram(message, fp);
  826. X        bzero(message, MSG_SIZ);
  827. X    }
  828. X
  829. X    SendToProgram(".\n", fp);
  830. X}
  831. X
  832. Xvoid
  833. XPlayFromGameFileProc()
  834. X{
  835. X    char buf[MSG_SIZ];
  836. X    FILE *game_file_fp;
  837. X
  838. X    gameMode = PlayFromGameFile;
  839. X    InitPosition();
  840. X    DisplayTimers(StopTimers);
  841. X    SendToProgram(appData.initString, toFirstProgFP);
  842. X    SendToProgram("force\n", toFirstProgFP);
  843. X
  844. X    if (!(game_file_fp = fopen(appData.readGameFile, "r"))) {
  845. X        sprintf(buf, "Can't open %s", appData.readGameFile);
  846. X        DisplayMessage(buf);
  847. X        return;
  848. X    }
  849. X
  850. X    /*
  851. X     * skip header information in game record file
  852. X     */
  853. X    fgets(buf, MSG_SIZ, game_file_fp);
  854. X    fgets(buf, MSG_SIZ, game_file_fp);
  855. X    fgets(buf, MSG_SIZ, game_file_fp);
  856. X
  857. X    ReadGameFile(game_file_fp);
  858. X}
  859. X
  860. XXtTimerCallbackProc
  861. XReadGameFile(fp)
  862. X    FILE *fp;
  863. X{
  864. X    int i, move_type, from_x, from_y, to_x, to_y;
  865. X    static char move_number[MSG_SIZ], white_move[MSG_SIZ], black_move[MSG_SIZ];
  866. X    char move[MSG_SIZ];
  867. X
  868. X    if (gameMode == PauseGame) {
  869. X        readGameXID = XtAddTimeOut((int) (1000 * appData.timeDelay),
  870. X            ReadGameFile, fp);
  871. X        return;
  872. X    }
  873. X
  874. X    if (gameMode == BeginningOfGame) {
  875. X        fclose(fp);
  876. X        return;
  877. X    }
  878. X
  879. X    if (currentMove % 2 == 0) {
  880. Xnext_line:
  881. X        if (fgets(move, sizeof(move), fp) == (char *) EOF) {
  882. Xend_parse:
  883. X            if (readGameXID != NULL) {
  884. X                XtRemoveTimeOut(readGameXID);
  885. X                readGameXID = NULL;
  886. X            }
  887. X            fclose(fp);
  888. X            DisplayTimers(StopTimers);
  889. X            gameMode = BeginningOfGame;
  890. X            return;
  891. X        }
  892. X
  893. X        if ((move[0] == '%') || (move[0] == '!'))
  894. X            goto next_line;
  895. X
  896. X        move_number[0] = white_move[0] = black_move[0] = NULL;
  897. X
  898. X        if (sscanf(move, "%s %s %s", move_number,
  899. X            white_move, black_move) == EOF)
  900. X            goto end_parse;
  901. X
  902. X        if (strlen(white_move) == 0) {
  903. X            if (strlen(move_number) != 0)
  904. X                strcpy(white_move, move_number);
  905. X            else {
  906. X                DisplayMessage("End of Game");
  907. X                goto end_parse;
  908. X            }
  909. X        }
  910. X
  911. X        if ((strcmp(white_move, "draw") == 0)
  912. X            || (strcmp(white_move, "Draw") == 0)
  913. X            || (strcmp(white_move, "DRAW") == 0)
  914. X            || (strcmp(white_move, "Resign") == 0)
  915. X            || (strcmp(white_move, "resign") == 0)
  916. X            || (strcmp(white_move, "RESIGN") == 0)
  917. X            || (strcmp(white_move, "0-1") == 0)
  918. X            || (strcmp(white_move, "1-0") == 0)) {
  919. X            DisplayMessage(white_move);
  920. X            goto end_parse;
  921. X        } if (strcmp(white_move, "o-o-o") == 0) {
  922. X            from_x = 4;
  923. X            from_y = 0;
  924. X            to_x = 2;
  925. X            to_y = 0;
  926. X        } else if (strcmp(white_move, "o-o") == 0) {
  927. X            from_x = 4;
  928. X            from_y = 0;
  929. X            to_x = 6;
  930. X            to_y = 0;
  931. X        } else {
  932. X            from_x = white_move[0] - 'a';
  933. X            from_y = white_move[1] - '1';
  934. X            to_x = white_move[2] - 'a';
  935. X            to_y = white_move[3] - '1';
  936. X        }
  937. X
  938. X        sprintf(move, "%s %s", move_number, white_move);
  939. X        DisplayMessage(move);
  940. X        strcat(white_move, "\n");
  941. X        SendToProgram(white_move, toFirstProgFP);
  942. X        MakeMove(&move_type, from_x, from_y, to_x, to_y);
  943. X        strcpy(moveList[currentMove], white_move);
  944. X    } else {
  945. X        if (strlen(black_move) == 0) {
  946. X            DisplayMessage("End of Game");
  947. X            goto end_parse;
  948. X        } if ((strcmp(black_move, "draw") == 0)
  949. X            || (strcmp(black_move, "Draw") == 0)
  950. X            || (strcmp(black_move, "DRAW") == 0)
  951. X            || (strcmp(black_move, "Resign") == 0)
  952. X            || (strcmp(black_move, "resign") == 0)
  953. X            || (strcmp(black_move, "RESIGN") == 0)
  954. X            || (strcmp(black_move, "0-1") == 0)
  955. X            || (strcmp(black_move, "1-0") == 0)) {
  956. X            DisplayMessage(black_move);
  957. X            goto end_parse;
  958. X        } if (strcmp(black_move, "o-o-o") == 0) {
  959. X            from_x = 4;
  960. X            from_y = 7;
  961. X            to_x = 2;
  962. X            to_y = 7;
  963. X        } else if (strcmp(black_move, "o-o") == 0) {
  964. X            from_x = 4;
  965. X            from_y = 7;
  966. X            to_x = 6;
  967. X            to_y = 7;
  968. X        } else {
  969. X            from_x = black_move[0] - 'a';
  970. X            from_y = black_move[1] - '1';
  971. X            to_x = black_move[2] - 'a';
  972. X            to_y = black_move[3] - '1';
  973. X        }
  974. X
  975. X        sprintf(move, "%s ... %s", move_number, black_move);
  976. X        DisplayMessage(move);
  977. X        strcat(black_move, "\n");
  978. X        SendToProgram(black_move, toFirstProgFP);
  979. X        MakeMove(&move_type, from_x, from_y, to_x, to_y);
  980. X        strcpy(moveList[currentMove], black_move);
  981. X    }
  982. X
  983. X    readGameXID = XtAddTimeOut((int) (1000 * appData.timeDelay),
  984. X        ReadGameFile, fp);
  985. X}
  986. X
  987. Xvoid
  988. XMachinePlaysBlackProc()
  989. X{
  990. X    if ((gameMode == PlayFromGameFile) || ((currentMove % 2) == 0))
  991. X        return;
  992. X
  993. X    gameMode = MachinePlaysBlack;
  994. X    DisplayTimers(SwitchTimers);
  995. X    SendToProgram("black\n", toFirstProgFP);
  996. X}
  997. X
  998. Xvoid
  999. XMachinePlaysWhiteProc()
  1000. X{
  1001. X    if ((gameMode == PlayFromGameFile) || ((currentMove % 2) == 1))
  1002. X        return;
  1003. X
  1004. X    gameMode = MachinePlaysWhite;
  1005. X    DisplayTimers(SwitchTimers);
  1006. X    SendToProgram("white\n", toFirstProgFP);
  1007. X}
  1008. X
  1009. Xvoid
  1010. XTwoMachinesPlayProc()
  1011. X{
  1012. X    int i;
  1013. X
  1014. X    switch (gameMode) {
  1015. X    case PlayFromGameFile:
  1016. X    case ForceMoves:
  1017. X        gameMode = TwoMachinesPlay;
  1018. X        InitChessProgram();
  1019. X        SendToProgram(appData.initString, toSecondProgFP);
  1020. X        SendToProgram("force\n", toSecondProgFP);
  1021. X        for (i = 0; i <= currentMove; i++)
  1022. X            SendToProgram(moveList[i], toSecondProgFP);
  1023. X        SendToProgram("white\n", toSecondProgFP);
  1024. X        break;
  1025. X    case SetupPosition:
  1026. X        gameMode = TwoMachinesPlay;
  1027. X        InitChessProgram();
  1028. X        SendToProgram(appData.initString, toSecondProgFP);
  1029. X        SendPosition(toSecondProgFP);
  1030. X        SendToProgram("white\n", toSecondProgFP);
  1031. X        firstMove = False;
  1032. X        break;
  1033. X    default:
  1034. X        gameMode = TwoMachinesPlay;
  1035. X        InitChessProgram();
  1036. X        firstMove = False;
  1037. X        SendToProgram(appData.initString, toSecondProgFP);
  1038. X        SendToProgram("white\n", toSecondProgFP);
  1039. X        break;
  1040. X    }
  1041. X}
  1042. X
  1043. Xvoid
  1044. XForceProc()
  1045. X{
  1046. X    if (gameMode == PlayFromGameFile)
  1047. X        return;
  1048. X
  1049. X    gameMode = ForceMoves;
  1050. X    DisplayTimers(StopTimers);
  1051. X    SendToProgram("force\n", toFirstProgFP);
  1052. X}
  1053. X
  1054. Xvoid
  1055. XPauseProc()
  1056. X{
  1057. X    static previous_mode = PauseGame;
  1058. X
  1059. X    if (gameMode != PauseGame) {
  1060. X        previous_mode = gameMode;
  1061. X        gameMode = PauseGame;
  1062. X    } else {
  1063. X        gameMode = previous_mode;
  1064. X        previous_mode = PauseGame;
  1065. X    }
  1066. X    DisplayTimers(StopTimers);
  1067. X}
  1068. X
  1069. Xvoid
  1070. XInitChessProgram()
  1071. X{
  1072. X    int pid, to_prog[2], from_prog[2];
  1073. X    char *host_name, *program_name, time_control[10], moves_per_session[10];
  1074. X    FILE *from_fp, *to_fp;
  1075. X
  1076. X    switch (gameMode) {
  1077. X    case TwoMachinesPlay:
  1078. X        host_name = appData.secondHost;
  1079. X        program_name = appData.secondChessProgram;
  1080. X        break;
  1081. X    default:
  1082. X        host_name = appData.firstHost;
  1083. X        program_name = appData.firstChessProgram;
  1084. X        break;
  1085. X    }
  1086. X
  1087. X    signal(SIGPIPE, EndOfGameProc);
  1088. X    pipe(to_prog);
  1089. X    pipe(from_prog);
  1090. X
  1091. X    if ((pid = fork()) == 0) {
  1092. X        signal(SIGPIPE, EndOfGameProc);
  1093. X        dup2(to_prog[0], 0);
  1094. X        dup2(from_prog[1], 1);
  1095. X        close(to_prog[0]);
  1096. X        close(to_prog[1]);
  1097. X        close(from_prog[0]);
  1098. X        close(from_prog[1]);
  1099. X        close(2);
  1100. X        open("/dev/null", O_WRONLY);
  1101. X        sprintf(time_control, "%d", appData.timeControl);
  1102. X        sprintf(moves_per_session, "%d", appData.movesPerSession);
  1103. X        if (strcmp(host_name, "localhost") == 0)
  1104. X            execlp(program_name, program_name,
  1105. X                moves_per_session, time_control, (char *) NULL);
  1106. X        else
  1107. X            execlp("/usr/ucb/rsh", "rsh", host_name, program_name,
  1108. X                moves_per_session, time_control, (char *) NULL);
  1109. X        perror(program_name);
  1110. X        exit(1);
  1111. X    }
  1112. X
  1113. X    close(to_prog[0]);
  1114. X    close(from_prog[1]);
  1115. X
  1116. X    from_fp = fdopen(from_prog[0], "r");
  1117. X    setbuf(from_fp, NULL);
  1118. X    to_fp = fdopen(to_prog[1], "w");
  1119. X    setbuf(to_fp, NULL);
  1120. X
  1121. X    switch (gameMode) {
  1122. X    case TwoMachinesPlay:
  1123. X        secondProgPID = pid;
  1124. X        fromSecondProgFP = from_fp;
  1125. X        toSecondProgFP = to_fp;
  1126. X        secondProgXID = XtAddInput(fileno(fromSecondProgFP), XtInputReadMask,
  1127. X            ReceiveFromProgram, fromSecondProgFP);
  1128. X        break;
  1129. X    default:
  1130. X        firstProgPID = pid;
  1131. X        fromFirstProgFP = from_fp;
  1132. X        toFirstProgFP = to_fp;
  1133. X        firstProgXID = XtAddInput(fileno(fromFirstProgFP), XtInputReadMask,
  1134. X            ReceiveFromProgram, fromFirstProgFP);
  1135. X        break;
  1136. X    }
  1137. X}
  1138. X
  1139. Xvoid
  1140. XSendToProgram(message, fp)
  1141. X    char *message;
  1142. X    FILE *fp;
  1143. X{
  1144. X    if (appData.debugMode == True)
  1145. X        fprintf(stderr, "Sending %s\n", message);
  1146. X    fputs(message, fp);
  1147. X}
  1148. X
  1149. Xvoid
  1150. XReceiveFromProgram(fp)
  1151. X    FILE *fp;
  1152. X{
  1153. X    char message[MSG_SIZ];
  1154. X
  1155. X    if (fgets(message, MSG_SIZ, fp) == NULL)
  1156. X        return;
  1157. X    if (appData.debugMode == True)
  1158. X        fprintf(stderr, "Received %s\n", message);
  1159. X    HandleMachineMove(message);
  1160. X}
  1161. X
  1162. Xvoid
  1163. XDisplayMessage(message)
  1164. X    char *message;
  1165. X{
  1166. X    Arg arg;
  1167. X
  1168. X    XtSetArg(arg, XtNlabel, message);
  1169. X    XtSetValues(messageWidget, &arg, 1);
  1170. X}
  1171. X
  1172. X/*
  1173. X * DisplayTimers manages the game clocks.
  1174. X *
  1175. X * In tournament play, black starts the clock and then white makes a move.
  1176. X * DisplayTimers starts black's clock when white makes the first move.
  1177. X * Also, DisplayTimers doesn't account for network lag so it could get
  1178. X * out of sync with GNU Chess's clock -- but then, referees are always right.
  1179. X */
  1180. XXtTimerCallbackProc
  1181. XDisplayTimers(clock_mode)
  1182. X    int clock_mode;
  1183. X{
  1184. X    Arg args[3];
  1185. X    char buf[MSG_SIZ];
  1186. X    static int white_move_flag = True, black_move_flag = True;
  1187. X    static time_t white_time_remaining, black_time_remaining,
  1188. X        white_last_time, black_last_time, current_time = 0;
  1189. X    static XtIntervalId white_timer_id = NULL, black_timer_id = NULL;
  1190. X
  1191. X    current_time = time((time_t *) NULL);
  1192. X
  1193. X    switch (clock_mode) {
  1194. X    case StopTimers:
  1195. X        if (white_timer_id != NULL)
  1196. X            XtRemoveTimeOut(white_timer_id);
  1197. X        if (black_timer_id != NULL)
  1198. X            XtRemoveTimeOut(black_timer_id);
  1199. X        white_last_time = black_last_time = current_time;
  1200. X        break;
  1201. X    case SwitchTimers:
  1202. X        if (currentMove % 2 == 0) {
  1203. X            if (white_move_flag) {
  1204. X                white_move_flag = False;
  1205. X                if (currentMove == 0 || firstMove == True)
  1206. X                    white_time_remaining = appData.timeControl * 60;
  1207. X                else
  1208. X                    white_time_remaining -= current_time - white_last_time;
  1209. X            } else
  1210. X                white_time_remaining -= current_time - white_last_time;
  1211. X            white_last_time = black_last_time = current_time;
  1212. X            if (white_time_remaining <= 0) {
  1213. X                white_time_remaining = 0;
  1214. X                DisplayMessage("White's flag dropped");
  1215. X            }
  1216. X            sprintf(buf, "white: %s", TimeString(white_time_remaining));
  1217. X            XtSetArg(args[0], XtNlabel, buf);
  1218. X            XtSetArg(args[1], XtNbackground, WHITE_PIXEL);
  1219. X            XtSetArg(args[2], XtNforeground, BLACK_PIXEL);
  1220. X            XtSetValues(whiteTimerWidget, args, 3);
  1221. X            sprintf(buf, "black: %s", TimeString(black_time_remaining));
  1222. X            XtSetArg(args[0], XtNlabel, buf);
  1223. X            XtSetArg(args[1], XtNbackground, BLACK_PIXEL);
  1224. X            XtSetArg(args[2], XtNforeground, WHITE_PIXEL);
  1225. X            XtSetValues(blackTimerWidget, args, 3);
  1226. X            if (black_timer_id != NULL)
  1227. X                XtRemoveTimeOut(black_timer_id);
  1228. X            white_timer_id = XtAddTimeOut(1000, DisplayTimers, SwitchTimers);
  1229. X        } else {
  1230. X            if (black_move_flag) {
  1231. X                black_move_flag = False;
  1232. X                if (currentMove == 1)
  1233. X                    black_time_remaining = appData.timeControl * 60;
  1234. X                else if (firstMove) {
  1235. X                    firstMove = False;
  1236. X                    white_time_remaining = appData.timeControl * 60;
  1237. X                } else
  1238. X                    black_time_remaining -= current_time - black_last_time;
  1239. X            } else
  1240. X                black_time_remaining -= current_time - black_last_time;
  1241. X            white_last_time = black_last_time = current_time;
  1242. X            if (black_time_remaining <= 0) {
  1243. X                black_time_remaining = 0;
  1244. X                DisplayMessage("Black's flag dropped");
  1245. X            }
  1246. X            sprintf(buf, "white: %s", TimeString(white_time_remaining));
  1247. X            XtSetArg(args[0], XtNlabel, buf);
  1248. X            XtSetArg(args[1], XtNbackground, BLACK_PIXEL);
  1249. X            XtSetArg(args[2], XtNforeground, WHITE_PIXEL);
  1250. X            XtSetValues(whiteTimerWidget, args, 3);
  1251. X            sprintf(buf, "black: %s", TimeString(black_time_remaining));
  1252. X            XtSetArg(args[0], XtNlabel, buf);
  1253. X            XtSetArg(args[1], XtNbackground, WHITE_PIXEL);
  1254. X            XtSetArg(args[2], XtNforeground, BLACK_PIXEL);
  1255. X            XtSetValues(blackTimerWidget, args, 3);
  1256. X            if (white_timer_id != NULL)
  1257. X                XtRemoveTimeOut(white_timer_id);
  1258. X            black_timer_id = XtAddTimeOut(1000, DisplayTimers, SwitchTimers);
  1259. X        }
  1260. X        /*
  1261. X         * reset clocks when time control is acheived
  1262. X         */
  1263. X        if ((((int) (currentMove + 2.5) / 2) % appData.movesPerSession == 0)
  1264. X                && (white_time_remaining > 0) && (black_time_remaining > 0)) {
  1265. X            white_time_remaining = appData.timeControl * 60;
  1266. X            black_time_remaining = appData.timeControl * 60;
  1267. X        }
  1268. X        break;
  1269. X    case ResetTimers:
  1270. X        if (white_timer_id != NULL) {
  1271. X            XtRemoveTimeOut(white_timer_id);
  1272. X            white_timer_id = NULL;
  1273. X        }
  1274. X        white_move_flag = True;
  1275. X        white_time_remaining = appData.timeControl * 60;
  1276. X        sprintf(buf, "white: %s", TimeString(white_time_remaining));
  1277. X        XtSetArg(args[0], XtNlabel, buf);
  1278. X        XtSetArg(args[1], XtNbackground, WHITE_PIXEL);
  1279. X        XtSetArg(args[2], XtNforeground, BLACK_PIXEL);
  1280. X        XtSetValues(whiteTimerWidget, args, 3);
  1281. X
  1282. X        if (black_timer_id != NULL) {
  1283. X            XtRemoveTimeOut(black_timer_id);
  1284. X            black_timer_id = NULL;
  1285. X        }
  1286. X        black_move_flag = True;
  1287. X        black_time_remaining = appData.timeControl * 60;
  1288. X        sprintf(buf, "black: %s", TimeString(black_time_remaining));
  1289. X        XtSetArg(args[0], XtNlabel, buf);
  1290. X        XtSetArg(args[1], XtNbackground, WHITE_PIXEL);
  1291. X        XtSetArg(args[2], XtNforeground, BLACK_PIXEL);
  1292. X        XtSetValues(blackTimerWidget, args, 3);
  1293. X        break;
  1294. X    }
  1295. X}
  1296. X
  1297. Xchar *
  1298. XTimeString(tm)
  1299. X    time_t tm;
  1300. X{
  1301. X    static char buf[32];
  1302. X    static int i, second, minute, hour, day;
  1303. X
  1304. X    bzero(buf, sizeof(buf));
  1305. X
  1306. X    if (tm >= (60 * 60 * 24)) {
  1307. X        day = (int) (tm / (60 * 60 * 24));
  1308. X        tm -= (int) day * 60 * 60 * 24;
  1309. X    } else
  1310. X        day = 0;
  1311. X
  1312. X    if (tm >= (60 * 60)) {
  1313. X        hour = (int) (tm / (60 * 60));
  1314. X        tm -= (int) hour * 60 * 60;
  1315. X    } else
  1316. X        hour = 0;
  1317. X
  1318. X    if (tm >= 60) {
  1319. X        minute = (int) (tm / 60);
  1320. X        tm -= (int) minute * 60;
  1321. X    } else
  1322. X        minute = 0;
  1323. X
  1324. X    second = tm % 60;
  1325. X
  1326. X    if (day > 0)
  1327. X        sprintf(buf, " %d:%02d:%02d:%02d ", day, hour, minute, second);
  1328. X    else if (hour > 0)
  1329. X        sprintf(buf, " %d:%02d:%02d ", hour, minute, second);
  1330. X    else
  1331. X        sprintf(buf, " %2d:%02d ", minute, second);
  1332. X
  1333. X    return buf;
  1334. X}
  1335. X
  1336. Xvoid
  1337. XSyntax(argc, argv)
  1338. X    int argc;
  1339. X    char **argv;
  1340. X{
  1341. X    fprintf(stderr, "Usage %s:\n", argv[0]);
  1342. X    fprintf(stderr, "\tstandard Xt options\n");
  1343. X    fprintf(stderr, "\t-whitePieceColor color\n");
  1344. X    fprintf(stderr, "\t-blackPieceColor color\n");
  1345. X    fprintf(stderr, "\t-lightSquareColor color\n");
  1346. X    fprintf(stderr, "\t-darkSquareColor color\n");
  1347. X    fprintf(stderr, "\t-timeDelay seconds\n");
  1348. X    fprintf(stderr, "\t-timeControl minutes\n");
  1349. X    fprintf(stderr, "\t-movesPerSession moves\n");
  1350. X    fprintf(stderr, "\t-saveGameFile file\n");
  1351. X    fprintf(stderr, "\t-readGameFile file\n");
  1352. X    fprintf(stderr, "\t-initString commands\n");
  1353. X    fprintf(stderr, "\t-savePositionFile file\n");
  1354. X    fprintf(stderr, "\t-readPositionFile file\n");
  1355. X    fprintf(stderr, "\t-firstChessProgram program\n");
  1356. X    fprintf(stderr, "\t-secondChessProgram program\n");
  1357. X    fprintf(stderr, "\t-firstHost host\n");
  1358. X    fprintf(stderr, "\t-secondHost host\n");
  1359. X    fprintf(stderr, "\t-solidPawnBitmap file\n");
  1360. X    fprintf(stderr, "\t-solidRookBitmap file\n");
  1361. X    fprintf(stderr, "\t-solidBishopBitmap file\n");
  1362. X    fprintf(stderr, "\t-solidKnightBitmap file\n");
  1363. X    fprintf(stderr, "\t-solidQueenBitmap file\n");
  1364. X    fprintf(stderr, "\t-solidKingBitmap file\n");
  1365. X    fprintf(stderr, "\t-outlinePawnBitmap file\n");
  1366. X    fprintf(stderr, "\t-outlineRookBitmap file\n");
  1367. X    fprintf(stderr, "\t-outlineBishopBitmap file\n");
  1368. X    fprintf(stderr, "\t-outlineKnightBitmap file\n");
  1369. X    fprintf(stderr, "\t-outlineQueenBitmap file\n");
  1370. X    fprintf(stderr, "\t-outlineKingBitmap file\n");
  1371. X    fprintf(stderr, "\t-matchMode (False | Init | Position | Opening)\n");
  1372. X    fprintf(stderr, "\t-monoMode (False | True)\n");
  1373. X    fprintf(stderr, "\t-debugMode (False | True)\n");
  1374. X    exit(0);
  1375. X}
  1376. SHAR_EOF
  1377. $TOUCH -am 1031191090 xboard.c &&
  1378. chmod 0644 xboard.c ||
  1379. echo "restore of xboard.c failed"
  1380. set `wc -c xboard.c`;Wc_c=$1
  1381. if test "$Wc_c" != "61279"; then
  1382.     echo original size 61279, current size $Wc_c
  1383. fi
  1384. # ============= xboard.h ==============
  1385. echo "x - extracting xboard.h (Text)"
  1386. sed 's/^X//' << 'SHAR_EOF' > xboard.h &&
  1387. X#define BOARD_SIZE                8                    /* rarely changed */
  1388. X#define SQUARE_SIZE                80
  1389. X#define LINE_GAP                3
  1390. X#define MAX_MOVES                512
  1391. X#define MSG_SIZ                    256
  1392. X#define TIME_CONTROL            5                    /* minutes */
  1393. X#define TIME_DELAY                1.5                    /* seconds between moves */
  1394. X#define MOVES_PER_SESSION        40                    /* moves per TIME_CONTROL */
  1395. X#define FIRST_CHESS_PROGRAM        "gnuchessr"
  1396. X#define SECOND_CHESS_PROGRAM    "gnuchessr"
  1397. X#define FIRST_HOST                "localhost"
  1398. X#define SECOND_HOST                "localhost"
  1399. X#define MATCH_MODE                MatchFalse
  1400. X#define SAVE_GAME_FILE            "xboard.game.save"
  1401. X#define READ_GAME_FILE            "xboard.game.read"
  1402. X#define INIT_STRING                "new\nbeep\nrandom\neasy\n"
  1403. X#define SAVE_POSITION_FILE        "xboard.position.save"
  1404. X#define READ_POSITION_FILE        "xboard.position.read"
  1405. X#define SOLID_PAWN_BITMAP        "solid_pawn.bitmap"
  1406. X#define SOLID_ROOK_BITMAP        "solid_rook.bitmap"
  1407. X#define SOLID_KNIGHT_BITMAP        "solid_knight.bitmap"
  1408. X#define SOLID_BISHOP_BITMAP        "solid_bishop.bitmap"
  1409. X#define SOLID_QUEEN_BITMAP        "solid_queen.bitmap"
  1410. X#define SOLID_KING_BITMAP        "solid_king.bitmap"
  1411. X#define OUTLINE_PAWN_BITMAP        "outline_pawn.bitmap"
  1412. X#define OUTLINE_ROOK_BITMAP        "outline_rook.bitmap"
  1413. X#define OUTLINE_KNIGHT_BITMAP    "outline_knight.bitmap"
  1414. X#define OUTLINE_BISHOP_BITMAP    "outline_bishop.bitmap"
  1415. X#define OUTLINE_QUEEN_BITMAP    "outline_queen.bitmap"
  1416. X#define OUTLINE_KING_BITMAP        "outline_king.bitmap"
  1417. X#define WHITE_PIECE_COLOR        "#FFFFCC"
  1418. X#define BLACK_PIECE_COLOR        "#202020"
  1419. X#define LIGHT_SQUARE_COLOR        "#C8C365"
  1420. X#define DARK_SQUARE_COLOR        "#77A26D"
  1421. X
  1422. Xtypedef unsigned char Board[BOARD_SIZE][BOARD_SIZE];
  1423. X
  1424. Xenum {
  1425. X    BeginningOfGame, MachinePlaysWhite, MachinePlaysBlack, TwoMachinesPlay,
  1426. X    ForceMoves, PlayFromGameFile, SetupPosition, PauseGame, EndOfGame
  1427. X};
  1428. X
  1429. Xenum { WhiteOnMove, BlackOnMove };
  1430. X
  1431. Xenum { MatchFalse, MatchInit, MatchPosition, MatchOpening };
  1432. X
  1433. Xenum {
  1434. X    WhitePawn, WhiteRook, WhiteKnight, WhiteBishop, WhiteQueen, WhiteKing,
  1435. X    BlackPawn, BlackRook, BlackKnight, BlackBishop, BlackQueen, BlackKing,
  1436. X    EmptySquare
  1437. X};
  1438. X
  1439. Xenum {
  1440. X    WhiteKingSideCastle = 1, WhiteQueenSideCastle, WhitePromotion,
  1441. X    BlackKingSideCastle, BlackQueenSideCastle, BlackPromotion,
  1442. X    WhiteCapturesEnPassant, BlackCapturesEnPassant, NormalMove,
  1443. X    WhiteWins, BlackWins, GameIsDrawn
  1444. X};
  1445. X
  1446. Xenum {            /* Same order as buttonStrings */
  1447. X    ButtonQuit, ButtonPlayFromFile, ButtonMachinePlaysBlack, ButtonForward,
  1448. X    ButtonReset, ButtonSetupFromFile, ButtonMachinePlaysWhite, ButtonBackward,
  1449. X    ButtonFlip, ButtonSaveGame, ButtonSwitch, ButtonForce,
  1450. X    ButtonHint, ButtonSavePosition, ButtonTwoMachinesPlay, ButtonPause
  1451. X};
  1452. X
  1453. Xenum {
  1454. X    ResetTimers, SwitchTimers, StopTimers
  1455. X};
  1456. SHAR_EOF
  1457. $TOUCH -am 1031190190 xboard.h &&
  1458. chmod 0644 xboard.h ||
  1459. echo "restore of xboard.h failed"
  1460. set `wc -c xboard.h`;Wc_c=$1
  1461. if test "$Wc_c" != "2561"; then
  1462.     echo original size 2561, current size $Wc_c
  1463. fi
  1464. exit 0
  1465.  
  1466. dan
  1467. ----------------------------------------------------
  1468. O'Reilly && Associates   argv@sun.com / argv@ora.com
  1469. Opinions expressed reflect those of the author only.
  1470. --
  1471. dan
  1472. ----------------------------------------------------
  1473. O'Reilly && Associates   argv@sun.com / argv@ora.com
  1474. Opinions expressed reflect those of the author only.
  1475.