#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