1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
32
33
36
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
139
140
141
144
145
146
147
148
149
150
151
152
153
154
155
162
169
170
177
183
184
191
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
221
222
223
224
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
247
248
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
273
274
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
300
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
334
335
336
337
338
339
340
341
342
345
346
348
349
350
351
352
353
355
356
357
358
359
364
365
366
367
368
371
372
373
374
391
392
393
394
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
419
422
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
451
452
461
462
463
465
466
467
468
469
470
471
472
473
490
494
495
496
497
498
499
500
507
508
509
510
511
516
517
518
519
520
521
528
529
533
534
535
538
539
540
541
546
563
564
571
572
573
574
575
576
577
578
579
580
581
582
591
592
593
594
595
596
597
598
603
604
605
606
607
608
613
614
615
616
617
618
619
620
621
622
623
645
646
647
648
653
667
668
673
674
675
676
677
678
679
680
681
682
683
684
691
715
716
721
728
729
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
759
762
763
764
765
766
767
768
769
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
808
825
826
833
834
835
836
837
838
839
840
841
842
843
844
845
846
849
850
/* ... */
#include "DIALOG.h"
#include "k_module.h"
#include "game_res.c"
/* ... */
/* ... */
Includes
static void Startup(WM_HWIN hWin, uint16_t xpos, uint16_t ypos);
Private function prototypes
K_ModuleItem_Typedef game_board =
{
2,
"Game",
&bmgame,
Startup,
NULL,
...}
;
Private typedef
#define ID_FRAMEWIN_INFO (GUI_ID_USER + 0x01)
#define ID_IMAGE_INFO (GUI_ID_USER + 0x02)
#define ID_BUTTON_INFO_CLOSE (GUI_ID_USER + 0x03)
#define NUM_CELL_X 8
#define NUM_CELL_Y 8
#define AA_USE_HIRES 0
#define AA_FACTOR 1
7 defines
#if AA_USE_HIRES
#define AA_CALCFACTOR AA_FACTOR
#else
#define AA_CALCFACTOR 1
#endif
#define CLIENT_COLOR GUI_TRANSPARENT
#define GRID_COLOR GUI_BROWN
#define DEPTH 4
#define END_GAME_DEPTH 9
#define INFINITY 1000000
#define WINNING_BONUS 100000
#define VALUE_OF_A_MOVE_POSSIBILITY 15
#define VALUE_OF_AN_UNSAFE_PIECE 8
#define VALUE_OF_A_SAFE_PIECE 20
#define VALUE_OF_A_CORNER 1000
10 defines
Private defines
typedef struct {
U8 aCells[NUM_CELL_X][NUM_CELL_Y];
U8 aMoves[NUM_CELL_X][NUM_CELL_Y];
int ActPlayer;
...} BOARD;
typedef char REVERSI_AI_Func(const BOARD * pBoard, int* px, int* py);
static WM_HWIN _hFrame;
static REVERSI_AI_Func* _pPlayerAI[2];
static BOARD _Board;
static int _GameOver;
static int _BoardX0;
static int _BoardY0;
static int _CellSize;
static int _ShowPossibleMoves = 1;
static int * _px;
static int * _py;
static BOARD _aBoardStack[END_GAME_DEPTH + 1];
static const int _xs[60] = {
7, 7, 0, 0, 7, 7, 5, 5, 2, 2,
0, 0, 5, 5, 2, 2, 5, 5, 4, 4,
3, 3, 2, 2, 7, 7, 4, 4, 3, 3,
0, 0, 6, 6, 6, 6, 5, 5, 4, 4,
3, 3, 2, 2, 1, 1, 1, 1, 7, 7,
6, 6, 1, 1, 0, 0, 6, 6, 1, 1
...};
static const int _ys[60] = {
7, 0, 7, 0, 5, 2, 7, 0, 7, 0,
5, 2, 5, 2, 5, 2, 4, 3, 5, 2,
5, 2, 4, 3, 4, 3, 7, 0, 7, 0,
4, 3, 5, 4, 3, 2, 6, 1, 6, 1,
6, 1, 6, 1, 5, 4, 3, 2, 6, 1,
7, 0, 7, 0, 6, 1, 6, 1, 6, 1
...};
static int _aaSafe[10][10];
static const I32 _aaValues[8][8] = {
{ 1000, -100, 25, 0, 0, 25, -100, 1000 },
{ -100, -400, -5, -5, -5, -5, -400, -100 },
{ 25, -5, 12, 2, 2, 12, -5, 25 },
{ 0, -5, 2, 2, 2, 2, -5, 0 },
{ 0, -5, 2, 2, 2, 2, -5, 0 },
{ 25, -5, 12, 2, 2, 12, -5, 25 },
{ -100, -400, -5, -5, -5, -5, -400, -100 },
{ 1000, -100, 25, 0, 0, 25, -100, 1000 }
...};
Private variables
static void _StartNewGame(void);
static void _CalcBoardDimensions(void) {
GUI_RECT r;
WM_GetClientRectEx(WM_GetClientWindow(_hFrame), &r);
_CellSize = ((r.x1 > r.y1) ? r.y1 : r.x1) >> 3;
_BoardX0 = (r.x1 - (_CellSize << 3)) >> 1;
_BoardY0 = (r.y1 - (_CellSize << 3)) >> 1;
}{ ... }
static void _InvalidateBoard(void) {
WM_InvalidateWindow(WM_GetClientWindow(_hFrame));
}{ ... }
static void _InvalidateCell(int x, int y) {
GUI_RECT r;
r.x0 = _BoardX0 + (x * _CellSize);
r.y0 = _BoardY0 + (y * _CellSize);
r.x1 = r.x0 + _CellSize - 1;
r.y1 = r.y0 + _CellSize - 1;
WM_InvalidateRect(WM_GetClientWindow(_hFrame), &r);
}{ ... }
/* ... */
static char _GetStone(const BOARD * pBoard, int x, int y) {
char r = 0;
if ((x >= 0) && (y >= 0) && (x < NUM_CELL_X) && (y < NUM_CELL_Y)) {
r = pBoard->aCells[x][y];
}if ((x >= 0) && (y >= 0) && (x < NUM_CELL_X) && (y < NUM_CELL_Y)) { ... }
return r;
}{ ... }
/* ... */
static void _SetStone(BOARD * pBoard, int x, int y) {
if ((x >= 0) && (y >= 0) && (x < NUM_CELL_X) && (y < NUM_CELL_Y)) {
pBoard->aCells[x][y] = pBoard->ActPlayer;
_InvalidateCell(x, y);
}if ((x >= 0) && (y >= 0) && (x < NUM_CELL_X) && (y < NUM_CELL_Y)) { ... }
}{ ... }
/* ... */
static char _IsValidMove(BOARD * pBoard, int x, int y) {
char r = 0;
if ((x >= 0) && (y >= 0) && (x < NUM_CELL_X) && (y < NUM_CELL_Y)) {
r = ((pBoard->aMoves[x][y]) ? 1 : 0);
}if ((x >= 0) && (y >= 0) && (x < NUM_CELL_X) && (y < NUM_CELL_Y)) { ... }
return r;
}{ ... }
/* ... */
static char _CheckDirection(const BOARD * pBoard, int x, int y, int dx, int dy) {
char Cell;
x += dx;
y += dy;
Cell = _GetStone(pBoard, x, y);
if ((Cell != pBoard->ActPlayer) && (Cell != 0)) {
do {
x += dx;
y += dy;
Cell = _GetStone(pBoard, x, y);
...} while ((Cell != pBoard->ActPlayer) && (Cell != 0));
return ((Cell == pBoard->ActPlayer) ? 1 : 0);
}if ((Cell != pBoard->ActPlayer) && (Cell != 0)) { ... }
return 0;
}{ ... }
/* ... */
static int _CalcValidMoves(BOARD * pBoard) {
int x, y, r = 0;
U8 Valid;
for (y = 0; y < NUM_CELL_Y; y++) {
for (x = 0; x < NUM_CELL_X; x++) {
Valid = 0;
if (pBoard->aCells[x][y] == 0) {
Valid |= _CheckDirection(pBoard, x, y, -1, -1) << 0;
Valid |= _CheckDirection(pBoard, x, y, 0, -1) << 1;
Valid |= _CheckDirection(pBoard, x, y, 1, -1) << 2;
Valid |= _CheckDirection(pBoard, x, y, 1, 0) << 3;
Valid |= _CheckDirection(pBoard, x, y, 1, 1) << 4;
Valid |= _CheckDirection(pBoard, x, y, 0, 1) << 5;
Valid |= _CheckDirection(pBoard, x, y, -1, 1) << 6;
Valid |= _CheckDirection(pBoard, x, y, -1, 0) << 7;
if (Valid) {
r++;
}if (Valid) { ... }
}if (pBoard->aCells[x][y] == 0) { ... }
if (Valid != pBoard->aMoves[x][y]) {
pBoard->aMoves[x][y] = Valid;
_InvalidateCell(x, y);
}if (Valid != pBoard->aMoves[x][y]) { ... }
}for (x = 0; x < NUM_CELL_X; x++) { ... }
}for (y = 0; y < NUM_CELL_Y; y++) { ... }
return r;
}{ ... }
/* ... */
static void _DoDirection(BOARD * pBoard, int x, int y, int dx, int dy) {
do {
_SetStone(pBoard, x, y);
x += dx;
y += dy;
...} while (_GetStone(pBoard, x, y) != pBoard->ActPlayer);
}{ ... }
/* ... */
static void _MakeMove(BOARD * pBoard, int x, int y) {
U8 Valid;
_SetStone(pBoard, x, y);
Valid = pBoard->aMoves[x][y];
if (Valid & (U8)(1 << 0)) { _DoDirection(pBoard, x, y, -1, -1); }
if (Valid & (U8)(1 << 1)) { _DoDirection(pBoard, x, y, 0, -1); }
if (Valid & (U8)(1 << 2)) { _DoDirection(pBoard, x, y, 1, -1); }
if (Valid & (U8)(1 << 3)) { _DoDirection(pBoard, x, y, 1, 0); }
if (Valid & (U8)(1 << 4)) { _DoDirection(pBoard, x, y, 1, 1); }
if (Valid & (U8)(1 << 5)) { _DoDirection(pBoard, x, y, 0, 1); }
if (Valid & (U8)(1 << 6)) { _DoDirection(pBoard, x, y, -1, 1); }
if (Valid & (U8)(1 << 7)) { _DoDirection(pBoard, x, y, -1, 0); }
}{ ... }
/* ... */
static int _CalcScore(const BOARD * pBoard) {
int x, y, r = 0;
char Cell;
for (y = 0; y < NUM_CELL_Y; y++) {
for (x = 0; x < NUM_CELL_X; x++) {
Cell = pBoard->aCells[x][y];
if (Cell) {
r += (Cell == pBoard->ActPlayer) ? (1) : (-1);
}if (Cell) { ... }
}for (x = 0; x < NUM_CELL_X; x++) { ... }
}for (y = 0; y < NUM_CELL_Y; y++) { ... }
return r;
}{ ... }
/* ... */
static I32 _valuePieces(BOARD * pBoard, int player) {
I32 sum;
int x, y, corners, changed, s, xCorner, yCorner, numberOfSafe;
sum = 0;
for (y = 1; y <= 8; y++) {
for (x = 1; x <= 8; x++) {
_aaSafe[x][y] = 0;
}for (x = 1; x <= 8; x++) { ... }
}for (y = 1; y <= 8; y++) { ... }
corners = 0;
corners += pBoard->aCells[0][0] == player;
corners += pBoard->aCells[7][0] == player;
corners += pBoard->aCells[0][7] == player;
corners += pBoard->aCells[7][7] == player;
if (corners) {
sum += corners * VALUE_OF_A_CORNER;
/* ... */
while (1) {
/* ... */
changed = 0;
numberOfSafe = 0;
for (y = 1; y <= 8; y++) {
for (x = 1; x <= 8; x++) {
if (!_aaSafe[x][y] && pBoard->aCells[x - 1][y - 1] == player) {
/* ... */
s = (_aaSafe[x - 1][y ] || _aaSafe[x + 1][y ])
&& (_aaSafe[x ][y - 1] || _aaSafe[x ][y + 1])
&& (_aaSafe[x - 1][y - 1] || _aaSafe[x + 1][y + 1])
&& (_aaSafe[x - 1][y + 1] || _aaSafe[x + 1][y - 1]);
if (s) {
_aaSafe[x][y] = 1;
changed = 1;
++numberOfSafe;
}if (s) { ... }
}if (!_aaSafe[x][y] && pBoard->aCells[x - 1][y - 1] == player) { ... }
}for (x = 1; x <= 8; x++) { ... }
sum += numberOfSafe * VALUE_OF_A_SAFE_PIECE;
}for (y = 1; y <= 8; y++) { ... }
if (!changed) {
break;
}if (!changed) { ... }
}while (1) { ... }
}if (corners) { ... }
for (y = 0; y < 8; y++) {
yCorner = (y < 4) ? 0 : 7;
for (x = 0; x < 8; x++) {
if (pBoard->aCells[x][y] == player && !_aaSafe[x + 1][y + 1]) {
xCorner = x<4 ? 0 : 7;
if (pBoard->aCells[xCorner][yCorner]) {
/* ... */
sum += VALUE_OF_AN_UNSAFE_PIECE;
}if (pBoard->aCells[xCorner][yCorner]) { ... } else {
/* ... */
sum += _aaValues[x][y];
}else { ... }
}if (pBoard->aCells[x][y] == player && !_aaSafe[x + 1][y + 1]) { ... }
}for (x = 0; x < 8; x++) { ... }
}for (y = 0; y < 8; y++) { ... }
return sum;
}{ ... }
/* ... */
static I32 _Eval(BOARD * pBoard) {
int ActPlayer, movesA, movesB;
I32 score, value;
ActPlayer = pBoard->ActPlayer;
pBoard->ActPlayer = 1;
movesA = _CalcValidMoves(pBoard);
pBoard->ActPlayer = 2;
movesB = _CalcValidMoves(pBoard);
pBoard->ActPlayer = ActPlayer;
if (movesA == 0 && movesB == 0) {
pBoard->ActPlayer = 1;
score = _CalcScore(pBoard);
pBoard->ActPlayer = ActPlayer;
if (score==0) {
return 0;
}if (score==0) { ... }
if (score > 0) {
return score + WINNING_BONUS;
}if (score > 0) { ... }
if (score > 0) {
return score - WINNING_BONUS;
}if (score > 0) { ... }
}if (movesA == 0 && movesB == 0) { ... }
value = VALUE_OF_A_MOVE_POSSIBILITY * (movesA - movesB);
value += _valuePieces(pBoard, 1);
value -= _valuePieces(pBoard, 2);
return value;
}{ ... }
/* ... */
static I32 _Descend(int depth, I32 alpha, I32 beta, int firstMove) {
BOARD * pBoard;
BOARD * nextBoard;
int x, y, moves, i, alt, maximize;
pBoard = _aBoardStack + depth;
nextBoard = _aBoardStack + depth - 1;
if (depth == 0) {
return _Eval(pBoard);
}if (depth == 0) { ... }
moves = _CalcValidMoves(pBoard);
if (moves == 0) {
pBoard->ActPlayer = 3 - pBoard->ActPlayer;
moves = _CalcValidMoves(pBoard);
if (moves == 0) {
return _Eval(pBoard);
}if (moves == 0) { ... }
}if (moves == 0) { ... }
maximize = pBoard->ActPlayer == 1;
for (i = 0; i < 60; ++i) {
/* ... */
x = _xs[i];
y = _ys[i];
if (pBoard->aMoves[x][y]) {
*nextBoard = *pBoard;
_MakeMove(nextBoard, x, y);
nextBoard->ActPlayer = 3 - pBoard->ActPlayer;
alt = _Descend(depth - 1, alpha, beta, 0);
if (maximize) {
if (alt > alpha) {
alpha = alt;
if (firstMove) {
*_px = x;
*_py = y;
}if (firstMove) { ... }
}if (alt > alpha) { ... }
}if (maximize) { ... } else {
if (alt < beta) {
beta = alt;
if (firstMove) {
*_px = x;
*_py = y;
}if (firstMove) { ... }
}if (alt < beta) { ... }
}else { ... }
if (beta <= alpha) {
goto end;
}if (beta <= alpha) { ... }
}if (pBoard->aMoves[x][y]) { ... }
}for (i = 0; i < 60; ++i) { ... }
end:
return maximize ? alpha : beta;
}{ ... }
/* ... */
static char _PlayerAI_SmartGecko(const BOARD * pBoard, int * px, int * py) {
int x, y, freeTiles, depth;
for (y = 0; y < 10; y++) {
for (x = 0; x < 10; x++) {
_aaSafe[x][y] = 1;
}for (x = 0; x < 10; x++) { ... }
}for (y = 0; y < 10; y++) { ... }
*px = -1;
*py = -1;
_px = px;
_py = py;
freeTiles = 0;
for (y = 0; y < 8; y++) {
for (x = 0; x < 8; x++) {
if (!pBoard->aCells[x][y]) {
++freeTiles;
}if (!pBoard->aCells[x][y]) { ... }
}for (x = 0; x < 8; x++) { ... }
}for (y = 0; y < 8; y++) { ... }
depth = DEPTH;
if (freeTiles <= END_GAME_DEPTH) {
depth = freeTiles;
}if (freeTiles <= END_GAME_DEPTH) { ... }
_aBoardStack[depth] = *pBoard;
_Descend(depth, -INFINITY, INFINITY, 1);
if (*px == -1) {
return 0;
}if (*px == -1) { ... }
return 1;
}{ ... }
/* ... */
static void _cbMessageBox(WM_MESSAGE* pMsg) {
WM_HWIN hWin;
int Id;
hWin = pMsg->hWin;
switch (pMsg->MsgId) {
case WM_NOTIFY_PARENT:
if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) {
Id = WM_GetId(pMsg->hWinSrc);
GUI_EndDialog(hWin, (Id == GUI_ID_OK) ? 1 : 0);
}if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) { ... }
break;case WM_NOTIFY_PARENT:
default:
WM_DefaultProc(pMsg);default
}switch (pMsg->MsgId) { ... }
}{ ... }
/* ... */
static int _ShowMessageBox(WM_HWIN hWin, const char* pTitle, const char* pText, int YesNo) {
WM_HWIN hFrame, hClient, hBut;
int r = 0;
hFrame = FRAMEWIN_CreateEx(65, 62, 190, 90, hWin, WM_CF_SHOW, FRAMEWIN_CF_MOVEABLE, 0, pTitle, &_cbMessageBox);
FRAMEWIN_SetClientColor (hFrame, GUI_WHITE);
FRAMEWIN_SetFont (hFrame, &GUI_Font16B_ASCII);
FRAMEWIN_SetTextAlign (hFrame, GUI_TA_HCENTER);
hClient = WM_GetClientWindow(hFrame);
TEXT_CreateEx(10, 7, 170, 30, hClient, WM_CF_SHOW, GUI_TA_HCENTER, 0, pText);
if (YesNo) {
hBut = BUTTON_CreateEx(97, 45, 55, 18, hClient, WM_CF_SHOW, 0, GUI_ID_CANCEL);
BUTTON_SetText (hBut, "No");
hBut = BUTTON_CreateEx(32, 45, 55, 18, hClient, WM_CF_SHOW, 0, GUI_ID_OK);
BUTTON_SetText (hBut, "Yes");
}if (YesNo) { ... } else {
hBut = BUTTON_CreateEx(64, 45, 55, 18, hClient, WM_CF_SHOW, 0, GUI_ID_OK);
BUTTON_SetText (hBut, "Ok");
}else { ... }
WM_SetFocus(_hFrame);
WM_MakeModal(hFrame);
r = GUI_ExecCreatedDialog(hFrame);
return r;
}{ ... }
/* ... */
static void _SetPlayer(int Player) {
int Score, ValidMoves, PossibleMoves;
char ac[256];
_Board.ActPlayer = Player;
if (Player == 1) {
FRAMEWIN_SetText(_hFrame, "Reversi - User");
}if (Player == 1) { ... } else {
FRAMEWIN_SetText(_hFrame, "Reversi - CPU");
}else { ... }
FRAMEWIN_SetBarColor(_hFrame, 1, (Player == 1) ? GUI_RED : GUI_BLUE);
PossibleMoves = _CalcValidMoves(&_Board);
GUI_Exec();
if (!PossibleMoves) {
GUI_Exec();
_Board.ActPlayer = 3 - Player;
ValidMoves = _CalcValidMoves(&_Board);
_Board.ActPlayer = Player;
_CalcValidMoves(&_Board);
if (ValidMoves) {
if (_pPlayerAI[_Board.ActPlayer - 1] == NULL) {
_ShowMessageBox(_hFrame, "Reversi", "No possible moves.\nYou have to pass!", 0);
}if (_pPlayerAI[_Board.ActPlayer - 1] == NULL) { ... } else {
}else { ... }
_SetPlayer(3 - _Board.ActPlayer);
}if (ValidMoves) { ... } else {
_GameOver = 1;
_Board.ActPlayer = 1;
Score = _CalcScore(&_Board);
if (Score > 0) {
sprintf(ac, "Red wins by %d stones!\nDo you want to start a new game?", Score);
}if (Score > 0) { ... } else if (Score) {
sprintf(ac, "Blue wins by %d stones!\nDo you want to start a new game?", -Score);
}else if (Score) { ... } else {
strcpy(ac, "The game ends in a draw!\nDo you want to start a new game?");
}else { ... }
if (_ShowMessageBox(_hFrame, "Reversi", ac, 1)) {
_StartNewGame();
}if (_ShowMessageBox(_hFrame, "Reversi", ac, 1)) { ... }
}else { ... }
}if (!PossibleMoves) { ... }
}{ ... }
/* ... */
static void _NextPlayer(void) {
int x, y;
do {
_SetPlayer(3 - _Board.ActPlayer);
if (_pPlayerAI[_Board.ActPlayer - 1]&& !_GameOver) {
char DoMove;
DoMove = (*_pPlayerAI[_Board.ActPlayer - 1])(&_Board, &x, &y);
if (DoMove) {
_MakeMove(&_Board, x, y);
}if (DoMove) { ... }
}if (_pPlayerAI[_Board.ActPlayer - 1]&& !_GameOver) { ... }
...} while (_pPlayerAI[_Board.ActPlayer - 1] && !_GameOver);
}{ ... }
/* ... */
static void _StartNewGame(void) {
memset(&_Board, 0, sizeof(BOARD));
_Board.aCells[3][3] = 1;
_Board.aCells[4][4] = 1;
_Board.aCells[3][4] = 2;
_Board.aCells[4][3] = 2;
_GameOver = 0;
_SetPlayer(1);
_InvalidateBoard();
}{ ... }
/* ... */
static void _HandlePID(int x, int y, int Pressed) {
static int _IsInHandlePID;
if (_IsInHandlePID++ == 0) {
_CalcBoardDimensions();
x -= _BoardX0;
y -= _BoardY0;
if ((x >= 0) && (y >= 0)) {
x /= _CellSize;
y /= _CellSize;
if ((x < 8) && (y < 8)) {
if (_IsValidMove(&_Board, x, y)) {
if (Pressed == 0) {
_MakeMove(&_Board, x, y);
_NextPlayer();
}if (Pressed == 0) { ... }
goto EndHandlePID;
}if (_IsValidMove(&_Board, x, y)) { ... }
}if ((x < 8) && (y < 8)) { ... }
}if ((x >= 0) && (y >= 0)) { ... }
}if (_IsInHandlePID++ == 0) { ... }
EndHandlePID:
_IsInHandlePID--;
}{ ... }
/* ... */
static void _OnTouch(WM_MESSAGE* pMsg) {
const GUI_PID_STATE* pState = (const GUI_PID_STATE*)pMsg->Data.p;
if (pState)
{
_HandlePID(pState->x, pState->y, pState->Pressed);
}if (pState) { ... }
}{ ... }
/* ... */
static void _OnPaint(WM_HWIN hWin) {
GUI_COLOR Color;
GUI_RECT r;
int x, y, xPos, yPos;
int CellSize, rStone, remove;
char Cell, IsValidMove;
int xCircle, yCircle;
_CalcBoardDimensions();
GUI_AA_SetFactor(AA_FACTOR);
#if AA_USE_HIRES
GUI_AA_EnableHiRes();
#endif
LCD_SetBkColor(CLIENT_COLOR);
WM_GetClientRectEx(hWin, &r);
GUI_ClearRect(r.x0, r.y0, r.x1, _BoardY0 - 1);
GUI_ClearRect(r.x0, _BoardY0, _BoardX0 - 1, _BoardY0 + (8 * _CellSize));
GUI_ClearRect(_BoardX0 + (8 * _CellSize) + 1, _BoardY0, r.x1, _BoardY0 + (8 * _CellSize));
GUI_ClearRect(r.x0, _BoardY0 + (8 * _CellSize) + 1, r.x1, r.y1);
CellSize = _CellSize - 1;
rStone = ((CellSize - 3) * AA_CALCFACTOR) >> 1;
remove = ((CellSize - 2) * AA_CALCFACTOR) >> 3;
if (rStone < AA_CALCFACTOR) {
rStone = AA_CALCFACTOR;
}if (rStone < AA_CALCFACTOR) { ... }
if (remove < (AA_CALCFACTOR >> AA_USE_HIRES)) {
remove = (AA_CALCFACTOR >> AA_USE_HIRES);
}if (remove < (AA_CALCFACTOR >> AA_USE_HIRES)) { ... }
for (yPos = _BoardY0, y = 0; y < 8; y++) {
for (xPos = _BoardX0, x = 0; x < 8; x++) {
Color = ((x + (y & 1)) & 1) ? (GUI_LIGHTGRAY) : (GUI_WHITE);
LCD_SetColor(Color);
GUI_FillRect(xPos + 1, yPos + 1, xPos + CellSize, yPos + CellSize);
Cell = _GetStone(&_Board, x, y);
IsValidMove = (_ShowPossibleMoves) ? _IsValidMove(&_Board, x, y) : 0;
if (_pPlayerAI[_Board.ActPlayer - 1]) {
IsValidMove = 0;
}if (_pPlayerAI[_Board.ActPlayer - 1]) { ... }
if (Cell || IsValidMove) {
xCircle = (xPos + 1) * AA_CALCFACTOR + ((CellSize * AA_CALCFACTOR) >> 1);
yCircle = (yPos + 1) * AA_CALCFACTOR + ((CellSize * AA_CALCFACTOR) >> 1);
if (Cell) {
Color = (Cell == 1) ? (GUI_RED) : (GUI_BLUE);
LCD_SetColor(Color);
#if (AA_FACTOR > 1)
GUI_AA_FillCircle(xCircle, yCircle, rStone);
#else
GUI_FillCircle(xCircle, yCircle, rStone);
#endif
}if (Cell) { ... } else {
LCD_SetColor(GUI_BLACK);
#if (AA_FACTOR > 1)
GUI_AA_FillCircle(xCircle, yCircle, remove);
#else
GUI_FillCircle(xCircle, yCircle, remove);
#endif
}else { ... }
}if (Cell || IsValidMove) { ... }
LCD_SetColor(GRID_COLOR);
GUI_DrawVLine(xPos, yPos + 1, yPos + CellSize);
xPos += _CellSize;
}for (xPos = _BoardX0, x = 0; x < 8; x++) { ... }
GUI_DrawVLine(xPos, yPos + 1, yPos + CellSize);
GUI_DrawHLine(yPos, _BoardX0, _BoardX0 + (_CellSize << 3));
yPos += _CellSize;
}for (yPos = _BoardY0, y = 0; y < 8; y++) { ... }
GUI_DrawHLine(yPos, _BoardX0, _BoardX0 + (_CellSize << 3));
}{ ... }
/* ... */
static void _cbReversiWin(WM_MESSAGE* pMsg) {
WM_HWIN hWin = pMsg->hWin;
switch (pMsg->MsgId) {
case WM_PAINT:
_OnPaint(hWin);
break;case WM_PAINT:
case WM_TOUCH:
_OnTouch(pMsg);
break;case WM_TOUCH:
case WM_DELETE:
_hFrame = 0;
break; case WM_DELETE:
default:
WM_DefaultProc(pMsg);default
}switch (pMsg->MsgId) { ... }
}{ ... }
/* ... */
static void Startup(WM_HWIN hWin, uint16_t xpos, uint16_t ypos)
{
_pPlayerAI[1] = _PlayerAI_SmartGecko;
_hFrame = FRAMEWIN_CreateEx(xpos, ypos, 320, 215, hWin, WM_CF_SHOW, FRAMEWIN_CF_ACTIVE, 0, NULL, &_cbReversiWin);
FRAMEWIN_SetClientColor(_hFrame, GUI_INVALID_COLOR);
FRAMEWIN_SetFont (_hFrame, GUI_FONT_13B_1);
FRAMEWIN_SetTextAlign (_hFrame, GUI_TA_HCENTER);
FRAMEWIN_AddCloseButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 0);
_StartNewGame();
}{ ... }
/* ... */
/* ... */