
/* RCS Info: $Revision: 1.3 $ on $Date: 89/03/15 16:33:15 $
 *           $Source: /yew3/faustus/src/scrabble/RCS/scrabble.c,v $
 * Copyright (c) 1989 Wayne A. Christopher, U. C. Berkeley CS Dept
 *      faustus@renoir.berkeley.edu, ucbvax!faustus
 * Permission is granted to modify and re-distribute this code in any manner
 * as long as this notice is preserved.  All standard disclaimers apply.
 *
 */

#include "scrabble.h"
#include "date.h"
#include <signal.h>

bool debug = false;
bool userpick = false;
bool confirm = false;

static bool domove(board_t *board, player_t **players, int which);
static void sighandler();

static char *dictfile = DICT_FILE;

int
main(int ac, char **av)
{
       board_t *board;
       player_t *players[MAX_PLAYERS];
       bool machine[MAX_PLAYERS];
       int numplayers = 2;
       int whosup = 0;
       int turn = 1;
       char buf[BSIZE];
       char *savedfile = NULL;
       FILE *sfp = NULL;
       int i, j, k;

       /*
       printf("\tScrabble 1.0, by Wayne Christopher\n");       
       printf("Compiled %s by %s@%s\n\n", DATE, USER, HOST);
       */

       srandom(time(0));

       for (i = 0; i < MAX_PLAYERS; i++)
               machine[i] = false;

       for (ac--, av++; ac && (**av == '-'); ac--, av++) {
               if (eq(*av, "-d")) {
                       debug = true;
               } else if (eq(*av, "-p")) {
                       userpick = true;
               } else if (eq(*av, "-c")) {
                       confirm = true;
               } else if (eq(*av, "-n")) {
                       numplayers = atoi(*++av);
                       ac--;
               } else if (eq(*av, "-w")) {
                       dictfile = *++av;
                       ac--;
               } else if (eq(*av, "-m")) {
                       machine[atoi(*++av)] = true;
                       ac--;
               } else {
                       goto usage;
               }
       }
       if (ac > 0)
               savedfile = *av;

       if (savedfile) {
               if (!(sfp = fopen(savedfile, "r"))) {
                       perror(savedfile);
                       savedfile = NULL;
               } else {
                       unlink(savedfile);
               }
       }

       /* Read the words. */
       readdict(dictfile);

       /* Create the board. */
       if (savedfile) {
               board = restoregame(sfp, &numplayers, &whosup, &turn);
               if (!board) {
                       savedfile = NULL;
                       board = makeboard();
               }
       } else {
               board = makeboard();
       }

       /* Create the players. */
       for (i = 0; i < numplayers; i++)
               if (savedfile) {
                       players[i] = restoreplayer(sfp);
               } else {
                       players[i] = makeplayer(board, i);
                       players[i]->machine = machine[i];
                       if (machine[i])
                               sprintf(buf, "Mach %d", i);
                       else {
                               printf("Enter name of player %d: ", i);
                               fgets(buf, BSIZE, stdin);
                               buf[strlen(buf) - 1] = '\0';
                               if (!*buf)
                                       sprintf(buf, "Dude %d", i);
                       }
                       players[i]->name = strsav(buf);
               }

       if (sfp)
               fclose(sfp);

       user_init(DEV_TTY, board, players, numplayers);

       signal(SIGINT, sighandler);

       /* Now take turns. */
       for (;;) {
               user_drawsummary(board, turn);
               while (whosup < numplayers)
                       if (!domove(board, players, whosup) ||
                                       !players[whosup]->numworking)
                               goto endgame;
                       else
                               whosup++;
               turn++;
               whosup = 0;
       }

endgame:
       if (players[whosup]->numworking > 0)
               whosup = -1;
       for (i = 0; i < numplayers; i++) {
               if (i == whosup)
                       continue;
               for (j = 0, k = 0; j < players[i]->numworking; j++) {
assert(players[i]->working[j]);
                       k += letterpoints(players[i]->working[j]);
               }
               sprintf(buf, "%s has %d points left.", players[i]->name,
                               players[i]->score);
               user_message(buf);
               players[i]->score -= k;
               if (whosup >= 0)
                       players[whosup]->score += k;

               user_drawplayer(players[i], i, false);
       }
       if (whosup >= 0)
               user_drawplayer(players[whosup], whosup, true);

       whosup = 0;
       for (i = 1; i < numplayers; i++)
               if (players[i]->score > players[whosup]->score)
                       whosup = i;

       sprintf(buf, "%s wins with %d points.  Hit return to exit...",
                       players[whosup]->name, players[whosup]->score);
       (void) user_confirm(buf);
~r
  

       if (user_confirm("Save updated dictionary?"))
               writedict(dictfile);

       user_cleanup();
       exit(0);

usage:
       fprintf(stderr, "Usage: scrabble [ options ] [ saved-game ]\n");
       fprintf(stderr, "\tOptions are: -d       Debug mode\n");
       fprintf(stderr, "\t             -p       Allow user to pick tiles\n");
       fprintf(stderr, "\t             -c       Confirm all words used\n");
       fprintf(stderr, "\t             -n num   Allow nnum players\n");
       fprintf(stderr, "\t             -m pnum  Player pnum is the machine\n");
       fprintf(stderr, "\t             -w words Use words for the dictfile\n");

       exit(1);
}

