source: trunk/core/gui_reversi.c @ 1323

Revision 1323, 13.6 KB checked in by philmoz, 3 years ago (diff)

Fix for game colors (from CHDK-DE changeset 781, thx msl).

  • Property svn:eol-style set to native
Line 
1#include "stdlib.h"
2#include "keyboard.h"
3#include "platform.h"
4#include "core.h"
5#include "lang.h"
6#include "gui.h"
7#include "gui_draw.h"
8#include "gui_lang.h"
9#include "gui_batt.h"
10#include "gui_mbox.h"
11#include "gui_reversi.h"
12
13//-------------------------------------------------------------------
14#define FIELD_EMPTY             0
15#define FIELD_PLAYER1           1
16#define FIELD_PLAYER2           2
17#define COMPUTER_ONLY           3
18
19
20#define FIELD_COLOR_WHITE       COLOR_YELLOW
21#define FIELD_COLOR_BLACK       COLOR_GREY
22#define MARKER_COLOR_WHITE      COLOR_WHITE
23#define MARKER_COLOR_BLACK      COLOR_BLACK
24#define SELECTED_COLOR          COLOR_RED
25
26
27//-------------------------------------------------------------------
28typedef unsigned char uchar;
29
30//-------------------------------------------------------------------
31static uchar Field[8][8];
32static uchar CurrPlayer, Computer, InGame=0, NumPl1, NumPl2;
33
34static unsigned short field_size, field_x, field_y, cell_size;
35
36static uchar xPos=3, yPos=3;
37static volatile uchar need_redraw = 0, need_redraw_all = 0;
38
39static char buf[128];
40
41//-------------------------------------------------------------------
42static void redraw();
43static void redrawstatus();
44
45//-------------------------------------------------------------------
46static uchar NotPlayer(uchar Pl) {
47    if (Pl==FIELD_PLAYER1)
48        return FIELD_PLAYER2;
49    else
50        return FIELD_PLAYER1;
51}
52
53//-------------------------------------------------------------------
54static void InitField() {
55    uchar x, y;
56 
57    for (x=0; x<8; ++x)
58        for (y=0; y<8; ++y)
59            Field[x][y]=FIELD_EMPTY;
60   
61    Field[3][3] = Field[4][4] = FIELD_PLAYER1;
62    Field[3][4] = Field[4][3] = FIELD_PLAYER2;
63}
64
65//-------------------------------------------------------------------
66static uchar GetNum(uchar Player) {
67    uchar x, y, N=0;
68   
69    for (x=0; x<8; ++x)
70        for (y=0; y<8; ++y)
71            if (Field[x][y]==Player) ++N;
72       
73    return N;
74}
75
76//-------------------------------------------------------------------
77static uchar Place(uchar x, uchar y, uchar Player, uchar Placed) {
78/*0..64 - Ok
79 0xFF - not empty*/
80    int I, J, x1, y1;
81    uchar Eated, E;
82 
83    if (Field[x][y]!=FIELD_EMPTY) {
84        return 0xFF;
85    } else {
86        Eated=0;
87        for (I=-1;I<=1;I++) {
88            for (J=-1;J<=1;J++) {
89                E=0;
90                x1=x+I;
91                y1=y+J;
92                while (((x1>=0) && (x1<8) && (y1>=0) && (y1<8)) && (Field[x1][y1]!=FIELD_EMPTY) && (Field[x1][y1]!=Player)) {
93                    E++;
94                    x1=x1+I;
95                    y1=y1+J;
96                }
97                if ((Placed) && ((x1>=0) && (x1<8) && (y1>=0) && (y1<8)) && (Field[x1][y1]!=FIELD_EMPTY) && (E>0)) {
98                    Field[x][y]=Player;
99                    x1=x+I;
100                    y1=y+J;
101                    while (((x1>=0) && (x1<8) && (y1>=0) && (y1<8)) && (Field[x1][y1]!=FIELD_EMPTY) && (Field[x1][y1]!=Player)) {
102                        Field[x1][y1]=Player;
103                        x1=x1+I;
104                        y1=y1+J;
105                    }
106                }
107                if (((x1>=0) && (x1<8) && (y1>=0) && (y1<8)) && (Field[x1][y1]!=FIELD_EMPTY))
108                    Eated+=E;
109            }
110        }
111        return Eated;
112    }
113}
114
115//-------------------------------------------------------------------
116static uchar ComputerPlace(uchar Player) {
117    static const uchar PlaceTable[8][8] ={{1,8,2,2,2,2,8,1},
118                                          {8,8,6,5,5,6,8,8},
119                                          {2,6,4,3,3,4,6,2},
120                                          {2,5,3,1,1,3,5,2},
121                                          {2,5,3,1,1,3,5,2},
122                                          {2,6,4,3,3,4,6,2},
123                                          {8,8,6,5,5,6,8,8},
124                                          {1,8,2,2,2,2,8,1}};
125    uchar PlX[61];
126    uchar PlY[61];
127    uchar NPl=0, I, J, MaxE=0, E, MinPr=9;
128   
129    for (I=0; I<8; I++) {
130        for (J=0; J<8; J++) {
131            E=Place(I, J, Player, 0);
132            if ((MinPr>PlaceTable[I][J]) && (E<0xFF) && (E>0)) {
133                MinPr=PlaceTable[I][J];
134                NPl=0;
135                MaxE=0;
136            }
137            if ((E<0xFF) && (MinPr==PlaceTable[I][J])) {
138                if (E>MaxE) {
139                    MaxE=E;
140                    NPl=1;
141                    PlX[1]=I;
142                    PlY[1]=J;
143                } else {
144                    if (E==MaxE) {
145                        NPl++;
146                        PlX[NPl]=I;
147                        PlY[NPl]=J;
148                    }
149                }
150            }
151        }
152    }
153//    E=1;
154    srand(get_tick_count());
155    E=(rand()%NPl)+1;
156    Place(PlX[E],PlY[E],Player,1);
157    return ((PlX[E] << 4) | PlY[E]);
158}
159
160//-------------------------------------------------------------------
161static uchar CanPlace(uchar Player) {
162    uchar I, J, E=0, E1;
163 
164    for (I=0;I<8;I++) {
165        for (J=0;J<8;J++) {
166            E1=Place(I,J,Player,0);
167            if (E1<0xFF) E+=E1;
168        }
169    }
170    return (E>0);
171}
172
173//-------------------------------------------------------------------
174static void Result() {
175    if (NumPl1>NumPl2)
176        gui_mbox_init(LANG_REVERSI_MSG_RESULTS_TITLE, LANG_REVERSI_MSG_RESULTS_WON, MBOX_TEXT_CENTER, NULL);
177    else if (NumPl1<NumPl2)
178        gui_mbox_init(LANG_REVERSI_MSG_RESULTS_TITLE, LANG_REVERSI_MSG_RESULTS_LOST, MBOX_TEXT_CENTER, NULL);
179    else
180        gui_mbox_init(LANG_REVERSI_MSG_RESULTS_TITLE, LANG_REVERSI_MSG_RESULTS_DRAW, MBOX_TEXT_CENTER, NULL);
181    redraw();
182    redrawstatus();
183    need_redraw_all = 1;
184}
185
186//-------------------------------------------------------------------
187static void DrawCell(uchar x, uchar y) {
188    draw_filled_rect(field_x+cell_size*x, field_y+cell_size*y,
189                     field_x+cell_size*(x+1), field_y+cell_size*(y+1),
190                     (x==xPos && y==yPos)?MAKE_COLOR(SELECTED_COLOR, COLOR_RED):((x+y)&1)?MAKE_COLOR(FIELD_COLOR_WHITE, COLOR_WHITE):MAKE_COLOR(FIELD_COLOR_BLACK, COLOR_WHITE));
191}
192
193//-------------------------------------------------------------------
194static void DrawMainWindow() {
195    uchar x, y;
196
197    draw_filled_rect(0, 0, screen_width-1, screen_height-1, MAKE_COLOR(SCREEN_COLOR, SCREEN_COLOR));
198    for (y=0; y<8; ++y) {
199        for (x=0; x<8; ++x) {
200            DrawCell(x, y);
201        }
202    }
203    for (x=0; x<8; ++x) {
204        draw_char(field_x+cell_size*x+((cell_size-FONT_WIDTH)>>1)+1,  field_y-FONT_HEIGHT-1, '1'+x,  MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
205        draw_char(field_x+cell_size*x+((cell_size-FONT_WIDTH)>>1)+1,  field_y+field_size+3,  '1'+x,  MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
206    }
207    for (y=0; y<8; ++y) {
208        draw_char(field_x-FONT_WIDTH-4,  field_y+cell_size*y+((cell_size-FONT_HEIGHT)>>1)+1, 'A'+y,  MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
209        draw_char(field_x+field_size+3,  field_y+cell_size*y+((cell_size-FONT_HEIGHT)>>1)+1, 'A'+y,  MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
210    }
211}
212
213//-------------------------------------------------------------------
214static void InitMainWindow() {
215    NumPl1=GetNum(FIELD_PLAYER1);
216    NumPl2=GetNum(FIELD_PLAYER2);
217    CurrPlayer=FIELD_PLAYER1;
218    Computer=FIELD_PLAYER2;
219    InGame=0;
220
221    field_size = (screen_height-2*FONT_HEIGHT-4)&0xFFF8;
222    field_x = FONT_WIDTH+8;
223    field_y = (screen_height-field_size)>>1;
224    cell_size = field_size >> 3;
225
226//    DrawMainWindow();
227}
228
229//-------------------------------------------------------------------
230static void NewGame() {
231    InitField();
232    CurrPlayer=FIELD_PLAYER1;
233    Computer=FIELD_PLAYER2;
234    NumPl1=2;
235    NumPl2=2;
236    xPos = yPos = 3;
237    InGame=1;
238    need_redraw = 1;
239}
240
241//-------------------------------------------------------------------
242static void Clk(uchar x, uchar y) {
243    uchar Placed;
244 
245    if ((CurrPlayer==Computer) || (! InGame) || (Computer==COMPUTER_ONLY))
246        ;
247    else {
248        Placed=Place(x,y ,CurrPlayer,0);
249        if (Placed==0) {
250            gui_mbox_init(LANG_REVERSI_MSG_WRONG_TITLE, LANG_REVERSI_MSG_WRONG_TEXT_1, MBOX_TEXT_CENTER, NULL);
251            need_redraw_all = 1;
252        } else if (Placed==0xFF) {
253            gui_mbox_init(LANG_REVERSI_MSG_WRONG_TITLE, LANG_REVERSI_MSG_WRONG_TEXT_2, MBOX_TEXT_CENTER, NULL);
254            need_redraw_all = 1;
255        } else {
256            Placed=Place(x, y, CurrPlayer,1);
257            CurrPlayer=NotPlayer(CurrPlayer);
258            NumPl1=GetNum(FIELD_PLAYER1);
259            NumPl2=GetNum(FIELD_PLAYER2);
260            need_redraw = 1;
261            if (!CanPlace(FIELD_PLAYER1) && !CanPlace(FIELD_PLAYER2)) {
262                InGame=0;
263                Result();
264            }
265            if (InGame && !CanPlace(CurrPlayer)) {
266                CurrPlayer=NotPlayer(CurrPlayer);
267                need_redraw = 1;
268            }
269        }
270    }
271}
272
273//-------------------------------------------------------------------
274static void Timer() {
275    uchar PPP;
276 
277    if ((InGame) & (CurrPlayer==Computer || Computer==COMPUTER_ONLY)) {
278        if (CanPlace(CurrPlayer)) {
279            PPP=ComputerPlace(CurrPlayer);
280            //xPos = PPP >> 4; yPos = PPP & 0x0F;
281            NumPl1=GetNum(FIELD_PLAYER1);
282            NumPl2=GetNum(FIELD_PLAYER2);
283            need_redraw=1;
284        }
285        CurrPlayer=NotPlayer(CurrPlayer);
286        if (!CanPlace(FIELD_PLAYER1) && !CanPlace(FIELD_PLAYER2)) {
287            InGame=0;
288            Result();
289        }
290        if (InGame && !CanPlace(CurrPlayer)) {
291            CurrPlayer=NotPlayer(CurrPlayer);
292            need_redraw=1;
293        }
294    }
295}
296
297//-------------------------------------------------------------------
298static void redraw() {
299    uchar x, y;
300 
301    for (x=0; x<8; ++x) {
302        for (y=0; y<8; ++y) {
303            DrawCell(x, y);
304            switch (Field[x][y]) {
305                case FIELD_EMPTY:
306                    break;
307                case FIELD_PLAYER1:
308                    draw_filled_ellipse(field_x+cell_size*x+(cell_size>>1), field_y+cell_size*y+(cell_size>>1),
309                                        (cell_size>>1)-4, (cell_size>>1)-4, MAKE_COLOR(MARKER_COLOR_WHITE, MARKER_COLOR_WHITE));
310                    break;
311                case FIELD_PLAYER2:
312                    draw_filled_ellipse(field_x+cell_size*x+(cell_size>>1), field_y+cell_size*y+(cell_size>>1),
313                                        (cell_size>>1)-4, (cell_size>>1)-4, MAKE_COLOR(MARKER_COLOR_BLACK, MARKER_COLOR_BLACK));
314                    break;
315            }
316        }
317    }
318
319    draw_rect(field_x+cell_size*xPos, field_y+cell_size*yPos, field_x+cell_size*(xPos+1), field_y+cell_size*(yPos+1), COLOR_RED);
320}
321
322//-------------------------------------------------------------------
323static void redrawstatus() {
324    uchar x=field_size+FONT_WIDTH*2+23, y = 25;
325    if (InGame) {
326        if (CurrPlayer==FIELD_PLAYER1) {
327            draw_string(x+1, y, lang_str(LANG_REVERSI_MOVE_WHITE), MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
328        } else {
329            draw_string(x+1, y, lang_str(LANG_REVERSI_MOVE_BLACK), MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
330        }
331    } else {
332        draw_string(x, y, lang_str(LANG_REVERSI_GAME_OVER), MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
333    }
334    draw_string(x, y+FONT_HEIGHT+8, lang_str(LANG_REVERSI_WHITE_BLACK), MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
335    sprintf(buf, " %d ", NumPl1);
336    draw_string(x+FONT_WIDTH*(7-strlen(buf))/2, y+FONT_HEIGHT*2+8, buf, MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
337    sprintf(buf, " %d ", NumPl2);
338    draw_string(x+FONT_WIDTH*7+FONT_WIDTH*(7-strlen(buf))/2, y+FONT_HEIGHT*2+8, buf, MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
339    draw_rect(x-4, y-4, x+FONT_WIDTH*14+4, y+FONT_HEIGHT*3+8+4, COLOR_WHITE);
340    draw_rect(x-2, y-2, x+FONT_WIDTH*14+2, y+FONT_HEIGHT*3+8+2, COLOR_WHITE);
341    draw_line(x-2, y+FONT_HEIGHT+4, x+FONT_WIDTH*14+2, y+FONT_HEIGHT+4, COLOR_WHITE);
342    draw_line(x+FONT_WIDTH*7, y+FONT_HEIGHT+4, x+FONT_WIDTH*7, y+FONT_HEIGHT*3+8+2, COLOR_WHITE);
343}
344
345//-------------------------------------------------------------------
346void gui_reversi_init() {
347    InitMainWindow();
348    NewGame();
349    need_redraw_all = 1;
350}
351
352//-------------------------------------------------------------------
353void gui_reversi_kbd_process() {
354    switch (kbd_get_autoclicked_key()) {
355        case KEY_UP:
356            yPos =(yPos-1)&7;
357            need_redraw = 1;
358            break;
359        case KEY_DOWN:
360            yPos =(yPos+1)&7;
361            need_redraw = 1;
362            break;
363        case KEY_LEFT:
364            xPos =(xPos-1)&7;
365            need_redraw = 1;
366            break;
367        case KEY_RIGHT:
368            xPos =(xPos+1)&7;
369            need_redraw = 1;
370            break;
371        case KEY_SET:
372            if (InGame)
373                Clk(xPos, yPos);
374            else
375                NewGame();
376            need_redraw = 1;
377            break;
378      #if CAM_HAS_ERASE_BUTTON
379        case KEY_ERASE:
380      #else
381        case KEY_DISPLAY:
382      #endif
383            if (InGame)
384                Computer=COMPUTER_ONLY;
385            else
386                NewGame();
387            need_redraw = 1;
388            break;
389      #if CAM_HAS_ERASE_BUTTON
390        case KEY_DISPLAY:
391            gui_mbox_init(LANG_MBOX_ABOUT_TITLE, (int)"REVERSI\n(c) GrAnd, 2007", MBOX_TEXT_CENTER, NULL);
392            need_redraw_all = 1;
393            break;
394      #endif
395    }
396}
397
398//-------------------------------------------------------------------
399void gui_reversi_draw() {
400    if (need_redraw_all) {
401        need_redraw_all = 0;
402        DrawMainWindow();
403        need_redraw = 1;
404    }
405    if (need_redraw) {
406        need_redraw = 0;
407        redraw();
408        redrawstatus();
409    }
410
411    sprintf(buf, "Batt:%3d%%", get_batt_perc());
412    draw_txt_string(screen_width/FONT_WIDTH-2-9, screen_height/FONT_HEIGHT-1, buf, MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
413
414    Timer();
415}
416
Note: See TracBrowser for help on using the repository browser.