1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
32
33
36
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
82
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
133
140
141
142
145
146
147
148
149
150
151
152
153
154
155
156
163
170
171
178
184
185
192
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
222
223
224
225
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
248
249
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
274
275
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
301
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
336
337
338
339
340
341
342
343
344
347
348
350
351
352
353
354
355
357
358
359
360
361
366
367
368
369
370
373
374
375
376
393
394
395
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
421
424
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
454
455
464
465
466
468
469
470
471
472
473
474
475
476
493
497
498
499
500
501
502
503
510
511
512
513
514
519
520
521
522
523
524
531
532
536
537
538
541
542
543
544
549
566
567
574
575
576
577
578
579
580
581
582
583
584
585
586
595
596
597
598
599
600
601
602
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
644
645
646
647
652
666
667
672
673
674
675
676
677
678
679
680
681
682
683
690
714
715
720
727
728
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
753
756
757
758
759
760
761
762
763
766
767
768
769
770
771
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
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
821
832
833
838
839
840
841
842
843
846
849
853
854
855
856
857
858
869
870
871
873
874
875
876
883
884
885
886
887
888
889
890
891
892
893
894
897
898
/* ... */
#include "main.h"
#include "games_res.c"
/* ... */
/* ... */
Includes
static void Startup(WM_HWIN hWin, uint16_t xpos, uint16_t ypos);
Private function prototypes
K_ModuleItem_Typedef games_board =
{
3,
" games",
open_games,
0,
Startup,
NULL,
...}
;
Private typedef
#define ID_FRAMEWIN_INFO (GUI_ID_USER + 0x01)
#define ID_IMAGE_INFO (GUI_ID_USER + 0x02)
#define ID_BUTTON_EXIT (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 NOLIMIT 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, -NOLIMIT, NOLIMIT, 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, hItem;
int r = 0;
hFrame = FRAMEWIN_CreateEx(265, 176, 270, 130, 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);
hItem = TEXT_CreateEx(10, 17, 250, 60, hClient, WM_CF_SHOW, GUI_TA_HCENTER, 0, pText);
TEXT_SetFont(hItem, &GUI_Font13_ASCII);
if (YesNo) {
hBut = BUTTON_CreateEx(137, 60, 55, 24, hClient, WM_CF_SHOW, 0, GUI_ID_CANCEL);
BUTTON_SetText (hBut, "No");
hBut = BUTTON_CreateEx(72, 60, 55, 24, hClient, WM_CF_SHOW, 0, GUI_ID_OK);
BUTTON_SetText (hBut, "Yes");
}if (YesNo) { ... } else {
hBut = BUTTON_CreateEx(104, 60, 55, 24, 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;
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, "you win by %d stones!\nDo you want to start a new game?", Score);
}if (Score > 0) { ... } else if (Score) {
sprintf(ac, "CPU 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();
#if AA_USE_HIRES
GUI_AA_EnableHiRes();
#endif
WM_GetClientRectEx(hWin, &r);
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_STCOLOR_DARKBLUE) : (GUI_STCOLOR_LIGHTBLUE);
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 _OnPaint_exit(BUTTON_Handle hObj) {
GUI_SetBkColor(FRAMEWIN_GetDefaultClientColor());
GUI_Clear();
GUI_SetColor(GUI_STCOLOR_LIGHTBLUE);
GUI_AA_FillCircle(100, 0, 100);
GUI_SetBkColor(GUI_STCOLOR_LIGHTBLUE);
GUI_SetColor(GUI_WHITE);
GUI_SetFont(&GUI_FontLubalGraph32);
GUI_DispStringAt("Menu", 20, 20);
}{ ... }
/* ... */
static void _cbButton_exit(WM_MESSAGE * pMsg) {
switch (pMsg->MsgId) {
case WM_PAINT:
_OnPaint_exit(pMsg->hWin);
break;case WM_PAINT:
default:
BUTTON_Callback(pMsg);
break;default
}switch (pMsg->MsgId) { ... }
}{ ... }
/* ... */
static void _cbReversiWin(WM_MESSAGE* pMsg) {
WM_HWIN hWin = pMsg->hWin;
int Id, NCode;
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:
case WM_NOTIFY_PARENT:
Id = WM_GetId(pMsg->hWinSrc);
NCode = pMsg->Data.v;
switch(Id) {
case ID_BUTTON_EXIT:
switch(NCode) {
case WM_NOTIFICATION_RELEASED:
GUI_EndDialog(pMsg->hWin, 0);
break;case WM_NOTIFICATION_RELEASED:
}switch (NCode) { ... }
break;case ID_BUTTON_EXIT:
}switch (Id) { ... }
break;
case WM_NOTIFY_PARENT:
default:
WM_DefaultProc(pMsg);default
}switch (pMsg->MsgId) { ... }
}{ ... }
/* ... */
static void Startup(WM_HWIN hWin, uint16_t xpos, uint16_t ypos)
{
WM_HWIN hItem;
_pPlayerAI[1] = _PlayerAI_SmartGecko;
_hFrame = WINDOW_CreateEx(xpos, ypos, 800, 480, hWin, WM_CF_SHOW, 0, 0x500, &_cbReversiWin);
hItem = BUTTON_CreateEx(700, 0, 100, 100, _hFrame, WM_CF_SHOW, 0, ID_BUTTON_EXIT);
WM_SetCallback(hItem, _cbButton_exit);
WINDOW_SetBkColor(_hFrame, GUI_WHITE);
_StartNewGame();
}{ ... }
/* ... */
/* ... */