source: trunk/core/gui_4wins.c @ 1323

Revision 1323, 14.9 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//Conect4: Kettmeister, CHDKLover german forum (forum.chdk-treff.de)
2#include "stdlib.h"
3#include "keyboard.h"
4#include "platform.h"
5#include "core.h"
6#include "lang.h"
7#include "conf.h"
8#include "gui.h"
9#include "gui_osd.h"
10#include "gui_draw.h"
11#include "gui_lang.h"
12#include "gui_batt.h"
13#include "gui_mbox.h"
14#include "gui_4wins.h"
15
16#define BORDER           20
17#define RECT_SIZE        30
18#define BORDER_TOP       RECT_SIZE
19#define FIELD_HEIGHT 7
20#define FIELD_WIDTH      7
21#define P1_COLOR         MAKE_COLOR(COLOR_HISTO_B_PLAY,COLOR_HISTO_B_PLAY)
22#define P2_COLOR         MAKE_COLOR(COLOR_HISTO_G_PLAY,COLOR_HISTO_G_PLAY)
23#define BG_COLOR         MAKE_COLOR(COLOR_GREY,COLOR_GREY)
24#define FIELD_COLOR      MAKE_COLOR(COLOR_SPLASH_GREY,COLOR_SPLASH_GREY)//(füllfarbe,rand)
25#define TEXT_COLOR   MAKE_COLOR(BG_COLOR, COLOR_WHITE)
26#define INFO_COLOR   MAKE_COLOR(COLOR_SPLASH_GREY, COLOR_SPLASH_GREY)
27#define INFO_TEXT_COLOR   MAKE_COLOR(INFO_COLOR, COLOR_WHITE)
28
29char cursor_position,cur_player=1;
30char field[FIELD_HEIGHT][FIELD_WIDTH];
31char finished=0;
32char badColumns[7];
33char in_game=0;
34char mode_rival=0; //1=person 0=cam
35char count_win[2]={0,0};
36
37//-------------------------------------------------------------------
38static char isFull(int column)
39{
40        if(field[column-1][6])
41                return 1;
42        else
43                return 0;
44}
45
46static char set_stone(int column, char player, char visible)
47{
48        int i;
49    in_game=1;
50        if(!isFull(column))
51        {
52                for(i=1;field[column-1][i];i++);                        //1 ist wichtig (0=Fundament)
53                if (visible) {
54                        draw_filled_ellipse((BORDER+((column-1)*RECT_SIZE))+15, (BORDER+((6-i)*RECT_SIZE))+15+BORDER_TOP, 10,10, (cur_player==1)?P1_COLOR:P2_COLOR);
55                }
56                field[column-1][i]=player;
57                return 1;
58        }
59        else return 0;
60}
61/*====================      KI   ===========================*/
62static void unset_stone(int column)
63{
64  int i;
65  for(i=1;field[column-1][i]&&i<=6;i++);                        //1 ist wichtig (0=Fundament)
66  field[column-1][i-1]=0;
67}
68
69char ki_isBadColumn(int column){
70  if(badColumns[column-1]) return column; else return 0;
71}
72
73char ki_3(char player) {
74  int i,j;
75  //waagerecht und Diagonal (über Anstieg)
76  for(i=0;i<=3;i++){            // column
77    for(j=1;j<=6;j++){          //row
78      if(field[i][j]==player&&field[i+1][j]==player&&field[i+2][j]==player&&field[i+3][j]==0&&field[i+3][j-1]) return i+4;      //***-
79      if(field[i][j]==player&&field[i+1][j]==player&&field[i+2][j]==0&&field[i+3][j]==player&&field[i+2][j-1]) return i+3;      //**-*
80      if(field[i][j]==player&&field[i+1][j]==0&&field[i+2][j]==player&&field[i+3][j]==player&&field[i+1][j-1]) return i+2;      //*-**
81      if(field[i][j]==0&&field[i+1][j]==player&&field[i+2][j]==player&&field[i+3][j]==player&&field[i][j-1]) return i+1;        //-***
82    }
83    for(j=1;j<=3;j++){
84      if(field[i][j]==player&&field[i+1][j+1]==player&&field[i+2][j+2]==player&&field[i+3][j+3]==0&&field[i+3][j+3-1]) return i+4;      //***-
85      if(field[i][j]==player&&field[i+1][j+1]==player&&field[i+2][j+2]==0&&field[i+3][j+3]==player&&field[i+2][j+2-1]) return i+3;      //**-*
86      if(field[i][j]==player&&field[i+1][j+1]==0&&field[i+2][j+2]==player&&field[i+3][j+3]==player&&field[i+1][j+1-1]) return i+2;      //*-**
87      if(field[i][j]==0&&field[i+1][j+1]==player&&field[i+2][j+2]==player&&field[i+3][j+3]==player&&field[i][j-1]) return i+1;          //-***
88    }
89    for(j=4;j<=6;j++){
90        if(field[i][j]==player&&field[i+1][j-1]==player&&field[i+2][j-2]==player&&field[i+3][j-3]==0&&field[i+3][j-3-1]) return i+4;    //***-
91        if(field[i][j]==player&&field[i+1][j-1]==player&&field[i+2][j-2]==0&&field[i+3][j-3]==player&&field[i+2][j-2-1]) return i+3;    //**-*
92        if(field[i][j]==player&&field[i+1][j-1]==0&&field[i+2][j-2]==player&&field[i+3][j-3]==player&&field[i+1][j-1-1]) return i+2;    //*-**
93        if(field[i][j]==0&&field[i+1][j-1]==player&&field[i+2][j-2]==player&&field[i+3][j-3]==player&&field[i][j-1]) return i+1;                //-***
94    }
95  }
96  //Unterreihentrick in allen ebenen
97  for(i=0;i<=2;i++){
98    for(j=1;j<=6;j++) if(field[i][j]==0&&field[i+1][j]==player&&field[i+2][j]==0&&field[i+3][j]==player&&field[i+4][j]==0&&field[i][j-1]&&field[i+2][j-1]&&field[i+4][j-1]) return i+3; //_*_*_
99    for(j=1;j<=3;j++) if(field[i][j]==0&&field[i+1][j+1]==player&&field[i+2][j+2]==0&&field[i+3][j+3]==player&&field[i+4][j+4]==0&&field[i][j-1]&&field[i+2][j+2-1]&&field[i+4][j+4-1]) return i+3;     //_*_*_
100    for(j=4;j<=6;j++) if(field[i][j]==0&&field[i+1][j-1]==player&&field[i+2][j-2]==0&&field[i+3][j-3]==player&&field[i+4][j-4]==0&&field[i][j-1]&&field[i+2][j-2-1]&&field[i+4][j-4-1]) return i+3;     //_*_*_
101  }
102  //senkrecht
103  for(i=0;i<=6;i++) for(j=1;j<=3;j++) if(field[i][j]==player&&field[i][j+1]==player&&field[i][j+2]==player&&field[i][j+3]==0) return i+1;
104  return 0;
105}
106
107char ki_2(char player) {
108  int i,j;
109  //waagerecht und Diagonal über Anstieg
110  for(i=0;i<=3;i++){            //column
111    for(j=1;j<=6;j++){          //row
112      if(field[i][j]==player&&field[i+1][j]==player&&field[i+2][j]==0&&field[i+3][j]==0&&(field[i+2][j-1]||field[i+3][j-1])&&!ki_isBadColumn(i+3)) return i+3;  //**-- return und if ändern
113      if(field[i][j]==player&&field[i+1][j]==0&&field[i+2][j]==0&&field[i+3][j]==player&&(field[i+1][j-1]||field[i+2][j-1])&&!ki_isBadColumn(i+2)) return i+2;  //*--* (i+3 geht auch)
114      if(field[i][j]==0&&field[i+1][j]==0&&field[i+2][j]==player&&field[i+3][j]==player&&(field[i][j-1]||field[i+1][j-1])&&!ki_isBadColumn(i+2)) return i+2;    //--**
115      if(field[i][j]==0&&field[i+1][j]==player&&field[i+2][j]==0&&field[i+3][j]==player&&(field[i][j-1]||field[i+2][j-1])&&!ki_isBadColumn(i+3)) return i+3;    //-*-*
116      if(field[i][j]==player&&field[i+1][j]==0&&field[i+2][j]==player&&field[i+3][j]==0&&(field[i+1][j-1]||field[i+3][j-1])&&!ki_isBadColumn(i+2)) return i+2;  //*-*-
117    }
118    for(j=1;j<=3;j++){
119      if(field[i][j]==player&&field[i+1][j+1]==player&&field[i+2][j+2]==0&&field[i+3][j+3]==0&&field[i+2][j+2-1]&&!ki_isBadColumn(i+3)) return i+3;     //**-- return und if ändern
120      if(field[i][j]==player&&field[i+1][j+1]==player&&field[i+2][j+2]==0&&field[i+3][j+3]==0&&field[i+3][j+3-1]&&!ki_isBadColumn(i+3)) return i+4;     //**-- return und if ändern
121      if(field[i][j]==player&&field[i+1][j+1]==0&&field[i+2][j+2]==0&&field[i+3][j+3]==player&&(field[i+1][j+1-1]||field[i+2][j+2-1])&&!ki_isBadColumn(i+2)) return i+2;        //*--* (i+3 geht auch)
122      if(field[i][j]==0&&field[i+1][j+1]==0&&field[i+2][j+2]==player&&field[i+3][j+3]==player&&(field[i][j-1]||field[i+1][j+1-1])&&!ki_isBadColumn(i+2)) return i+2;    //--**
123      if(field[i][j]==0&&field[i+1][j+1]==player&&field[i+2][j+2]==0&&field[i+3][j+3]==player&&(field[i][j-1]||field[i+2][j+2-1])&&!ki_isBadColumn(i+3)) return i+3;    //-*-*
124      if(field[i][j]==player&&field[i+1][j+1]==0&&field[i+2][j+2]==player&&field[i+3][j+3]==0&&(field[i+1][j+1-1]||field[i+3][j+3-1])&&!ki_isBadColumn(i+2)) return i+2;        //*-*-
125    }
126    for(j=4;j<=6;j++){
127      if(field[i][j]==player&&field[i+1][j-1]==player&&field[i+2][j-2]==0&&field[i+3][j-3]==0&&field[i+2][j-2-1]&&!ki_isBadColumn(i+3)) return i+3;     //**-- return und if ändern
128      if(field[i][j]==player&&field[i+1][j-1]==player&&field[i+2][j-2]==0&&field[i+3][j-3]==0&&field[i+3][j-3-1]&&!ki_isBadColumn(i+3)) return i+4;     //**-- return und if ändern
129      if(field[i][j]==player&&field[i+1][j-1]==0&&field[i+2][j-2]==0&&field[i+3][j-3]==player&&(field[i+1][j-1-1]||field[i+2][j-2-1])&&!ki_isBadColumn(i+2)) return i+2;        //*--* (i+3 geht auch)
130      if(field[i][j]==0&&field[i+1][j-1]==0&&field[i+2][j-2]==player&&field[i+3][j-3]==player&&(field[i][j-1]||field[i+1][j-1-1])&&!ki_isBadColumn(i+2)) return i+2;    //--**
131      if(field[i][j]==0&&field[i+1][j-1]==player&&field[i+2][j-2]==0&&field[i+3][j-3]==player&&(field[i][j-1]||field[i+2][j-2-1])&&!ki_isBadColumn(i+3)) return i+3;    //-*-*
132      if(field[i][j]==player&&field[i+1][j-1]==0&&field[i+2][j-2]==player&&field[i+3][j-3]==0&&(field[i+1][j-1-1]||field[i+3][j-3-1])&&!ki_isBadColumn(i+2)) return i+2;        //*-*-
133    }
134  }
135  //senkrecht
136  for(i=0;i<=6;i++) for(j=1;j<=3;j++) if(field[i][j]==player&&field[i][j+1]==player&&field[i][j+2]==0&&!ki_isBadColumn(i+1)) return i+1;
137  return 0;
138}
139
140char ki_findColumn(char mode, char player) {                                                    //player = 1|2
141  char erg=0, cam=player, otherplayer, i, counter=0;
142  otherplayer=(player==1)?2:1;
143  switch(mode) {
144  case 'b':
145  case 1: erg=ki_3(cam);                                                                                                //ich3
146          if(!erg&&mode!='b') erg=ki_3(otherplayer); else break;                //du3
147          if(!erg) {                                                                                                    //ungünstige Spalten ermitteln
148            for(i=1;i<=7;i++) {
149              if(!isFull(i)) {
150                set_stone(i,9,0);                                                                               //Stein setzen 9=irgendwas
151                badColumns[i-1]=ki_findColumn('b',otherplayer);                 //ungünstige Spalten ermitteln b=bad
152                if(!badColumns[i-1]) badColumns[i-1]=ki_findColumn('b',cam);
153                unset_stone(i);
154              } else badColumns[i-1]=9;                                                         //9=full
155            }
156          } else break;
157          erg=ki_2(cam);                                                                                                //ich2 (für passivere Methode vertauschen)
158          if(!erg) erg=ki_2(otherplayer); else break;                                   //du2
159          if(!erg) erg=(!isFull(4)&&!ki_isBadColumn(4))?4:0; else break;//mitte
160          if(!erg) do erg=(rand()%7)+1; while((isFull(erg)||erg==0||ki_isBadColumn(erg))&&counter++<100);       //zufall
161          if(counter>100) for(i=1;i<=7;i++) if(!isFull(i)) erg=i;
162          break;
163  }
164  return erg;
165}
166/*======================= K I   END ===============================*/
167void draw_txt_message(char* text) {
168    coord w, x, y;
169    int l;
170    color cl = MAKE_COLOR(COLOR_RED, COLOR_WHITE);
171    l=strlen(text);
172    w=l*FONT_WIDTH+10;
173
174    x = (screen_width-w)>>1; y = ((screen_height)>>1);
175    draw_filled_round_rect(x, y, x+w, y+FONT_HEIGHT+6, MAKE_COLOR(COLOR_RED, COLOR_RED));
176    draw_string(x+((w-strlen(text)*FONT_WIDTH)>>1), y+4, text, cl);
177}
178//-------------------------------------------------------------------
179static void change_player()
180{
181        if (cur_player==1) cur_player=2; else cur_player=1;
182        draw_filled_ellipse((BORDER+((cursor_position)*RECT_SIZE))+15, BORDER+10, 10,10, (cur_player==1)?P1_COLOR:P2_COLOR);
183}
184//-------------------------------------------------------------------
185static char win_query()
186{
187        int i=0,j=0;
188
189        for(i=0;i<4;i++)
190        {
191                for(j=1;j<4;j++)
192                {
193                        // '1'
194                        if(field[i][j]==1 && field[i+1][j+1]==1 && field[i+2][j+2]==1 && field[i+3][j+3]==1) return 1; // diagonal  > 
195                        if(field[i][j+3]==1 && field[i+1][j+2]==1 && field[i+2][j+1]==1 && field[i+3][j]==1) return 1; // diagonal  >  /
196                        // '2'
197                        if(field[i][j]==2 && field[i+1][j+1]==2 && field[i+2][j+2]==2 && field[i+3][j+3]==2) return 1;// diagonal  > 
198                        if(field[i][j+3]==2 && field[i+1][j+2]==2 && field[i+2][j+1]==2 && field[i+3][j]==2) return 1;// diagonal  >  /
199                }
200        }
201       
202        for(i=0;i<7;i++)
203        {
204                for(j=1;j<4;j++)
205                {
206                        if(field[i][j]==2 && field[i][j+1]==2 && field[i][j+2]==2 && field[i][j+3]==2) return 1; // vertical  >  |
207                        if(field[i][j]==1 && field[i][j+1]==1 && field[i][j+2]==1 && field[i][j+3]==1) return 1; // vertical  >  |
208                }
209        }
210       
211        for(i=0;i<4;i++)
212        {
213                for(j=1;j<7;j++)
214                {
215                        if(field[i][j]==2 && field[i+1][j]==2 && field[i+2][j]==2 && field[i+3][j]==2) return 1; // horizontal  >  -
216                        if(field[i][j]==1 && field[i+1][j]==1 && field[i+2][j]==1 && field[i+3][j]==1) return 1;        // horizontal  >  -
217                }
218        }
219
220        if (isFull(1) && isFull(2) && isFull(3) && isFull(4) && isFull(5) && isFull(6) && isFull(7)) return 9;
221       
222        return 0;
223}
224//-------------------------------------------------------------------
225void win() {
226  if(win_query()==1){
227    finished=1;
228    count_win[cur_player-1]++;
229    draw_txt_message(lang_str((cur_player==1)?LANG_CONNECT4_P1_WIN:(mode_rival)?LANG_CONNECT4_P2_WIN:LANG_CONNECT4_CAM_WIN));
230  }     else if (win_query()==9) {
231    finished=1;
232    draw_txt_message(lang_str(LANG_CONNECT4_DRAW));
233  }
234  change_player();
235}
236//-------------------------------------------------------------------
237void draw_mode()
238{
239        draw_txt_string(30, 4, "            ", TEXT_COLOR);
240        if (mode_rival==1)
241                draw_txt_string(30, 4, lang_str(LANG_CONNECT4_HUMAN), TEXT_COLOR);
242        else
243                draw_txt_string(30, 4, PLATFORM, TEXT_COLOR);
244}
245//-------------------------------------------------------------------
246void change_mode()
247{
248        cur_player=1;
249        count_win[0]=count_win[1]=0;
250        if(mode_rival==1)
251                mode_rival=0;   //CAM
252        else
253                mode_rival=1;   //HUMAN
254        draw_mode();
255}
256//-------------------------------------------------------------------
257void set()
258{
259        if(finished==0)
260        {
261                if(cursor_position==7 && in_game==0)   
262                {
263                        change_mode();
264                }
265                else
266                {
267                        if(cur_player==1 || (cur_player==2 && mode_rival==1)) if(set_stone(cursor_position+1,cur_player,1)) win();
268                        if((mode_rival==0 && cur_player==2) && !finished) if(set_stone(ki_findColumn(1, cur_player),cur_player, 1)) win();
269                }
270        }
271}
272//-------------------------------------------------------------------
273static void move_cursor(int in_x_pos)
274{
275        draw_filled_ellipse((BORDER+((cursor_position)*RECT_SIZE))+15, BORDER+10, 10,10,BG_COLOR);
276        if(in_game)
277        {
278                if(cursor_position==0 && in_x_pos<0)
279                        cursor_position=7+in_x_pos;
280                else
281                        cursor_position=(cursor_position+in_x_pos)%7;
282        }
283        else
284        {
285                if(cursor_position==0 && in_x_pos<0)
286                        cursor_position=8+in_x_pos;
287                else
288                        cursor_position=(cursor_position+in_x_pos)%8;
289        }
290        draw_filled_ellipse((BORDER+((cursor_position)*RECT_SIZE))+15, BORDER+10, 10,10, (cur_player==1)?P1_COLOR:P2_COLOR);
291}
292//-------------------------------------------------------------------
293int gui_4wins_init()
294{
295        static char str[16];
296        int i=0,j=0;
297
298        cursor_position=3;
299        finished=in_game=0;
300        srand(time(NULL));
301       
302        draw_filled_rect(0, 0, 360, 240, BG_COLOR);             // draw backgraund
303        draw_filled_rect(BORDER, BORDER+BORDER_TOP, BORDER+(7*RECT_SIZE), BORDER+(6*RECT_SIZE)+BORDER_TOP, FIELD_COLOR);
304        draw_filled_round_rect(240, 90, 360-BORDER, 240-10, INFO_COLOR);
305    draw_txt_string(12, 0, lang_str(LANG_MENU_GAMES_CONNECT4), TEXT_COLOR);
306    draw_line(0,15,360,15,0xEF);
307
308        for(i=0;i<7;i++)
309        {
310                for(j=0;j<6;j++)
311                {
312                        field[i][j+1]=0;
313                        draw_filled_ellipse(BORDER+(i*RECT_SIZE)+(RECT_SIZE/2), BORDER+(j*RECT_SIZE)+(RECT_SIZE/2)+BORDER_TOP, 10, 10, BG_COLOR);
314                }
315        }
316        for(i=0;i<7;i++)
317        {
318                field[i][0]=9;
319        }
320
321        move_cursor(0);
322        draw_txt_string(30, 3, lang_str(LANG_CONNECT4_RIVAL), TEXT_COLOR);
323    sprintf(str, "%d",count_win[0]);
324        draw_txt_string(screen_width/FONT_WIDTH-2-10, screen_height/FONT_HEIGHT-9, str, MAKE_COLOR(INFO_COLOR, P1_COLOR));
325    sprintf(str, ":");
326        draw_txt_string(screen_width/FONT_WIDTH-2-7, screen_height/FONT_HEIGHT-9, str, INFO_TEXT_COLOR);
327    sprintf(str, "%d",count_win[1]);
328        draw_txt_string(screen_width/FONT_WIDTH-2-4, screen_height/FONT_HEIGHT-9, str, MAKE_COLOR(INFO_COLOR, P2_COLOR));
329        draw_mode();
330        if(cur_player==2&&!mode_rival) set();
331        return 1;
332}
333//-------------------------------------------------------------------
334void gui_4wins_kbd_process()
335{
336        switch (kbd_get_autoclicked_key())
337        {
338                case KEY_SET:
339                    if(!finished) set(); else gui_4wins_init();
340                        break;
341                case KEY_LEFT:
342                        if(finished==0)
343                                move_cursor(-1);
344                        break;
345                case KEY_RIGHT:
346                        if(finished==0)
347                                move_cursor(1);
348                        break;
349        }
350}
351//-------------------------------------------------------------------
352void gui_4wins_draw() {
353  static char str[16];
354  sprintf(str, "%3d%%", get_batt_perc());
355  draw_txt_string(screen_width/FONT_WIDTH-2-13, screen_height/FONT_HEIGHT-2, str, INFO_TEXT_COLOR);
356  gui_osd_draw_clock(300,208,INFO_TEXT_COLOR);
357}
Note: See TracBrowser for help on using the repository browser.