static bool
domove(board_t *board, player_t **players, int which)
{
       move_t move;
       char buf[BSIZE];
       command_t com;

#ifdef notdef
       if (debug)
               fprintf(stderr, "Moving for player %d...\n", which);
#endif

       user_drawplayer(players[which], which, true);

       if (players[which]->numworking == 0)
               return (false);

       if (players[which]->machine) {
               do {
                       bestmove(board, players[which], &move);
                       if (confirm)
                               trymove(&move, board, players[which], true);
               } while (confirm && (move.points < 0));

               if (move.points < 0)
                       return (false);

               user_drawmove(board, &move, players[which]);
               playermove(board, players[which], &move);
               boardmove(board, &move);
               user_drawplayer(players[which], which, false);
       } else {
               for (;;) {
                       com = user_command(board, players[which], &move);
                       switch (com) {
                           case NOTHING:
                               continue;

                           case MOVE:
                               trymove(&move, board, players[which], false);

                               if (!isaword(move.word)) {
                                       sprintf(buf,
                               "I don't think \"%s\" is a word.  Do you?",
                                                       move.word);
                                       if (user_confirm(buf)) {
                                               addword(move.word);
                                       } else
                                               continue;
                               }

                               if (move.points < 0) {
                                       user_message("You can't do that.");
                                       continue;
                               }

                               user_drawmove(board, &move, players[which]);
                               playermove(board, players[which], &move);
                               boardmove(board, &move);
                               user_drawplayer(players[which], which, false);
                               break;

                           case ADVICE:
                               players[which]->machine = true;
                               bestmove(board, players[which], &move);
                               players[which]->machine = false;
{_}i
    
                               sprintf(buf,
                       "I'd suggest \"%s\" at (%d, %d) %s for %d points.",
                                               move.word, move.x, move.y,
                                               move.horiz ? "horiz" : "vert",
                                               move.points);
                               user_message(buf);
                               continue;

                           case TRADEIN:
                               user_message("Sorry, can't do that yet.");
                               continue;

                           case SAVE:
                               user_message("Sorry, can't do that yet.");
                               continue;

                           case RESTORE:
                               user_message("Sorry, can't do that yet.");
                               continue;

                           case HELP:
                               user_givehelp();
                               continue;

                           case QUIT:
                               if (user_confirm("Save updated dictionary?"))
                                       writedict(dictfile);
                               user_cleanup();
                               exit(0);
                       }

                       break;
               }
       }

       return (true);
}

static void
sighandler()
{
       user_cleanup();
       exit(0);
}

