This is the doxygen documentation for gtkboard.

.
Main Page   Data Structures   File List   Data Fields   Globals  

rgb.c

Go to the documentation of this file.
00001 /*  This file is a part of gtkboard, a board games system.
00002     Copyright (C) 2003, Arvind Narayanan <arvindn@users.sourceforge.net>
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
00017 
00018 */
00019 #include <stdio.h>
00020 #include <string.h>
00021 #include <assert.h>
00022 #include <stdlib.h>
00023 
00024 #include "game.h"
00025 #include "aaball.h"
00026 
00027 #define RGB_CELL_SIZE 55
00028 #define RGB_NUM_PIECES 3
00029 
00030 #define RGB_BOARD_WID 3
00031 #define RGB_BOARD_HEIT 3
00032 
00033 #define RGB_RP 1
00034 #define RGB_GP 2
00035 #define RGB_BP 3
00036 #define RGB_EMPTY 0
00037 
00038 char rgb_colors[9] = {200, 200, 200, 200, 200, 200, 0, 0, 0};
00039 
00040 int * rgb_init_pos = NULL;
00041 
00042 void rgb_init ();
00043 
00044 Game Rgb = { RGB_CELL_SIZE, RGB_BOARD_WID, RGB_BOARD_HEIT, 
00045         RGB_NUM_PIECES,
00046         rgb_colors,  NULL, NULL, "Rgb", rgb_init};
00047 
00048 
00049 static int rgb_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **);
00050 static ResultType rgb_who_won (Pos *, Player, char **);
00051 static void rgb_set_init_pos (Pos *pos);
00052 void rgb_init (void);
00053 static byte * rgb_movegen (Pos *);
00054 static ResultType rgb_eval (Pos *, Player, float *eval);
00055 
00056 static unsigned char * rgb_get_rgbmap (int idx, int color);
00057 
00058 void rgb_init ()
00059 {
00060         game_eval = rgb_eval;
00061         game_movegen = rgb_movegen;
00062         game_getmove = rgb_getmove;
00063         game_who_won = rgb_who_won;
00064         game_set_init_pos = rgb_set_init_pos;
00065         game_get_rgbmap = rgb_get_rgbmap;
00066         game_draw_cell_boundaries = TRUE;
00067         game_allow_flip = TRUE;
00068         game_doc_about = 
00069                 "Rgb\n"
00070                 "Two player game\n"
00071                 "Status: Fully implemented\n"
00072                 "URL: "GAME_DEFAULT_URL ("rgb");
00073         game_doc_rules = 
00074                 "Rgb rules\n"
00075                 "\n"
00076                 "Rgb, short for red-green-blue, is a harder version of tic-tac-toe. The goal is to get 3 balls in a line (row, column, or diagonal) of any one color. Clicking on an empty square puts a red ball on it, clicking on a red ball turns it green, and clicking on a green ball turns it blue.";
00077 }
00078 
00079 static void rgb_set_init_pos (Pos *pos)
00080 {
00081         int i;
00082         for (i=0; i<board_wid * board_heit; i++)
00083                 pos->board [i] = RGB_EMPTY;
00084 }
00085 
00086 static byte * rgb_movegen (Pos *pos)
00087 {
00088         int i, j;
00089         byte movbuf [64];
00090         byte *movlist, *movp = movbuf;
00091         int lines[8][2] = 
00092         { 
00093                 {0, 1}, {3, 1}, {6, 1},
00094                 {0, 3}, {1, 3}, {2, 3},
00095                 {0, 4}, {2, 2},
00096         };
00097         int val, found;
00098         for (i=0; i<8; i++)
00099         {
00100                 val = -1; found = 1;
00101                 for (j=0; j<3; j++)
00102                 {
00103                         if (val >= 0 && pos->board[lines[i][0] + j * lines[i][1]] != val) 
00104                         { found = 0; break; }
00105                         val = pos->board[lines[i][0] + j * lines[i][1]];
00106                         if (val == RGB_EMPTY) { found = 0; break; }
00107                 }
00108                 if (found) 
00109                         break;
00110         }
00111         if (!found)
00112         {
00113                 for (i=0; i<board_wid; i++)
00114                 for (j=0; j<board_heit; j++)
00115                         if (pos->board[j * board_wid + i] != RGB_BP)
00116                         {
00117                                 *movp++ = i;
00118                                 *movp++ = j;
00119                                 *movp++ = pos->board[j * board_wid + i] + 1;
00120                                 *movp++ = -1;
00121                         }
00122         }
00123         *movp++ = -2;
00124         movlist = (byte *) (malloc (movp - movbuf));
00125         memcpy (movlist, movbuf, (movp - movbuf));
00126         return movlist;
00127 }
00128 
00129 static ResultType rgb_who_won (Pos *pos, Player to_play, char **commp)
00130 {
00131         static char comment[32];
00132         char *who_str [] = { "White won", "Black won"};
00133         int lines[8][2] = 
00134         { 
00135                 {0, 1}, {3, 1}, {6, 1},
00136                 {0, 3}, {1, 3}, {2, 3},
00137                 {0, 4}, {2, 2},
00138         };
00139         int i, j;
00140         int val, found;
00141         for (i=0; i<8; i++)
00142         {
00143                 val = -1; found = 1;
00144                 for (j=0; j<3; j++)
00145                 {
00146                         if (val >= 0 && pos->board[lines[i][0] + j * lines[i][1]] != val) 
00147                         { found = 0; break; }
00148                         val = pos->board[lines[i][0] + j * lines[i][1]];
00149                         if (val == RGB_EMPTY) { found = 0; break; }
00150                 }
00151                 if (found) 
00152                 {
00153                         *commp = who_str[to_play == WHITE ? 1 : 0];
00154                         return to_play == WHITE ? RESULT_BLACK : RESULT_WHITE;
00155                 }
00156         }
00157         *commp = NULL;
00158         return RESULT_NOTYET;
00159 }
00160 
00161 static int rgb_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, byte **movp, int ** rmovep)
00162 {
00163         int val;
00164         static byte move[4];
00165         if (type != GTKBOARD_BUTTON_RELEASE)
00166                 return 0;
00167         val = pos->board [y * board_wid + x];
00168         if (val == RGB_BP) return -1;
00169         move[0] = x;
00170         move[1] = y;
00171         move[2] = val+1;
00172         move[3] = -1;
00173         if (movp)
00174                 *movp = move;   
00175         return 1;
00176 }
00177 
00178 static unsigned char * rgb_get_rgbmap (int idx, int color)
00179 {
00180         int fg = 0, bg, i;
00181         char *colors;
00182         static char rgbbuf[3 * RGB_CELL_SIZE * RGB_CELL_SIZE];
00183         colors = rgb_colors;
00184         if (idx == RGB_RP) fg = 255 << 16;
00185         else if (idx == RGB_GP) fg = 255 << 8;
00186         else if (idx == RGB_BP) fg = 255;
00187         else { return NULL;}
00188         for(i=0, bg=0;i<3;i++) 
00189         { int col = colors[i]; if (col<0) col += 256; bg += col * (1 << (16-8*i));}
00190         rgbmap_ball_shadow_gen(55, rgbbuf, fg, bg, 17.0, 35.0, 3);
00191         return rgbbuf;
00192 }
00193 
00194 
00195 static ResultType rgb_eval (Pos *pos, Player to_play, float *eval)
00196 {
00197         int i, j;
00198         int lines[8][2] = 
00199         { 
00200                 //{start, incr}
00201                 // rows
00202                 {0, 1}, {3, 1}, {6, 1},
00203                 // cols
00204                 {0, 3}, {1, 3}, {2, 3},
00205                 // diagonals
00206                 {0, 4}, {2, 2},
00207         };
00208         int val, found;
00209         for (i=0; i<8; i++)
00210         {
00211                 val = -1; found = 1;
00212                 for (j=0; j<3; j++)
00213                 {
00214                         if (val >= 0 && pos->board[lines[i][0] + j * lines[i][1]] != val) 
00215                         { found = 0; break; }
00216                         val = pos->board[lines[i][0] + j * lines[i][1]];
00217                         if (val == RGB_EMPTY) { found = 0; break; }
00218                 }
00219                 if (found)
00220                 {
00221                         *eval = (to_play == WHITE ? -2*GAME_EVAL_INFTY : 2*GAME_EVAL_INFTY);
00222                         return RESULT_NOTYET;
00223                 }
00224         }
00225         *eval = 0;
00226         return RESULT_NOTYET;
00227 }