This is the doxygen documentation for gtkboard.

.
Main Page   Data Structures   File List   Data Fields   Globals  

hiq.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 #include <time.h>
00024 
00025 #include "game.h"
00026 #include "aaball.h"
00027 
00028 #define HIQ_CELL_SIZE 54
00029 #define HIQ_NUM_PIECES 5
00030 
00031 #define HIQ_BOARD_WID 7
00032 #define HIQ_BOARD_HEIT 7
00033 
00034 
00035 #define abs(x) ((x) < 0 ? -(x):(x))
00036 
00037 char hiq_colors[6] = {170, 170, 170, 170, 170, 170};
00038 
00039 int hiq_init_pos [HIQ_BOARD_WID*HIQ_BOARD_HEIT] = 
00040 {
00041          3 , 3 , 1 , 1 , 1 , 3 , 3 ,
00042          3 , 3 , 1 , 1 , 1 , 3 , 3 ,
00043          1 , 1 , 1 , 1 , 1 , 1 , 1 ,
00044          1 , 1 , 1 , 4 , 1 , 1 , 1 ,
00045          1 , 1 , 1 , 1 , 1 , 1 , 1 ,
00046          3 , 3 , 1 , 1 , 1 , 3 , 3 ,
00047          3 , 3 , 1 , 1 , 1 , 3 , 3 ,
00048 };
00049 
00050 #define HIQ_EMPTY 0
00051 #define HIQ_RP 1
00052 #define HIQ_BP 2
00053 #define HIQ_UNUSED 3
00054 #define HIQ_HOLE 4
00055 
00056 static char * grey_square_54_xpm [] =
00057 {
00058 "54 54 1 1",
00059 ". c #d7d7d7",
00060 "......................................................",
00061 "......................................................",
00062 "......................................................",
00063 "......................................................",
00064 "......................................................",
00065 "......................................................",
00066 "......................................................",
00067 "......................................................",
00068 "......................................................",
00069 "......................................................",
00070 "......................................................",
00071 "......................................................",
00072 "......................................................",
00073 "......................................................",
00074 "......................................................",
00075 "......................................................",
00076 "......................................................",
00077 "......................................................",
00078 "......................................................",
00079 "......................................................",
00080 "......................................................",
00081 "......................................................",
00082 "......................................................",
00083 "......................................................",
00084 "......................................................",
00085 "......................................................",
00086 "......................................................",
00087 "......................................................",
00088 "......................................................",
00089 "......................................................",
00090 "......................................................",
00091 "......................................................",
00092 "......................................................",
00093 "......................................................",
00094 "......................................................",
00095 "......................................................",
00096 "......................................................",
00097 "......................................................",
00098 "......................................................",
00099 "......................................................",
00100 "......................................................",
00101 "......................................................",
00102 "......................................................",
00103 "......................................................",
00104 "......................................................",
00105 "......................................................",
00106 "......................................................",
00107 "......................................................",
00108 "......................................................",
00109 "......................................................",
00110 "......................................................",
00111 "......................................................",
00112 "......................................................",
00113 "......................................................",
00114 };
00115 
00116 
00117 void hiq_init ();
00118 
00119 Game Hiq = { HIQ_CELL_SIZE, HIQ_BOARD_WID, HIQ_BOARD_HEIT, 
00120         HIQ_NUM_PIECES, 
00121         hiq_colors, hiq_init_pos, NULL, "Hiq", 
00122         hiq_init};
00123 
00124 typedef struct
00125 {
00126         int score;
00127 }Hiq_state;
00128 
00129 static int hiq_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **);
00130 ResultType hiq_who_won (Pos *, Player , char **);
00131 char ** hiq_get_pixmap (int , int); 
00132 void hiq_reset_uistate ();
00133 
00134 void hiq_init ()
00135 {
00136         game_single_player = 1;
00137         game_getmove = hiq_getmove;
00138         game_who_won = hiq_who_won;
00139         game_get_pixmap = hiq_get_pixmap;
00140         game_who_won = hiq_who_won;
00141         game_scorecmp = game_scorecmp_def_iscore;
00142         game_reset_uistate = hiq_reset_uistate;
00143         game_doc_about = 
00144                 "Hiq\n"
00145                 "Single player game\n"
00146                 "Status: Fully implemented\n"
00147                 "URL: "GAME_DEFAULT_URL ("hiq");
00148         game_doc_rules = 
00149                 "Hiq rules\n"
00150                 "\n"
00151                 "The objective is to eliminate as many balls as possible.\n"
00152                 "\n"
00153                 "Each move consists of clicking on a filled square and then clicking on an empty square with exactly one square in between, which must be filled. The ball on the original square goes to the empty square and the middle ball disappears. Diagonal moves are not allowed.\n"
00154                 "\n"
00155                 "If you have managed to leave only a single ball remaining then try the problem of leaving only a single ball on the center square.\n"; 
00156         game_doc_strategy =
00157                 "Get the balls out of the edges as soon as possible.";
00158 }
00159 
00160 char ** hiq_get_pixmap (int idx, int color)
00161 {
00162         int bg, i, fg, rad, grad;
00163         char *colors;
00164         static char pixbuf[HIQ_CELL_SIZE * (HIQ_CELL_SIZE+1)];
00165         if (idx == HIQ_UNUSED) return grey_square_54_xpm;
00166         colors = hiq_colors;
00167         if (color == BLACK) colors += 3;
00168         for(i=0, bg=0;i<3;i++) 
00169         { int col = colors[i]; if (col<0) col += 256; bg += col * (1 << (16-8*i));}
00170         fg = (idx == HIQ_RP ? 0xff << 16 : 0xd0d0d0);
00171         rad = (idx == HIQ_RP ? 16 : 18);
00172         grad = (idx == HIQ_RP ? 24 : 36);
00173         return pixmap_ball_gen(54, pixbuf, fg, bg, rad, grad);
00174 }
00175 
00176 ResultType hiq_who_won (Pos *pos, Player player, char **commp)
00177 {
00178         static char comment [32];
00179         int i, j, k;
00180         int found = 0, count = 0;
00181         int incx [] = { 0, 0, -1, 1 };
00182         int incy [] = { -1, 1, 0, 0 };
00183         for (i=0; i<board_wid; i++)
00184         for (j=0; j<board_heit; j++)
00185         {
00186                 if (pos->board [j * board_heit + i] != HIQ_RP) continue;
00187                 count++;
00188                 for (k=0; k<4; k++)
00189                 {
00190                         int x = i + incx[k];
00191                         int y = j + incy[k];
00192                         if (x < 0 || y < 0 || x >= board_wid || y >= board_heit) continue;
00193                         if (pos->board [y * board_heit + x] != HIQ_RP) continue;
00194                         x += incx[k];
00195                         y += incy[k];
00196                         if (x < 0 || y < 0 || x >= board_wid || y >= board_heit) continue;
00197                         if (pos->board [y * board_heit + x] != HIQ_HOLE) continue;
00198                         found = 1;
00199                 }
00200         }
00201         if (!found)
00202         {
00203                 snprintf (comment, 32, "%s %d %s left", 
00204                                 count == 1 ? "Congrats!" : "Game over.", 
00205                                 count, count == 1 ? "ball" : "balls");
00206                 *commp = comment;
00207                 return RESULT_WHITE;
00208         }
00209         snprintf (comment, 32, "%d balls left", 32 - pos->num_moves);
00210         *commp = comment;
00211         return RESULT_NOTYET;
00212 }
00213 
00214 static int  oldx = -1, oldy = -1;
00215 
00216 void hiq_reset_uistate ()
00217 {
00218         oldx = oldy = -1;
00219 }
00220 
00221 int hiq_getmove 
00222         (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, byte **movp, int ** rmovep)
00223 {
00224         static byte move[10];
00225         static int rmove[10];
00226         int diffx, diffy;
00227         if (type != GTKBOARD_BUTTON_RELEASE)
00228                 return 0;
00229         if (oldx == -1)
00230         {
00231                 if (hiq_init_pos[y * board_wid + x] == HIQ_UNUSED) 
00232                         { return oldx = oldy = -1; }
00233                 if (pos->board [y * board_wid + x] == HIQ_HOLE)
00234                         return -1;
00235                 oldx = x; oldy = y;
00236                 rmove[0] = x;
00237                 rmove[1] = y;
00238                 rmove[2] = RENDER_HIGHLIGHT1;
00239                 rmove[3] = -1;
00240                 *rmovep = rmove;
00241                 return 0;
00242         }
00243 
00244         rmove[0] = oldx;
00245         rmove[1] = oldy;
00246         rmove[2] = RENDER_NONE;
00247         rmove[3] = -1;
00248         *rmovep = rmove;
00249         if (hiq_init_pos[y * board_wid + x] == HIQ_UNUSED) 
00250                 { return oldx = oldy = -1; }
00251 
00252         if (x == oldx && y == oldy)
00253         {
00254                 oldx = -1; oldy = -1; return 0;
00255         }
00256         
00257         if (pos->board [y * board_wid + x] != HIQ_HOLE) { return oldx = oldy = -1; }
00258         diffx = abs (x - oldx); diffy = abs (y - oldy);
00259         if (diffx * diffy) { return oldx = oldy = -1; }
00260         if (diffx != 2 && diffy != 2) { return oldx = oldy = -1; }
00261         move[0] = oldx; move[1] = oldy; move[2] = HIQ_HOLE;
00262         move[3] = x; move[4] = y; move[5] = pos->board [oldy * board_wid + oldx];
00263         move[6] = (x+oldx)/2; move[7] = (y+oldy)/2; move[8] = HIQ_HOLE;
00264         move[9] = -1;
00265         oldx = -1; oldy = -1;
00266 
00267         if (movp)
00268                 *movp = move;   
00269         return 1;
00270 }
00271