#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