home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!zephyr.ens.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v14i110: scrabble2 - another version of the crossword-puzzle board game, Part18/18
- Message-ID: <3628@master.CNA.TEK.COM>
- Date: 22 Sep 92 18:57:15 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 1535
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: jac@doe.carleton.ca (James A. Cherry)
- Posting-number: Volume 14, Issue 110
- Archive-name: scrabble2/Part18
- Environment: curses
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 18 (of 18)."
- # Contents: pmove.c score.c scrabble.6 smain.c
- # Wrapped by billr@saab on Tue Sep 22 11:47:52 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'pmove.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pmove.c'\"
- else
- echo shar: Extracting \"'pmove.c'\" \(8730 characters\)
- sed "s/^X//" >'pmove.c' <<'END_OF_FILE'
- X/*
- X *
- X * pmove.c -- player move routines
- X *
- X */
- X
- X#include "scrab.h"
- X#include "globals.h"
- X
- X
- Xplayer_move() {
- X char c;
- X int xpos, ypos, done;
- X
- X xpos = BOARD_LX;
- X ypos = BOARD_UY;
- X for( ;; ) {
- X clear_prompt();
- X printw( " Use the 'hjkl' keys to move the cursor.\n" );
- X printw( " Press <RETURN> on an empty square to start placing tiles on the board.\n" );
- X printw( " Press <SPACE> to rearrange your tiles.\n" );
- X printw( " Press '.' to use your turn to draw new tiles.\n" );
- X refresh();
- X done = 0;
- X do {
- X move( ypos, xpos );
- X refresh();
- X c = get_key();
- X switch( c ) {
- X case 'H':
- X if( xpos > BOARD_LX ) xpos--;
- X break;
- X case 'L':
- X if( xpos < BOARD_RX ) xpos++;
- X break;
- X case 'J':
- X if( ypos < BOARD_LY ) ypos++;
- X break;
- X case 'K':
- X if( ypos > BOARD_UY ) ypos--;
- X break;
- X case '\n':
- X if( board[ypos - BOARD_UY + 1][xpos - BOARD_LX + 1] < 'A' )
- X done = place_tiles( xpos, ypos );
- X break;
- X case ' ':
- X done = rearrange_tiles();
- X break;
- X case '.':
- X done = draw_new_tiles();
- X break;
- X }
- X } while( done == 0 );
- X if( done == 1 ) break;
- X }
- X if( c == '.' ) game_done++;
- X else game_done = 0;
- X}
- X
- Xint place_tiles( xpos, ypos )
- X int xpos, ypos;
- X{
- X char c;
- X int xinc, yinc;
- X int i, j, t1, t2, ct1, ct2, tile;
- X struct plrlet newlet[7];
- X int placed;
- X int err, xt, yt;
- X
- X clear_prompt();
- X printw( " Which direction would you like to place your tiles:" );
- X printw( " horizontally or\n vertically (h/v)? " );
- X refresh();
- X c = get_key();
- X if( c != 'H' && c != 'V' ) return( -1 );
- X if( c == 'H' ) {
- X xinc = 1;
- X yinc = 0;
- X } else {
- X xinc = 0;
- X yinc = 1;
- X }
- X show_instructions();
- X placed = 0;
- X for( ;; ) {
- X move( ypos, xpos );
- X refresh();
- X c = get_key();
- X if( c == '-' || c == 127 || c == 8 ) {
- X if( placed == 0 ) break;
- X --placed;
- X do {
- X xpos -= xinc;
- X ypos -= yinc;
- X } while( board[ypos - BOARD_UY + 1][xpos - BOARD_LX + 1] >= 'A' );
- X move( ypos, xpos );
- X addch( newlet[placed].oldlet );
- X plr_tiles[human_player][newlet[placed].tilepos]
- X = newlet[placed].letter;
- X print_tiles();
- X } else if( c == 27 ) {
- X while( placed-- > 0 ) {
- X do {
- X xpos -= xinc;
- X ypos -= yinc;
- X } while( board[ypos - BOARD_UY + 1][xpos - BOARD_LX + 1] >= 'A' );
- X move( ypos, xpos );
- X addch( newlet[placed].oldlet );
- X plr_tiles[human_player][newlet[placed].tilepos]
- X = newlet[placed].letter;
- X }
- X print_tiles();
- X break;
- X } else if( c == '\n' ) {
- X if( placed == 0 ) break;
- X clear_prompt();
- X err = 0;
- X if( board[8][8] == CH_DW ) {
- X if( placed < 2 ) {
- X printw( " On the first move, you must place at least two tiles!\n" );
- X err = 1;
- X } else {
- X for( i = 0; i < placed; i++ )
- X if( newlet[i].x != 8 || newlet[i].y != 8 ) err++;
- X if( err == placed )
- X printw( " On the first move, you must place a tile on the centre square!\n" );
- X else err = 0;
- X }
- X } else {
- X for( i = 0; i < placed; i++ ) {
- X xt = newlet[i].x;
- X yt = newlet[i].y;
- X if( board[yt][xt - 1] >= 'A' || board[yt][xt + 1] >= 'A'
- X || board[yt - 1][xt] >= 'A' || board[yt + 1][xt] >= 'A' )
- X break;
- X }
- X if( i == placed ) {
- X printw( " You must add to part of the existing puzzle!\n" );
- X err = 1;
- X }
- X }
- X if( err == 0 ) {
- X clear_prompt();
- X for( tile = 0, t1 = -1, t2 = -1, i = 0; i < placed; i++ )
- X if( newlet[i].letter == CH_BL ) {
- X tile++;
- X if( t1 == -1 ) {
- X t1 = i;
- X ct1 = newlet[i].blankchar;
- X } else if( t2 == -1 ) {
- X t2 = i;
- X ct2 = newlet[i].blankchar;
- X }
- X }
- X for( i = 0, xt = 2; i < tile; i++ ) {
- X if( i == 0 ) j = t1;
- X else if( i == 1 ) j = t2;
- X if( newlet[j].blankchar == CH_BL ) {
- X clear_rect( 20, 0, 20, 79 );
- X printw( " What letter do you want the " );
- X if( tile == 2 && i == 0 ) printw( "first " );
- X else if( tile == 2 ) printw( "second " );
- X printw( "blank tile to be? " );
- X refresh();
- X do {
- X c = get_key();
- X } while( c < 'A' || c > 'Z' );
- X newlet[j].blankchar = c;
- X }
- X move( 22, xt );
- X if( tile == 2 && i == 0 ) printw( "First b" );
- X else if( tile == 2 ) printw( "Second b" );
- X else printw( "B" );
- X printw( "lank tile is a" );
- X if( index( "AEFHILMNORSX", newlet[j].blankchar ) != 0 ) {
- X printw( "n" );
- X xt++;
- X }
- X printw( " %c.", newlet[j].blankchar );
- X xt += 26;
- X }
- X clear_rect( 20, 0, 20, 79 );
- X printw( " Type <RETURN> to end your turn. Otherwise, type 'n'. -> " );
- X refresh();
- X do {
- X c = getch();
- X } while( c != '\n' && c != 'N' && c != 'n' );
- X if( c == '\n' ) break;
- X if( t1 != -1 ) newlet[t1].blankchar = ct1;
- X if( t2 != -1 ) newlet[t2].blankchar = ct2;
- X } else press_return();
- X show_instructions();
- X } else {
- X if( xpos > BOARD_RX || ypos > BOARD_LY ) continue;
- X tile = -1;
- X for( i = 0; i < 7; i++ ) {
- X if( c == plr_tiles[human_player][i] ) tile = i;
- X else if( plr_tiles[human_player][i] == CH_BL && tile == -1 )
- X tile = i;
- X }
- X if( tile == -1 ) continue;
- X if( plr_tiles[human_player][tile] == CH_BL )
- X newlet[placed].blankchar = c;
- X newlet[placed].letter = plr_tiles[human_player][tile];
- X plr_tiles[human_player][tile] = 0;
- X newlet[placed].x = xpos - BOARD_LX + 1;
- X newlet[placed].y = ypos - BOARD_UY + 1;
- X newlet[placed].oldlet =
- X board[ypos - BOARD_UY + 1][xpos - BOARD_LX + 1];
- X if( newlet[placed].oldlet == CH_DW ) newlet[placed].oldlet = 'o';
- X newlet[placed].tilepos = tile;
- X addch( newlet[placed].letter );
- X do {
- X xpos += xinc;
- X ypos += yinc;
- X } while( board[ypos - BOARD_UY + 1][xpos - BOARD_LX + 1] >= 'A'
- X && xpos <= BOARD_RX && ypos <= BOARD_LY );
- X print_tiles();
- X placed++;
- X }
- X }
- X if( placed <= 0 ) return( -1 );
- X err = find_new_words( &newlet[0], placed, xinc, yinc );
- X display_words( human_player, &newlet[0], err, placed );
- X return( 1 );
- X}
- X
- Xshow_instructions() {
- X clear_prompt();
- X printw( " Type the letter to be placed in each square, and '%c' for a blank tile.\n", CH_BL );
- X printw( " If you type a letter which you do not have, and you have a blank tile, then\n" );
- X printw( " it will be placed for you automatically.\n" );
- X printw( " Press '-' to backspace, <ESC> to cancel, and <RETURN> when done.\n" );
- X refresh();
- X}
- X
- Xint rearrange_tiles() {
- X char c;
- X int i, j;
- X
- X clear_prompt();
- X printw( " Each letter you type will be moved to the end of your rack.\n" );
- X printw( " Type '%c' for a blank tile, and <RETURN> when you are done.\n",
- X CH_BL );
- X refresh();
- X print_tiles();
- X do {
- X c = get_key();
- X for( i = 0; i < 7; i++ ) {
- X if( c == plr_tiles[human_player][i] ) {
- X for( j = i; j < 6; j++ )
- X plr_tiles[human_player][j] = plr_tiles[human_player][j + 1];
- X plr_tiles[human_player][6] = c;
- X print_tiles();
- X break;
- X }
- X }
- X } while( c != '\n' );
- X return( -1 );
- X}
- X
- Xdisp_instr() {
- X clear_rect( 19, 0, 20, 79 );
- X printw( " Type the tiles that you wish to discard, using '%c' for a blank tile.\n", CH_BL );
- X printw( " Press '-' to backspace, <ESC> to cancel, and <RETURN> when done.\n" );
- X refresh();
- X}
- X
- Xint draw_new_tiles() {
- X char c, tile[7];
- X int i, j, plr;
- X int used[7];
- X
- X clear_prompt();
- X disp_instr();
- X plr = human_player;
- X j = 0;
- X for( i = 0; i < 7; i++ ) {
- X used[i] = 0;
- X tile[i] = plr_tiles[plr][i];
- X }
- X for( ;; ) {
- X clear_rect( 22, 0, 22, 79 );
- X printw( " Tiles to discard:" );
- X for( i = 0; i < 7; i++ )
- X if( used[i] != 0 ) printw( " %c", tile[i] );
- X print_tiles();
- X c = get_key();
- X if( c == '\n' ) {
- X if( j != 0 ) {
- X clear_rect( 19, 0, 20, 79 );
- X printw( " Type <RETURN> to confirm your selection. Otherwise, type 'n'. -> " );
- X } else {
- X clear_rect( 19, 0, 20, 79 );
- X printw( " Type <RETURN> to pass your turn. Otherwise, type 'n'. -> " );
- X }
- X refresh();
- X do {
- X c = getch();
- X } while( c != '\n' && c != 'N' && c != 'n' );
- X if( c == '\n' ) break;
- X disp_instr();
- X } else if( c == '-' || c == 127 || c == 8 ) {
- X if( j > 0 ) {
- X for( i = 0; i < 7; i++ )
- X if( used[i] == j ) {
- X used[i] = 0;
- X plr_tiles[plr][i] = tile[i];
- X j--;
- X break;
- X }
- X } else {
- X j = -1;
- X break;
- X }
- X } else if( c == 27 ) {
- X for( i = 0; i < 7; i++ )
- X if( used[i] != 0 ) plr_tiles[plr][i] = tile[i];
- X print_tiles();
- X j = -1;
- X break;
- X } else {
- X for( i = 0; i < 7; i++ ) {
- X if( c == plr_tiles[plr][i] ) {
- X j++;
- X used[i] = j;
- X plr_tiles[plr][i] = 0;
- X break;
- X }
- X }
- X }
- X }
- X if( j == -1 ) return( -1 );
- X for( i = 0; i < 7; i++ )
- X if( used[i] != 0 ) {
- X c = tile[i] - 'A';
- X if( tile[i] == CH_BL ) c = 26;
- X tiles_left[c]++;
- X }
- X for( i = 0; i < 7; i++ )
- X if( used[i] != 0 ) plr_tiles[plr][i] = draw_tile();
- X print_tiles();
- X return( 1 );
- X}
- END_OF_FILE
- if test 8730 -ne `wc -c <'pmove.c'`; then
- echo shar: \"'pmove.c'\" unpacked with wrong size!
- fi
- # end of 'pmove.c'
- fi
- if test -f 'score.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'score.c'\"
- else
- echo shar: Extracting \"'score.c'\" \(6224 characters\)
- sed "s/^X//" >'score.c' <<'END_OF_FILE'
- X/*
- X *
- X * score.c -- find score for a turn
- X *
- X */
- X
- X#include "scrab.h"
- X#include "globals.h"
- X
- X
- Xint find_new_words( newlet, placed, xinc, yinc )
- X struct plrlet (*newlet)[];
- X int placed, xinc, yinc;
- X{
- X struct plrlet *currlet;
- X int i, w, j;
- X int dx, dy;
- X int x, y;
- X int score, mult, tsc, cptr, blloc;
- X char c, ch;
- X
- X w = 0;
- X dx = 1 - xinc;
- X dy = 1 - yinc;
- X for( i = 0; i <= placed; i++ ) {
- X if( i < placed ) {
- X currlet = &((*newlet)[i]);
- X x = currlet->x;
- X y = currlet->y;
- X } else {
- X x = ((*newlet)[0]).x;
- X y = ((*newlet)[0]).y;
- X dx = xinc;
- X dy = yinc;
- X }
- X if( ( y - dy > 0 && x - dx > 0 && board[y - dy][x - dx] >= 'A' )
- X || ( y + dy < 16 && x + dx < 16 && board[y + dy][x + dx] >= 'A' )
- X || i == placed ) {
- X while( board[y - dy][x - dx] >= 'A' && x - dx > 0 && y - dy > 0 ) {
- X x -= dx;
- X y -= dy;
- X }
- X new_words[w].startx = x;
- X new_words[w].starty = y;
- X new_words[w].dir = dy;
- X score = 0;
- X mult = 1;
- X cptr = 0;
- X blloc = -1;
- X for( ;; ) {
- X c = board[y][x];
- X if( c >= 'A' ) {
- X if( ( x != b1x || y != b1y ) && ( x != b2x || y != b2y ) )
- X score += letters[c - 'A'].points;
- X new_words[w].letters[cptr++] = c;
- X } else {
- X for( j = 0; j < placed; j++ )
- X if( x == ((*newlet)[j]).x && y == ((*newlet)[j]).y )
- X break;
- X if( j == placed ) break;
- X if( blloc == -1 ) blloc = cptr;
- X else blloc = -2;
- X ch = ((*newlet)[j]).letter;
- X if( ch == CH_BL ) {
- X tsc = 0;
- X new_words[w].letters[cptr++] = ((*newlet)[j]).blankchar;
- X } else {
- X tsc = letters[ch - 'A'].points;
- X new_words[w].letters[cptr++] = ch;
- X }
- X if( c == CH_DL ) tsc *= 2;
- X else if( c == CH_TL ) tsc *= 3;
- X else if( c == CH_DW ) mult *= 2;
- X else if( c == CH_TW ) mult *= 3;
- X score += tsc;
- X }
- X x += dx;
- X y += dy;
- X if( x > 15 || y > 15 ) break;
- X }
- X score *= mult;
- X if( placed == 7 && i == placed ) score += 50;
- X new_words[w].length = cptr;
- X new_words[w].letters[cptr] = '\0';
- X new_words[w].blankloc = blloc;
- X new_words[w].score = score;
- X if( i != placed || cptr != 1 ) w++;
- X }
- X }
- X return( w );
- X}
- X
- Xlong bin_search( word )
- X char *word;
- X{
- X long f, l, m;
- X int found;
- X
- X f = wlen[strlen( word )];
- X l = wlen[strlen( word ) + 1] - 1;
- X found = 0;
- X do {
- X m = ( f + l ) / 2;
- X if( strcmp( word, &(words[wptr[m]]) ) > 0 )
- X f = m + 1;
- X else if( strcmp( word, &(words[wptr[m]]) ) < 0 )
- X l = m - 1;
- X else {
- X found = 1;
- X f = m;
- X l = m;
- X }
- X } while( f < l );
- X if( strcmp( word, &(words[wptr[f]]) ) == 0
- X || strcmp( word, &(words[wptr[l]]) ) == 0 ) found = 1;
- X return( found );
- X}
- X
- Xdisplay_words( plr, newlet, nwords, placed )
- X int plr, nwords, placed;
- X struct plrlet (*newlet)[];
- X{
- X int i, j, xloc, score;
- X char c, tile, *word;
- X int x, y;
- X int illword, ind[8];
- X int shift;
- X
- X clear_turn();
- X clear_prompt();
- X move( 18, 0 );
- X printw( " %s made the following words:\n", you[plr] );
- X refresh();
- X score = 0;
- X illword = 0;
- X printw( " " );
- X xloc = 4;
- X for( i = 0; i < nwords; i++ ) {
- X word = &(new_words[i].letters[0]);
- X if( strlen( word ) + xloc + 2 > 79 ) {
- X printw( "\n " );
- X xloc = 4;
- X }
- X printw( "%s ", word );
- X score += new_words[i].score;
- X if( bin_search( word ) == 0 ) {
- X ind[illword++] = i;
- X }
- X }
- X move( 21, 0 );
- X if( illword != 0 ) {
- X if( plr != human_player ) {
- X printw( "*** Fatal error in display_words()\n" );
- X exit_window();
- X exit( 1 );
- X }
- X for( i = 0; i < illword; i++ ) {
- X clear_rect( 21, 0, 22, 79 );
- X printw( " %s is not in the computer's dictionary.\n",
- X &(new_words[i].letters[0]) );
- X printw( " Is it a valid Scrabble word (y/n)? " );
- X refresh();
- X do {
- X c = get_key();
- X } while( c != 'Y' && c != 'N' );
- X if( c == 'N' ) break;
- X clear_rect( 21, 0, 22, 79 );
- X printw( " Inserting %s into the dictionary...",
- X &(new_words[i].letters[0]) );
- X refresh();
- X add_dict( &(new_words[i].letters[0]) );
- X dict_changed = 1;
- X }
- X clear_rect( 21, 0, 22, 79 );
- X if( i == illword ) {
- X illword = 0;
- X } else {
- X printw( " For placing an invalid word, you score zero this round.\n" );
- X printw( " You remove your tiles from the board.\n" );
- X for( j = 0; j < placed; j++ )
- X plr_tiles[plr][((*newlet)[j]).tilepos] = ((*newlet)[j]).letter;
- X }
- X }
- X if( illword == 0 ) {
- X if( placed == 7 )
- X printw( " %s used all seven tiles!", you[plr] );
- X printw( " %s score this round is %3d.\n", your[plr], score );
- X plr_scores[plr] += score;
- X for( i = 0; i < placed; i++ ) {
- X x = ((*newlet)[i]).x;
- X y = ((*newlet)[i]).y;
- X tile = ((*newlet)[i]).letter;
- X if( tile == CH_BL ) {
- X tile = ((*newlet)[i]).blankchar;
- X if( b1x == 0 ) {
- X b1x = x;
- X b1y = y;
- X } else {
- X b2x = x;
- X b2y = y;
- X }
- X }
- X board[y][x] = tile;
- X }
- X for( i = 0, shift = 0; i < 7; i++ ) {
- X if( plr_tiles[plr][i] == 0 ) shift++;
- X else if( shift > 0 ) {
- X plr_tiles[plr][i - shift] = plr_tiles[plr][i];
- X plr_tiles[plr][i] = 0;
- X }
- X }
- X for( i = 7 - shift; i < 7; i++ ) {
- X tile = draw_tile();
- X if( tile == 0 ) break;
- X plr_tiles[plr][i] = tile;
- X }
- X move( 22, 0 );
- X if( tile == 0 && i == 7 - shift) {
- X if( plr != human_player )
- X printw( " There are no tiles left for %s to draw.\n", you[plr] );
- X else
- X printw( " There are no tiles left for you to draw.\n" );
- X } else {
- X if( tile == 0 ) {
- X printw( " %s can only draw ", you[plr] );
- X shift = i - ( 7 - shift );
- X } else {
- X printw( " %s dra%s ", you[plr],
- X ( ( plr == human_player ) ? "w" : "ws" ) );
- X }
- X printw( "%d til%s.\n", shift, ( shift == 1 ? "e" : "es" ) );
- X }
- X }
- X print_board();
- X print_tiles();
- X press_return();
- X}
- X
- Xadd_dict( word )
- X char *word;
- X{
- X int i, l;
- X long p1, p2;
- X
- X l = strlen( word );
- X for( p1 = wlen[l];
- X p1 < wlen[l + 1] && strcmp( word, &(words[wptr[p1]]) ) > 0;
- X p1++ );
- X for( p2 = dict_size - 1; p2 >= wptr[p1]; p2-- ) words[p2 + l + 1] = words[p2];
- X for( p2 = wlen[16]; p2 > p1; p2-- ) wptr[p2] = wptr[p2 - 1] + l + 1;
- X for( i = l + 1; i < 17; i++ ) wlen[i]++;
- X strcpy( &(words[wptr[p1]]), word );
- X dict_size += l + 1;
- X/* printw( "\n " );
- X for( p2 = p1 - 2; p2 < p1 + 3; p2++ )
- X printw( "%s ", &(words[wptr[p2]]) );
- X printw( "%s %s", &(words[wptr[wlen[8]]]), &(words[wptr[wlen[16] - 1]]) );
- X press_return(); */
- X}
- END_OF_FILE
- if test 6224 -ne `wc -c <'score.c'`; then
- echo shar: \"'score.c'\" unpacked with wrong size!
- fi
- # end of 'score.c'
- fi
- if test -f 'scrabble.6' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'scrabble.6'\"
- else
- echo shar: Extracting \"'scrabble.6'\" \(16325 characters\)
- sed "s/^X//" >'scrabble.6' <<'END_OF_FILE'
- X.\" @(#)scrabble.6 1.02 92/09/16 JAC
- X.TH SCRABBLE 6 "16 September 1992"
- X.SH NAME
- Xscrabble \- play the Scrabble(TM) board game
- X.SH SYNOPSIS
- X.B scrabble
- X.SH DESCRIPTION
- X.LP
- X.B scrabble
- Xis a computer version of the Selchow & Righter board game, Scrabble.
- XOnly one human player plays; the user may select the number of
- Xcomputer opponents, from one to three.
- X.SH BASIC SCRABBLE RULES
- X.LP
- XThe object of the game is to form English words in a
- Xcrossword\-like grid. Words are formed using
- X.I tiles,
- Xeach of which has a letter on it.
- XThe player with the highest score at the
- Xend of the game is the winner.
- X.LP
- XEach letter has a
- Xparticular score associated with it. For example, the letter
- X.B E
- Xis worth one point, while
- X.B Q
- Xis worth ten points. There are a fixed number of tiles with
- Xeach letter. For example, there are twelve
- X.B E
- Xtiles, and only one
- X.B Q
- Xtile. There are also two blank tiles, which
- Xmay be used as any letter. Once a blank tile is placed on the
- Xboard as a certain letter, that letter may not change.
- X.LP
- XEach player starts with seven tiles,
- Xwhich are placed in their
- X.I rack.
- XThese tiles are drawn from a shuffled pool of
- Xone hundred tiles.
- X.LP
- XThe first player to
- Xmove must play a word that covers the center square;
- Xas well, this player must place two or more of their
- Xtiles. After the first move,
- Xplayers take turns placing one or more of their tiles
- Xon the board, so as to form new words in the
- Xstandard crossword\-like manner: new words must read
- Xacross or down, not diagonally.
- X.LP
- XNew words may be formed one of three ways:
- X.TP
- X1.
- XBy adding a tiles to an already existing word, e.g.,
- Xadding
- X.B ABLE
- Xto
- X.B READ.
- X.TP
- X2.
- XBy adding tiles that intersect another word, e.g.,
- Xspelling
- X.B WARY
- Xby placing
- X.B W,
- X.B R,
- Xand
- X.B Y
- Xaround the
- X.B A
- Xof
- X.B REAL.
- X.TP
- X3.
- XBy spelling a word in one direction and forming
- Xnew words in the other direction, e.g., by adding
- X.B FOX
- Xnext to
- X.B PIG
- Xso that the
- X.B I
- Xof
- X.B PIG
- Xis used to spell
- X.B IF
- Xwith the
- X.B F
- Xfrom
- X.B FOX
- Xand, similarly, the
- X.B G
- Xis used to spell
- X.B GO.
- X.LP
- XIf all the new words formed are valid English words,
- Xthat player's score is increased by the value of the
- Xtiles in
- X.I all
- Xnew words formed. The player then draws new tiles from
- Xthe pool until the player again has seven tiles in his/her
- Xrack, or until there are no more tiles left to draw.
- X.LP
- XIf
- X.I any
- Xof the new
- Xwords formed are not valid English words, the player
- Xscores zero for that turn, and must remove the tiles just
- Xplaced from the board and replace them in his/her rack.
- X.LP
- XValid English words in Scrabble constitute any word so long
- Xas it is not an abbreviation (LTD, CORP), is not normally
- Xcapitalized (MATTHEW, LONDON), does not contain punctuation
- X(COLD\-HEARTED, CAN'T),
- Xand is not a prefix or suffix (PRE, ATION).
- XForeign words that are used frequently in English
- Xare allowed (words such as CIAO and QUO). Slang
- Xand colloquial words are also allowed.
- X.LP
- XOnce a tile has been placed on the board, it may not
- Xbe moved.
- X.LP
- XCertain board squares are special, in that they increase
- Xthe value of a letter or a word. Double and triple letter
- Xsquares increase the value of a tile by double and triple,
- Xrespectively. Double and triple word scores increase the
- Xvalue of a word by double and triple, respectively. Double
- Xand triple letter squares are counted
- X.I before
- Xdouble and triple word squares. These special squares only
- Xcount on the turn in which they are covered; the squares
- Xare no longer special in subsequent turns.
- X.LP
- XA player who uses all seven tiles on one turn gets a premium
- Xof fifty points on top of the regular score for that turn.
- X.LP
- XInstead of placing tiles, a player may forfeit his/her
- Xturn and draw between zero and seven new tiles. The player
- Xselects which of his/her tiles to replace, puts them back
- Xin the pool, and then draws the same number of tiles from
- Xthe pool again. A player doing this scores zero for that
- Xturn.
- X.LP
- XThe game ends when there are no tiles left to draw and
- Xone player has no tiles left to place,
- X.I or
- Xwhen no player can make a valid move. Each player's score
- Xis adjusted by subtracting from it
- Xthe value of each tile remaining
- Xin his/her own rack. As well, if one player uses all his/her
- Xtiles, his/her score is increased by the sum of all unplayed
- Xletters in the other players' racks. The player with the
- Xhighest score wins the game. In the event of a tie, the
- Xplayer with the highest score prior to the score adjustment
- Xis the winner.
- X.SH SCRABBLE SCREEN LAYOUT
- X.LP
- XThe upper\-left side of the screen lists the special board
- Xsymbols used in
- X.B scrabble.
- X.TP
- X\+
- XDouble letter score.
- X.TP
- X\#
- XTriple letter score.
- X.TP
- Xo
- XDouble word score.
- X.TP
- X\@
- XTriple word score.
- X.TP
- X*
- XBlank tile. This is the character displayed in a player's
- Xrack when he/she owns a blank tile. Once the tile is
- Xplaced on the board, it is shown in lower\-case as the letter
- Xit represents.
- X.LP
- XThe lower\-left side of the screen lists the value of each
- Xtile, as well as the total number of tiles of each type.
- XFor example, "A\-1, 9" means that there are a total of nine
- Xtiles with
- X.B A
- Xon them, and that each tile is worth one point.
- X.LP
- XThe center of the screen shows the
- X.B scrabble
- Xboard.
- X.LP
- XThe upper\-right of the screen displays the number of
- Xtiles left in the pool to draw. As well, it displays
- Xthe number of passed turns, if any.
- X.LP
- XThe central\-right of the screen shows all players'
- Xtile racks. The computer players' tiles are represented
- Xby dashes. As well, the computer players' skill levels
- Xare displayed in brackets next to their designations
- X(e.g., CPU1). Finally, each player's score is shown here.
- X.LP
- XThe lower\-right of the screen indicates the location of
- Xany blank tiles that have been placed on the board, as
- Xwell as the letter they represent.
- X.LP
- XThe bottom of the screen is the message and input area.
- X.SH PLAYING SCRABBLE
- X.LP
- XThe user must select the number of computer players
- Xto play against. Then, each player draws a tile.
- XThe player with the lowest tile alphabetically starts
- Xthe game. A blank tile is considered lower alphabetically
- Xthan all other letters.
- X.LP
- XThe user then selects the skill level of each
- Xcomputer player. Skill levels go from 1 (easy to beat)
- Xto 5 (hard to beat, but still possible), and skill level
- X6 ("expert mode") makes the computer player play its
- Xhighest\-scoring move every turn.
- X.LP
- XWhen it is the computer's turn to play, it searches the
- Xboard for a move. The cursor shows the square that the
- Xcomputer is thinking about playing on. After the search,
- Xthe computer chooses its move based on its skill level.
- XIf it could not find a move, it will say so.
- X.LP
- XWhen it is your turn to play, the cursor
- Xstarts at the upper\-left corner of the board. The following
- Xkeys may then be used.
- X.TP
- Xh
- XMoves the cursor left. If the cursor is on the left edge
- Xof the board, this key has no effect.
- X.TP
- Xj
- XMoves the cursor down. If the cursor is on the bottom edge
- Xof the board, this key has no effect.
- X.TP
- Xk
- XMoves the cursor up. If the cursor is on the top edge
- Xof the board, this key has no effect.
- X.TP
- Xl
- XMoves the cursor right. If the cursor is on the right edge
- Xof the board, this key has no effect.
- X.TP
- XRETURN
- XStarts placing tiles on the board. If the cursor is over
- Xa square that is already occupied by a tile, this key has
- Xno effect. More on this key below.
- X.TP
- XSPACE
- XRearrange your tiles. Sometimes it's easier to see what words
- Xyou can form if you group your tiles in your rack a certain
- Xway. This key allows you to regroup your tiles. Typing the
- Xletter of a tile in your rack moves it to the end of your rack.
- XUse the asterisk for a blank tile. Pressing RETURN exits this
- Xmode.
- X.TP
- X\\.
- XDraw new tiles. If you really hate the tiles in
- Xyour rack, or even if you
- Xdon't, you can replace none, some, or all of your tiles and
- Xdraw (potentially) new ones.
- XType this key, followed by the
- Xletters in your rack that you wish to replace. Pressing dash
- Xor DEL will put your most recent selection back in your rack.
- XPressing ESC will cancel this operation, and pressing RETURN
- Xwill ask you to confirm your selection.
- X.TP
- X.I Note
- X.I If you cannot move
- Xand wish to pass your turn,
- Xthen you must press the "Draw new tiles" key,
- Xand then draw zero new tiles.
- X.LP
- XOnce you press RETURN to start placing tiles, you can press
- Xeither
- X.I h
- Xor
- X.I v
- Xto place your tiles horizontally or vertically,
- Xrespectively.
- X.LP
- XThen, you simply begin typing. Each time you type a tile
- Xthat is in your rack, the tile is placed on the board at the
- Xcursor's position. The cursor then moves to the next blank
- Xsquare in the appropriate direction. If you type a letter
- Xthat is not in your rack, it is ignored
- X.I except
- Xif you have a blank tile. In this case, the blank tile is
- Xplaced on the board for you. If you type an asterisk and you
- Xhave a blank tile, it is placed on the board as usual.
- X.LP
- XWhile typing, you may press dash or DEL to remove the last
- Xtile placed from the board and put it back in your rack. Or, you
- Xmay press ESC to cancel this particular placement all together.
- XIf you're satisfied with what you've placed, you may press
- XRETURN. If you placed any blank tiles by typing asterisk, you
- Xwill be asked for the letters that the blank tiles represent.
- XPress RETURN to confirm your move, or
- X.I n
- Xto alter it.
- X.LP
- XYour words are then checked against the dictionary. If all
- Xthe words are in the dictionary, your score is increased and
- Xnew tiles are drawn for you. If any of your words are not
- Xin the dictionary, you are asked if said words are valid
- X.B scrabble
- Xwords. You are expected to answer honestly! If any word is
- Xinvalid, your tiles are removed from the board and replaced in
- Xyour rack. If the word is valid, it is added to the dictionary.
- XSo beware! The computer players can then use the word too.
- X.LP
- X.B scrabble
- Xdoes all the drawing of new tiles automatically. It also
- Xdoes all the scoring, including the score adjustments at the
- Xend of the game. It can even handle multiple\-way ties at the
- Xend of the game, should this unlikely event occur.
- X.LP
- XAt the end of the game, if any words have been added to
- Xthe dictionary,
- X.B scrabble
- Xwill ask you if you want to save the dictionary. If you
- Xsay yes, the old dictionary file is overwritten with the
- Xnew one. Otherwise, the original dictionary remains intact.
- X(The option of rewriting the dictionary is useful if you
- Xwere simply cheating and spelling really long garbage words
- Xfor the satisfaction of totally annihilating the computer.)
- X.LP
- XOne minor point: often throughout the game, you will be
- Xprompted to "Press <RETURN>". If you press the
- X.I q
- Xkey followed by RETURN, you will exit scrabble. This can
- Xbe safer than pressing an interrupt key to exit, which may
- Xmess up your window.
- X.SH COMPUTER PLAYERS' ALGORITHM
- X.LP
- XFor the curious, here is a brief description of how the
- Xcomputer players decide on their moves.
- X.LP
- XIf the board is empty, the computer simply searches the
- Xdictionary for any word whose length is between two and
- Xseven that can be formed with its tiles. It stores all
- Xpossibilities, and computes the score for all possible
- Xplacements of each word.
- X.LP
- XFor the remainder of this section, a
- X.I legal move
- Xis one which adjoins to the existing puzzle.
- X.LP
- XThe computer players do an exhaustive search of the board,
- Xfinding all positions in which a legal move can be made.
- X.LP
- XAt each square, the computer determines how many of its tiles
- Xit can place and still be a legal move. This can be anywhere
- Xbetween one and seven tiles, inclusive. For example, the
- Xcomputer might be able to place any number of tiles between
- Xthree and seven, and still be making a legal move. The computer
- Xthen performs an exhaustive dictionary search for each of
- Xthese numbers of tiles. In the example, the computer would
- Xperform five exhaustive searches.
- X.LP
- XThe searching algorithm prunes the search tree in three ways.
- X.TP
- X1.
- XFor a given number of tiles to be placed (say three),
- Xall words formed will be of the same length (say four). Thus,
- Xthe computer only need search all four\-letter words.
- X.TP
- X2.
- XOften one or more of the letters in the new word to be formed
- Xwill be fixed, because the computer might be adding to
- Xa word that has already been placed on the board. For example,
- Xif the word
- X.B WENT
- Xis on the board horizontally, the computer might be trying
- Xto add a word vertically to the
- X.B N.
- XThus, any
- Xword that does not have the fixed letter(s) in the proper
- Xplace(s) can be eliminated right away.
- X.TP
- X3.
- XThe computer might be forming other words in the opposite
- Xdirection to which it is placing tiles.
- XFor example, suppose the computer
- Xis trying to form a word horizontally with three tiles.
- XFurthermore, suppose that its first tile has to adjoin
- Xto a vertical word such as
- X.B PIT.
- XThen, the computer checks
- Xif it can form a valid word of the form
- X.B PIT_
- X(where the
- Xunderscore represents an unknown tile) before the
- Xexhaustive search. In this case, the computer would
- Xhave to own an
- X.B A,
- X.B H,
- X.B S,
- Xor
- X.B Y
- Xto form
- X.B PITA,
- X.B PITH,
- X.B PITS,
- Xor
- X.B PITY.
- XOtherwise, the search would be abandoned.
- X.LP
- XThe computer stores all possible moves in a linked list sorted
- Xfrom highest\-scoring move to lowest\-scoring move. Once the
- Xsearch is complete, the computer then selects a move. In expert
- Xmode (level 6), the computer merely chooses the move at the
- Xhead of the list. On the other levels, the computer picks
- Xa move using a normal p.d.f. The mean of the distribution is
- Xplaced close to the highest\-scoring move on level 5, and
- Xsort of close to the lowest\-scoring move on level 1. The standard
- Xdeviation of the distribution is one\-fifth of the number
- Xof distinct scores that each move might give. For example,
- Xthe computer might be able to make moves that would give it
- X4, 6, 7, 9, or 10 points. In this case, the standard deviation
- Xwould be one.
- X.SH FILES
- X.TP
- Xscrabble
- XThis is the executable file.
- X.TP
- Xscrabbledict
- XThis is the dictionary file.
- X.SH DICTIONARY FILES
- X.LP
- XIf desired, the user may supply his/her own version of
- Xthe dictionary file.
- XThe dictionary file must have the following properties:
- X.TP
- X1.
- XIt must be sorted from shortest words (two letters)
- Xto longest words (fifteen letters).
- X.TP
- X2.
- XWithin each word length, the words must be sorted
- Xalphabetically from A to Z.
- X.TP
- X3.
- XWords
- X.I must
- Xbe all capitals.
- X.B scrabble
- Xignores any word that contains
- Xpunctuation, as well as any word longer than
- Xfifteen characters.
- X.SH AUTHOR
- X.LP
- X.B scrabble
- Xwas written by James A. Cherry, at Carleton University,
- XOttawa, Ontario, Canada. Questions, comments, etc., may
- Xbe addressed to jac@doe.carleton.ca.
- X.SH BUGS
- X.LP
- XThe computer search algorithm is highly inelegant. It is
- Xsimply brute\-force.
- X.LP
- X.B scrabble
- Xis a complete pig for memory; it stores the entire dictionary
- Xin memory for fast searching. Also, every possible computer
- Xmove on a given turn is stored; no moves are erased until the
- Xcomputer has decided on its move. Since it is sometimes
- Xpossible to make 3,000 or more moves, the move list occupies
- Xa large chunk of memory.
- X.LP
- XIf you play a garbage word, and tell the computer that it really
- Xis a word, it will believe you.
- X.LP
- XThe whole concept of challenging another
- Xplayer's word is non\-existent in
- X.B scrabble.
- XThis is unfortunate, as it is an important part of the game.
- XThe computer players only spell words that are in the dictionary.
- XThey never try to "pull a fast one" on you. Likewise, if the
- Xcomputer plays a word that you're
- X.I sure
- Xis not a valid
- X.B scrabble
- Xword, it will not allow you to challenge it. After all, the
- Xword was in the dictionary, so it
- X.I must
- Xbe valid. (Yeah, right.) Perhaps removing the offending
- Xword from the dictionary at the end of the game is the solution.
- X.LP
- XIn expert mode, the computers are practically impossible to beat.
- X.LP
- XThere is no way to get the computer to suggest a move for you.
- X.LP
- XOn any level but expert, the computer players tend to keep their
- XQ and Z tiles right until the end; this means they lose a lot of
- Xpoints after the game is over. Even a bad human player would try
- Xto get rid of these high\-scoring tiles quickly, but the computer's
- Xalgorithm does not allow it to.
- X.LP
- XInterrupt characters are not caught, and they might mess up your
- Xwindow to the point that it is no longer usable.
- X.LP
- XIf something bad happens (like an interrupt character) while
- X.B scrabble
- Xis re\-writing the dictionary, the dictionary file might be lost.
- END_OF_FILE
- if test 16325 -ne `wc -c <'scrabble.6'`; then
- echo shar: \"'scrabble.6'\" unpacked with wrong size!
- fi
- # end of 'scrabble.6'
- fi
- if test -f 'smain.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'smain.c'\"
- else
- echo shar: Extracting \"'smain.c'\" \(7661 characters\)
- sed "s/^X//" >'smain.c' <<'END_OF_FILE'
- X/*
- X *
- X * smain.c -- main program
- X *
- X */
- X
- X#include "scrab.h"
- X#include "globals.h"
- X
- X
- Xset_up_window() {
- X int xsize, ysize;
- X WINDOW *screen;
- X
- X screen = initscr();
- X refresh();
- X if( screen->_maxx < 80 || screen->_maxy < 24 ) {
- X endwin();
- X fprintf( stderr, "Need at least a 24x80 screen\n" );
- X exit( 1 );
- X }
- X cbreak();
- X noecho();
- X}
- X
- Xexit_window() {
- X char c;
- X
- X move( 23, 0 );
- X printw( "Press any key to end? " );
- X refresh();
- X c = getch();
- X endwin();
- X}
- X
- Xinit_board() {
- X int i, j;
- X
- X for( i = 1; i < 16; i++ )
- X for( j = 1; j < 16; j++ )
- X board[i][j] = CH_EM;
- X board[1][1] = CH_TW;
- X board[8][1] = CH_TW;
- X board[8][8] = CH_DW;
- X for( i = 2; i < 6; i++ ) {
- X board[i][i] = CH_DW;
- X }
- X board[2][6] = CH_TL;
- X board[6][2] = CH_TL;
- X board[6][6] = CH_TL;
- X board[1][4] = CH_DL;
- X board[4][1] = CH_DL;
- X board[3][7] = CH_DL;
- X board[7][3] = CH_DL;
- X board[8][4] = CH_DL;
- X board[7][7] = CH_DL;
- X for( i = 1; i < 9; i++ )
- X for( j = 1; j < 8; j++ ) {
- X board[16-j][i] = board[i][j];
- X board[16-i][16-j] = board[i][j];
- X board[j][16-i] = board[i][j];
- X }
- X}
- X
- Xprint_info() {
- X move( INFO_Y , INFO_X );
- X printw( "Special symbols:" );
- X move( INFO_Y + 1, INFO_X + 2 );
- X printw( "%c: Double letter score", CH_DL );
- X move( INFO_Y + 2, INFO_X + 2 );
- X printw( "%c: Triple letter score", CH_TL );
- X move( INFO_Y + 3, INFO_X + 2 );
- X printw( "%c: Double word score", 'o' );
- X move( INFO_Y + 4, INFO_X + 2 );
- X printw( "%c: Triple word score", CH_TW );
- X move( INFO_Y + 5, INFO_X + 2 );
- X printw( "%c: Blank tile", CH_BL );
- X move( INFO_Y + 7, INFO_X );
- X printw( "Tile values & distributions:" );
- X move( INFO_Y + 8, INFO_X + 2 );
- X printw( "A-1, 9 H-4, 2 O-1, 8 V-4, 2" );
- X move( INFO_Y + 9, INFO_X + 2 );
- X printw( "B-3, 2 I-1, 9 P-3, 2 W-4, 2" );
- X move( INFO_Y +10, INFO_X + 2 );
- X printw( "C-3, 2 J-8, 1 Q10, 1 X-8, 1" );
- X move( INFO_Y +11, INFO_X + 2 );
- X printw( "D-2, 4 K-5, 1 R-1, 6 Y-4, 2" );
- X move( INFO_Y +12, INFO_X + 2 );
- X printw( "E-1,12 L-1, 4 S-1, 4 Z10, 1" );
- X move( INFO_Y +13, INFO_X + 2 );
- X printw( "F-4, 2 M-3, 2 T-1, 6 %c-0, 2", CH_BL );
- X move( INFO_Y +14, INFO_X + 2 );
- X printw( "G-2, 3 N-1, 6 U-1, 4" );
- X refresh();
- X}
- X
- Xinit_tiles() {
- X int i, j;
- X
- X for( i = 0; i < 27; i++ )
- X tiles_left[i] = letters[i].tiles;
- X for( i = 0; i < 4; i++ )
- X for( j = 0; j < 7; j++ )
- X plr_tiles[i][j] = 0;
- X b1x = 0;
- X b2x = 0;
- X b1y = 0;
- X b2y = 0;
- X normal_sum = 0;
- X for( i = 0; i < 40; i++ ) normal_sum += normal_dist[i];
- X}
- X
- Xget_num_players() {
- X char c;
- X int i, j;
- X char ft[4], cs[7];
- X
- X clear_prompt();
- X printw( " Number of computer players (1-3)? " );
- X refresh();
- X for( ;; ) {
- X c = getch();
- X if( c >= '1' && c <= '3' ) break;
- X }
- X players = c - '0' + 1;
- X for( ;; ) {
- X init_tiles();
- X for( i = 0; i < players; i++ ) ft[i] = draw_tile();
- X for( i = 1; i < players; i++ )
- X if( ft[0] == ft[i] ) break;
- X if( i != players ) continue;
- X move( 20, 0 );
- X printw( " All players draw a tile. You: %c", ft[0] );
- X for( i = 1; i < players; i++ ) {
- X printw( " Player %d: %c", i + 1, ft[i] );
- X if( ft[i] == CH_BL ) ft[i] = 'A' - 1;
- X }
- X j = players;
- X for( i = 1; i < players; i++ )
- X if( ft[0] < ft[i] ) j--;
- X if( j == 1 ) strcpy( cs, "first" );
- X if( j == 2 ) strcpy( cs, "second" );
- X if( j == 3 ) strcpy( cs, "third" );
- X if( j == 4 ) strcpy( cs, "fourth" );
- X printw( "\n You will play %s.", cs );
- X human_player = j - 1;
- X print_tiles_left( 100 );
- X press_return();
- X clear_prompt();
- X refresh();
- X break;
- X }
- X
- X init_tiles();
- X j = '1';
- X for( i = 0; i < 4; i++ ) {
- X if( i == human_player ) {
- X strcpy( &(your[i][0]), "Your" );
- X strcpy( &(you[i][0]), "You" );
- X } else {
- X strcpy( &(your[i][0]), "CPU 's" );
- X strcpy( &(you[i][0]), "CPU " );
- X your[i][3] = j;
- X you[i][3] = j++;
- X }
- X plr_skills[i] = 0;
- X }
- X
- X for( i = 0; i < players; i++ ) {
- X print_tiles();
- X if( i == human_player ) continue;
- X clear_prompt();
- X printw( " Select skill level 1-%d for %s, where 1 is beginner, %d is advanced, and\n", SKILL_EXPERT, you[i], SKILL_LEVELS );
- X printw( " %d is expert. -> ", SKILL_EXPERT );
- X refresh();
- X for( ;; ) {
- X c = getch();
- X if( c >= '1' && c <= '6' ) break;
- X }
- X plr_skills[i] = c - '0';
- X }
- X
- X for( i = 0; i < players; i++ ) {
- X plr_scores[i] = 0;
- X for( j = 0; j < 7; j++ )
- X plr_tiles[i][j] = draw_tile();
- X }
- X print_tiles();
- X}
- X
- Xend_game() {
- X int i, j;
- X int adj[4], wbs, wb[4], was, wa[4];
- X long p1;
- X FILE *fp;
- X char c;
- X
- X clear_turn();
- X printw( "*** GAME OVER\n" );
- X print_tiles();
- X clear_prompt();
- X printw( " Here are the score adjustments: " );
- X wbs = -1;
- X for( i = 0; i < players; i++ )
- X if( plr_scores[i] > wbs ) wbs = plr_scores[i];
- X for( i = 0; i < players; i++ ) {
- X if( plr_scores[i] == wbs ) wb[i] = 1;
- X else wb[i] = 0;
- X }
- X for( i = 0; i < players; i++ ) {
- X adj[i] = 1;
- X for( j = 0; j < 7; j++ ) {
- X c = plr_tiles[i][j];
- X if( c != 0 ) {
- X if( adj[i] == 1 ) adj[i] = 0;
- X if( c != CH_BL ) adj[i] -= letters[c - 'A'].points;
- X }
- X }
- X }
- X for( j = 0; j < players; j++ )
- X if( adj[j] == 1 ) break;
- X if( j < players ) {
- X adj[j] = 0;
- X for( i = 0; i < players; i++ )
- X if( i != j ) adj[j] -= adj[i];
- X }
- X for( i = 0; i < players; i++ ) {
- X move( 19 + i, 36 );
- X if( i == human_player ) addch( ' ' );
- X printw( "%s: %d", you[i], adj[i] );
- X plr_scores[i] += adj[i];
- X }
- X was = -1;
- X for( i = 0; i < players; i++ )
- X if( plr_scores[i] > was ) was = plr_scores[i];
- X for( i = 0; i < players; i++ ) {
- X if( plr_scores[i] == was ) wa[i] = 1;
- X else wa[i] = 0;
- X }
- X press_return();
- X print_tiles();
- X clear_prompt();
- X move( 20, 0 );
- X was = 0;
- X for( i = 0; i < players; i++ ) was += wa[i];
- X wbs = 0;
- X for( i = 0; i < players; i++ ) wbs += wb[i];
- X if( was == 1 || wbs == 1 ) {
- X if( was == 1 ) {
- X for( i = 0; i < players; i++ )
- X if( wa[i] == 1 ) break;
- X } else {
- X for( i = 0; i < players; i++ )
- X if( wb[i] == 1 ) break;
- X }
- X printw( " And the winner is: %s!", you[i] );
- X } else {
- X printw( " It was a tie between: " );
- X wbs = 1;
- X for( i = 0; i < players; i++ )
- X if( wa[i] == 1 ) {
- X if( wbs < was - 1 ) printw( ", " );
- X else {
- X if( was > 2 ) printw( ", and " );
- X else printw( " and " );
- X }
- X printw( "%s", you[i] );
- X wbs++;
- X }
- X printw( "!" );
- X }
- X refresh();
- X if( dict_changed == 1 ) {
- X press_return();
- X clear_prompt();
- X printw( " The computer's dictionary was modified this game.\n" );
- X printw( " Would you like to save the new dictionary (y/n)? " );
- X refresh();
- X do {
- X c = get_key();
- X } while( c != 'Y' && c != 'N' );
- X if( c == 'Y' ) {
- X printw( "\n\n Writing new dictionary..." );
- X refresh();
- X fp = fopen( DICT_FILE, "w+" );
- X if( fp == NULL ) {
- X printw( "error writing new dictionary!\n" );
- X exit_window();
- X exit( 1 );
- X }
- X for( p1 = 0; p1 < wlen[16]; p1++ )
- X fprintf( fp, "%s\n", &(words[wptr[p1]]) );
- X fclose( fp );
- X }
- X }
- X}
- X
- Xint main() {
- X int plr;
- X int i;
- X
- X set_up_window();
- X clear();
- X printw( "*** SCRABBLE 1.21 ***\n\n" );
- X
- X read_words();
- X dict_changed = 0;
- X
- X clear();
- X printw( "*** SCRABBLE 1.21 ***\n\n" );
- X
- X init_board();
- X seed_random();
- X print_board();
- X print_info();
- X get_num_players();
- X
- X game_done = 0;
- X abort = 0;
- X do {
- X for( plr = 0; plr < players; plr++ ) {
- X clear_turn();
- X printw( "*** %s turn to play ", your[plr] );
- X if( plr == human_player ) {
- X player_move();
- X } else {
- X computer_move( plr );
- X }
- X if( abort != 0 ) break;
- X if( game_done == 0 ) clear_rect( 1, 50, 1, 79 );
- X else {
- X move( 1, 64 );
- X printw( "Passed turns: %d", game_done );
- X }
- X refresh();
- X if( game_done == players ) break;
- X for( i = 0; i < 7; i++ )
- X if( plr_tiles[plr][i] != 0 ) break;
- X if( i == 7 ) {
- X game_done = players;
- X break;
- X }
- X }
- X } while( game_done < players && abort == 0 );
- X
- X if( abort == 0 ) end_game();
- X exit_window();
- X}
- END_OF_FILE
- if test 7661 -ne `wc -c <'smain.c'`; then
- echo shar: \"'smain.c'\" unpacked with wrong size!
- fi
- # end of 'smain.c'
- fi
- echo shar: End of archive 18 \(of 18\).
- cp /dev/null ark18isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 18 archives.
- echo "now type ./blddict.sh to build dictionary file"
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-