This is the doxygen documentation for gtkboard.

.
Main Page   Data Structures   File List   Data Fields   Globals  

ninemm.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 <stdlib.h>
00021 #include <string.h>
00022 #include <assert.h>
00023 
00024 #include "game.h"
00025 #include "../pixmaps/ninemm_bg.xpm"
00026 
00027 #define NINEMM_CELL_SIZE 36
00028 #define NINEMM_NUM_PIECES 2
00029 
00030 #define NINEMM_BOARD_WID 7
00031 #define NINEMM_BOARD_HEIT 7
00032 
00033 char ninemm_colors[6] = {200, 200, 200, 140, 140, 140};
00034 
00035 static char *ninemm_wp_xpm[] = 
00036 {
00037         "36 36 2 1",
00038         "  c none",
00039         ". c blue",
00040         "                                    ",
00041         "                                    ",
00042         "                                    ",
00043         "                                    ",
00044         "                                    ",
00045         "                                    ",
00046         "                                    ",
00047         "                                    ",
00048         "        ....................        ",
00049         "        ....................        ",
00050         "        ....................        ",
00051         "        ....................        ",
00052         "        ....................        ",
00053         "        ....................        ",
00054         "        ....................        ",
00055         "        ....................        ",
00056         "        ....................        ",
00057         "        ....................        ",
00058         "        ....................        ",
00059         "        ....................        ",
00060         "        ....................        ",
00061         "        ....................        ",
00062         "        ....................        ",
00063         "        ....................        ",
00064         "        ....................        ",
00065         "        ....................        ",
00066         "        ....................        ",
00067         "        ....................        ",
00068         "                                    ",
00069         "                                    ",
00070         "                                    ",
00071         "                                    ",
00072         "                                    ",
00073         "                                    ",
00074         "                                    ",
00075         "                                    ",
00076 };
00077 
00078 static char *ninemm_bp_xpm[] = 
00079 {
00080         "36 36 2 1",
00081         "  c none",
00082         ". c red",
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         "                                    ",
00118         "                                    ",
00119 };
00120 
00121 static char ** ninemm_pixmaps[] = { ninemm_wp_xpm, ninemm_bp_xpm };
00122 
00123 int ninemm_init_pos [NINEMM_BOARD_WID*NINEMM_BOARD_HEIT] = {0};
00124 
00125 #define NINEMM_EMPTY 0
00126 #define NINEMM_WP 1
00127 #define NINEMM_BP 2
00128 
00129 
00130 void ninemm_init ();
00131 int ninemm_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **);
00132 void ninemm_reset_uistate ();
00133 
00134 Game Ninemm = { NINEMM_CELL_SIZE, NINEMM_BOARD_WID, NINEMM_BOARD_HEIT, 
00135         NINEMM_NUM_PIECES, 
00136         ninemm_colors, ninemm_init_pos, ninemm_pixmaps, "Nine Men's Morris", ninemm_init};
00137 
00138 static int ninemm_allowed [] = 
00139 {
00140         1, 0, 0, 1, 0, 0, 1,
00141         0, 1, 0, 1, 0, 1, 0,
00142         0, 0, 1, 1, 1, 0, 0,
00143         1, 1, 1, 0, 1, 1, 1,
00144         0, 0, 1, 1, 1, 0, 0,
00145         0, 1, 0, 1, 0, 1, 0,
00146         1, 0, 0, 1, 0, 0, 1,
00147 
00148 };
00149 
00150 static int ninemm_mills [][3][3] = 
00151 {
00152         /* triples of squares that form mills 
00153            The four rotations of these will produce all the mills */
00154         { {0, 0}, {3, 0}, {6, 0} },
00155         { {1, 1}, {3, 1}, {5, 1} },
00156         { {2, 2}, {3, 0}, {4, 2} },
00157         { {0, 0}, {1, 1}, {2, 2} },
00158 };
00159 
00160 void ninemm_init ()
00161 {
00162         game_white_string = "Blue";
00163         game_black_string = "Red";
00164         game_bg_pixmap = ninemm_bg_xpm;
00165         game_getmove = ninemm_getmove;
00166         game_reset_uistate = ninemm_reset_uistate;
00167         game_doc_about = 
00168                 "Ninemm\n"
00169                 "Two player game\n"
00170                 "Status: Partially implemented\n"
00171                 "URL: "GAME_DEFAULT_URL ("ninemm");
00172 }
00173 
00174 static int curx = -1, cury = -1;
00175 
00176 // does the move (x, y) complete a mill for player
00177 static gboolean makes_mill (byte *board, Player player, int x, int y)
00178 {
00179         int i, j;
00180         int thepiece = player == WHITE ? NINEMM_WP : NINEMM_BP;
00181         for (i=x-2; i<=x; i++)
00182         {
00183                 gboolean found = TRUE;
00184                 if (i < 0 || i >= board_wid-2)
00185                         continue;
00186                 for (j=i; j<=i+2; j++)
00187                         if (j != x && board [y * board_wid + j] != thepiece)
00188                                 found = FALSE;
00189                 if (found) return TRUE;
00190         }
00191         
00192         for (i=y-2; i<=y; i++)
00193         {
00194                 gboolean found = TRUE;
00195                 if (i < 0 || i >= board_heit-2)
00196                         continue;
00197                 for (j=i; j<=i+2; j++)
00198                         if (j != y && board [j * board_wid + x] != thepiece)
00199                                 found = FALSE;
00200                 if (found) return TRUE;
00201         }
00202 
00203         return FALSE;
00204 }
00205 
00206 int ninemm_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, byte **movp, int ** rmovep)
00207 {
00208         int val;
00209         static byte move[16];
00210         static int rmove[16];
00211         if (type != GTKBOARD_BUTTON_RELEASE)
00212                 return 0;
00213         if (!ninemm_allowed [y * board_wid + x]) return -1;
00214         if (curx < 0)
00215         {
00216                 if (pos->board [y * board_wid + x] != NINEMM_EMPTY)
00217                         return -1;
00218                 if (makes_mill (pos->board, to_play, x, y))
00219                 {
00220                         curx = x;
00221                         cury = y;
00222                         rmove[0] = x;
00223                         rmove[1] = y;
00224                         rmove[2] = RENDER_REPLACE | 
00225                                 ((to_play == WHITE ? NINEMM_WP : NINEMM_BP) << 8);
00226                         rmove[3] = -1;
00227                         *rmovep = rmove;
00228                         return 0;
00229                 }
00230                 else
00231                 {
00232                         move[0] = x;
00233                         move[1] = y;
00234                         move[2] = (to_play == WHITE ? NINEMM_WP : NINEMM_BP);
00235                         move[3] = -1;
00236                         *movp = move;
00237                         return 1;                       
00238                 }
00239         }
00240         if (pos->board [y * board_wid + x] != (to_play == WHITE ? NINEMM_BP : NINEMM_WP))
00241                 return -1;
00242         rmove[0] = curx;
00243         rmove[1] = cury;
00244         rmove[2] = 0;
00245         rmove[3] = -1;
00246         *rmovep = rmove;
00247         move[0] = x;
00248         move[1] = y;
00249         move[2] = 0;
00250         move[3] = curx;
00251         move[4] = cury;
00252         move[5] = (to_play == WHITE ? NINEMM_WP : NINEMM_BP);
00253         move[6] = -1;
00254         *movp = move;   
00255         curx = -1;
00256         cury = -1;
00257         return 1;
00258 }
00259 
00260 void ninemm_reset_uistate ()
00261 {
00262         curx = cury = -1;
00263 }