Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1542 lines
42 KiB

  1. /****************************************************************************/
  2. /* */
  3. /* Windows Reversi - */
  4. /* */
  5. /* Originally written by Chris Peters */
  6. /* */
  7. /****************************************************************************/
  8. #include "windows.h"
  9. #include <port1632.h>
  10. #include <process.h>
  11. #include <stdlib.h>
  12. #include "reversi.h"
  13. /* Exported procedures called from other modules */
  14. LRESULT APIENTRY ReversiWndProc(HWND, UINT, WPARAM, LPARAM);
  15. VOID APIENTRY InverseMessage(HWND, UINT, UINT_PTR, DWORD);
  16. INT_PTR APIENTRY AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
  17. PSTR pDisplayMessage;
  18. HBRUSH hbrBlack;
  19. HBRUSH hbrPat;
  20. HBRUSH hbrWhite;
  21. HBRUSH hbrRed;
  22. HBRUSH hbrGreen;
  23. HBRUSH hbrBlue;
  24. HBRUSH hbrHuman;
  25. HBRUSH hbrComputer;
  26. HANDLE hInst;
  27. HANDLE curIllegal;
  28. HANDLE curLegal;
  29. HANDLE curThink;
  30. HANDLE curBlank;
  31. BOOL fThinking = FALSE;
  32. BOOL fCheated = FALSE;
  33. INT direc[9] = {9, 10, 11, 1, -1, -9, -10, -11, 0};
  34. WORD prevCheck;
  35. BYTE board[max_depth+2][BoardSize];
  36. INT fPass;
  37. INT flashtimes;
  38. INT count;
  39. INT MessageOn;
  40. INT charheight;
  41. INT charwidth;
  42. INT xscr;
  43. CHAR strBuf[80];
  44. BOOL bMouseDownInReversi = FALSE;
  45. INT xExt;
  46. INT yExt;
  47. INT Bx;
  48. INT By;
  49. INT ASPECT;
  50. INT COLOR;
  51. INT TXMIN;
  52. INT TYMIN = 45;
  53. INT dimension;
  54. BOOL ffirstmove;
  55. CHAR szReversi[20];
  56. CHAR szReversiPractice[40];
  57. CHAR szPass[30];
  58. CHAR szMustPass[30];
  59. CHAR szTie[30];
  60. CHAR szLoss[30];
  61. CHAR szWon[30];
  62. CHAR szWonPost[30];
  63. CHAR szLossPost[30];
  64. CHAR szAbout[20];
  65. CHAR szIllegal[70];
  66. CHAR szNoPass[70];
  67. CHAR szHelpFile[15];
  68. HANDLE hAccel;
  69. POINT MousePos;
  70. INT depth;
  71. INT BestMove[max_depth+2];
  72. HDC hDisp;
  73. HWND hWin;
  74. INT moves[61] = {11,18,81,88, 13,31,16,61,
  75. 38,83,68,86, 14,41,15,51,
  76. 48,84,58,85, 33,36,63,66,
  77. 34,35,43,46, 53,56,64,65,
  78. 24,25,42,47, 52,57,74,75,
  79. 23,26,32,37, 62,67,73,76,
  80. 12,17,21,28, 71,78,82,87,
  81. 22,27,72,77,
  82. 0};
  83. INT NEAR PASCAL minmax(BYTE b[max_depth + 2][100], INT move, INT friendly,
  84. INT enemy, INT ply, INT vmin, INT vmax);
  85. VOID NEAR PASCAL makemove(BYTE b[], INT move, INT friendly, INT enemy);
  86. INT NEAR PASCAL legalcheck(BYTE b[], INT move, INT friendly, INT enemy);
  87. /*--------------------------------------------------------------------------*/
  88. /* */
  89. /* UpdateCursor() - */
  90. /* */
  91. /*--------------------------------------------------------------------------*/
  92. /* To use UpdateCursor, set the global var MousePos.x and MousePos.y and make
  93. * the call. The cursor will appear at the new position
  94. */
  95. VOID NEAR PASCAL UpdateCursor(
  96. HWND hwnd)
  97. {
  98. POINT curpoint;
  99. curpoint.x = MousePos.x;
  100. curpoint.y = MousePos.y;
  101. ClientToScreen(hwnd, (LPPOINT)&curpoint);
  102. SetCursorPos(curpoint.x, curpoint.y);
  103. }
  104. /*--------------------------------------------------------------------------*/
  105. /* */
  106. /* checkdepth() - */
  107. /* */
  108. /*--------------------------------------------------------------------------*/
  109. VOID NEAR PASCAL checkdepth(
  110. HWND hWindow,
  111. WORD d)
  112. {
  113. HMENU hMenu;
  114. hMenu = GetMenu(hWindow);
  115. CheckMenuItem(hMenu, prevCheck, MF_UNCHECKED);
  116. CheckMenuItem(hMenu, d, MF_CHECKED);
  117. prevCheck = d;
  118. }
  119. /*--------------------------------------------------------------------------*/
  120. /* */
  121. /* clearboard() - */
  122. /* */
  123. /*--------------------------------------------------------------------------*/
  124. VOID NEAR PASCAL clearboard(
  125. BYTE b[max_depth+2][BoardSize])
  126. {
  127. register INT i,j;
  128. INT k;
  129. for (i=0; i<=max_depth ; i++)
  130. for (j=0 ; j<=99 ; j++)
  131. b[i][j] = edge;
  132. for (i=0 ; i<=max_depth ; i++)
  133. {
  134. for (j=11 ; j<=81 ; j=j+10)
  135. for (k=j ; k<j+8 ; k++)
  136. b[i][k] = empty;
  137. b[i][45]=computer;
  138. b[i][54]=computer;
  139. b[i][44]=human;
  140. b[i][55]=human;
  141. }
  142. }
  143. /*--------------------------------------------------------------------------*/
  144. /* */
  145. /* RevCreate() - */
  146. /* */
  147. /*--------------------------------------------------------------------------*/
  148. /* Called on WM_CREATE messages. */
  149. VOID NEAR PASCAL RevCreate(
  150. register HWND hWindow)
  151. {
  152. register HDC hDC;
  153. TEXTMETRIC charsize; /* characteristics of the characters */
  154. MessageOn = FALSE;
  155. hDC = GetDC(hWindow);
  156. GetTextMetrics(hDC, (LPTEXTMETRIC)&charsize);
  157. charheight = charsize.tmHeight;
  158. charwidth = charsize.tmAveCharWidth;
  159. ReleaseDC(hWindow, hDC);
  160. if (COLOR == TRUE)
  161. {
  162. hbrComputer = hbrBlue;
  163. hbrHuman = hbrRed;
  164. }
  165. else
  166. {
  167. hbrComputer = hbrBlack;
  168. hbrHuman = hbrWhite;
  169. }
  170. TXMIN = 45 * ASPECT;
  171. clearboard(board);
  172. /* Okay to pass on first move */
  173. fPass = PASS;
  174. depth = 1;
  175. prevCheck = EASY;
  176. ffirstmove = TRUE;
  177. checkdepth(hWindow, prevCheck);
  178. }
  179. /*--------------------------------------------------------------------------*/
  180. /* */
  181. /* printboard() - */
  182. /* */
  183. /*--------------------------------------------------------------------------*/
  184. VOID NEAR PASCAL printboard(
  185. BYTE b[max_depth+2][BoardSize])
  186. {
  187. register INT i,j;
  188. INT sq;
  189. for (i=0; i < 8; i++)
  190. {
  191. for (j=0; j < 8; j++)
  192. {
  193. if ((sq = (INT)b[0][i*10+j+11]) != empty)
  194. {
  195. if (sq == computer)
  196. SelectObject(hDisp, hbrComputer);
  197. else
  198. SelectObject(hDisp, hbrHuman);
  199. Ellipse(hDisp,
  200. Bx+2*ASPECT+i*xExt,
  201. By+2+j*yExt,
  202. Bx+2*ASPECT + i*xExt + xExt-4*ASPECT,
  203. By+2+j*yExt + yExt-4);
  204. }
  205. }
  206. }
  207. }
  208. /*--------------------------------------------------------------------------*/
  209. /* */
  210. /* ClearMessageTop() - */
  211. /* */
  212. /*--------------------------------------------------------------------------*/
  213. VOID NEAR PASCAL ClearMessageTop(
  214. HDC hDC)
  215. {
  216. if (MessageOn == TRUE)
  217. {
  218. flashtimes = count + 1;
  219. SelectObject(hDC, (COLOR) ? hbrGreen : hbrWhite);
  220. PatBlt(hDC, 0, 0, xscr, charheight, PATCOPY);
  221. MessageOn = FALSE;
  222. }
  223. }
  224. /*--------------------------------------------------------------------------*/
  225. /* */
  226. /* ShowMessageTop() - */
  227. /* */
  228. /*--------------------------------------------------------------------------*/
  229. VOID NEAR PASCAL ShowMessageTop(
  230. HDC hDC,
  231. PSTR string)
  232. {
  233. INT dx;
  234. pDisplayMessage = string;
  235. ClearMessageTop(hDC);
  236. SelectObject(hDC, hbrWhite);
  237. PatBlt(hDC, 0, 0, xscr, charheight, PATCOPY);
  238. SetBkMode(hDC, TRANSPARENT);
  239. MGetTextExtent(hDC, (LPSTR)string, lstrlen(string), &dx, NULL);
  240. TextOut(hDC, (INT)(xscr - dx)/2, 0, (LPSTR)string, lstrlen(string));
  241. MessageOn = TRUE;
  242. SetBkMode(hDC, OPAQUE);
  243. }
  244. /*--------------------------------------------------------------------------*/
  245. /* */
  246. /* drawboard() - */
  247. /* */
  248. /*--------------------------------------------------------------------------*/
  249. VOID NEAR PASCAL drawboard(
  250. BYTE b[max_depth+2][BoardSize])
  251. {
  252. register INT i;
  253. INT lcx,lcy;
  254. register INT xdimension;
  255. INT xLineExt,yLineExt;
  256. yLineExt = 8 * yExt;
  257. xLineExt = 8 * xExt;
  258. xdimension = dimension * ASPECT;
  259. SelectObject(hDisp, hbrBlack);
  260. PatBlt(hDisp, Bx+2*xdimension, By+2*dimension, xLineExt, yLineExt, PATCOPY);
  261. MUnrealizeObject(hbrPat);
  262. SelectObject(hDisp, hbrPat);
  263. PatBlt(hDisp, Bx, By, xLineExt, yLineExt, PATCOPY);
  264. SelectObject(hDisp, hbrBlack);
  265. for (i=Bx; i <= Bx + xLineExt; i += xExt)
  266. PatBlt(hDisp, i, By, ASPECT, yLineExt, PATCOPY);
  267. for (i=By; i <= By + yLineExt; i += yExt)
  268. PatBlt(hDisp, Bx, i, xLineExt, 1, PATCOPY);
  269. lcx = Bx+xLineExt;
  270. lcy = By+yLineExt;
  271. MUnrealizeObject(hbrPat);
  272. SelectObject(hDisp, hbrPat);
  273. for (i=1; i < xdimension; ++i)
  274. PatBlt(hDisp, lcx+i, By+i/ASPECT, 1, yLineExt, PATCOPY);
  275. /* Fill in bottom edge of puzzle. */
  276. for (i=1; i < dimension; ++i)
  277. PatBlt(hDisp, Bx+i*ASPECT, lcy+i, xLineExt, 1, PATCOPY);
  278. SelectObject(hDisp, hbrBlack);
  279. MMoveTo(hDisp, lcx, By);
  280. LineTo(hDisp, lcx+xdimension, By+dimension);
  281. LineTo(hDisp, lcx+xdimension, lcy+dimension);
  282. LineTo(hDisp, Bx+xdimension, lcy+dimension);
  283. LineTo(hDisp, Bx, lcy);
  284. MMoveTo(hDisp, lcx+xdimension, lcy+dimension);
  285. LineTo(hDisp, lcx, lcy);
  286. printboard(b);
  287. }
  288. /*--------------------------------------------------------------------------*/
  289. /* */
  290. /* RevPaint() - */
  291. /* */
  292. /*--------------------------------------------------------------------------*/
  293. /* Called on WM_PAINT messages. */
  294. VOID NEAR PASCAL RevPaint(
  295. HWND hWindow,
  296. HDC hDC)
  297. {
  298. register INT Tx, Ty;
  299. INT xLineExt, yLineExt;
  300. RECT lpSize;
  301. /* Since it is easy to resize we'll do it on every repaint */
  302. hDisp = hDC;
  303. hWin = hWindow;
  304. SetBkMode(hDisp, OPAQUE);
  305. GetClientRect(hWindow, (LPRECT)&lpSize);
  306. xscr = Tx = lpSize.right - lpSize.left;
  307. Ty = lpSize.bottom - lpSize.top;
  308. /* Dont go below minimum size */
  309. if (Tx < Ty*ASPECT)
  310. {
  311. if (Tx < TXMIN)
  312. Tx = TXMIN;
  313. xExt = Tx / (9 + 1);
  314. yExt = xExt / ASPECT;
  315. }
  316. else
  317. {
  318. if (Ty < TYMIN)
  319. Ty = TYMIN;
  320. yExt = Ty / (9 + 1);
  321. xExt = yExt * ASPECT;
  322. }
  323. yLineExt = 8 * yExt;
  324. xLineExt = 8 * xExt;
  325. dimension = yLineExt/30;
  326. Bx = (Tx > xLineExt) ? (Tx - xLineExt) / 2 : 0;
  327. By = (Ty > yLineExt) ? (Ty - yLineExt) / 2 : 0;
  328. drawboard(board);
  329. if (MessageOn)
  330. {
  331. ShowMessageTop(hDisp, pDisplayMessage);
  332. PatBlt(hDC, 0, 0, xscr, charheight, DSTINVERT);
  333. }
  334. }
  335. /*--------------------------------------------------------------------------*/
  336. /* */
  337. /* FlashMessageTop() - */
  338. /* */
  339. /*--------------------------------------------------------------------------*/
  340. VOID NEAR PASCAL FlashMessageTop(
  341. HWND hWindow)
  342. {
  343. flashtimes = 0;
  344. count = 4;
  345. SetTimer(hWindow, 666, 200, InverseMessage); /* Timer ID is 666 */
  346. }
  347. /*--------------------------------------------------------------------------*/
  348. /* */
  349. /* RevMessage() - */
  350. /* */
  351. /*--------------------------------------------------------------------------*/
  352. VOID NEAR PASCAL RevMessage(
  353. HWND hWindow,
  354. HDC hDC,
  355. register CHAR *pS,
  356. INT n,
  357. CHAR *pchPostStr)
  358. {
  359. register CHAR *pch;
  360. pch = strBuf;
  361. while (*pS)
  362. *pch++ = *pS++;
  363. if (n)
  364. {
  365. if (n / 10)
  366. *pch++ = (CHAR)(n / 10 + '0');
  367. *pch++ = (CHAR)(n % 10 + '0');
  368. }
  369. if (pchPostStr)
  370. {
  371. while (*pchPostStr)
  372. *pch++ = *pchPostStr++;
  373. }
  374. *pch = TEXT('\0');
  375. ShowMessageTop(hDC, strBuf);
  376. FlashMessageTop(hWindow);
  377. }
  378. /*--------------------------------------------------------------------------*/
  379. /* */
  380. /* flashsqr() - */
  381. /* */
  382. /*--------------------------------------------------------------------------*/
  383. VOID NEAR PASCAL flashsqr(
  384. register HDC hDC,
  385. INT x1,
  386. INT y1,
  387. INT Ex,
  388. INT Ey,
  389. INT color,
  390. BOOL fBlankSquare,
  391. INT n)
  392. {
  393. register INT i;
  394. if (fBlankSquare)
  395. SelectObject(hDC, GetStockObject(NULL_PEN));
  396. SetCursor(curBlank);
  397. for (i=0; i < n; ++i)
  398. {
  399. if (color == 1)
  400. color = 2;
  401. else
  402. color = 1;
  403. if (color == 1)
  404. SelectObject(hDC,hbrComputer);
  405. else
  406. SelectObject(hDC, hbrHuman);
  407. SetBkMode(hDC, OPAQUE);
  408. Ellipse(hDC, x1, y1, x1+Ex, y1+Ey);
  409. }
  410. if (fBlankSquare)
  411. {
  412. MUnrealizeObject(hbrPat);
  413. SelectObject(hDC, hbrPat);
  414. Ellipse(hDC, x1, y1, x1+Ex, y1+Ey);
  415. }
  416. else
  417. SetCursor(curThink);
  418. }
  419. /*--------------------------------------------------------------------------*/
  420. /* */
  421. /* RevMouseMove() - */
  422. /* */
  423. /*--------------------------------------------------------------------------*/
  424. VOID NEAR PASCAL RevMouseMove(
  425. POINT point)
  426. {
  427. INT move;
  428. INT Si, Sj;
  429. INT yLineExt = 8 * yExt;
  430. INT xLineExt = 8 * xExt;
  431. HANDLE cur;
  432. MousePos.x = point.x;
  433. MousePos.y = point.y;
  434. if(xExt ==0 || yExt == 0)
  435. return;
  436. cur = curIllegal;
  437. if ((point.x > Bx) && (point.x < (Bx+xLineExt)) && (point.y > By) && (point.y < (By+yLineExt)))
  438. {
  439. Si = (point.x - Bx) / xExt;
  440. Sj = (point.y - By) / yExt;
  441. move = Si * 10 + Sj + 11;
  442. if (legalcheck(board[0], move, human, computer))
  443. cur = curLegal;
  444. }
  445. SetCursor(cur);
  446. }
  447. /*--------------------------------------------------------------------------*/
  448. /* */
  449. /* ShowBestMove() - */
  450. /* */
  451. /*--------------------------------------------------------------------------*/
  452. VOID NEAR PASCAL ShowBestMove(
  453. HWND hwnd)
  454. {
  455. HDC hdc;
  456. INT sq;
  457. register INT x, y;
  458. INT *pMoves;
  459. BOOL bDone;
  460. if (fPass == PASS && !ffirstmove)
  461. return;
  462. if (!fCheated)
  463. SetWindowText(hwnd, (LPSTR)szReversiPractice);
  464. fCheated = TRUE;
  465. SetCursor(curThink);
  466. fThinking = TRUE;
  467. if (ffirstmove)
  468. {
  469. /* HACK: Hardcode the first move hint. */
  470. x = 4;
  471. y = 2;
  472. }
  473. else
  474. {
  475. if (depth == 1)
  476. {
  477. bDone = FALSE;
  478. pMoves = moves;
  479. sq = *pMoves;
  480. while (!bDone)
  481. {
  482. sq = *pMoves;
  483. if (legalcheck(board[0], sq, human, computer))
  484. bDone = TRUE;
  485. else
  486. pMoves++;
  487. }
  488. y = (sq - 11) % 10;
  489. x = (sq - 11) / 10;
  490. }
  491. else
  492. {
  493. minmax(board, BestMove[0], computer, human, 1, -infin, infin);
  494. y = (BestMove[1] - 11) % 10;
  495. x = (BestMove[1] - 11) / 10;
  496. }
  497. }
  498. MousePos.x = (x * xExt) + Bx + xExt/2;
  499. MousePos.y = (y * yExt) + By + yExt/2;
  500. UpdateCursor(hwnd);
  501. hdc = GetDC(hwnd);
  502. x = x * xExt + Bx + 2 * ASPECT;
  503. y = y * yExt + By + 2;
  504. flashsqr(hdc, x, y, xExt - 4 * ASPECT, yExt - 4, computer, TRUE, 3);
  505. fThinking = FALSE;
  506. ReleaseDC(hwnd, hdc);
  507. RevMouseMove(MousePos);
  508. }
  509. /*--------------------------------------------------------------------------*/
  510. /* */
  511. /* gameover() - */
  512. /* */
  513. /*--------------------------------------------------------------------------*/
  514. /* Find a human reply to the computers move.
  515. * As a side effect set flag fPass if the human
  516. * has a legal move.
  517. */
  518. VOID NEAR PASCAL gameover(
  519. register HWND hWindow,
  520. HDC hDC,
  521. BYTE b[max_depth + 2][BoardSize],
  522. INT r)
  523. {
  524. register INT i;
  525. INT cc;
  526. INT hc;
  527. INT sq;
  528. INT reply2;
  529. INT *pMoves;
  530. pMoves = moves;
  531. fPass = PASS;
  532. reply2 = PASS;
  533. while ((sq = *pMoves++) != 0)
  534. {
  535. if (legalcheck(b[0], sq, human, computer))
  536. fPass = sq;
  537. else if (legalcheck(b[0], sq, computer, human))
  538. reply2 = sq;
  539. }
  540. if (fPass == PASS)
  541. {
  542. if ((r == PASS) || (reply2 == PASS))
  543. {
  544. hc = 0;
  545. cc = 0;
  546. for (i=11; i <= 88; i++)
  547. {
  548. if (b[0][i] == human)
  549. hc++;
  550. else if (b[0][i] == computer)
  551. cc++;
  552. }
  553. if (hc > cc)
  554. RevMessage(hWindow, hDC, szWon, hc-cc, szWonPost);
  555. else if (hc < cc)
  556. RevMessage(hWindow, hDC, szLoss, cc-hc, szLossPost);
  557. else
  558. RevMessage(hWindow, hDC, szTie, 0, NULL);
  559. }
  560. else
  561. {
  562. RevMessage(hWindow, hDC, szMustPass, 0, NULL);
  563. }
  564. }
  565. else if (r == PASS)
  566. {
  567. RevMessage(hWindow, hDC, szPass, 0, NULL);
  568. }
  569. }
  570. /*--------------------------------------------------------------------------*/
  571. /* */
  572. /* paintmove() - */
  573. /* */
  574. /*--------------------------------------------------------------------------*/
  575. /* Make a move and show the results. */
  576. VOID NEAR PASCAL paintmove(
  577. BYTE b[BoardSize],
  578. INT move,
  579. BYTE friendly,
  580. BYTE enemy)
  581. {
  582. INT d;
  583. INT sq;
  584. INT *p;
  585. register INT i,j;
  586. INT color;
  587. if (move != PASS)
  588. {
  589. if (friendly == computer)
  590. {
  591. SelectObject(hDisp, hbrComputer);
  592. color = 1;
  593. }
  594. else
  595. {
  596. SelectObject(hDisp, hbrHuman);
  597. color = 2;
  598. }
  599. i = ((move - 11) / 10) * xExt + Bx + 2 * ASPECT;
  600. j = ((move - 11) % 10) * yExt + By + 2;
  601. Ellipse(hDisp, i, j, i + xExt - 4 * ASPECT, j + yExt - 4);
  602. flashsqr(hDisp, i, j, xExt - 4 * ASPECT, yExt - 4, color, FALSE, 4);
  603. p = direc;
  604. while ((d = *p++) != 0)
  605. {
  606. sq=move;
  607. if (b[sq += d] == enemy)
  608. {
  609. while(b[sq += d] == enemy)
  610. ;
  611. if (b[sq] == (BYTE)friendly)
  612. {
  613. while(b[sq -= d] == enemy)
  614. {
  615. board[0][sq] = b[sq] = friendly;
  616. i = ((sq - 11)/10)*xExt+Bx+2*ASPECT;
  617. j = ((sq - 11)%10)*yExt+By+2;
  618. Ellipse(hDisp, i, j, i + xExt-4*ASPECT, j + yExt-4);
  619. }
  620. }
  621. }
  622. }
  623. b[move]=friendly;
  624. }
  625. }
  626. /*--------------------------------------------------------------------------*/
  627. /* */
  628. /* RevMenu() - */
  629. /* */
  630. /*--------------------------------------------------------------------------*/
  631. /* Called on WM_COMMAND messages. */
  632. VOID NEAR PASCAL RevMenu(
  633. register HWND hWindow,
  634. INT idval)
  635. {
  636. HDC hDC;
  637. register INT cmd;
  638. if (fThinking)
  639. return;
  640. hWin = hWindow;
  641. switch (idval)
  642. {
  643. case EXIT:
  644. PostMessage(hWindow, WM_CLOSE, 0, 0L);
  645. break;
  646. case MN_HELP_ABOUT:
  647. DialogBox(hInst, MAKEINTRESOURCE(3), hWindow, AboutDlgProc);
  648. break;
  649. case MN_HELP_INDEX:
  650. //TEMPFIX WinHelp(hWindow, (LPSTR)szHelpFile, HELP_INDEX, 0L);
  651. break;
  652. case MN_HELP_USINGHELP:
  653. //TEMPFIX WinHelp(hWindow, (LPSTR)NULL, HELP_HELPONHELP, 0L);
  654. break;
  655. case MN_HELP_KEYBOARD:
  656. cmd = 0x1e;
  657. goto HelpCommon;
  658. case MN_HELP_COMMANDS:
  659. cmd = 0x20;
  660. goto HelpCommon;
  661. case MN_HELP_PLAYING:
  662. cmd = 0x21;
  663. goto HelpCommon;
  664. case MN_HELP_RULES:
  665. cmd = 0x22;
  666. HelpCommon:
  667. //TEMPFIX WinHelp(hWindow, (LPSTR)szHelpFile, HELP_CONTEXT, (DWORD)cmd);
  668. break;
  669. case HINT:
  670. ShowBestMove(hWindow);
  671. return;
  672. break;
  673. case NEW:
  674. SetWindowText(hWindow , (LPSTR)szReversi);
  675. ffirstmove = TRUE;
  676. hDisp = hDC = GetDC(hWindow);
  677. fCheated = FALSE;
  678. SetBkMode(hDisp, OPAQUE);
  679. ClearMessageTop(hDC);
  680. fPass = PASS;
  681. clearboard(board);
  682. drawboard(board);
  683. ReleaseDC(hWindow, hDC);
  684. hDisp = 0;
  685. break;
  686. case EASY:
  687. depth = 1; /* MUST BE AT LEAST 1. */
  688. checkdepth(hWindow, EASY); /* KEEP HANDS OFF! */
  689. break;
  690. case MEDIUM:
  691. depth = 2;
  692. checkdepth(hWindow, MEDIUM);
  693. break;
  694. case HARD:
  695. depth = 4;
  696. checkdepth(hWindow, HARD);
  697. break;
  698. case VHARD:
  699. depth = 6;
  700. checkdepth(hWindow, VHARD);
  701. break;
  702. case PASS:
  703. if (fPass == PASS)
  704. {
  705. hDisp = hDC = GetDC(hWindow);
  706. SetBkMode(hDisp, OPAQUE);
  707. fThinking = TRUE;
  708. ClearMessageTop(hDC);
  709. SetCursor(curThink);
  710. ReleaseDC(hWindow, hDC);
  711. hDisp = 0;
  712. minmax(board, PASS, human, computer, 0, -infin, infin);
  713. hDisp = hDC = GetDC(hWindow);
  714. paintmove(board[0], BestMove[0], (BYTE)computer, (BYTE)human);
  715. gameover(hWindow, hDC, board, BestMove[0]);
  716. SetCursor(curIllegal);
  717. fThinking = FALSE;
  718. ReleaseDC(hWindow, hDC);
  719. hDisp = 0;
  720. }
  721. else
  722. MessageBox(hWindow, (LPSTR)szNoPass, (LPSTR)szReversi, MB_OK | MB_ICONASTERISK);
  723. break;
  724. }
  725. }
  726. /*--------------------------------------------------------------------------*/
  727. /* */
  728. /* msgcheck() - */
  729. /* */
  730. /*--------------------------------------------------------------------------*/
  731. /* Called by ASM routine to allow other tasks to run. */
  732. BOOL NEAR PASCAL msgcheck()
  733. {
  734. MSG msg;
  735. if (PeekMessage((LPMSG)&msg, NULL, 0, 0, TRUE))
  736. {
  737. if (msg.message == WM_QUIT)
  738. exit(0);
  739. if (TranslateAccelerator(msg.hwnd, hAccel, (LPMSG)&msg) == 0)
  740. {
  741. TranslateMessage((LPMSG)&msg);
  742. DispatchMessage((LPMSG)&msg);
  743. }
  744. return(TRUE);
  745. }
  746. return(FALSE);
  747. }
  748. /*--------------------------------------------------------------------------*/
  749. /* */
  750. /* RevInit() - */
  751. /* */
  752. /*--------------------------------------------------------------------------*/
  753. BOOL NEAR PASCAL RevInit(
  754. HANDLE hInstance)
  755. {
  756. register PWNDCLASS pRevClass;
  757. HANDLE hbmdel;
  758. HDC hdc;
  759. static INT rgpat[] = { 170, 85, 170, 85, 170, 85, 170, 85 };
  760. hbrWhite = GetStockObject(WHITE_BRUSH);
  761. hbrBlack = GetStockObject(BLACK_BRUSH);
  762. hbmdel = CreateBitmap(8, 8, 1, 1, (LPSTR)rgpat);
  763. hbrPat = CreatePatternBrush(hbmdel);
  764. if (!hbrPat)
  765. return(FALSE);
  766. if (hbmdel)
  767. DeleteObject(hbmdel);
  768. ffirstmove = TRUE;
  769. hdc = GetDC((HWND)NULL);
  770. COLOR = GetDeviceCaps(hdc, NUMCOLORS) > 2;
  771. if (GetDeviceCaps(hdc, VERTRES) == 200)
  772. ASPECT = 2;
  773. else
  774. ASPECT = 1;
  775. ReleaseDC((HWND)NULL, hdc);
  776. hbrRed = (HBRUSH)CreateSolidBrush(RGB(0xFF,0,0));
  777. hbrGreen = (HBRUSH)CreateSolidBrush(RGB(0,0xFF,0));
  778. hbrBlue = (HBRUSH)CreateSolidBrush(RGB(0,0,0xFF));
  779. if (!hbrRed || !hbrGreen || !hbrBlue)
  780. return(FALSE);
  781. LoadString(hInstance, 3, (LPSTR)szReversi, 20);
  782. LoadString(hInstance, 4, (LPSTR)szReversiPractice, 40);
  783. LoadString(hInstance, 5, (LPSTR)szPass, 30);
  784. LoadString(hInstance, 6, (LPSTR)szMustPass, 30);
  785. LoadString(hInstance, 7, (LPSTR)szTie, 30);
  786. LoadString(hInstance, 8, (LPSTR)szLoss, 30);
  787. LoadString(hInstance, 9, (LPSTR)szWon, 30);
  788. LoadString(hInstance, 10, (LPSTR)szAbout, 20);
  789. LoadString(hInstance, 11, (LPSTR)szLossPost, 30);
  790. LoadString(hInstance, 12, (LPSTR)szWonPost, 30);
  791. LoadString(hInstance, 13, (LPSTR)szIllegal, 70);
  792. LoadString(hInstance, 14, (LPSTR)szNoPass, 70);
  793. LoadString(hInstance, 15, (LPSTR)szHelpFile, 15);
  794. hAccel = LoadAccelerators(hInstance, (LPSTR)"MAINACC");
  795. pRevClass = (PWNDCLASS)((CHAR *)LocalAlloc(LMEM_ZEROINIT, sizeof(WNDCLASS)));
  796. if (!pRevClass)
  797. return(FALSE);
  798. curLegal = LoadCursor(NULL, IDC_CROSS);
  799. curIllegal = LoadCursor(NULL, IDC_ARROW);
  800. curThink = LoadCursor(NULL, IDC_WAIT);
  801. curBlank = LoadCursor(hInstance, MAKEINTRESOURCE(1));
  802. if (!curLegal || !curIllegal || !curThink || !curBlank)
  803. return(FALSE);
  804. pRevClass->hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(3));
  805. pRevClass->lpszClassName = (LPSTR)"Reversi";
  806. pRevClass->hbrBackground = ((COLOR) ? hbrGreen : hbrWhite);
  807. pRevClass->lpfnWndProc = ReversiWndProc;
  808. pRevClass->lpszMenuName = MAKEINTRESOURCE(1);
  809. pRevClass->hInstance = hInstance;
  810. pRevClass->style = CS_VREDRAW | CS_HREDRAW | CS_BYTEALIGNCLIENT;
  811. if (!RegisterClass((LPWNDCLASS)pRevClass))
  812. {
  813. LocalFree((HANDLE)pRevClass);
  814. return(FALSE);
  815. }
  816. LocalFree((HANDLE)pRevClass);
  817. return(TRUE);
  818. }
  819. /*--------------------------------------------------------------------------*/
  820. /* */
  821. /* RevMouseClick() - */
  822. /* */
  823. /*--------------------------------------------------------------------------*/
  824. VOID NEAR PASCAL RevMouseClick(
  825. HWND hWnd,
  826. POINT point)
  827. {
  828. INT move;
  829. INT Si, Sj;
  830. INT yLineExt = 8 * yExt;
  831. INT xLineExt = 8 * xExt;
  832. HDC hDC;
  833. MousePos.x = point.x;
  834. MousePos.y = point.y;
  835. if (xExt == 0 || yExt == 0)
  836. return;
  837. if ((point.x > Bx) && (point.x < (Bx+xLineExt)) && (point.y > By) && (point.y < (By+yLineExt)))
  838. {
  839. Si = (point.x - Bx) / xExt;
  840. Sj = (point.y - By) / yExt;
  841. move = Si * 10 + Sj + 11;
  842. if (legalcheck(board[0], move, human, computer))
  843. {
  844. board[0][move] = human;
  845. ffirstmove = FALSE;
  846. fThinking = TRUE;
  847. SetCursor(curThink);
  848. hDisp = hDC = GetDC(hWnd);
  849. ClearMessageTop(hDC);
  850. minmax(board, move, human, computer, 0, -infin, infin);
  851. makemove(board[0], move, human, computer);
  852. hDisp = hDC;
  853. paintmove(board[0], BestMove[0], computer, human);
  854. gameover(hWnd, hDC, board, BestMove[0]);
  855. ReleaseDC(hWnd, hDC);
  856. hDisp = 0;
  857. SetCursor(curIllegal);
  858. fThinking = FALSE;
  859. }
  860. else
  861. MessageBox(hWnd, (LPSTR)szIllegal, (LPSTR)szReversi, MB_OK | MB_ICONASTERISK);
  862. }
  863. }
  864. /*--------------------------------------------------------------------------*/
  865. /* */
  866. /* Next() - */
  867. /* */
  868. /*--------------------------------------------------------------------------*/
  869. VOID NEAR PASCAL Next(
  870. register INT *px,
  871. register INT *py)
  872. {
  873. (*px)++;
  874. if (*px > 7)
  875. {
  876. *px = 0;
  877. (*py)++;
  878. if (*py > 7)
  879. *py = 0;
  880. }
  881. }
  882. /*--------------------------------------------------------------------------*/
  883. /* */
  884. /* Previous() - */
  885. /* */
  886. /*--------------------------------------------------------------------------*/
  887. VOID NEAR PASCAL Previous(
  888. register INT *px,
  889. register INT *py)
  890. {
  891. (*px)--;
  892. if (*px < 0)
  893. {
  894. *px = 7;
  895. (*py)--;
  896. if (*py < 0)
  897. *py = 7;
  898. }
  899. }
  900. /*--------------------------------------------------------------------------*/
  901. /* */
  902. /* ShowNextMove() - */
  903. /* */
  904. /*--------------------------------------------------------------------------*/
  905. VOID NEAR PASCAL ShowNextMove(
  906. HWND hwnd,
  907. BOOL fforward)
  908. {
  909. INT x, y;
  910. INT potentialmove;
  911. BOOL done;
  912. /* What out for infinite loops. */
  913. if (fPass == PASS && !ffirstmove)
  914. return;
  915. x = (MousePos.x - Bx) / xExt;
  916. y = (MousePos.y - By) / yExt;
  917. done = FALSE;
  918. while (!done)
  919. {
  920. do
  921. {
  922. if (fforward)
  923. Next(&x, &y);
  924. else
  925. Previous(&x, &y);
  926. }
  927. while ((board[0][potentialmove = (x * 10 + y + 11)]) != empty);
  928. fThinking = TRUE;
  929. if (legalcheck(board[0], potentialmove, human, computer))
  930. done = TRUE;
  931. fThinking = FALSE;
  932. }
  933. MousePos.x = x * xExt + Bx + xExt / 2;
  934. MousePos.y = y * yExt + By + yExt / 2;
  935. UpdateCursor(hwnd);
  936. RevMouseMove(MousePos);
  937. }
  938. /*--------------------------------------------------------------------------*/
  939. /* */
  940. /* RevChar() - */
  941. /* */
  942. /*--------------------------------------------------------------------------*/
  943. VOID NEAR PASCAL RevChar(
  944. HWND hwnd,
  945. register WORD code)
  946. {
  947. INT a;
  948. POINT curpoint;
  949. curpoint.x = curpoint.y = 1;
  950. switch (code)
  951. {
  952. case 0x27:
  953. MousePos.x += xExt;
  954. break;
  955. case 0x28:
  956. MousePos.y += yExt;
  957. break;
  958. case 0x25:
  959. curpoint.x = (MousePos.x - Bx)/xExt;
  960. MousePos.x -= xExt;
  961. break;
  962. case 0x26:
  963. curpoint.y = (MousePos.y - By)/yExt;
  964. MousePos.y -= yExt;
  965. break;
  966. case 0x24:
  967. curpoint.y = (MousePos.y - By)/yExt;
  968. curpoint.x = (MousePos.x - Bx)/xExt;
  969. MousePos.y -= yExt;
  970. MousePos.x -= xExt;
  971. break;
  972. case 0x21:
  973. curpoint.y = (MousePos.y - By)/yExt;
  974. MousePos.y -= yExt;
  975. MousePos.x += xExt;
  976. break;
  977. case 0x23:
  978. curpoint.x = (MousePos.x - Bx)/xExt;
  979. MousePos.y += yExt;
  980. MousePos.x -= xExt;
  981. break;
  982. case 0x22:
  983. MousePos.y += yExt;
  984. MousePos.x += xExt;
  985. break;
  986. case 0x0020:
  987. case 0x000D:
  988. if (!fThinking)
  989. RevMouseClick(hwnd, MousePos);
  990. return;
  991. case 0x0009:
  992. if (fThinking)
  993. break;
  994. if (GetKeyState(VK_SHIFT) < 0)
  995. ShowNextMove(hwnd, FALSE); /* look backwards */
  996. else
  997. ShowNextMove(hwnd, TRUE); /* look forwards */
  998. return;
  999. default:
  1000. return;
  1001. }
  1002. if (((a = ((MousePos.x - Bx) / xExt)) >7) || a <= 0)
  1003. MousePos.x = Bx + xExt / 2; /* wrap around horizontally */
  1004. if (a > 8 || (curpoint.x == 0 && a == 0))
  1005. MousePos.x = (7*xExt) + Bx + xExt / 2 ;
  1006. if ( ((a = ((MousePos.y - By) / yExt)) >7) || a <= 0)
  1007. MousePos.y = By + yExt / 2;
  1008. if ( a > 8 || (curpoint.y == 0 && a == 0))
  1009. MousePos.y = (7*yExt) + By + yExt / 2;
  1010. MousePos.x = ((MousePos.x - Bx) / xExt) * xExt + Bx + xExt / 2;
  1011. MousePos.y = ((MousePos.y - By) / yExt) * yExt + By + yExt / 2;
  1012. UpdateCursor(hwnd);
  1013. RevMouseMove(MousePos);
  1014. }
  1015. /*--------------------------------------------------------------------------*/
  1016. /* */
  1017. /* InverseMessage() - */
  1018. /* */
  1019. /*--------------------------------------------------------------------------*/
  1020. VOID APIENTRY InverseMessage(
  1021. register HWND hWindow,
  1022. UINT message,
  1023. UINT_PTR wParam,
  1024. DWORD lParam)
  1025. {
  1026. HDC hDC;
  1027. message;
  1028. wParam;
  1029. lParam;
  1030. if (flashtimes <= count)
  1031. {
  1032. hDC = GetDC(hWindow);
  1033. PatBlt(hDC, 0, 0, xscr, charheight, DSTINVERT);
  1034. flashtimes++;
  1035. ReleaseDC(hWindow, hDC);
  1036. }
  1037. else
  1038. KillTimer(hWindow, 666);
  1039. return;
  1040. }
  1041. /*--------------------------------------------------------------------------*/
  1042. /* */
  1043. /* ReversiWndProc() - */
  1044. /* */
  1045. /*--------------------------------------------------------------------------*/
  1046. LRESULT APIENTRY ReversiWndProc(
  1047. HWND hWnd,
  1048. register UINT message,
  1049. WPARAM wParam,
  1050. LPARAM lParam)
  1051. {
  1052. HMENU hm;
  1053. PAINTSTRUCT ps;
  1054. POINT curpoint;
  1055. switch (message)
  1056. {
  1057. case WM_COMMAND:
  1058. RevMenu(hWnd, GET_WM_COMMAND_ID(wParam, lParam));
  1059. break;
  1060. case WM_INITMENU: /* disable the menu if thinking */
  1061. hm = GetMenu(hWnd);
  1062. if (fThinking)
  1063. {
  1064. EnableMenuItem(hm, 0, MF_DISABLED | MF_BYPOSITION);
  1065. EnableMenuItem(hm, 1, MF_DISABLED | MF_BYPOSITION);
  1066. }
  1067. else
  1068. {
  1069. EnableMenuItem(hm, 0, MF_ENABLED | MF_BYPOSITION);
  1070. EnableMenuItem(hm, 1, MF_ENABLED | MF_BYPOSITION);
  1071. }
  1072. break;
  1073. case WM_CREATE:
  1074. RevCreate(hWnd);
  1075. hWin = hWnd;
  1076. break;
  1077. case WM_CLOSE:
  1078. if (hDisp)
  1079. ReleaseDC(hWnd, hDisp);
  1080. return(DefWindowProc(hWnd, message, wParam, lParam));
  1081. case WM_DESTROY:
  1082. if (MGetModuleUsage(hInst) == 1)
  1083. {
  1084. DeleteObject(hbrGreen);
  1085. DeleteObject(hbrPat);
  1086. DeleteObject(hbrRed);
  1087. DeleteObject(hbrBlue);
  1088. }
  1089. /* In case WinHelp keys off hWindow, we need to do the HELP_QUIT
  1090. * here instead of when there is just one instance of help...
  1091. */
  1092. //TEMPFIX WinHelp(hWnd, (LPSTR)szHelpFile, HELP_QUIT, 0L);
  1093. PostQuitMessage(0);
  1094. break;
  1095. case WM_KEYDOWN:
  1096. if (IsIconic(hWnd))
  1097. return 0L;
  1098. RevChar(hWnd, (WORD)wParam);
  1099. break;
  1100. case WM_ACTIVATE:
  1101. if (!GetSystemMetrics(SM_MOUSEPRESENT))
  1102. {
  1103. if (GET_WM_ACTIVATE_STATE(wParam, lParam))
  1104. {
  1105. if (GET_WM_ACTIVATE_HWND(wParam, lParam) != hWnd)
  1106. {
  1107. curpoint.x = MousePos.x;
  1108. curpoint.y = MousePos.y;
  1109. ClientToScreen(hWnd, (LPPOINT)&curpoint);
  1110. SetCursorPos(curpoint.x, curpoint.y);
  1111. RevMouseMove(MousePos);
  1112. ShowCursor(GET_WM_ACTIVATE_STATE(wParam, lParam));
  1113. }
  1114. }
  1115. else
  1116. ShowCursor((BOOL) wParam);
  1117. }
  1118. if (wParam && (!HIWORD(lParam)))
  1119. SetFocus(hWnd);
  1120. break;
  1121. case WM_PAINT:
  1122. BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
  1123. RevPaint(hWnd, ps.hdc);
  1124. EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
  1125. break;
  1126. case WM_MOUSEMOVE:
  1127. {
  1128. POINT pt;
  1129. LONG2POINT(lParam, pt); /* convert LONG lParam to POINT structure*/
  1130. if (!fThinking)
  1131. #ifdef ORGCODE
  1132. RevMouseMove(MAKEPOINT(lParam));
  1133. #else
  1134. RevMouseMove(pt);
  1135. #endif
  1136. else
  1137. SetCursor(curThink);
  1138. break;
  1139. }
  1140. case WM_LBUTTONDOWN:
  1141. SetCapture(hWnd);
  1142. bMouseDownInReversi = TRUE;
  1143. break;
  1144. case WM_LBUTTONUP:
  1145. {
  1146. POINT pt;
  1147. LONG2POINT(lParam, pt); /* convert LONG lParam to POINT structure*/
  1148. ReleaseCapture();
  1149. if (!fThinking && bMouseDownInReversi)
  1150. #ifdef ORGCODE
  1151. RevMouseClick(hWnd, MAKEMPOINT(lParam));
  1152. #else
  1153. RevMouseClick(hWnd, pt);
  1154. #endif
  1155. bMouseDownInReversi = FALSE;
  1156. break;
  1157. }
  1158. case WM_TIMER:
  1159. /* This should never be called. */
  1160. break;
  1161. case WM_VSCROLL:
  1162. case WM_HSCROLL:
  1163. break;
  1164. default:
  1165. return(DefWindowProc(hWnd, message, wParam, lParam));
  1166. break;
  1167. }
  1168. return(0L);
  1169. }
  1170. /*--------------------------------------------------------------------------*/
  1171. /* */
  1172. /* AboutDlgProc() */
  1173. /* */
  1174. /*--------------------------------------------------------------------------*/
  1175. INT_PTR APIENTRY AboutDlgProc(
  1176. HWND hDlg,
  1177. UINT message,
  1178. WPARAM wParam,
  1179. LPARAM lParam)
  1180. {
  1181. if (message == WM_COMMAND)
  1182. {
  1183. EndDialog(hDlg, TRUE);
  1184. return(TRUE);
  1185. }
  1186. if (message == WM_INITDIALOG)
  1187. return(TRUE);
  1188. else
  1189. return(FALSE);
  1190. UNREFERENCED_PARAMETER(wParam);
  1191. UNREFERENCED_PARAMETER(lParam);
  1192. }
  1193. /*--------------------------------------------------------------------------*/
  1194. /* */
  1195. /* WinMain() - */
  1196. /* */
  1197. /*--------------------------------------------------------------------------*/
  1198. MMain(hInstance, hPrev, lpszCmdLine, cmdShow) /* { */
  1199. HWND hWnd;
  1200. MSG msg;
  1201. _argc;
  1202. _argv;
  1203. hInst = hInstance;
  1204. if (!hPrev)
  1205. {
  1206. if (!RevInit(hInstance))
  1207. return(FALSE);
  1208. }
  1209. else
  1210. {
  1211. if (fThinking)
  1212. return FALSE;
  1213. #ifdef WIN16
  1214. GetInstanceData(hPrev, (PSTR)&hbrBlack, sizeof(HBRUSH));
  1215. GetInstanceData(hPrev, (PSTR)&hbrPat, sizeof(HBRUSH));
  1216. GetInstanceData(hPrev, (PSTR)&hbrWhite, sizeof(HBRUSH));
  1217. GetInstanceData(hPrev, (PSTR)&hbrRed, sizeof(HBRUSH));
  1218. GetInstanceData(hPrev, (PSTR)&hbrBlue, sizeof(HBRUSH));
  1219. GetInstanceData(hPrev, (PSTR)&hbrGreen, sizeof(HBRUSH));
  1220. GetInstanceData(hPrev, (PSTR)&hbrComputer, sizeof(HBRUSH));
  1221. GetInstanceData(hPrev, (PSTR)&hbrHuman, sizeof(HBRUSH));
  1222. GetInstanceData(hPrev, (PSTR)&curIllegal, sizeof(HCURSOR));
  1223. GetInstanceData(hPrev, (PSTR)&curLegal, sizeof(HCURSOR));
  1224. GetInstanceData(hPrev, (PSTR)&curThink, sizeof(HCURSOR));
  1225. GetInstanceData(hPrev, (PSTR)&curBlank, sizeof(HCURSOR));
  1226. GetInstanceData(hPrev, (PSTR)&prevCheck, sizeof(prevCheck));
  1227. GetInstanceData(hPrev, (PSTR)&depth, sizeof(depth));
  1228. GetInstanceData(hPrev, (PSTR)direc, sizeof(direc));
  1229. GetInstanceData(hPrev, (PSTR)moves, sizeof(moves));
  1230. GetInstanceData(hPrev, (PSTR)szReversi, 20);
  1231. GetInstanceData(hPrev, (PSTR)szReversiPractice, 40);
  1232. GetInstanceData(hPrev, (PSTR)szPass, 10);
  1233. GetInstanceData(hPrev, (PSTR)szMustPass, 20);
  1234. GetInstanceData(hPrev, (PSTR)szTie, 15);
  1235. GetInstanceData(hPrev, (PSTR)szLoss, 15);
  1236. GetInstanceData(hPrev, (PSTR)szWon, 15);
  1237. GetInstanceData(hPrev, (PSTR)szAbout, 20);
  1238. GetInstanceData(hPrev, (PSTR)&COLOR, sizeof(INT));
  1239. GetInstanceData(hPrev, (PSTR)&ASPECT, sizeof(INT));
  1240. GetInstanceData(hPrev, (PSTR)&hAccel, 2);
  1241. GetInstanceData(hPrev, (PSTR)szIllegal, 70);
  1242. GetInstanceData(hPrev, (PSTR)szNoPass, 70);
  1243. GetInstanceData(hPrev, (PSTR)szHelpFile, 15);
  1244. #endif /* WIN16 */
  1245. }
  1246. TYMIN = 45;
  1247. fThinking = FALSE;
  1248. hWnd = CreateWindow((LPSTR) "Reversi",
  1249. fCheated ? (LPSTR)szReversiPractice : (LPSTR)szReversi,
  1250. WS_TILEDWINDOW,
  1251. CW_USEDEFAULT,
  1252. 0,
  1253. (GetSystemMetrics(SM_CXSCREEN) >> 1),
  1254. (GetSystemMetrics(SM_CYSCREEN) * 4 / 5),
  1255. (HANDLE)NULL,
  1256. (HANDLE)NULL,
  1257. (HANDLE)hInstance,
  1258. NULL);
  1259. if (!hWnd)
  1260. return(FALSE);
  1261. ShowWindow(hWnd, cmdShow);
  1262. UpdateWindow(hWnd);
  1263. /* Messaging Loop. */
  1264. while (GetMessage((LPMSG)&msg, NULL, 0, 0))
  1265. {
  1266. if (!TranslateAccelerator(msg.hwnd, hAccel, (LPMSG)&msg))
  1267. {
  1268. TranslateMessage((LPMSG)&msg);
  1269. DispatchMessage((LPMSG)&msg);
  1270. }
  1271. }
  1272. return(0);
  1273. }
  1274.