#define TOAL #ifdef TOAL /* NOTES: See scrab.p for better documentation. There is some major bogosity here with much duplicated code; this is not because I don't know how to program, it's because this was originally written in portable ISO Pascal which does not have variable length strings and then auto translated into C. If I were re-writing this in C from scratch I would be able to collapse all the duplicated code into single fragments with a length parameter. TO DO: 1) Known bugs: works out value of placing a word with a blank in it as if the blank had the value of the letter placed (I think) -- this was all under reconstruction, and has been bodged together for the competition... 2) Remove my last played word if challenged! 3) Undo wrong placing of tiles by opponent 4) high-light tiles as being placed (in frontend.c) 5) What to do if can't play? Beep? Should swap tiles? 6) Update dict for better list of 2/3 letter words! */ /* #define TTY */ /* Is there code in TTY which should ALWAYS be excecuted??? */ /* #define DEBUG */ /* #define TESTING */ /* for 1/4 size dictionary */ /* ** Code derived from program newscrab */ #include <stdio.h> #include <string.h> #include <stdlib.h> #ifdef TTY #else #ifdef NEVER /* removed because now passed in */ extern int rackindex; /* Communicating with c.frontend. Sorry! */ extern char rackbuff[7] ; #endif #endif void poll_wimp() { fprintf(stderr, ""); } /* ** Definitions for i/o */ # define Fscan(f, p, a) Scanck(fscanf(f, p, a)) # define Eoln(f) (ungetc(fgetc(f), f) == '\n') # define Eof(f) (ungetc(fgetc(f), f) == EOF) void printstring(FILE *f, int len, char *s) { int i; for (i = 0; i < len; i++) fputc(s[i], f); } # define Resetx(f, n) (void)((f == NULL ? 0 : fclose(f)), f = fopen(n, "r")) # define Rewritex(f, n) (void)((f == NULL ? 0 : fclose(f)), f = fopen(n, "w")) /* ** Definitions for standard types */ int ReadNum(void) { int ch, num; for (;;) { ch = fgetc(stdin); if (ch != ' ' && ch != '\n') break; } num = 0; for (;;) { num=num*10+(ch-'0'); ch = fgetc(stdin); if (ch == ' ' || ch == '\n') break; } return(num); } int ReadChar(void) { int ch; for (;;) { ch = fgetc(stdin); if (ch != ' ' && ch != '\n') break; } return(ch); } typedef int boolean; # define false (boolean)0 # define true (boolean)1 typedef int integer; # define maxint 2147483647 typedef unsigned int setword; static void Scanck(n) int n; { if (n != 1) { fprintf(stderr, "Bad input\n"); /*exit(1);*/ } } static void Getl(f) FILE *f; { char c; do { c = fgetc(f); } while (c != '\n'); } static void Caseerror(n) int n; { fprintf(stderr, "Missing case limb: line %d\n", n); /*exit(1);*/ } /* ** Start of program definitions */ # define xmin 1 # define xmax 15 # define ymin 1 # define ymax 15 # define aletter 'a' # define zletter 'z' # define maxtiles 7 #ifdef TESTING # define wc2 (92>>2) # define wc3 (966>>2) # define wc4 (4146>>2) # define wc5 (8991>>2) # define wc6 (15452>>2) # define wc7 (22144>>2) # define wc8 (25269>>2) # define wc9 (24268>>2) # define wc10 (21092>>2) # define wc11 (15674>>2) # define wc12 (10605>>2) # define wc13 (6539>>2) # define wc14 (3692>>2) # define wc15 (1896>>2) #else # define wc2 92 /* Increased from 105 for 'old-2' */ # define wc3 966 # define wc4 4146 # define wc5 8991 # define wc6 15452 # define wc7 22144 # define wc8 25269 # define wc9 24268 # define wc10 21092 # define wc11 15674 # define wc12 10605 # define wc13 6539 # define wc14 3692 # define wc15 1896 #endif typedef enum { horizontal, vertical } direction; typedef char letter; typedef letter Y1_tile; typedef struct { setword S; } tileset; typedef int score; typedef unsigned char freq; typedef unsigned char tileindex; typedef unsigned char xtilepos; typedef unsigned char ytilepos; typedef unsigned char xtilerange; typedef unsigned char ytilerange; typedef struct { struct { Y1_tile A[16 + 1]; } A[16 + 1]; } xytilearray; typedef struct { struct { letter A[16 + 1]; } A[16 + 1]; } xyletterarray; typedef struct { Y1_tile A[maxtiles]; } rack; typedef struct { letter A[maxtiles]; } letterrack; typedef struct { struct { xtilerange A[16 + 1]; } A[16 + 1]; } allowed; typedef struct { struct { tileset A[16 + 1]; } A[16 + 1]; } choicearray; typedef struct { struct { score A[16 + 1]; } A[16 + 1]; } scorearray; typedef struct { char A[4]; } t2; typedef struct { char A[6]; } t3; typedef struct { char A[8]; } t4; typedef struct { char A[10]; } t5; typedef struct { char A[12]; } t6; typedef struct { char A[14]; } t7; typedef struct { char A[16]; } t8; typedef struct { char A[18]; } t9; typedef struct { char A[20]; } t10; typedef struct { char A[22]; } t11; typedef struct { char A[24]; } t12; typedef struct { char A[26]; } t13; typedef struct { char A[28]; } t14; typedef struct { char A[30]; } t15; typedef unsigned char r15; typedef unsigned char factor; typedef struct { factor letterfactor; factor wordfactor; } factors; typedef struct { struct { factors A[16 + 1]; } A[16 + 1]; } factorarray; typedef struct { score A['|' - aletter + 1]; } T59; typedef struct { freq A['|' - aletter + 1]; } T60; typedef struct { t2 A[wc2]; } T61; typedef struct { t3 A[wc3]; } T62; typedef struct { t4 A[wc4]; } T63; typedef struct { t5 A[wc5]; } T64; typedef struct { t6 A[wc6]; } T65; typedef struct { t7 A[wc7]; } T66; typedef struct { t8 A[wc8]; } T67; typedef struct { t9 A[wc9]; } T68; typedef struct { t10 A[wc10]; } T69; typedef struct { t11 A[wc11]; } T70; typedef struct { t12 A[wc12]; } T71; typedef struct { t13 A[wc13]; } T72; typedef struct { t14 A[wc14]; } T73; typedef struct { t15 A[wc15]; } T74; FILE *dict = NULL, *boardf = NULL; direction axis; integer move; integer realmove; boolean empty; boolean cantmove; score bestscore; direction bestaxis; rack bestt; letterrack besttl; rack best_orig_t; letterrack best_orig_tl; tileindex bestcount; xtilerange bestlength; xtilepos bestx; ytilepos besty; t15 bestword; rack heldtile; letterrack heldletter; tileindex lasttile; scorearray vscore; factorarray special; allowed min, max; xytilearray boardtile; xyletterarray apparentboardletter; choicearray choice; boolean blanktileheld; letter blankletter, freeletter; Y1_tile blanktile; Y1_tile freetile; Y1_tile atile; tileset everyheldtile, everytile; T59 letterscore; T60 letterfreq; t2 s2; t3 s3; t4 s4; t5 s5; t6 s6; t7 s7; t8 s8; t9 s9; t10 s10; t11 s11; t12 s12; t13 s13; t14 s14; t15 s15; T61 *a2P; T62 *a3P; T63 *a4P; T64 *a5P; T65 *a6P; T66 *a7P; T67 *a8P; T68 *a9P; T69 *a10P; T70 *a11P; T71 *a12P; T72 *a13P; T73 *a14P; T74 *a15P; #define a2 (*a2P) #define a3 (*a3P) #define a4 (*a4P) #define a5 (*a5P) #define a6 (*a6P) #define a7 (*a7P) #define a8 (*a8P) #define a9 (*a9P) #define a10 (*a10P) #define a11 (*a11P) #define a12 (*a12P) #define a13 (*a13P) #define a14 (*a14P) #define a15 (*a15P) #include "movegen.h" void hsort(word, len) t15 *word; r15 len; { register r15 j; register r15 i; char c; { r15 B2 = 1, B3 = len; if (B2 <= B3) for (i = B2; ; i++) { { r15 B4 = i, B5 = len; if (B4 <= B5) for (j = B4; ; j++) { if (word->A[j - 1] < word->A[i - 1]) { c = word->A[i - 1]; word->A[i - 1] = word->A[j - 1]; word->A[j - 1] = c; } if (j == B5) break; } } if (i == B3) break; } } } void initdict() { t15 x; r15 len; register r15 c; register integer w; Resetx(dict, "w.2"); len = 1; len = len + 1; { integer B6 = 1, B7 = wc2; if (B6 <= B7) for (w = B6; ; w++) { { r15 B8 = 1, B9 = len; if (B8 <= B9) for (c = B8; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B9) break; } } fgetc(dict);hsort(&x, len); #ifdef DEBUG {int i; for (i = 0; i < len*2; i++) fprintf(stderr, "%c", x.A[i]); fprintf(stderr, "\n"); } #endif { r15 B10 = 1, B11 = len * 2; if (B10 <= B11) for (c = B10; ; c++) { a2.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B11) break; } } if (w == B7) break; } } #ifdef DEBUG printf("dict a2 read from %.4s to %.4s\n", a2.A[1 - 1].A, a2.A[wc2 - 1].A); #endif poll_wimp(); Resetx(dict, "w.3"); len = len + 1; { integer B12 = 1, B13 = wc3; if (B12 <= B13) for (w = B12; ; w++) { { r15 B14 = 1, B15 = len; if (B14 <= B15) for (c = B14; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B15) break; } } fgetc(dict);hsort(&x, len); { r15 B16 = 1, B17 = len * 2; if (B16 <= B17) for (c = B16; ; c++) { a3.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B17) break; } } if (w == B13) break; } } #ifdef DEBUG printf("dict a3 read from %.6s to %.6s\n", a3.A[1 - 1].A, a3.A[wc3 - 1].A); #endif poll_wimp(); Resetx(dict, "w.4"); len = len + 1; { integer B18 = 1, B19 = wc4; if (B18 <= B19) for (w = B18; ; w++) { { r15 B20 = 1, B21 = len; if (B20 <= B21) for (c = B20; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B21) break; } } fgetc(dict);hsort(&x, len); { r15 B22 = 1, B23 = len * 2; if (B22 <= B23) for (c = B22; ; c++) { a4.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B23) break; } } if (w == B19) break; } } #ifdef DEBUG printf("dict a4 read from %.8s to %.8s\n", a4.A[1 - 1].A, a4.A[wc4 - 1].A); #endif poll_wimp(); Resetx(dict, "w.5"); len = len + 1; { integer B24 = 1, B25 = wc5; if (B24 <= B25) for (w = B24; ; w++) { { r15 B26 = 1, B27 = len; if (B26 <= B27) for (c = B26; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B27) break; } } fgetc(dict);hsort(&x, len); { r15 B28 = 1, B29 = len * 2; if (B28 <= B29) for (c = B28; ; c++) { a5.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B29) break; } } if (w == B25) break; } } #ifdef DEBUG printf("dict a5 read from %.10s to %.10s\n", a5.A[1 - 1].A, a5.A[wc5 - 1].A); #endif poll_wimp(); Resetx(dict, "w.6"); len = len + 1; { integer B30 = 1, B31 = wc6; if (B30 <= B31) for (w = B30; ; w++) { { r15 B32 = 1, B33 = len; if (B32 <= B33) for (c = B32; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B33) break; } } fgetc(dict);hsort(&x, len); { r15 B34 = 1, B35 = len * 2; if (B34 <= B35) for (c = B34; ; c++) { a6.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B35) break; } } if (w == B31) break; } } #ifdef DEBUG printf("dict a6 read from %.12s to %.12s\n", a6.A[1 - 1].A, a6.A[wc6 - 1].A); #endif poll_wimp(); Resetx(dict, "w.7"); len = len + 1; { integer B36 = 1, B37 = wc7; if (B36 <= B37) for (w = B36; ; w++) { { r15 B38 = 1, B39 = len; if (B38 <= B39) for (c = B38; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B39) break; } } fgetc(dict);hsort(&x, len); { r15 B40 = 1, B41 = len * 2; if (B40 <= B41) for (c = B40; ; c++) { a7.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B41) break; } } if (w == B37) break; } } #ifdef DEBUG printf("dict a7 read from %.14s to %.14s\n", a7.A[1 - 1].A, a7.A[wc7 - 1].A); #endif poll_wimp(); Resetx(dict, "w.8"); len = len + 1; { integer B42 = 1, B43 = wc8; if (B42 <= B43) for (w = B42; ; w++) { { r15 B44 = 1, B45 = len; if (B44 <= B45) for (c = B44; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B45) break; } } fgetc(dict);hsort(&x, len); { r15 B46 = 1, B47 = len * 2; if (B46 <= B47) for (c = B46; ; c++) { a8.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B47) break; } } if (w == B43) break; } } #ifdef DEBUG printf("dict a8 read from %.16s to %.16s\n", a8.A[1 - 1].A, a8.A[wc8 - 1].A); #endif poll_wimp(); Resetx(dict, "w.9"); len = len + 1; { integer B48 = 1, B49 = wc9; if (B48 <= B49) for (w = B48; ; w++) { { r15 B50 = 1, B51 = len; if (B50 <= B51) for (c = B50; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B51) break; } } fgetc(dict);hsort(&x, len); { r15 B52 = 1, B53 = len * 2; if (B52 <= B53) for (c = B52; ; c++) { a9.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B53) break; } } if (w == B49) break; } } #ifdef DEBUG printf("dict a9 read from %.18s to %.18s\n", a9.A[1 - 1].A, a9.A[wc9 - 1].A); #endif poll_wimp(); Resetx(dict, "w.10"); len = len + 1; { integer B54 = 1, B55 = wc10; if (B54 <= B55) for (w = B54; ; w++) { { r15 B56 = 1, B57 = len; if (B56 <= B57) for (c = B56; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B57) break; } } fgetc(dict);hsort(&x, len); { r15 B58 = 1, B59 = len * 2; if (B58 <= B59) for (c = B58; ; c++) { a10.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B59) break; } } if (w == B55) break; } } #ifdef DEBUG printf("dict a10 read from %.20s to %.20s\n", a10.A[1 - 1].A, a10.A[wc10 - 1].A); #endif poll_wimp(); Resetx(dict, "w.11"); len = len + 1; { integer B60 = 1, B61 = wc11; if (B60 <= B61) for (w = B60; ; w++) { { r15 B62 = 1, B63 = len; if (B62 <= B63) for (c = B62; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B63) break; } } fgetc(dict);hsort(&x, len); { r15 B64 = 1, B65 = len * 2; if (B64 <= B65) for (c = B64; ; c++) { a11.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B65) break; } } if (w == B61) break; } } #ifdef DEBUG printf("dict a11 read from %.22s to %.22s\n", a11.A[1 - 1].A, a11.A[wc11 - 1].A); #endif poll_wimp(); Resetx(dict, "w.12"); len = len + 1; { integer B66 = 1, B67 = wc12; if (B66 <= B67) for (w = B66; ; w++) { { r15 B68 = 1, B69 = len; if (B68 <= B69) for (c = B68; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B69) break; } } fgetc(dict);hsort(&x, len); { r15 B70 = 1, B71 = len * 2; if (B70 <= B71) for (c = B70; ; c++) { a12.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B71) break; } } if (w == B67) break; } } #ifdef DEBUG printf("dict a12 read from %.24s to %.24s\n", a12.A[1 - 1].A, a12.A[wc12 - 1].A); #endif poll_wimp(); Resetx(dict, "w.13"); len = len + 1; { integer B72 = 1, B73 = wc13; if (B72 <= B73) for (w = B72; ; w++) { { r15 B74 = 1, B75 = len; if (B74 <= B75) for (c = B74; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B75) break; } } fgetc(dict);hsort(&x, len); { r15 B76 = 1, B77 = len * 2; if (B76 <= B77) for (c = B76; ; c++) { a13.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B77) break; } } if (w == B73) break; } } #ifdef DEBUG printf("dict a13 read from %.26s to %.26s\n", a13.A[1 - 1].A, a13.A[wc13 - 1].A); #endif poll_wimp(); Resetx(dict, "w.14"); len = len + 1; { integer B78 = 1, B79 = wc14; if (B78 <= B79) for (w = B78; ; w++) { { r15 B80 = 1, B81 = len; if (B80 <= B81) for (c = B80; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B81) break; } } fgetc(dict);hsort(&x, len); { r15 B82 = 1, B83 = len * 2; if (B82 <= B83) for (c = B82; ; c++) { a14.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B83) break; } } if (w == B79) break; } } #ifdef DEBUG printf("dict a14 read from %.28s to %.28s\n", a14.A[1 - 1].A, a14.A[wc14 - 1].A); #endif poll_wimp(); Resetx(dict, "w.15"); len = len + 1; { integer B84 = 1, B85 = wc15; if (B84 <= B85) for (w = B84; ; w++) { { r15 B86 = 1, B87 = len; if (B86 <= B87) for (c = B86; ; c++) { x.A[c - 1] = fgetc(dict); x.A[c + len - 1] = x.A[c - 1]; if (c == B87) break; } } fgetc(dict);hsort(&x, len); { r15 B88 = 1, B89 = len * 2; if (B88 <= B89) for (c = B88; ; c++) { a15.A[w - 1].A[c - 1] = x.A[c - 1]; if (c == B89) break; } } if (w == B85) break; } } #ifdef DEBUG printf("dict a15 read from %.30s to %.30s\n", a15.A[1 - 1].A, a15.A[wc15 - 1].A); #endif poll_wimp(); } void setscoreandfreq(ch, sc, fr) char ch; score sc; freq fr; { letterscore.A[ch - aletter] = sc; letterfreq.A[ch - aletter] = fr; } void initboard() { register xtilerange x; register ytilerange y; register integer n; char ch; register tileindex t; setscoreandfreq('a', 1, 9); setscoreandfreq('b', 3, 2); setscoreandfreq('c', 3, 2); setscoreandfreq('d', 2, 4); setscoreandfreq('e', 1, 12); setscoreandfreq('f', 4, 2); setscoreandfreq('g', 2, 3); setscoreandfreq('h', 4, 2); setscoreandfreq('i', 1, 9); setscoreandfreq('j', 8, 1); setscoreandfreq('k', 5, 1); setscoreandfreq('l', 1, 4); setscoreandfreq('m', 3, 2); setscoreandfreq('n', 1, 6); setscoreandfreq('o', 1, 8); setscoreandfreq('p', 3, 2); setscoreandfreq('q', 10, 1); setscoreandfreq('r', 1, 6); setscoreandfreq('s', 1, 4); setscoreandfreq('t', 1, 6); setscoreandfreq('u', 1, 4); setscoreandfreq('v', 4, 2); setscoreandfreq('w', 4, 2); setscoreandfreq('x', 8, 1); setscoreandfreq('y', 4, 2); setscoreandfreq('z', 10, 1); setscoreandfreq(blankletter, 0, 2); { xtilerange B90 = xmin - 1, B91 = xmax + 1; if (B90 <= B91) for (x = B90; ; x++) { { ytilerange B92 = ymin - 1, B93 = ymax + 1; if (B92 <= B93) for (y = B92; ; y++) { apparentboardletter.A[x].A[y] = freeletter; boardtile.A[x].A[y] = freetile; special.A[x].A[y].letterfactor = 1; special.A[x].A[y].wordfactor = 1; if (y == B93) break; } } if (x == B91) break; } } special.A[8].A[8].wordfactor = 2; special.A[1].A[1].wordfactor = 3; special.A[8].A[1].wordfactor = 3; special.A[15].A[1].wordfactor = 3; special.A[1].A[8].wordfactor = 3; special.A[15].A[8].wordfactor = 3; special.A[1].A[15].wordfactor = 3; special.A[8].A[15].wordfactor = 3; special.A[15].A[15].wordfactor = 3; { integer B94 = 1, B95 = 4; if (B94 <= B95) for (n = B94; ; n++) { special.A[1 + n].A[1 + n].wordfactor = 2; special.A[15 - n].A[1 + n].wordfactor = 2; special.A[1 + n].A[15 - n].wordfactor = 2; special.A[15 - n].A[15 - n].wordfactor = 2; if (n == B95) break; } } special.A[6].A[2].letterfactor = 3; special.A[10].A[2].letterfactor = 3; special.A[2].A[6].letterfactor = 3; special.A[6].A[6].letterfactor = 3; special.A[10].A[6].letterfactor = 3; special.A[14].A[6].letterfactor = 3; special.A[2].A[10].letterfactor = 3; special.A[6].A[10].letterfactor = 3; special.A[10].A[10].letterfactor = 3; special.A[14].A[10].letterfactor = 3; special.A[6].A[14].letterfactor = 3; special.A[10].A[14].letterfactor = 3; special.A[1].A[4].letterfactor = 2; special.A[1].A[12].letterfactor = 2; special.A[15].A[4].letterfactor = 2; special.A[15].A[12].letterfactor = 2; special.A[4].A[1].letterfactor = 2; special.A[12].A[1].letterfactor = 2; special.A[4].A[15].letterfactor = 2; special.A[12].A[15].letterfactor = 2; special.A[7].A[7].letterfactor = 2; special.A[7].A[9].letterfactor = 2; special.A[9].A[7].letterfactor = 2; special.A[9].A[9].letterfactor = 2; special.A[8].A[4].letterfactor = 2; special.A[8].A[12].letterfactor = 2; special.A[4].A[8].letterfactor = 2; special.A[12].A[8].letterfactor = 2; special.A[7].A[3].letterfactor = 2; special.A[9].A[3].letterfactor = 2; special.A[3].A[7].letterfactor = 2; special.A[3].A[9].letterfactor = 2; special.A[13].A[7].letterfactor = 2; special.A[13].A[9].letterfactor = 2; special.A[7].A[13].letterfactor = 2; special.A[9].A[13].letterfactor = 2; lasttile = 0; if (!Eof(boardf)) { if (axis == horizontal) { { ytilerange B96 = ymin, B97 = ymax; if (B96 <= B97) for (y = B96; ; y++) { { xtilerange B98 = xmin, B99 = xmax; if (B98 <= B99) for (x = B98; ; x++) { ch = fgetc(boardf); if (ch == '.') ch = freeletter; else empty = false; if (('A' <= ch) && (ch <= 'Z')) { ch = (unsigned)(ch) + 32; boardtile.A[x].A[y] = ch; apparentboardletter.A[x].A[y] = blankletter; if (letterfreq.A[blankletter - aletter] == 0) { #ifdef TTY printf("ILLEGAL BOARD! Too many letter blanks (%c')!\n", ch); #endif } else { letterfreq.A[blankletter - aletter] -= 1; } } else if (ch == freeletter) { boardtile.A[x].A[y] = freeletter; apparentboardletter.A[x].A[y] = freetile; } else { boardtile.A[x].A[y] = ch; apparentboardletter.A[x].A[y] = ch; if (letterfreq.A[ch - aletter] == 0) { #ifdef TTY printf("ILLEGAL BOARD! Too many letter %c's!\n", ch); #endif } else { letterfreq.A[ch - aletter] -= 1; } } if (ch != freeletter) { special.A[x].A[y].letterfactor = 1; special.A[x].A[y].wordfactor = 1; } if (x == B99) break; } } Getl(boardf); if (y == B97) break; } } } else { { xtilerange B100 = xmin, B101 = xmax; if (B100 <= B101) for (x = B100; ; x++) { { ytilerange B102 = ymin, B103 = ymax; if (B102 <= B103) for (y = B102; ; y++) { ch = fgetc(boardf); if (ch == '.') ch = freeletter; else empty = false; if (('A' <= ch) && (ch <= 'Z')) { ch = (unsigned)(ch) + 32; boardtile.A[x].A[y] = ch; apparentboardletter.A[x].A[y] = blankletter; } else if (ch == freeletter) { boardtile.A[x].A[y] = freeletter; apparentboardletter.A[x].A[y] = freetile; } else { boardtile.A[x].A[y] = ch; apparentboardletter.A[x].A[y] = ch; } if (ch != freeletter) { special.A[x].A[y].letterfactor = 1; special.A[x].A[y].wordfactor = 1; } if (y == B103) break; } } Getl(boardf); if (x == B101) break; } } } if (!Eof(boardf)) { while (!Eoln(boardf)) { ch = fgetc(boardf); lasttile = lasttile + 1; if (ch == ' ') ch = blankletter; heldletter.A[lasttile - 1] = ch; } Getl(boardf); } if (!Eof(boardf)) { Fscan(boardf, "%d", &move); /***Getx(boardf),Getl(boardf);***/ } } else { } everyheldtile.S = 0; /**/SET if (lasttile > 0) { tileindex B104 = 1, B105 = lasttile; if (B104 <= B105) for (t = B104; ; t++) { heldtile.A[t - 1] = heldletter.A[t - 1]; everyheldtile.S |= 1<<(heldtile.A[t - 1]-'a'); if (t == B105) break; } } } boolean checkw(userword, len, anag, where) t15 *userword; r15 len; boolean anag; integer *where; { register boolean R76; integer mid, hi; register integer lo; boolean check2; r15 i, alen; char s, a; check2 = false; alen = len; mid = -1; if ((!(anag))) len = len * 2; switch (alen) { case 1: break ; case 2: { integer B106 = 1, B107 = len; if (B106 <= B107) for (lo = B106; ; lo++) { s2.A[lo - 1] = userword->A[lo - 1]; if (lo == B107) break; } } lo = 1; hi = wc2; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s2.A[i - 1]; a = a2.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; case 3: { integer B108 = 1, B109 = len; if (B108 <= B109) for (lo = B108; ; lo++) { s3.A[lo - 1] = userword->A[lo - 1]; if (lo == B109) break; } } lo = 1; hi = wc3; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s3.A[i - 1]; a = a3.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; case 4: { integer B110 = 1, B111 = len; if (B110 <= B111) for (lo = B110; ; lo++) { s4.A[lo - 1] = userword->A[lo - 1]; if (lo == B111) break; } } lo = 1; hi = wc4; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s4.A[i - 1]; a = a4.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; case 5: { integer B112 = 1, B113 = len; if (B112 <= B113) for (lo = B112; ; lo++) { s5.A[lo - 1] = userword->A[lo - 1]; if (lo == B113) break; } } lo = 1; hi = wc5; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s5.A[i - 1]; a = a5.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; case 6: { integer B114 = 1, B115 = len; if (B114 <= B115) for (lo = B114; ; lo++) { s6.A[lo - 1] = userword->A[lo - 1]; if (lo == B115) break; } } lo = 1; hi = wc6; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s6.A[i - 1]; a = a6.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; case 7: { integer B116 = 1, B117 = len; if (B116 <= B117) for (lo = B116; ; lo++) { s7.A[lo - 1] = userword->A[lo - 1]; if (lo == B117) break; } } lo = 1; hi = wc7; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s7.A[i - 1]; a = a7.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; case 8: { integer B118 = 1, B119 = len; if (B118 <= B119) for (lo = B118; ; lo++) { s8.A[lo - 1] = userword->A[lo - 1]; if (lo == B119) break; } } lo = 1; hi = wc8; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s8.A[i - 1]; a = a8.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; case 9: { integer B120 = 1, B121 = len; if (B120 <= B121) for (lo = B120; ; lo++) { s9.A[lo - 1] = userword->A[lo - 1]; if (lo == B121) break; } } lo = 1; hi = wc9; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s9.A[i - 1]; a = a9.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; case 10: { integer B122 = 1, B123 = len; if (B122 <= B123) for (lo = B122; ; lo++) { s10.A[lo - 1] = userword->A[lo - 1]; if (lo == B123) break; } } lo = 1; hi = wc10; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s10.A[i - 1]; a = a10.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; case 11: { integer B124 = 1, B125 = len; if (B124 <= B125) for (lo = B124; ; lo++) { s11.A[lo - 1] = userword->A[lo - 1]; if (lo == B125) break; } } lo = 1; hi = wc11; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s11.A[i - 1]; a = a11.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; case 12: { integer B126 = 1, B127 = len; if (B126 <= B127) for (lo = B126; ; lo++) { s12.A[lo - 1] = userword->A[lo - 1]; if (lo == B127) break; } } lo = 1; hi = wc12; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s12.A[i - 1]; a = a12.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; case 13: { integer B128 = 1, B129 = len; if (B128 <= B129) for (lo = B128; ; lo++) { s13.A[lo - 1] = userword->A[lo - 1]; if (lo == B129) break; } } lo = 1; hi = wc13; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s13.A[i - 1]; a = a13.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; case 14: { integer B130 = 1, B131 = len; if (B130 <= B131) for (lo = B130; ; lo++) { s14.A[lo - 1] = userword->A[lo - 1]; if (lo == B131) break; } } lo = 1; hi = wc14; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s14.A[i - 1]; a = a14.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; case 15: { integer B132 = 1, B133 = len; if (B132 <= B133) for (lo = B132; ; lo++) { s15.A[lo - 1] = userword->A[lo - 1]; if (lo == B133) break; } } lo = 1; hi = wc15; while ((lo <= hi)) { mid = (lo + hi) / 2; i = 0; do { i = i + 1; s = s15.A[i - 1]; a = a15.A[mid - 1].A[i - 1]; } while (!((s != a) || (i == len))); if ((s < a)) { hi = mid - 1; } else if ((s > a)) { lo = mid + 1; } else { check2 = true; lo = 1; hi = 0; } } break ; default: Caseerror(__LINE__); } (*where) = mid; R76 = check2; return R76; } boolean check(userword, len) t15 *userword; integer len; { register boolean R77; t15 word; register r15 i; integer where; { r15 B134 = 1, B135 = len; if (B134 <= B135) for (i = B134; ; i++) { word.A[i + len - 1] = userword->A[i - 1]; word.A[i - 1] = userword->A[i - 1]; if (i == B135) break; } } hsort(&word, len); R77 = checkw(&word, len, false, &where); return R77; } boolean checkanag(w, len, w1, w2, outword) t15 *w; r15 len; integer *w1, *w2; t15 *outword; { register boolean R78; boolean checkanag2; register r15 i; hsort(&(*w), len); checkanag2 = checkw(&(*w), len, true, &(*w1)); (*w2) = (*w1); if (checkanag2) switch (len) { case 2: { r15 B136 = 1, B137 = len; if (B136 <= B137) for (i = B136; ; i++) { outword->A[i - 1] = a2.A[*w1 - 1].A[i + len - 1]; if (i == B137) break; } } break ; case 3: { r15 B138 = 1, B139 = len; if (B138 <= B139) for (i = B138; ; i++) { outword->A[i - 1] = a3.A[*w1 - 1].A[i + len - 1]; if (i == B139) break; } } break ; case 4: { r15 B140 = 1, B141 = len; if (B140 <= B141) for (i = B140; ; i++) { outword->A[i - 1] = a4.A[*w1 - 1].A[i + len - 1]; if (i == B141) break; } } break ; case 5: { r15 B142 = 1, B143 = len; if (B142 <= B143) for (i = B142; ; i++) { outword->A[i - 1] = a5.A[*w1 - 1].A[i + len - 1]; if (i == B143) break; } } break ; case 6: { r15 B144 = 1, B145 = len; if (B144 <= B145) for (i = B144; ; i++) { outword->A[i - 1] = a6.A[*w1 - 1].A[i + len - 1]; if (i == B145) break; } } break ; case 7: { r15 B146 = 1, B147 = len; if (B146 <= B147) for (i = B146; ; i++) { outword->A[i - 1] = a7.A[*w1 - 1].A[i + len - 1]; if (i == B147) break; } } break ; case 8: { r15 B148 = 1, B149 = len; if (B148 <= B149) for (i = B148; ; i++) { outword->A[i - 1] = a8.A[*w1 - 1].A[i + len - 1]; if (i == B149) break; } } break ; case 9: { r15 B150 = 1, B151 = len; if (B150 <= B151) for (i = B150; ; i++) { outword->A[i - 1] = a9.A[*w1 - 1].A[i + len - 1]; if (i == B151) break; } } break ; case 10: { r15 B152 = 1, B153 = len; if (B152 <= B153) for (i = B152; ; i++) { outword->A[i - 1] = a10.A[*w1 - 1].A[i + len - 1]; if (i == B153) break; } } break ; case 11: { r15 B154 = 1, B155 = len; if (B154 <= B155) for (i = B154; ; i++) { outword->A[i - 1] = a11.A[*w1 - 1].A[i + len - 1]; if (i == B155) break; } } break ; case 12: { r15 B156 = 1, B157 = len; if (B156 <= B157) for (i = B156; ; i++) { outword->A[i - 1] = a12.A[*w1 - 1].A[i + len - 1]; if (i == B157) break; } } break ; case 13: { r15 B158 = 1, B159 = len; if (B158 <= B159) for (i = B158; ; i++) { outword->A[i - 1] = a13.A[*w1 - 1].A[i + len - 1]; if (i == B159) break; } } break ; case 14: { r15 B160 = 1, B161 = len; if (B160 <= B161) for (i = B160; ; i++) { outword->A[i - 1] = a14.A[*w1 - 1].A[i + len - 1]; if (i == B161) break; } } break ; case 15: { r15 B162 = 1, B163 = len; if (B162 <= B163) for (i = B162; ; i++) { outword->A[i - 1] = a15.A[*w1 - 1].A[i + len - 1]; if (i == B163) break; } } break ; default: Caseerror(__LINE__); } R78 = checkanag2; return R78; } boolean spellcheckvertical(x, ypos, try) xtilepos x; ytilepos ypos; Y1_tile try; { register boolean R79; t15 w; ytilepos y1, y2; register ytilepos y; unsigned char yy; y1 = ypos; y2 = ypos; yy = 1; while (apparentboardletter.A[x].A[y1 - 1] != freeletter) y1 = y1 - 1; while (apparentboardletter.A[x].A[y2 + 1] != freeletter) y2 = y2 + 1; if (y1 < ypos) { ytilepos B164 = y1, B165 = ypos - 1; if (B164 <= B165) for (y = B164; ; y++) { w.A[yy - 1] = apparentboardletter.A[x].A[y]; yy = yy + 1; if (y == B165) break; } } w.A[yy - 1] = try; yy = yy + 1; if (y2 > ypos) { ytilepos B166 = ypos + 1, B167 = y2; if (B166 <= B167) for (y = B166; ; y++) { w.A[yy - 1] = apparentboardletter.A[x].A[y]; yy = yy + 1; if (y == B167) break; } } R79 = check(&w, yy - 1); return R79; } score scorevertical(x, ypos) xtilepos x; ytilepos ypos; { register score R80; ytilepos y1, y2; register ytilepos y; score vtot; vtot = 0; y1 = ypos; y2 = ypos; while (apparentboardletter.A[x].A[y1 - 1] != freeletter) y1 = y1 - 1; while (apparentboardletter.A[x].A[y2 + 1] != freeletter) y2 = y2 + 1; if (y1 < ymin) printf("y1 < ymin\n"); if (y2 > ymax) printf("y2 > ymin\n"); if (y1 < ypos) { ytilepos B168 = y1, B169 = ypos - 1; if (B168 <= B169) for (y = B168; ; y++) { vtot = vtot + letterscore.A[apparentboardletter.A[x].A[y] - aletter]; if (y == B169) break; } } if (y2 > ypos) { ytilepos B170 = ypos + 1, B171 = y2; if (B170 <= B171) for (y = B170; ; y++) { vtot = vtot + letterscore.A[apparentboardletter.A[x].A[y] - aletter]; if (y == B171) break; } } R80 = vtot; return R80; } boolean empty_board(void) { int xpos, ypos; for (ypos = ymin; ; ypos++) { for (xpos = xmin; ; xpos++) { if (apparentboardletter.A[xpos].A[ypos] != freeletter) { return(false); } if (xpos == xmax) break; } if (ypos == ymax) break; } return(true); } void constrainplacements(board, boardletter, choice, vscore, min, max, heldtile, lasttile) xytilearray board; xyletterarray boardletter; choicearray *choice; scorearray *vscore; allowed *min, *max; rack heldtile; tileindex lasttile; { Y1_tile thistile; letter thislet; tileset debugtileset; register letter wildletter; register xtilepos xpos; register ytilepos ypos; register tileindex eachtile; int c; unsigned char xx; register xtilepos x; register ytilepos y; int minxy, maxxy; blanktileheld = false; debugtileset.S = 0; { tileindex B172 = 1, B173 = lasttile; if (B172 <= B173) for (eachtile = B172; ; eachtile++) { if (heldtile.A[eachtile - 1] == blanktile) blanktileheld = true; debugtileset.S |= 1<<(heldtile.A[eachtile - 1]-'a'); if (eachtile == B173) break; } } if (empty_board()) { { ytilepos B174 = ymin, B175 = ymax; if (B174 <= B175) for (ypos = B174; ; ypos++) { { xtilepos B176 = xmin, B177 = xmax; if (B176 <= B177) for (xpos = B176; ; xpos++) { choice->A[xpos].A[ypos].S = 0; vscore->A[xpos].A[ypos] = -1; min->A[xpos].A[ypos] = 0; max->A[xpos].A[ypos] = 0; if (xpos == B177) break; } } if (ypos == B175) break; } } { xtilepos B178 = 8, B179 = 2; if (B178 >= B179) for (x = B178; ; x--) { min->A[x].A[8] = 9 - x; max->A[x].A[8] = 7; vscore->A[x].A[8] = 0; vscore->A[8].A[8] = 0; if (blanktileheld) { /* THIS MAY BE A BUG??? (GT, 1999) */ choice->A[x].A[8].S = everyheldtile.S; } else { choice->A[x].A[8].S = everytile.S; } if (x == B179) break; } } } else { { ytilepos B180 = ymin, B181 = ymax; if (B180 <= B181) for (ypos = B180; ; ypos++) { { xtilepos B182 = xmin, B183 = xmax; if (B182 <= B183) for (xpos = B182; ; xpos++) { choice->A[xpos].A[ypos].S = 0; vscore->A[xpos].A[ypos] = -1; thistile = board.A[xpos].A[ypos]; if (thistile == freetile) { if ((board.A[xpos].A[ypos - 1] == freetile) && (board.A[xpos].A[ypos + 1] == freetile)) { if (blanktileheld) { choice->A[xpos].A[ypos].S = everytile.S; } else { choice->A[xpos].A[ypos].S = everyheldtile.S; } vscore->A[xpos].A[ypos] = 0; } else { vscore->A[xpos].A[ypos] = scorevertical(xpos, ypos); if (blanktileheld) { { letter B184 = aletter, B185 = zletter; if (B184 <= B185) for (wildletter = B184; ; wildletter++) { thistile = wildletter; if (spellcheckvertical(xpos, ypos, thistile)) { choice->A[xpos].A[ypos].S |= 1<<(thistile-'a'); } if (wildletter == B185) break; } } } else { { tileindex B186 = 1, B187 = lasttile; if (B186 <= B187) for (eachtile = B186; ; eachtile++) { thistile = heldtile.A[eachtile - 1]; thislet = heldletter.A[eachtile - 1]; if (thistile != blanktile) { if (spellcheckvertical(xpos, ypos, thistile)) { choice->A[xpos].A[ypos].S |= 1<<(thistile-'a'); } } else { } if (eachtile == B187) break; } } } } } else { choice->A[xpos].A[ypos].S = 1<<(board.A[xpos].A[ypos]-'a'); } if (xpos == B183) break; } } if (ypos == B181) break; } } { ytilepos B188 = ymin, B189 = ymax; if (B188 <= B189) for (y = B188; ; y++) { { xtilepos B190 = xmin, B191 = xmax; if (B190 <= B191) for (x = B190; ; x++) { xx = x; c = 0; if (boardletter.A[x - 1].A[y] != freeletter) { minxy = 0; maxxy = 0; } else { minxy = 0; maxxy = -1; xx = x; while ((c >= 0) && (c < lasttile)) { while ((xx <= xmax) && (boardletter.A[xx].A[y] != freeletter)) xx = xx + 1; if (xx > xmax) { c = -1; } else { c = c + 1; if ((minxy == 0) && ((boardletter.A[xx - 1].A[y] != freeletter) || (boardletter.A[xx].A[y - 1] != freeletter) || (boardletter.A[xx].A[y + 1] != freeletter) || (boardletter.A[xx + 1].A[y] != freeletter))) { minxy = c; } xx = xx + 1; maxxy = c; } } } if (minxy == 0) maxxy = 0; if (maxxy < 0) maxxy = 0; if ((minxy == 1) && (boardletter.A[x].A[y] == freeletter)) { if ((boardletter.A[x - 1].A[y] == freeletter) && (boardletter.A[x + 1].A[y] == freeletter)) { if (maxxy > 1) minxy = 2; } } min->A[x].A[y] = minxy; max->A[x].A[y] = maxxy; if (x == B191) break; } } if (y == B189) break; } } } } boolean placet(tiles, tileletter, last, x, y, word, length, totscore) rack *tiles; letterrack *tileletter; tileindex last; xtilerange x; ytilerange y; t15 *word; xtilerange *length; score *totscore; { register boolean R81; r15 w; tileindex t; score htot, vtot; score wfact; boolean place2; (*length) = 0; t = 0; w = 0; (*totscore) = 0; vtot = 0; htot = 0; wfact = 1; do { if (apparentboardletter.A[x].A[y] == freeletter) { if (t == last) { } else { t = t + 1; w = w + 1; word->A[w - 1] = tiles->A[t - 1]; if (!(('a' <= word->A[w - 1]) && (word->A[w - 1] <= 'z'))) { printf("Internal error 3: %c\n", word->A[w - 1]); } if ((1<<(tiles->A[t - 1]-'a') & choice.A[x].A[y].S) == 0) { R81 = false; (*totscore) = 0; goto L99; } if (vscore.A[x].A[y] > 0) { vtot = vtot + ((vscore.A[x].A[y] + (letterscore.A[tileletter->A[t - 1] - aletter] * special.A[x].A[y].letterfactor)) * special.A[x].A[y].wordfactor); } wfact = wfact * special.A[x].A[y].wordfactor; htot = htot + letterscore.A[tileletter->A[t - 1] - aletter] * special.A[x].A[y].letterfactor; } } else { w = w + 1; word->A[w - 1] = boardtile.A[x].A[y]; if (!(('a' <= word->A[w - 1]) && (word->A[w - 1] <= 'z'))) { printf("Internal error 2: %c\n", word->A[w - 1]); } htot = htot + letterscore.A[word->A[w - 1] - aletter]; } x = x + 1; } while (!(((t == last) && (apparentboardletter.A[x].A[y] == freeletter)) || (x > xmax))); htot = htot * wfact; if (last == 7) htot = htot + 50; (*totscore) = htot + vtot; (*length) = w; place2 = check(&(*word), w); R81 = place2; L99: ; return R81; } boolean placeanag(tiles, tileletter, outrack, outlet, last, x, y, word, length, totscore) rack *tiles; letterrack *tileletter; rack *outrack; letterrack *outlet; tileindex last; xtilerange x; ytilerange y; t15 *word; xtilerange *length; score *totscore; { typedef struct { xtilerange A[maxtiles + 1]; } T75; register boolean R82; xtilerange ix; integer w1, w2; r15 w; register r15 i; tileindex t; t15 outword, wordlet; T75 where; ix = x; R82 = false; (*length) = 0; (*totscore) = 0; t = 0; w = 0; do { if (apparentboardletter.A[x].A[y] == freeletter) { if (t == last) { } else { t = t + 1; w = w + 1; word->A[w - 1] = tiles->A[t - 1]; wordlet.A[w - 1] = tileletter->A[t - 1]; where.A[t] = w; } } else { w = w + 1; word->A[w - 1] = boardtile.A[x].A[y]; wordlet.A[w - 1] = apparentboardletter.A[x].A[y]; } x = x + 1; } while (!(((t == last) && (apparentboardletter.A[x].A[y] == freeletter)) || (x == xmax + 1))); if (checkanag(&(*word), w, &w1, &w2, &outword)) { if (w1 != w2) { printf("Warning: words temporarily ignored!\n"); } t = 0; { r15 B192 = 1, B193 = w; if (B192 <= B193) for (i = B192; ; i++) { if (apparentboardletter.A[ix + i - 1].A[y] == freeletter) { t = t + 1; outrack->A[t - 1] = outword.A[i - 1]; outlet->A[t - 1] = outword.A[i - 1]; } if (i == B193) break; } } R82 = placet(&(*outrack), &(*outlet), last, ix, y, &(*word), &(*length), &(*totscore)); } return R82; } void checkone(t, tl, n, x, y) rack *t; letterrack *tl; tileindex n; xtilepos x; ytilepos y; { rack ot; letterrack otl; score thisscore; xtilerange length; register xtilerange xx; ytilerange yy; char ch; register tileindex nexttl; t15 word; if (placeanag(&(*t), &(*tl), &ot, &otl, n, x, y, &word, &length, &thisscore)) { if (thisscore > bestscore) { bestt = ot; besttl = otl; best_orig_t = *t; best_orig_tl = *tl; bestcount = n; bestaxis = axis; bestword = word; bestlength = length; if (axis == horizontal) { bestx = x; besty = y; } else { bestx = y; besty = x; } nexttl = 0; #ifdef TTY printf("Placing "); for (nexttl = 1; nexttl <= n ; nexttl++) { if (tl->A[nexttl - 1] == blankletter) { printf("(Blank %c)", t->A[nexttl - 1]); } else { putchar(ot.A[nexttl - 1]); } } printf(" to give "); printstring(stdout, length, word.A); if (axis == horizontal) { printf(" across at %d, %d", x, y); } else { printf(" down at %d, %d", y, x); } printf(" would score %d\n", thisscore); nexttl = 0; { xtilerange B196 = x, B197 = x + length - 1; if (B196 <= B197) for (xx = B196; ; xx++) { if ((apparentboardletter.A[xx].A[y] == freeletter) && ((apparentboardletter.A[xx].A[y - 1] != freeletter) || (apparentboardletter.A[xx].A[y + 1] != freeletter))) { printf(" (Also forms "); ch = word.A[xx - x];/*BUG?*/ yy = y; while (apparentboardletter.A[xx].A[yy - 1] != freeletter) yy = yy - 1; while (yy < y) { putchar(apparentboardletter.A[xx].A[yy]); yy = yy + 1; } putchar((unsigned)(ch) - 32); yy = y; while (apparentboardletter.A[xx].A[yy + 1] != freeletter) { yy = yy + 1; putchar(apparentboardletter.A[xx].A[yy]); } putchar(')'),putchar('\n'); } if (xx == B197) break; } } #endif bestscore = thisscore; } } else { } } void perms(t, tl, n) rack *t; letterrack *tl; tileindex n; { register xtilepos x; register ytilepos y; int bp, blanks, b1pos, b2pos, b1, b2; if (blanktileheld) { b1pos = -1; b2pos = -1; for (bp = 0; bp < n; bp++) { if ((tl->A[bp] == blankletter) && (b1pos == -1)) { b1pos = bp; } if (tl->A[bp] == blankletter) { b2pos = bp; } } if (b1pos == -1) { blanks = 0; } else if (b1pos == b2pos) { blanks = 1; } else blanks = 2; if (blanks == 0) { for (y = ymin; y <= ymax ; y++) { for (x = xmin; x <= xmax-n+1 ; x++) { if ((min.A[x].A[y] <= n) && (n <= max.A[x].A[y])) { checkone(t, tl, n, x, y); } } } } else if (blanks == 1) { for (b1 = aletter; b1 <= zletter; b1++) { t->A[b1pos] = b1; /*tl->A[b1pos] = ???;*/ for (y = ymin; y <= ymax ; y++) { for (x = xmin; x <= xmax-n+1 ; x++) { if ((min.A[x].A[y] <= n) && (n <= max.A[x].A[y])) { checkone(t, tl, n, x, y); } } } } t->A[b1pos] = blankletter; } else { /* blanks == 2 */ for (b1 = aletter; b1 <= zletter; b1++) { t->A[b1pos] = b1; /*tl->A[b1pos] = ???;*/ for (b2 = aletter; b2 <= zletter; b2++) { t->A[b2pos] = b2; /*tl->A[b2pos] = ???;*/ for (y = ymin; y <= ymax ; y++) { for (x = xmin; x <= xmax-n+1 ; x++) { if ((min.A[x].A[y] <= n) && (n <= max.A[x].A[y])) { checkone(t, tl, n, x, y); } } } } } t->A[b1pos] = blankletter; t->A[b2pos] = blankletter; } } else { for (y = ymin; y <= ymax ; y++) { for (x = xmin; x <= xmax-n+1 ; x++) { if ((min.A[x].A[y] <= n) && (n <= max.A[x].A[y])) { checkone(t, tl, n, x, y); } } } } } void permnofm(t, l, n, m) rack *t; letterrack *l; tileindex n, m; { tileindex c0; register tileindex c7; register tileindex c6; register tileindex c5; register tileindex c4; register tileindex c3; register tileindex c2; register tileindex c1; rack ot; letterrack ol; c0 = 0; if (n >= 1) { tileindex B202 = c0 + 1, B203 = m; if (B202 <= B203) for (c1 = B202; ; c1++) { ot.A[1 - 1] = t->A[c1 - 1]; ol.A[1 - 1] = l->A[c1 - 1]; if (n >= 2) { tileindex B204 = c1 + 1, B205 = m; if (B204 <= B205) for (c2 = B204; ; c2++) { ot.A[2 - 1] = t->A[c2 - 1]; ol.A[2 - 1] = l->A[c2 - 1]; if (n >= 3) { tileindex B206 = c2 + 1, B207 = m; if (B206 <= B207) for (c3 = B206; ; c3++) { ot.A[3 - 1] = t->A[c3 - 1]; ol.A[3 - 1] = l->A[c3 - 1]; if (n >= 4) { tileindex B208 = c3 + 1, B209 = m; if (B208 <= B209) for (c4 = B208; ; c4++) { ot.A[4 - 1] = t->A[c4 - 1]; ol.A[4 - 1] = l->A[c4 - 1]; if (n >= 5) { tileindex B210 = c4 + 1, B211 = m; if (B210 <= B211) for (c5 = B210; ; c5++) { ot.A[5 - 1] = t->A[c5 - 1]; ol.A[5 - 1] = l->A[c5 - 1]; if (n >= 6) { tileindex B212 = c5 + 1, B213 = m; if (B212 <= B213) for (c6 = B212; ; c6++) { ot.A[6 - 1] = t->A[c6 - 1]; ol.A[6 - 1] = l->A[c6 - 1]; if (n >= 7) { tileindex B214 = c6 + 1, B215 = m; if (B214 <= B215) for (c7 = B214; ; c7++) { ot.A[7 - 1] = t->A[c7 - 1]; ol.A[7 - 1] = l->A[c7 - 1]; perms(&ot, &ol, n); if (c7 == B215) break; } } else { perms(&ot, &ol, n); } if (c6 == B213) break; } } else { perms(&ot, &ol, n); } if (c5 == B211) break; } } else { perms(&ot, &ol, n); } if (c4 == B209) break; } } else { perms(&ot, &ol, n); } if (c3 == B207) break; } } else { perms(&ot, &ol, n); } if (c2 == B205) break; } } else { perms(&ot, &ol, n); } if (c1 == B203) break; } } } void placehorizontalwords(heldtile, lasttile) rack *heldtile; tileindex lasttile; { tileindex n; if (lasttile > 0) { n = 0; do { n = n + 1; permnofm(&(*heldtile), &heldletter, n, lasttile); } while (!((n == lasttile))); } } void init_heap(void) { a2P = (T61 *) malloc(sizeof(T61)); if (a2P == NULL) {fprintf(stderr, "%cNo room for 2 letter words\n",12); exit(0);} a3P = (T62 *) malloc(sizeof(T62)); if (a3P == NULL) {fprintf(stderr, "%cNo room for 3 letter words\n",12); exit(0);} a4P = (T63 *) malloc(sizeof(T63)); if (a4P == NULL) {fprintf(stderr, "%cNo room for 4 letter words\n",12); exit(0);} a5P = (T64 *) malloc(sizeof(T64)); if (a5P == NULL) {fprintf(stderr, "%cNo room for 5 letter words\n",12); exit(0);} a6P = (T65 *) malloc(sizeof(T65)); if (a6P == NULL) {fprintf(stderr, "%cNo room for 6 letter words\n",12); exit(0);} a7P = (T66 *) malloc(sizeof(T66)); if (a7P == NULL) {fprintf(stderr, "%cNo room for 7 letter words\n",12); exit(0);} a8P = (T67 *) malloc(sizeof(T67)); if (a8P == NULL) {fprintf(stderr, "%cNo room for 8 letter words\n",12); exit(0);} a9P = (T68 *) malloc(sizeof(T68)); if (a9P == NULL) {fprintf(stderr, "%cNo room for 9 letter words\n",12); exit(0);} a10P = (T69 *) malloc(sizeof(T69)); if (a10P == NULL) {fprintf(stderr, "%cNo room for 10 letter words\n",12); exit(0);} a11P = (T70 *) malloc(sizeof(T70)); if (a11P == NULL) {fprintf(stderr, "%cNo room for 11 letter words\n",12); exit(0);} a12P = (T71 *) malloc(sizeof(T71)); if (a12P == NULL) {fprintf(stderr, "%cNo room for 12 letter words\n",12); exit(0);} a13P = (T72 *) malloc(sizeof(T72)); if (a13P == NULL) {fprintf(stderr, "%cNo room for 13 letter words\n",12); exit(0);} a14P = (T73 *) malloc(sizeof(T73)); if (a14P == NULL) {fprintf(stderr, "%cNo room for 14 letter words\n",12); exit(0);} a15P = (T74 *) malloc(sizeof(T74)); if (a15P == NULL) {fprintf(stderr, "%cNo room for 15 letter words\n",12); exit(0);} } void initialise() { register unsigned char xpos; register unsigned char ypos; atile = 'a'; blankletter = ((zletter)+1); blanktile = blankletter; freeletter = ((blankletter)+1); freetile = freeletter; everytile.S = 0x3ffffff; /**/SET /* 'a'..'z' */ { unsigned char B216 = ymin - 1, B217 = ymax + 1; if (B216 <= B217) for (ypos = B216; ; ypos++) { { unsigned char B218 = xmin - 1, B219 = xmax + 1; if (B218 <= B219) for (xpos = B218; ; xpos++) { boardtile.A[xpos].A[ypos] = freetile; apparentboardletter.A[xpos].A[ypos] = freeletter; if (xpos == B219) break; } } if (ypos == B217) break; } } } int TilesPlaced; move_info Move_List[7]; void placebest() { xtilepos x; ytilepos y; tileindex htile; register tileindex nexttl; char ch; letter tile; TilesPlaced = 0; /* Note: if couldn't play, this will be wrong - because this code will not be called to initialise it */ #ifdef TTY printf("****************************\n"); printf("My move: place "); #endif x = bestx; y = besty; if (bestaxis == vertical) { for (nexttl = 1; nexttl <= bestcount; nexttl++) { while (apparentboardletter.A[x].A[y] != freeletter) y = y + 1; ch = besttl.A[nexttl - 1]; htile = 0; for (;;) { htile = htile + 1; #ifdef DEBUG fprintf(stderr, "heldletter[%d] = %c (not %c?)\n", htile-1, heldletter.A[htile - 1], ch); #endif if (heldletter.A[htile - 1] == ch) { /* This one will do - lets take it. */ break; } if (htile == lasttile) { /* got to the end and didn't find it - so must have been a wildcard which generated this letter */ #ifdef DEBUG fprintf(stderr, "BLANK detected\n"); #endif htile = 0; for (;;) { htile = htile + 1; if (heldletter.A[htile - 1] == blankletter) { /* This one will do - lets take it. */ bestt.A[nexttl - 1] = ch; besttl.A[nexttl - 1] = blankletter; break; } if (htile == lasttile) { #ifdef DEBUG fprintf(stderr, "Damn. Didn't think it worked like that\n"); #endif break; } } break; } }; heldtile.A[htile - 1] = freetile; heldletter.A[htile - 1] = freeletter; if (besttl.A[nexttl - 1] == blankletter) { ch = (unsigned)(bestt.A[nexttl - 1]) - 'a' + 'A'; tile = ' '; } else { ch = bestt.A[nexttl - 1]; tile = ch; } #ifdef TTY putchar(ch); #endif Move_List[TilesPlaced].rack_position = htile-1; Move_List[TilesPlaced].x = x-1; Move_List[TilesPlaced].y = y-1; Move_List[TilesPlaced].placed_letter = ch; Move_List[TilesPlaced].tile = besttl.A[nexttl - 1]; TilesPlaced++; apparentboardletter.A[x].A[y] = ch; boardtile.A[x].A[y] = tile; special.A[x].A[y].letterfactor = 1; special.A[x].A[y].wordfactor = 1; letterfreq.A[besttl.A[nexttl - 1] - aletter] -= 1; if (y < ymax) y = y + 1; } #ifdef TTY printf(" at %d,%d down to make ", bestx, besty); printstring(stdout, bestlength, bestword.A); printf(" (scoring %d)\n", bestscore); #endif } else { for (nexttl = 1; nexttl <= bestcount; nexttl++) { while (apparentboardletter.A[x].A[y] != freeletter) { x = x + 1; } ch = besttl.A[nexttl - 1]; htile = 0; for (;;) { htile = htile + 1; #ifdef DEBUG fprintf(stderr, "heldletter[%d] = %c (not %c?)\n", htile-1, heldletter.A[htile - 1], ch); #endif if (heldletter.A[htile - 1] == ch) { /* This one will do - lets take it. */ break; } if (htile == lasttile) { /* got to the end and didn't find it - so must have been a wildcard which generated this letter */ #ifdef DEBUG fprintf(stderr, "BLANK detected\n"); #endif htile = 0; for (;;) { htile = htile + 1; if (heldletter.A[htile - 1] == blankletter) { /* This one will do - lets take it. */ bestt.A[nexttl - 1] = ch; besttl.A[nexttl - 1] = blankletter; break; } if (htile == lasttile) { #ifdef DEBUG fprintf(stderr, "Damn. Didn't think it worked like that\n"); #endif break; } } break; } }; heldtile.A[htile - 1] = freetile; heldletter.A[htile - 1] = freeletter; if (besttl.A[nexttl - 1] == blankletter) { ch = (unsigned)(bestt.A[nexttl - 1]) - 'a' + 'A'; tile = ' '; } else { ch = bestt.A[nexttl - 1]; tile = ch; } #ifdef TTY putchar(ch); #endif Move_List[TilesPlaced].rack_position = htile-1; Move_List[TilesPlaced].x = x-1; Move_List[TilesPlaced].y = y-1; Move_List[TilesPlaced].placed_letter = ch; /* 'a'..'z', 'A'..'Z' */ Move_List[TilesPlaced].tile = tile; /* 'a'..'z', ' ' */ TilesPlaced++; apparentboardletter.A[x].A[y] = ch; boardtile.A[x].A[y] = tile; special.A[x].A[y].letterfactor = 1; special.A[x].A[y].wordfactor = 1; if (letterfreq.A[besttl.A[nexttl - 1] - aletter] == 0) { #ifdef TTY putchar('\n'); printf("Too many copies of: %c\n", besttl.A[nexttl - 1]); putchar('\n'); #endif } else letterfreq.A[besttl.A[nexttl - 1] - aletter] -= 1; if (x < xmax) x = x + 1; } #ifdef TTY printf(" at %d,%d across to make ", bestx, besty); printstring(stdout, bestlength, bestword.A); printf(" (scoring %d)\n", bestscore); #endif } } void remove_played_tiles() { char ch; tileindex htile; register tileindex nexttl; if ((signed char)lasttile < 0) { fprintf(stderr, "Oops! I've spotted something wrong... variable 'lasttile' is set to %d\n", (signed char)lasttile); lasttile = 0; } if (lasttile > 0) { { tileindex B224 = 1, B225 = lasttile; #ifdef TTY #else #ifdef NEVER /* Removed because rack now passed in */ rackindex -= lasttile; #endif #endif if (B224 <= B225) for (nexttl = B224; ; nexttl++) { if (heldtile.A[nexttl - 1] == freetile) { htile = nexttl; if (htile < lasttile) do { htile = htile + 1; if ((heldtile.A[nexttl - 1] == freetile) && (heldtile.A[htile - 1] != freetile)) { heldtile.A[nexttl - 1] = heldtile.A[htile - 1]; heldtile.A[htile - 1] = freetile; heldletter.A[nexttl - 1] = heldletter.A[htile - 1]; heldletter.A[htile - 1] = freeletter; } } while (!(htile == lasttile)); } if (nexttl == B225) break; } } lasttile = lasttile - bestcount; } bestcount = 0; /* THIS WAS MISSING!!!(but is the the best place for it?)*/ } void writeboard() { char ch; register xtilepos x; register ytilepos y; register tileindex htile; { ytilepos B226 = 1, B227 = 15; if (B226 <= B227) for (y = B226; ; y++) { { xtilepos B228 = 1, B229 = 15; if (B228 <= B229) for (x = B228; ; x++) { if (apparentboardletter.A[x].A[y] == blankletter) { ch = (unsigned)(boardtile.A[x].A[y]) - 32; } else if (apparentboardletter.A[x].A[y] == freeletter) { ch = '.'; } else ch = apparentboardletter.A[x].A[y]; fputc(ch, boardf); if (x == B229) break; } } fputc('\n', boardf); if (y == B227) break; } } if (lasttile > 0) { tileindex B230 = 1, B231 = lasttile; if (B230 <= B231) for (htile = B230; ; htile++) { ch = heldletter.A[htile - 1]; if (ch == blankletter) ch = ' '; fputc(ch, boardf); if (htile == B231) break; } } fprintf(boardf, "\n%d\n", move + 1); } /*---------------------------------------------------------------------------*/ /* boolean state (whether valid move found) * the following routines will recursively call the given wimp poll function * allowing higher level game functions (and other RISC OS applications) * a look-in... a suitable return code will notify the move code whether * a search sequence is to be terminated */ boolean find_move( /* in */ char **boardt, /* board[15][15] 'a'..'z' '.' */ int player, /* 0..3 */ int tilecount, /* 1..7 */ char *tilerack, /* 0..6 "[a..z]" or " " */ void (*poll_function)(), /* wimp poll routine */ /* inout */ void *player_info, /* private object */ /* out */ int *tiles_placed, /* 0..7 */ move_info *move_list, /* move_list[0..6] */ int *actual_length, /* 0..15 */ char *actual_word, /* word[15] -- all lowercase */ int *actual_direction, /* 0-horizontal, 1-vertical */ int *incidentals_formed, /* count of below: 0..15 */ char ***incidental_words, /* array of ditto -- for info */ int *actual_start_x, /* Xpos of 1st letter */ int *actual_start_y, /* Ypos of 1st letter */ int *placed_score /* score of resulting word */ ) { #ifdef TTY #else int r_index; #endif Resetx(boardf, "board.temp"); initialise(); initboard(); #ifdef TTY if (lasttile != 7) { int ch; printf("%cMay I have %d tile", 12, 7 - lasttile); if (lasttile != 6) putchar('s'); printf(" please?\n"); do { if (!Eoln(stdin)) { ch = getchar(); lasttile = lasttile + 1; if (ch == ' ') { heldletter.A[lasttile - 1] = blankletter; heldtile.A[lasttile - 1] = blanktile; } else { heldletter.A[lasttile - 1] = ch; heldtile.A[lasttile - 1] = ch; } } } while (!((lasttile == 7) || Eoln(stdin))); Getl(stdin); #ifdef NEVER r_index = rackindex; while (r_index > 0) { r_index--; lasttile++; ch = rackbuff[r_index]; if (ch == ' ') { heldletter.A[lasttile - 1] = blankletter; heldtile.A[lasttile - 1] = blanktile; } else { heldletter.A[lasttile - 1] = ch; heldtile.A[lasttile - 1] = ch; } } #endif Rewritex(boardf, "board.temp"); writeboard(); tilecount = lasttile; } #else /* Copy rack from that passed in. */ lasttile = tilecount; for (r_index = 0; r_index < lasttile; r_index++) { int ch; ch = tilerack[r_index]; if (ch == ' ') { heldletter.A[r_index] = blankletter; heldtile.A[r_index] = blanktile; } else { heldletter.A[r_index] = ch; heldtile.A[r_index] = ch; } } Rewritex(boardf, "board.temp"); writeboard(); tilecount = lasttile; #endif bestscore = 0; { direction B232 = horizontal, B233 = vertical; #ifdef DEBUG fprintf(stderr, "searching\n"); #endif if ((int)(B232) <= (int)(B233)) for (axis = B232; ; axis = (direction)((int)(axis)+1)) { /* if ((move != 0) || ((move == 0) && (axis == horizontal))) {*/ Resetx(boardf, "board.temp"); initialise(); initboard(); if (lasttile > 0) { constrainplacements(boardtile, apparentboardletter, &choice, &vscore, &min, &max, heldtile, lasttile); placehorizontalwords(&heldtile, lasttile); } /* }*/ if (axis == B233) break; } } axis = horizontal; Resetx(boardf, "board.temp"); initialise(); initboard(); TilesPlaced = 0; /* Set by placebest() */ if (bestscore > 0) { int i; placebest(); *tiles_placed = TilesPlaced; for (i = 0; i < TilesPlaced; i++) { move_list[i] = Move_List[i]; } } else { printf("Couldn't move - exchange tiles?\n"); cantmove = true; *tiles_placed = 0; } remove_played_tiles(); Rewritex(boardf, "board.temp"); writeboard(); /* Test here to see if game is out! */ move = move + 1; realmove = realmove + 1; return(false); } /*---------------------------------------------------------------------------*/ /* Identical to find_move, but finds the move suggested by * the human player instead of looking for one. Use '?' for * characters in fields you don't know such as 'tilerack'; * expect other fields to be filled in if possible. */ boolean place( /* in */ char **boardch, /* board[15][15] 'a'..'z' '.' */ int player, /* 0..3 */ int tilecount, /* 1..7 */ char *tilerack, void (*poll_function)(), /* poll routine called regularly */ /* inout */ void *player_info, /* private object */ /* In the case of 'Place', these are now 'in's... */ int tiles_placed, /* 0..7 */ move_info *move_list, /* move_list[0..6] */ /* in */ int *actual_length, /* 0..15 */ char *actual_word, /* word[15] -- all lowercase */ int *actual_direction, /* 0-horizontal, 1-vertical */ int *incidentals_formed, /* count of below: 0..15 */ /* out */ char ***incidental_words, /* array of ditto -- for info */ int *actual_start_x, /* Xpos of 1st letter */ int *actual_start_y, int *placed_score /* score of resulting word */ ) { char ch, let; int x, y, moves; #ifdef DEBUG fprintf(stderr, "Updating board from opponent's move\n"); #endif Resetx(boardf, "board.temp"); initialise(); initboard(); for (moves = 0; moves < tiles_placed; moves++) { ch = move_list[moves].placed_letter; let = move_list[moves].tile; x = move_list[moves].x; y = move_list[moves].y; #ifdef DEBUG fprintf(stderr, "Placing '%c' at %d,%d\n", ch, x, y); #endif apparentboardletter.A[x+1].A[y+1] = let; boardtile.A[x+1].A[y+1] = ch; } Rewritex(boardf, "board.temp"); move = move + 1; writeboard(); return(true); } /*---------------------------------------------------------------------------*/ /* ** Start of program code */ boolean mystart(void) { boolean mymove; int ch; mymove = false; ch = '\n'; do { if (ch == '\n') fprintf(stderr, "Are you going to play first? "); ch = fgetc(stdin); if (('A' <= ch) && (ch <= 'Z')) ch = ch-'A'+'Z'; } while ((ch != 'y') && (ch != 'n')); mymove = (ch == 'n'); while (ch != '\n') { ch = fgetc(stdin); /* Drain input */ } return(mymove); } int tiles_on_board(void) { int x, y, tiles = 0;; for (y = ymin; y <= ymax; y++) { for (x = xmin; x < xmax; x++) { if (boardtile.A[x].A[y] != freetile) tiles++; } } return(tiles); } boolean mymove; void initmain(int argc, char **argv) { init_heap(); cantmove = false; empty = true; lasttile = 0; move = 0; realmove = 0; initdict(); mymove = #ifdef TTY mystart(); #else false /* ARGH!!!! */ ; #endif Resetx(boardf, "board.init"); initialise(); initboard(); /* remove_played_tiles(); */ Rewritex(boardf, "board.temp"); writeboard(); } #ifdef TTY int main(int argc, char **argv) #else int retired(int argc, char **argv) #endif { initmain(argc, argv); do { if (mymove) { /* Our move */ static char ch, let; static int i, x, y; static char board[15][15]; static int player; static int tilecount; static char tilerack[/8*really */7]; /* inout */ static int *player_info; /* In the case of 'Place', these are now 'in's... */ static int tiles_placed; static move_info move_list[7]; /* out */ static int actual_length; static char actual_word[15]; static int actual_direction; static int incidentals_formed; static char **incidental_words; static int actual_start_x; static int actual_start_y; static int placed_score; player = 1; player_info = NULL; (void) find_move((char **) board, player, tilecount, (char *) tilerack, &poll_wimp, (void *) player_info, &tiles_placed, move_list, &actual_length, (char *) actual_word, &actual_direction, &incidentals_formed, (char ***) &incidental_words, &actual_start_x, &actual_start_y, &placed_score); for (i = 0; i < tiles_placed; i++) { ch = move_list[i].placed_letter; let = move_list[i].tile; x = move_list[i].x; y = move_list[i].y; #ifdef DEBUG fprintf(stderr, "I placed '%c' at %d,%d\n", ch, x, y); #endif } } else { /* Opponents move */ static int i, x, y, ch; static char board[15][15]; static int player; static int tilecount; static char tilerack[/8*really */7]; /* inout */ static int *player_info; /* In the case of 'Place', these are now 'in's... */ static int tiles_placed; static move_info move_list[7]; /* out */ static int actual_length; static char actual_word[15]; static int actual_direction; static int incidentals_formed; static char **incidental_words; static int actual_start_x; static int actual_start_y; static int placed_score; #ifdef DEBUG fprintf(stderr, "Reading opponents move...\n"); #endif player = 2; tilecount = 7; /* assumed */ player_info = NULL; fprintf(stderr, "How many tiles are you playing: "); tiles_placed = ReadNum(); fprintf(stderr, "Please type in all %d tiles & coordinates.\n", tiles_placed); for (i = 0; i < tiles_placed; i++) { fprintf(stderr, "c f8: "); ch = ReadChar(); x = ReadChar()-'a'+1; y = ReadNum(); x = x - 1; y = y - 1; fprintf(stderr, "placing letter %x at %d,%d\n", ch, x, y); move_list[i].placed_letter = ch; if (('A' <= ch) && (ch <= 'Z')) ch = ch - 'A' + 'a'; move_list[i].tile = ch; move_list[i].x = x; move_list[i].y = y; } (void) place((char **) board, player, tilecount, (char *) tilerack, &poll_wimp, (void *) player_info, tiles_placed, move_list, &actual_length, (char *) actual_word, &actual_direction, &incidentals_formed, (char ***) &incidental_words, &actual_start_x, &actual_start_y, &placed_score); } mymove = !mymove; } while (tiles_on_board() < 100); return(0); } /* ** End of program code */ #endif #ifndef TOAL typedef int boolean; # define false (boolean)0 # define true (boolean)1 typedef int integer; # define maxint 2147483647 #include "movegen.h" int TilesPlaced; move_info Move_List[7]; /* boolean state (whether valid move found) * the following routines will recursively call the given wimp poll function * allowing higher level game functions (and other RISC OS applications) * a look-in... a suitable return code will notify the move code whether * a search sequence is to be terminated */ boolean find_move( /* in */ char **boardt, /* board[15][15] 'a'..'z' '.' */ int player, /* 0..3 */ int tilecount, /* 1..7 */ char *tilerack, /* 0..6 "[a..z]" or " " */ void (*poll_function)(), /* wimp poll routine */ /* inout */ void *player_info, /* private object */ /* out */ int *tiles_placed, /* 0..7 */ move_info *move_list, /* move_list[0..6] */ int *actual_length, /* 0..15 */ char *actual_word, /* word[15] -- all lowercase */ int *actual_direction, /* 0-horizontal, 1-vertical */ int *incidentals_formed, /* count of below: 0..15 */ char ***incidental_words, /* array of ditto -- for info */ int *actual_start_x, /* Xpos of 1st letter */ int *actual_start_y, /* Ypos of 1st letter */ int *placed_score /* score of resulting word */ ) { return(0!=0); } /* Identical to find_move, but finds the move suggested by * the human player instead of looking for one. Use '?' for * characters in fields you don't know such as 'tilerack'; * expect other fields to be filled in if possible. */ boolean place( /* in */ char **boardch, /* board[15][15] 'a'..'z' '.' */ int player, /* 0..3 */ int tilecount, /* 1..7 */ char *tilerack, void (*poll_function)(), /* poll routine called regularly */ /* inout */ void *player_info, /* private object */ /* In the case of 'Place', these are now 'in's... */ int tiles_placed, /* 0..7 */ move_info *move_list, /* move_list[0..6] */ /* in */ int *actual_length, /* 0..15 */ char *actual_word, /* word[15] -- all lowercase */ int *actual_direction, /* 0-horizontal, 1-vertical */ int *incidentals_formed, /* count of below: 0..15 */ /* out */ char ***incidental_words, /* array of ditto -- for info */ int *actual_start_x, /* Xpos of 1st letter */ int *actual_start_y, int *placed_score /* score of resulting word */ ) { } void initmain(int argc, char **argv) { } void poll_wimp() { } #endif