This is the doxygen documentation for gtkboard.
.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 #include <gdk/gdkkeysyms.h> 00025 00026 00027 #include "game.h" 00028 #include "../pixmaps/alpha.xpm" 00029 #include "flwords.h" 00030 00031 00032 #define WORDTRIS_CELL_SIZE 36 00033 00034 #define WORDTRIS_NUM_PIECES 27 00035 00036 #define WORDTRIS_BOARD_WID 4 00037 #define WORDTRIS_BOARD_HEIT 14 00038 00039 #define WORDTRIS_LEN 4 00040 00041 #define WORDTRIS_EMPTY 0 00042 #define WORDTRIS_WILDCARD 27 00043 00044 char wordtris_colors[9] = {0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0, 0, 0xff}; 00045 char wordtris_highlight_colors[9] = {0x0, 0x0, 0xff, 0, 0, 0, 0, 0, 0}; 00046 00047 static char *smiley_xpm[] = 00048 { 00049 "36 36 2 1", 00050 " c none", 00051 ". c #ffff77", 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 " .... .... ", 00079 " .......... ", 00080 " ...... ", 00081 " .. ", 00082 " ", 00083 " ", 00084 " ", 00085 " ", 00086 " ", 00087 " ", 00088 }; 00089 00090 static char **wordtris_pixmaps [] = 00091 { 00092 char_A_grey_36_36_xpm, 00093 char_B_grey_36_36_xpm, 00094 char_C_grey_36_36_xpm, 00095 char_D_grey_36_36_xpm, 00096 char_E_grey_36_36_xpm, 00097 char_F_grey_36_36_xpm, 00098 char_G_grey_36_36_xpm, 00099 char_H_grey_36_36_xpm, 00100 char_I_grey_36_36_xpm, 00101 char_J_grey_36_36_xpm, 00102 char_K_grey_36_36_xpm, 00103 char_L_grey_36_36_xpm, 00104 char_M_grey_36_36_xpm, 00105 char_N_grey_36_36_xpm, 00106 char_O_grey_36_36_xpm, 00107 char_P_grey_36_36_xpm, 00108 char_Q_grey_36_36_xpm, 00109 char_R_grey_36_36_xpm, 00110 char_S_grey_36_36_xpm, 00111 char_T_grey_36_36_xpm, 00112 char_U_grey_36_36_xpm, 00113 char_V_grey_36_36_xpm, 00114 char_W_grey_36_36_xpm, 00115 char_X_grey_36_36_xpm, 00116 char_Y_grey_36_36_xpm, 00117 char_Z_grey_36_36_xpm, 00118 smiley_xpm, 00119 }; 00120 00121 00122 00123 // TODO: change this so that we only need to specify pixmaps for individual squares 00124 00125 static const int lava_xpm_header_size = 253+1; 00126 static char * lava_xpm_header[] = 00127 { 00128 "144 504 253 2", 00129 " c #d7d7d7", 00130 ". c #FFD800", 00131 "+ c #FFAC00", 00132 "@ c #FFA800", 00133 "# c #FF8000", 00134 "$ c #FF0600", 00135 "% c #830000", 00136 "& c #310000", 00137 "* c #150000", 00138 "= c #1F0000", 00139 "- c #2D0000", 00140 "; c #270000", 00141 "> c #210000", 00142 ", c #1B0000", 00143 "' c #230000", 00144 ") c #1D0000", 00145 "! c #0B0000", 00146 "~ c #010000", 00147 "{ c #090000", 00148 "] c #2F0000", 00149 "^ c #3B0000", 00150 "/ c #630000", 00151 "( c #8B0000", 00152 "_ c #930000", 00153 ": c #8D0000", 00154 "< c #CF0000", 00155 "[ c #FF6600", 00156 "} c #FF9E00", 00157 "| c #FF4C00", 00158 "1 c #FF7A00", 00159 "2 c #FF8E00", 00160 "3 c #FF7600", 00161 "4 c #FF5800", 00162 "5 c #FF6200", 00163 "6 c #FFB600", 00164 "7 c #FFDA00", 00165 "8 c #FF8C00", 00166 "9 c #FF9400", 00167 "0 c #FFCE00", 00168 "a c #FFD200", 00169 "b c #FF9A00", 00170 "c c #FF7800", 00171 "d c #FFF000", 00172 "e c #FFDE00", 00173 "f c #FFAE00", 00174 "g c #FF8400", 00175 "h c #FF7000", 00176 "i c #FF8200", 00177 "j c #FFA400", 00178 "k c #FFB000", 00179 "l c #FFA000", 00180 "m c #FF9800", 00181 "n c #FFAA00", 00182 "o c #FFEA00", 00183 "p c #FFD400", 00184 "q c #FF7400", 00185 "r c #FF6E00", 00186 "s c #FFCC00", 00187 "t c #FFBC00", 00188 "u c #FF7200", 00189 "v c #FFC400", 00190 "w c #FFEE00", 00191 "x c #FFA200", 00192 "y c #FF9200", 00193 "z c #FFB400", 00194 "A c #FFA600", 00195 "B c #FF9000", 00196 "C c #FF8800", 00197 "D c #FFD000", 00198 "E c #FF9C00", 00199 "F c #FF1000", 00200 "G c #D90000", 00201 "H c #FF0E00", 00202 "I c #FF5000", 00203 "J c #FF8600", 00204 "K c #FF9600", 00205 "L c #FF7E00", 00206 "M c #FF6C00", 00207 "N c #FF6000", 00208 "O c #FF4200", 00209 "P c #FF2600", 00210 "Q c #FF4400", 00211 "R c #FFE600", 00212 "S c #FF5C00", 00213 "T c #E50000", 00214 "U c #B30000", 00215 "V c #A90000", 00216 "W c #7F0000", 00217 "X c #550000", 00218 "Y c #5F0000", 00219 "Z c #890000", 00220 "` c #BF0000", 00221 " . c #F30000", 00222 ".. c #ED0000", 00223 "+. c #AD0000", 00224 "@. c #7D0000", 00225 "#. c #DD0000", 00226 "$. c #FF2E00", 00227 "%. c #FF2C00", 00228 "&. c #FF1200", 00229 "*. c #370000", 00230 "=. c #110000", 00231 "-. c #070000", 00232 ";. c #0F0000", 00233 ">. c #130000", 00234 ",. c #190000", 00235 "'. c #170000", 00236 "). c #450000", 00237 "!. c #4D0000", 00238 "~. c #510000", 00239 "{. c #570000", 00240 "]. c #9F0000", 00241 "^. c #FF3200", 00242 "/. c #FF4800", 00243 "(. c #D70000", 00244 "_. c #AF0000", 00245 ":. c #E90000", 00246 "<. c #BD0000", 00247 "[. c #A30000", 00248 "}. c #FF8A00", 00249 "|. c #FF5200", 00250 "1. c #E30000", 00251 "2. c #9D0000", 00252 "3. c #FF3000", 00253 "4. c #FF0200", 00254 "5. c #FFD600", 00255 "6. c #910000", 00256 "7. c #C10000", 00257 "8. c #FF1E00", 00258 "9. c #FF3C00", 00259 "0. c #FF1800", 00260 "a. c #FF0800", 00261 "b. c #F10000", 00262 "c. c #E70000", 00263 "d. c #FF1400", 00264 "e. c #F50000", 00265 "f. c #970000", 00266 "g. c #FF4E00", 00267 "h. c #FF2A00", 00268 "i. c #FF1A00", 00269 "j. c #FF0400", 00270 "k. c #F70000", 00271 "l. c #F90000", 00272 "m. c #EF0000", 00273 "n. c #FF4000", 00274 "o. c #FF2800", 00275 "p. c #FF2200", 00276 "q. c #DB0000", 00277 "r. c #A50000", 00278 "s. c #D10000", 00279 "t. c #C50000", 00280 "u. c #670000", 00281 "v. c #6F0000", 00282 "w. c #9B0000", 00283 "x. c #AB0000", 00284 "y. c #DF0000", 00285 "z. c #8F0000", 00286 "A. c #A70000", 00287 "B. c #C90000", 00288 "C. c #FFB800", 00289 "D. c #FFE000", 00290 "E. c #FF0C00", 00291 "F. c #6D0000", 00292 "G. c #290000", 00293 "H. c #410000", 00294 "I. c #750000", 00295 "J. c #EB0000", 00296 "K. c #D50000", 00297 "L. c #5B0000", 00298 "M. c #000000", 00299 "N. c #050000", 00300 "O. c #390000", 00301 "P. c #770000", 00302 "Q. c #C30000", 00303 "R. c #B70000", 00304 "S. c #B50000", 00305 "T. c #FFB200", 00306 "U. c #A10000", 00307 "V. c #FFBA00", 00308 "W. c #FF5400", 00309 "X. c #FF0000", 00310 "Y. c #CB0000", 00311 "Z. c #870000", 00312 "`. c #D30000", 00313 " + c #4B0000", 00314 ".+ c #250000", 00315 "++ c #FF6A00", 00316 "@+ c #FFC000", 00317 "#+ c #CD0000", 00318 "$+ c #FF3600", 00319 "%+ c #FF3400", 00320 "&+ c #2B0000", 00321 "*+ c #3F0000", 00322 "=+ c #730000", 00323 "-+ c #590000", 00324 ";+ c #850000", 00325 ">+ c #790000", 00326 ",+ c #3D0000", 00327 "'+ c #B90000", 00328 ")+ c #330000", 00329 "!+ c #030000", 00330 "~+ c #430000", 00331 "{+ c #690000", 00332 "]+ c #FFBE00", 00333 "^+ c #FFCA00", 00334 "/+ c #FD0000", 00335 "(+ c #FF3A00", 00336 "_+ c #BB0000", 00337 ":+ c #490000", 00338 "<+ c #7B0000", 00339 "[+ c #810000", 00340 "}+ c #6B0000", 00341 "|+ c #650000", 00342 "1+ c #E10000", 00343 "2+ c #FF5E00", 00344 "3+ c #B10000", 00345 "4+ c #0D0000", 00346 "5+ c #FFC600", 00347 "6+ c #710000", 00348 "7+ c #FFC800", 00349 "8+ c #C70000", 00350 "9+ c #470000", 00351 "0+ c #FFE400", 00352 "a+ c #FF0A00", 00353 "b+ c #FF5A00", 00354 "c+ c #FFC200", 00355 "d+ c #FF5600", 00356 "e+ c #FF1600", 00357 "f+ c #990000", 00358 "g+ c #FF7C00", 00359 "h+ c #5D0000", 00360 "i+ c #530000", 00361 "j+ c #FF2400", 00362 "k+ c #FFE200", 00363 "l+ c #FF6400", 00364 "m+ c #610000", 00365 "n+ c #4F0000", 00366 "o+ c #950000", 00367 "p+ c #FF3E00", 00368 "q+ c #FF2000", 00369 "r+ c #350000", 00370 "s+ c #FB0000", 00371 "t+ c #FF6800", 00372 "u+ c #FF1C00", 00373 "v+ c #FF4A00", 00374 "w+ c #FFEC00", 00375 "x+ c #FF4600", 00376 "y+ c #FF3800", 00377 "z+ c #FFDC00", 00378 "A+ c #FFE800", 00379 "B+ c #FFF600", 00380 "C+ c #FFF200", 00381 "D+ c #FFF400", 00382 }; 00383 00384 static char *lava_xpm_data[] = 00385 { 00386 ". + @ # $ % & * = - - ; > , = ' ) ! ~ { = ] ^ / ( _ : ( < [ } [ | 1 2 3 4 5 6 7 6 8 3 3 9 0 a b c 9 a d e f g h h i j k j l m 8 9 n a o d p 9 q r q 9 s t r u v w o p 6 x x x x } y 9 f z A A z n B # 3 c C n D E F G H I h 1 J y E K L h r M N O P Q f R a @ m S T U V W X Y Z ` ...+.@.W #.8 ", 00387 "} $.%.&._ *.=.-.{ ;.>.,.) ,., > , ! ~ -.'.) ) ] ).!.~.{.].^./.(._.:. .<.[.:.}.z |.1.[.2. .B @ 3.< 4.m 5.} %.` _ 6.7.8.9.0.a.b.G c.d.5 A D K e.2.: f...g C d.$.n . 6 C g.h.i.j.k.l.m.k.n.I o.3./.p.q.U ].r.s.%.} 1 t.u.v.Z w.x.7.G ..y.+.z._ w.A.B.4.|.C.D.k 5 n.E.V W Z F.*.G.H.I.B.J.V {.).+.1 ", 00388 "i m.J.K.L.=.~ M.M.~ N.>.= = ) = '.-.~ N.=.>.! ;.= - *.O.P.E.3.Q.Z R.< S.+.l.B T.n.x.H.] U.r V.S :.$ 9 C.W.< Y ] - u.(.X.Y.r.6.% Z.w.B.%.l J `. += .+( I g 9.++@+@ |.$.d.4.q.: F.( V #+$.I $.$+%+y.W ).G.& F.T i M V *.; &+& *+{.u.=+/ *.] -+Z +.T 9.# k a s l [ X.].I.;+>+,+'.) H.6.#.'+{.)+w.q ", 00389 "C e.c.(./ * !+M.M.M.{ , G.; .+; , { ~ N.=.=.-.{ ) O.~+,+{+m.O d.Y.q.%.5 h J ]+^+C /+v.O.Z.(+6 t y 9 @+x o._+=+!.:+<+< :.S.[+}+{+}+|+P...2 f O _+|+*.>+3.x f v 6 | 1+(.1. .(.>+~+P.q.P g + l A }.o.S.-+' ' L.q.# M V *..+- *+X {+P.>+/ ).F.y.9.5 3 J h 2+9 p 7 2 j.3+_ U.A.P.,+.+&+/ ` t.F.~+r.c ", 00390 "b $.8.E.U. +; >.N.N.>.; - ' > G.' 4+!+! >.=.-.{ *.Z.+.V R.X.n.3.1+J.h 5+6 i h C x ++y.6+{+t.Q m 7+7+b 4 4.8+].<+>+r.B.Y._.P. +9+~.!.F.k.C C.A h 8.Q.B.O t 0+v I R.W _+J.H a+'+% < b+@ D s + c+^+j I K.W }+: l.8 r x.O.- !.W r.U _+_+2._ ..N # ++d+%+a.e+[ v D.8 .+.f+]._+R.;+!.& +2.7.[+~._.g+", 00391 "@+B L 4 e.].F.~+= '..+& ; * * .+G.'.;.* '.;.N.>.=+i.M h M q 1 Q 8+Y.q 6 W.#+w.s.I 9 n.+.L.h+2.i.} 9 F <.V [.6.W f.8+Q.x.r.Z.i+9+~.X Z i.J 2 l ]+f g+q j . 0+B < +u.k.5 C i Q j+M c+k+k+x 9.W.9 v c+# (+8.p.4 + q +.^ ,+>+_+Y.<._+S.].t.Q u &.+.Z.<+_.9.l D p g m.2.% P.( +.x.W +).% U Z.X A.++", 00392 "z 8 l+3.1+U.;+v.!.O.*.] , { ! ' & ; ) ,.>.4+>.*+B.# V.j T.7+c+5 x.V l+L #+*+) !.1.L r `.Y O.X (.i M V ). +/ m+h+6.1+K.f.2.2.F.-+-+L.6.i.g i 1 j l 3 3 } 6 c+u _.:+w.| } b f 6 6 s 7+6 5+i 1+S.b.N V.p 7+t C.v p 3 A.^ n+6.+.% L.i+i+{.A.(+9.w.- >.' o+l+V.K M 3.#+z.I.|+h+=+w.U.6+ +<+U ].>+V %.", 00393 "n.X.S.Z u.~.X }+6+{.*.) ! !+{ = & ] = ;.4+; }+8+W.V.b Q N n s h x.x.5 N 6.* ~ , Z p+L q+_+f++.&.9 l+z.> &+:+:+H.>+1+:.A.U B.6.h+9+).v.s.(+M 1 ++i.` 8+i.| u r X.` E.c S 0.d+z e v l+$+8 h R.X |+Q.|.V.e k+D.0+7 r 2.,+m+o+% H.'.=.>..+% 0.H F.=.!+) ].M E j+U ( [+@.{+h+{.L.@._.f+h+}++.< Y.B.y.", 00394 "_.;+X O.- G.] +P.F.r+;.!+M.N.* .+; * -.=.}+F g+V.@+[ s+$ S T.}.s+s+i 5 ( =.M.-.9+G N # M [ q E @+5 Z = G.~+ +9+=+K.s+1+4.p.:.Z.9+O.9+u.].e.%+H w.H.i+R./+q+g.|./.l+N ..w.b.1 7+8 1+B.[ N f+.+) ~.#+Q u 3 c g 8 (+( ).6+6./ .+{ -.{ ,.6+j.a+P.> * ] r.t+A o.I.& !.}+|+X i+Y @._+B.% {.I.x.t.Q.` ", 00395 "F./ -+~.9+O.- O.u.<+ +'.-.-.! >.> &+' , *+8+L V.m t+u+1+..3.2 k }.B @+M 6.* M.~ , }+J.| M C ]+a f (+>+, ' ^ ).9+u.S...$ %.d+Q Y.-+*.*.r+!.2.1+t.|+> G.P.Q.1+e.j+p+O u+V ;+1.2+6 h _.V 2+S ( >.N..+=++._.U.U.t.s+q.{+H.F.% X ) N.N.-.* h+c.0._.{.H.:+_ $+A 4 ( &+^ L.u.{.:+-+[+B. .S.-+9+L.}+W [.", 00396 "W v.F.P.v.!.r+& !.=+Y - ,.'.,.) - X W _ #+W.V.K j+ .y.#+s.m.o.2+# f ^+L S.G.N.-.>.*.P.+.` X.8 f d+:.|+> ' & )+& 9+;+R.G .%.4 l.6+H.*+*+n+: `.K.( ).- ).[+_._+J.a.d.H G `.a.v+@ J y.t.l+2+( >.!+= X {+9+&+G.-+3+` @./ @.% X = N.~ !+>.n+8+p.k.A.[+}+=+1.i [ U.*.^ {.}+|+!. +{+U a.T =+*+)+] n+o+", 00397 "A.Z.W ( [+-+*.&+*./ =+!.- ) ,.= n+Q.(+t+g C.@+t+e.(.t.V V x.+.<.:.p+}.2 j.i+=.,.&+,+~.-+{.V ++B 8.< ( L. +~+*..+- Y z.x.8+&.d+&.w.=+>+>+=+Z._+T K.].v.-+=+w.'+T J.T $ 0.0.4.d.2 z /.a.3 ++[.; >.- Y |+*.,.> -+Q./+c.`.` : i+> -.~ 4+)+P.s.0.F 1+8+U.<+7.r M 3+^ )+~.v.=+L.).).Z H F 6.).G., ~+].", 00398 "_+( ;+6.% |+9+r+O.Y Z W X - > ~+U W.C.6 8 g u %. .Y.2.Z f+2._ _ 3+ .I m Q @.= ; *.,+*+O.r+o+l+B %.&.H m.Y._.: i+- H.v.6.` u+d+e+Y.Q.(.K.3+( 6.Q.:.T #+3+V U `./+K.2.+.K.s.U.+.n.z C 9.8 B X.w.% 6.[.% ,+.+:+( 1.^.4 I H _.u.)+>.* *+( s.l.F s+q.s.t.2.B.r 3 Q.~+&+:+6+>+Y ~+r+I.F $.x.H.,.;.*+V ", 00399 "S.6+I.6.[+/ +^ ^ L.o+'+r.W Z < |.V.c+M a+/+&.X.K.].;+o++._.r.3+s.F c t q R.~+& ] > ,.>.> o+M k i 2 l B 3 t+n.G {+^ :+|+f.l.| P q.8+`.s.` +.x.Q.1+:.k.a.X.m.4.E.7.{+-+u.Y 9+Y c.B @ 3 + V.q O $+9.o.(.}+i+<+f+x.(.d.h.a.G _.P.i+u.+...l.../+$ :.(.G ` G q K a+Z.~.{.I.[+{+~+&+h+e.n.#+).>.>.:+U ", 00400 "+.-+L.( @.n+O.] &+*+v.+.`. .O J t c+c j.t.s.1.#+[.( w.S.'+r.o++.G 8.B p f q+[+,+G.=.N.{ ^ #+2 7 p 7 p V.T.+ m 5 J.W X {.=+R.u+%+c.2.<+6+@.f+` 1.b.T y./+e+d.a+:.o+~.,+:+~.h+;+e.K D 5+7+} 4 p+Q b+u v+q.].f.>+!.:+|+<+o+S.B.8+8+:.H X.B.r.S.< #+< .. .e+K 7+i H A.v.m+}+|+*+) O.7.Q a+P.~+i+Z q.", 00401 "f.).H.W @.).' * ;.* - u.#+Q f v b N a+t.S._+S.U._ r.Q.t.A.@.v.f.<.T d+c+^+d+A.:+- >.{ - r.I 5+o w+o s j l y y n g+0.s._.6.;+7.F .w.X O.^ X ;+<.c.m.8+_.` s.Q.2.}+ + +u.Z R.s+W.k R o 6 p+K.<.< $ [ 8 ^.'+I.~+,.{ 4+,.)+-+Z t.e.a.c.3+[+{+/ v.% U H I g @+p k [ 4.Z H.).L.).,.) _ x+/.Q.2.Y.k.e+", 00402 "=+*+*+<+% :+, { ~ ~ { O.Q.q s E 8.`._.w.f+w.w.f.[._+8+x.@.L.|+f+3+'+d.} T.^.w.L.9+] G.P.3.6 a c+c+5.D @+v ]+t 5.p k }.d+J.W P.t.c.R.<+X ).:+Y <+r.q.G U 2.o+W {+Y m+6+f.K.o.L f v 0+o m m.[+6+f+m.q 2 a+=+] * N.M.M.-.'.G.!.;+r.o+F.-+!.O..+' H.r.O l j i [ I v+y+<.~+& i+ +) * Z.W.t+G S.1.e...", 00403 "v.L.Y Z f+u.&+! M.M.~ ' _.1 @+5 `.6.( : _ f+o+o+].A.f+@./ m+W x._+_+X.B x %.< _+S.r.U...C 5+B d+W.r L 9 @+z+0+o 0+R A+^+M T U.r.#+8+3+U.6.Z Z.>+>+2.7.8+_+].I.|+6+( x.1+9.K a k+e w+o b .[+u.: .J q R.- -.~ M.M.~ ! ) - ,+:+~+- ' ] ] ,.-.N..+r.[ j n.Q.z.6.(.^.X.6+r+~.n+.+> o+N [ R.@.A._.w.", 00404 "% I.<+2._+[.{.'.~ M.M.* _ t+b 0.V : o+A.+.].z.z.: <+F.{+{+F.[+[.Q.q.q+E @+2 r ++++[ ++2 v j %+e.1+t.'+1.Q E 5.0+. A+B+C+0 2 O /+k.4.j.b.` [.o+Z.% <+P.( x.+.;+v.@.x...n.y 5+R w+0+k+e z x+7.I.Z X.2 ++w.= !+M.M.~ 4+&+~.{+u.9+= { ;.; ; ;.!+-.&+_.r c Q.^ * > v.X.3.'+~.i+|+Y W :.# N f+~.@.U.V ", 00405 "[.F.u.: t.(._ )+-.M.M.=.( 5 }.a.3+V <.B.U : [+;+I.m+{+P.F.Y v.U.y.p.S y 9 u 5 5 t+3 b 5+D L s+7.2.m+,+-+S.%+n 5.p e w+D+d z+6 8 # C }.I #+<+m+}+: Z -+ +<+U.f.( w.q.Q K z c+z+0 y u r q t+0.U 3+q+} q U ^ ,.! ! = ).% _+(.8+Z *+, , &+; >.>.& {+1+# 5 6.* M.N.r+` (+k.6+|+A.m.y+1 x Q W & {.f.s.", 00406 "Q.|+^ X w.y.Y./ ) ! { ,.6.t+@ /.e.(.s._+( }+6+6+/ }+% @.m+m+( #+e+W.N (+k.S.f+].S.m.|.l } 9.Y.U [.F.X @.< %.++q h u 9 0 0 9 r N l+g V.y ../ & ~+[+[.6+H.6+8+:.m.a+v+l ^+5+D . }.J.f.6._+8.I 3.%.++z c 7.-+*+)+,+F.r.K.c.m.l.T x.<+m+n+*+O.-+w.1+(+l [ z.* M.M.,.Z %.p.2.[.e+++L q I y.!.>..+v.(.", 00407 ":.W H.,+F.B...f+^ , ,.G.f.++7+9 P `.A.Z.u./ v.{+/ P.W Y ~.@.Q.j.p+|.8.s.f.Y r+& |+#.d+M y+:.Q.1+k.1+T 0.O %.c.V z.w.b.}.}. .w.Z o+:.J V.x+_ *.r+P.'+2.m+2.y+i }.B + 0 7 . D.c+%+P.) * *+3+^.2+5 g k 2+[.n+ +L.@.+.t.S.z.W A.:.H H b.t.r.U.B.l.F p+E c U ; !+M.;.P.%.| k.q+q ++F t.f+-+, !+=.Y 1.", 00408 "a+U.{+Y }+_.b._+n+) ,..+@.y+V.l F 2.P.{+/ {+F.u.{+I.|+*+i+x.s+$+4 %+1._.o+=+).] I.E.g.s+A.].Q.k.^.d+5 4 h.G [+,+= - ].[ q _+r+>.) >+9.t 9 j.f.u._ m.X.#+4.8 t 8 ++[ M h y v }.Y.r+N.~ >.h+< 0.n.8 b &.|+' - ~.[+f.% X - = ,+Z q.8.v+W.v+p.k.s._.y.++9 a.-+4+!+, Z /.2 u i r s+W ).& ,.-.M.=.{+/+", 00409 "u+V P.=+>+[...s.L.= '., +y.8 l o.s.R.f+I.Y -+Y {+u.~.).% e.v+l+n...S.f+% <+u.X o+u+$.U >+_ r.A.s.&.i.#.f+=+h+^ > - 6.I C s+~.! 4+-+E.n 0 b /.b.a.M y g+}.C.2 X.U.: ( 2.e.i h 3+- ! { ) {+q.j+W.x 3 S.&+-.4+&+X L.,+' ;.N.4+; X r.8.c b I t.{+ +W 0.y S x.*.& F.1+g 7+6 g+4.<+- , ,.=.-.~ =.F.d.", 00410 "o.A.v.P.( 7.F 4.2.u./ |+W y.h + 2 3 l+d.f.X ~./ {+h+L.Z.b.S g+/.:.x.f.I.i+|+( +.m.g.v+T _+S.: X !.u.v.~.r+O.!.:+^ ,+P.d.2 W.].)+^ x.W.v 0+k+^+} l @+C.g t+l+$.].O.,.>.] U.| g+$ Z n+).6+#.v+q K c+[ ( >.M.~ '.,+*+.+'.4+!+M.!+* F.u+8 J d.@.] = ~+` N 2 $.7.t.j+L V.t 1 a+W G.;.4+=.>.4+-.=.6+j+", 00411 "9.J.< q.e.$.t+2+i.s+s+l.l.E.h.I l+i n l+<.u.6+6.A.+.8+&.u 2 I #.f+z.W n+G.~+2.0.3 x # q+q.V 6+,+= '., ) ) &+,+,+r+& :+'+2+C 8._+< /.k t A v e . ]+2 Q q.2.f.f.=+,+'.! .+[+j.M u P < U 1+(+2+/.u 6 [ Z =.M.~ * O.^ = * =.N.M.M.=.W v+y h.].).= * )+: u+g 9 g+C k f g+y+y.% ] { N.! =.>.;.{ =.6+%.", 00412 "u u c L J B C l+%+H 4.l.J.t.f+Z f...i 8 a.R.Q.j.p+2+3 y B | G <+|+=+h+r+' ^ ].O m L y+K.Z.{.*+& > =.4+>.> )+r+.+'.=., m+k.3 B 3 i k n g.E.(+t+r Q J.2.i+.+> O.{.{.^ ' & }+_+q+q [ &.:.j.o.a.1+3.l l+( =.M.~ * *.^ > * =.N.M.~ > A.t+q < X ] ' ' 9+z.1.%.5 C c+t |.B.% u.).,.-.! * ,.* ;.-.;.F.j+", 00413 "A K q l+S x+&.:.7.: I.=+|+:+G.'..+( g.@ i I | h g+i B g+P R.|+,+~+Y / / @.U.J.2+N m.6.i+G.* * ' G.= >.;.) O.O.) { !+N..+Z.0.g+2 3 l+j+V Y v.Z o+: {+9+.+;.-.* *.X -+:+9+{+f.K.%.n.a+m./+l.7.Y.d+C.N Z.=.M.~ =.& ^ .+,.=.N.M.{ n+e.# /.f.^ )+*+i+P.w.+.U <.4.2 } a.m+- *+^ ,.4+* ,.* 4+N.~ ! h+k.", 00414 "[ &.R.z.Z.<+6+P.F.~+&+> '.! N.N.* Y ..2+K f j u $.i.j+/+U.~.- .+& L.2.c.3.S 1 J ^.o+^ , ! N.-.'.G.- .+'.) ,+ +*+- ,.4+, -+Y.e+X.7.o+{+- ;.4+>.) ; - &+> '.>.=.) *.n+n+!.}+f+B.$ p.e+E.4.`.f+s.g+T.%.u.4+M.~ ;.G.*.&+) >.N.!+> f.v+g+e./ - ^ {+f.+.[.% }+m++.M 6 9.>+&+^ ^ ) * '.;.-.~ M.M.! !.Q.", 00415 "G >+&+>.;.=.= 9+L.H.> 4+!+M.~ ! ,.)+/ V i.8 9 p+X.k.1.[.L.] = , .+/ :.S c u 5 $+#+-+G..+' = ,.'.> ] r+] ] +6+Z.W / i+Y z.`.G : ).> ;.!+M.M.!+{ =.) &+)+*.)+.+, > r+^ ^ L._ #+e.H p.P /+U ( y.i i B.)+!+M.N.>..+)+- = >.{ ,.u./+1 | [.O.; H.>+U.2.@.h+~.n+o+I c+g #+X 9+H.' ,.=.N.M.M.M.!+>.9+2.", 00416 "f+,+{ M.M.M.4+] n+~+, N.M.M.N.=.'.>.>.] f+$+r n.&.T U.Y *.> >.* )+Z p.u $.K.V W n+- ] 9+h+Y +O.H.L.P.Z.;+Z.o+r.V +.` K.c.c.3+{.= -.M.M.~ -.4+* ,.' *. +X ~.*+&+= ; )+*.9+P.U < :.j+| $.1.8+e+y t+6.* ~ ~ { * > ] &+) ,., ~.G S 5 :.Y &+] ).|+6+h+n+n+-+L.Z.8.k ]+n.U./ n+- ,.4+!+M.M.!+4+) :+o+", 00417 "A.!.>.!+M.M.N.= H.,+'.~ M.!+4+* =.N.M.! -+ .W.y+y.Z ).' , * 4+.+v.Y.3.b+e.=+O..+, = r+h+% Z P.6+o+8+..j.$ T _.@.6+6.` K.#+x.F.] ;.!+!+-.4+* ,., ,.= & 9+i+X n+~+)+] *.,+!.v.w.3+s.H p+9.p.p.4 @ [ Z =.!+{ >.,.= &+G.) G.-+<.| q 4.@.r+; ] O.9+X -+|+v.I.{+@. .2 0 1 B.>+Y r+'.-.~ M.!+4+* ) *+Z ", 00418 "G 6.~.; 4+!+N.) *+^ * !+!+4+* * ! !+M.N.^ 3+E.:.>+- ;.{ =.* ,.n+_.:.a.%.:./ > =.;., r+{.I.P.>+: <.1.J.m.s+b.+.i+&+,+/ }+-+~+- '.! -.4+* ,.,.* ;.! ! =.) ' G.*.i+P.% =+m+u.P.z.U.3+t.s.#. .E.Q l l+( >.N.;.'.* , G.G.G./ K.x+i n.2.*.) '.* ,.)+m+W W v.Y ~.m+Q.5 @+# `.[+u.*+) ! !+!+4+* * =.- }+", 00419 "$ s+K._ n+> >.&+9+O.'.{ ;.,., =.{ -.-.4+] <+Q.U n+>.-.{ * ; !.w.1+K.7.l.J.>+& > > ] +m+F.}+@.f+U V % P._ 7.x.{..+&+H.*+&+> > = , = ; &+; > ,.* =.=.>.>.* '.- <+k.$+e+y.Y.t.R.r.U.2.: ( 2.3+X.C [ f.' '.' G..+&+*.*.~.8+| 3 | #.Y ' ,.'.* = :+Z f.{+H.,+n+6+Q.S ]+i s.>+u.X *.) ;.;.'.,.=.4+' ~.", 00420 "^.b+W.H U Y & ^ +^ ' , ) = , >.;.>.'.) )+|+A.U F.,+& - *+=+8+u+%+X.1.q+o.`.[.w.2.V _+Q.t.R.S.G ..s.V w.S.m.s+t.2.w.x.V o+: z.z.z.o+w.f.6.: Z Z Z Z Z Z.[+P.Z T 3 @+z K J h p+a.e.m.q.B.B.G j+} }...f.: f.2.].2.: P.U.h.J t+u+G [.: ( Z Z o+7.b.y.: u.( _+1.j+9 D L s.6+|+F.}+{.H.*.)+)+] - O.~.", 00421 "@ C.b (+q.Z.:+H. +9+^ - = ,.=.4+>.= ' ; )+-+U.B.3+o+% I.: J.5 x l i i } y N 5 q c 1 i g g+| 8.4 J i q h 3 B b J 3 3 1 1 u h M r r u q h h r r r r M M ++4 (+9.3 5+w d w+A+z+@+l m K 8 i # J A 5.D 9 u h u 3 u b+i.T /+r C.f 2 1 h M M M M u J B [ a...(+1 y + 5.7 1 q.>+|+@.].x.f+I.m+{+v.6+6+I.", 00422 }; 00423 00424 00425 typedef struct 00426 { 00427 int score; 00428 int lives; 00429 } Wordtris_state; 00430 00431 static int total_lives = 10; 00432 00433 00434 static int wordtris_wordcmp (const void *p1, const void *p2) 00435 { 00436 return strcmp ((char *)p1, *(char **)p2); 00437 } 00438 00439 static void wordtris_init (); 00440 int wordtris_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **); 00441 int wordtris_getmove_kb (Pos *, int, Player, byte **, int **); 00442 void wordtris_free (); 00443 ResultType wordtris_who_won (Pos *, Player , char **); 00444 int wordtris_animate (Pos *pos, byte **movp); 00445 static void *wordtris_newstate (Pos *, byte *); 00446 00447 Game Wordtris = { WORDTRIS_CELL_SIZE, WORDTRIS_BOARD_WID, WORDTRIS_BOARD_HEIT, 00448 WORDTRIS_NUM_PIECES, 00449 wordtris_colors, NULL, wordtris_pixmaps, 00450 "Wordtris", 00451 wordtris_init}; 00452 00453 /* This list was produced using 00454 00455 $ egrep -x [a-z]{4} /usr/share/dict/words | perl -e 'while (<>) {foreach $i ((0 .. 3)) {$count{substr($_,$i,1)}++}} foreach $c (("a" .. "z")) {print $count{$c}, "\n"}' 00456 00457 Perl totally rocks 00458 */ 00459 00460 static float charcounts[26] = 00461 { 00462 629, 00463 223, 00464 205, 00465 302, 00466 746, 00467 152, 00468 186, 00469 182, 00470 395, 00471 30, 00472 167, 00473 460, 00474 234, 00475 338, 00476 503, 00477 272, 00478 6, 00479 395, 00480 622, 00481 404, 00482 276, 00483 63, 00484 173, 00485 24, 00486 125, 00487 28, 00488 }; 00489 00490 static char ** wordtris_getbgxpm () 00491 { 00492 int i; 00493 static char *xpm[lava_xpm_header_size + WORDTRIS_CELL_SIZE * WORDTRIS_BOARD_HEIT]; 00494 static char emptyline[WORDTRIS_CELL_SIZE * WORDTRIS_BOARD_WID * 2]; 00495 for (i=0; i<WORDTRIS_CELL_SIZE * WORDTRIS_BOARD_WID * 2; i++) 00496 emptyline[i] = ' '; 00497 for (i=0; i<lava_xpm_header_size; i++) 00498 xpm[i] = lava_xpm_header[i]; 00499 for (i=0; i<WORDTRIS_CELL_SIZE*WORDTRIS_BOARD_HEIT; i++) 00500 xpm[i+lava_xpm_header_size] = emptyline; 00501 for (i=WORDTRIS_CELL_SIZE; i<2*WORDTRIS_CELL_SIZE; i++) 00502 xpm[WORDTRIS_CELL_SIZE * (WORDTRIS_BOARD_HEIT-3)+i+lava_xpm_header_size] = lava_xpm_data [i-WORDTRIS_CELL_SIZE]; 00503 return xpm; 00504 } 00505 00506 // returns hamming distance 00507 static int diffcnt (const char *w1, const char *w2, int len) 00508 { 00509 int cnt = 0, i; 00510 for (i=0; i<len; i++) 00511 if (w1[i] != w2[i]) 00512 cnt++; 00513 return cnt; 00514 } 00515 00516 static void wordtris_set_init_pos (Pos *pos) 00517 { 00518 int i, j; 00519 const char *word; 00520 for (i=0; i<board_wid * board_heit; i++) 00521 pos->board[i] = 0; 00522 // make sure we have a neighbor 00523 while (1) 00524 { 00525 word = flwords [random() % num_flwords]; 00526 for (i=0; i<WORDTRIS_LEN; i++) 00527 pos->board [i] = word[i] - 'a' + 1; 00528 for (j=0; j<num_flwords; j++) 00529 if (diffcnt (word, flwords[j], WORDTRIS_LEN) == 1) 00530 return; 00531 } 00532 } 00533 00534 static void wordtris_set_init_render (Pos *pos) 00535 { 00536 pos->render [0] = RENDER_HIGHLIGHT1; 00537 } 00538 00539 static void wordtris_init () 00540 { 00541 int i; 00542 static char emptyline[WORDTRIS_BOARD_WID * WORDTRIS_CELL_SIZE]; 00543 static char dottedline[WORDTRIS_BOARD_WID * WORDTRIS_CELL_SIZE]; 00544 game_single_player = TRUE; 00545 game_set_init_pos = wordtris_set_init_pos; 00546 game_free = wordtris_free; 00547 game_getmove = wordtris_getmove; 00548 game_getmove_kb = wordtris_getmove_kb; 00549 game_who_won = wordtris_who_won; 00550 game_scorecmp = game_scorecmp_def_dscore; 00551 game_animation_time = 2000; 00552 game_animate = wordtris_animate; 00553 game_stateful = TRUE; 00554 game_state_size = sizeof (Wordtris_state); 00555 game_newstate = wordtris_newstate; 00556 game_bg_pixmap = wordtris_getbgxpm (); 00557 game_highlight_colors = wordtris_highlight_colors; 00558 game_set_init_render = wordtris_set_init_render; 00559 game_doc_about = 00560 "Wordtris\n" 00561 "Single player game\n" 00562 "Status: Partially implemented (playable)\n" 00563 "URL: "GAME_DEFAULT_URL("wordtris"); 00564 game_doc_rules = 00565 " Wordtris rules\n\n" 00566 "Press Ctrl+G to start the game.\n\n" 00567 " Click one of the letters of the word at the bottom and type the letter on one of the falling blocks to change that letter to the new letter. The new word must be legal.\n" 00568 "The smiley face acts as a wildcard and can be used as an arbitrary letter.\n" 00569 "\n" 00570 "You get a point for every new word you make. You have a total of ten lives. You lose a life when a block falls to the bottom row. The game ends when you lose all your lives."; 00571 game_doc_strategy = 00572 "Try to replace rarely occuring letters with more commonly occuring letters\n"; 00573 } 00574 00575 static int wordtris_curx = 0, wordtris_cury = 0; 00576 00577 ResultType wordtris_who_won (Pos *pos, Player to_play, char **commp) 00578 { 00579 static char comment[32]; 00580 int i; 00581 *commp = comment; 00582 for (i=0; i<WORDTRIS_LEN; i++) 00583 if (pos->board [2 * board_wid + i] != WORDTRIS_EMPTY 00584 && pos->state && ((Wordtris_state *)pos->state)->lives == 0) 00585 { 00586 snprintf (comment, 32, "Game over. Score: %d", 00587 pos->state ? ((Wordtris_state *)pos->state)->score: 0); 00588 return RESULT_WON; 00589 } 00590 snprintf (comment, 32, "Score: %d; Lives: %d", 00591 pos->state ? ((Wordtris_state *)pos->state)->score: 0, 00592 pos->state ? ((Wordtris_state *)pos->state)->lives: total_lives); 00593 return RESULT_NOTYET; 00594 } 00595 00596 void *wordtris_newstate (Pos *pos, byte *move) 00597 { 00598 static Wordtris_state state; 00599 int i, score = 0, count = 0, died = 0; 00600 for (i=0; move[3*i] >= 0; i++) 00601 { 00602 if (move[3*i+1] == 0) 00603 score = 1; 00604 if (move[3*i+2] == WORDTRIS_EMPTY) 00605 count--; 00606 else 00607 count++; 00608 } 00609 if (count + score < 1) died = 1; 00610 state.score = (pos->state ? ((Wordtris_state *)pos->state)->score : 0) + score; 00611 state.lives = (pos->state ? ((Wordtris_state *)pos->state)->lives : total_lives) - died; 00612 return &state; 00613 } 00614 00615 int wordtris_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, 00616 byte **movp, int ** rmovep) 00617 { 00618 static int rmove[7]; 00619 int *rp = rmove; 00620 if (type != GTKBOARD_BUTTON_RELEASE) 00621 return 0; 00622 if (y != 0) return 0; 00623 if (wordtris_curx != x) 00624 { 00625 *rp++ = wordtris_curx; 00626 *rp++ = 0; 00627 *rp++ = 0; 00628 *rp++ = x; 00629 *rp++ = 0; 00630 *rp++ = RENDER_HIGHLIGHT1; 00631 *rp++ = -1; 00632 *rmovep = rmove; 00633 } 00634 wordtris_curx = x; 00635 return 0; 00636 } 00637 00638 00639 gboolean wordtris_findletter (byte *board, int letter, int *x, int *y) 00640 { 00641 int i, j; 00642 int minx = -1, miny = board_heit, minval = WORDTRIS_WILDCARD; 00643 for (i=0; i < WORDTRIS_LEN; i++) 00644 { 00645 for (j=1; j<board_heit; j++) 00646 { 00647 int val = board [j * board_wid + i]; 00648 if (val == letter || val == WORDTRIS_WILDCARD) 00649 { 00650 if ((j < miny 00651 && (val != WORDTRIS_WILDCARD || minval == WORDTRIS_WILDCARD)) 00652 || (minval == WORDTRIS_WILDCARD && val != WORDTRIS_WILDCARD)) 00653 { 00654 minx = i; 00655 miny = j; 00656 minval = val; 00657 } 00658 } 00659 #ifdef ONLY_LOWEST 00660 else if (val != WORDTRIS_EMPTY) 00661 break; 00662 #endif 00663 } 00664 } 00665 if (miny >= board_heit) return FALSE; 00666 *x = minx; 00667 *y = miny; 00668 return TRUE; 00669 } 00670 00671 int wordtris_getmove_kb (Pos *pos, int key, Player glob_to_play, byte **movp, int **rmovp) 00672 { 00673 static int rmove[10]; 00674 static byte move[10]; 00675 byte *mp = move; 00676 int *rp = rmove; 00677 if (key == GDK_Right) 00678 { 00679 *rp++ = wordtris_curx; 00680 *rp++ = 0; 00681 *rp++ = 0; 00682 if (++wordtris_curx == WORDTRIS_LEN) wordtris_curx = 0; 00683 *rp++ = wordtris_curx; 00684 *rp++ = 0; 00685 *rp++ = RENDER_HIGHLIGHT1; 00686 *rp++ = -1; 00687 *rmovp = rmove; 00688 return 0; 00689 } 00690 if (key == GDK_Left) 00691 { 00692 *rp++ = wordtris_curx; 00693 *rp++ = 0; 00694 *rp++ = 0; 00695 if (--wordtris_curx < 0) wordtris_curx = WORDTRIS_LEN - 1; 00696 *rp++ = wordtris_curx; 00697 *rp++ = 0; 00698 *rp++ = RENDER_HIGHLIGHT1; 00699 *rp++ = -1; 00700 *rmovp = rmove; 00701 return 0; 00702 } 00703 if (key >= GDK_A && key <= GDK_Z) 00704 key = key + GDK_a - GDK_A; 00705 if (key >= GDK_a && key <= GDK_z) 00706 { 00707 int i, x, y; 00708 char word [WORDTRIS_LEN+1]; 00709 gboolean found = wordtris_findletter (pos->board, key - GDK_a + 1, &x, &y); 00710 if (!found) return -1; 00711 if (wordtris_curx < 0) return -1; 00712 for (i=0; i<WORDTRIS_LEN; i++) 00713 word[i] = pos->board [i] - 1 + 'a'; 00714 word [WORDTRIS_LEN] = '\0'; 00715 if (word [wordtris_curx] == key - GDK_a + 'a') return -1; 00716 word [wordtris_curx] = key - GDK_a + 'a'; 00717 if (!bsearch (word, flwords, num_flwords, sizeof (flwords[0]), wordtris_wordcmp)) 00718 return -1; 00719 *mp++ = wordtris_curx; *mp++ = wordtris_cury; *mp++ = key - GDK_a + 1; 00720 *mp++ = x; *mp++ = y; *mp++ = WORDTRIS_EMPTY; 00721 *mp++ = -1; 00722 *movp = move; 00723 return 1; 00724 } 00725 return -1; 00726 } 00727 00728 void wordtris_free () 00729 { 00730 wordtris_curx = wordtris_cury = 0; 00731 } 00732 00733 int wordtris_get_rand_char () 00734 { 00735 int i, sum, thresh; 00736 if (random () % 10 == 0) 00737 return WORDTRIS_WILDCARD; 00738 for (i=0, sum=0; i<26; i++) 00739 sum += charcounts[i]; 00740 thresh = random() % sum; 00741 for (i=0, sum=0; i<26; i++) 00742 if ((sum += charcounts[i]) > thresh) 00743 return i + 1; 00744 assert (0); 00745 return -1; 00746 } 00747 00748 int wordtris_animate (Pos *pos, byte **movp) 00749 { 00750 static byte move[1024]; 00751 int i, j; 00752 byte *mp = move; 00753 byte *board = pos->board; 00754 for (i=0; i<board_wid; i++) 00755 for (j=board_heit-1; j>=1; j--) 00756 { 00757 int val; 00758 if ((val = pos->board [j * board_wid + i]) != WORDTRIS_EMPTY) 00759 { 00760 *mp++ = i; 00761 *mp++ = j; 00762 *mp++ = WORDTRIS_EMPTY; 00763 if (j > 2) 00764 { 00765 *mp++ = i; 00766 *mp++ = j-1; 00767 *mp++ = val; 00768 } 00769 } 00770 } 00771 while (1) 00772 { 00773 i = random() % WORDTRIS_LEN; 00774 if (pos->board [(board_heit - 1) * board_wid + i]) 00775 continue; 00776 *mp++ = i; 00777 *mp++ = board_heit - 1; 00778 *mp++ = wordtris_get_rand_char(); 00779 break; 00780 } 00781 *mp = -1; 00782 *movp = move; 00783 return 1; 00784 } 00785 00786 00787