/*
 *
 * score.c -- find score for a turn
 *
 */

#include "scrab.h"
#include "globals.h"


int find_new_words( newlet, placed, xinc, yinc )
  struct plrlet (*newlet)[];
  int placed, xinc, yinc;
{
	struct plrlet *currlet;
	int i, w, j;
	int dx, dy;
	int x, y;
	int score, mult, tsc, cptr, blloc;
	char c, ch;

	w = 0;
	dx = 1 - xinc;
	dy = 1 - yinc;
	for( i = 0; i <= placed; i++ ) {
		if( i < placed ) {
			currlet = &((*newlet)[i]);
			x = currlet->x;
			y = currlet->y;
		} else {
			x = ((*newlet)[0]).x;
			y = ((*newlet)[0]).y;
			dx = xinc;
			dy = yinc;
		}
		if( ( y - dy > 0 && x - dx > 0 && board[y - dy][x - dx] >= 'A' )
		  || ( y + dy < 16 && x + dx < 16 && board[y + dy][x + dx] >= 'A' )
		  || i == placed ) {
			while( board[y - dy][x - dx] >= 'A' && x - dx > 0 && y - dy > 0 ) {
				x -= dx;
				y -= dy;
			}
			new_words[w].startx = x;
			new_words[w].starty = y;
			new_words[w].dir = dy;
			score = 0;
			mult = 1;
			cptr = 0;
			blloc = -1;
			for( ;; ) {
				c = board[y][x];
				if( c >= 'A' ) {
					if( ( x != b1x || y != b1y ) && ( x != b2x || y != b2y ) )
						score += letters[c - 'A'].points;
					new_words[w].letters[cptr++] = c;
				} else {
					for( j = 0; j < placed; j++ )
						if( x == ((*newlet)[j]).x && y == ((*newlet)[j]).y )
							break;
					if( j == placed ) break;
					if( blloc == -1 ) blloc = cptr;
					else blloc = -2;
					ch = ((*newlet)[j]).letter;
					if( ch == CH_BL ) {
						tsc = 0;
						new_words[w].letters[cptr++] = ((*newlet)[j]).blankchar;
					} else {
						tsc = letters[ch - 'A'].points;
						new_words[w].letters[cptr++] = ch;
					}
					if( c == CH_DL ) tsc *= 2;
					else if( c == CH_TL ) tsc *= 3;
					else if( c == CH_DW ) mult *= 2;
					else if( c == CH_TW ) mult *= 3;
					score += tsc;
				}
				x += dx;
				y += dy;
				if( x > 15 || y > 15 ) break;
			}
			score *= mult;
			if( placed == 7 && i == placed ) score += 50;
			new_words[w].length = cptr;
			new_words[w].letters[cptr] = '\0';
			new_words[w].blankloc = blloc;
			new_words[w].score = score;
			if( i != placed || cptr != 1 ) w++;
		}
	}
	return( w );
}

long bin_search( word )
  char *word;
{
	long f, l, m;
	int found;

	f = wlen[strlen( word )];
	l = wlen[strlen( word ) + 1] - 1;
	found = 0;
	do {
		m = ( f + l ) / 2;
		if( strcmp( word, &(words[wptr[m]]) ) > 0 )
			f = m + 1;
		else if( strcmp( word, &(words[wptr[m]]) ) < 0 )
			l = m - 1;
		else {
			found = 1;
			f = m;
			l = m;
		}
	} while( f < l );
	if( strcmp( word, &(words[wptr[f]]) ) == 0 
		|| strcmp( word, &(words[wptr[l]]) ) == 0 ) found = 1;
	return( found );
}

display_words( plr, newlet, nwords, placed )
  int plr, nwords, placed;
  struct plrlet (*newlet)[];
{
	int i, j, xloc, score;
	char c, tile, *word;
	int x, y;
	int illword, ind[8];
	int shift;

	clear_turn();
	clear_prompt();
	move( 18, 0 );
	printw( "  %s faris tiujn vortojn:\n", you[plr] );
	refresh();
	score = 0;
	illword = 0;
	printw( "    " );
	xloc = 4;
	for( i = 0; i < nwords; i++ ) {
		word = &(new_words[i].letters[0]);
		if( strlen( word ) + xloc + 2 > 79 ) {
			printw( "\n    " );
			xloc = 4;
		}
		printw( "%s  ", word );
		score += new_words[i].score;
		if( bin_search( word ) == 0 ) {
			ind[illword++] = i;
		}
	}
	move( 21, 0 );
	if( illword != 0 ) {
		if( plr != human_player ) {
			printw( "*** Morta eraro en display_words()\n" );
			exit_window();
			exit( 1 );
		}
		for( i = 0; i < illword; i++ ) {
			clear_rect( 21, 0, 22, 79 );
			printw( "  %s ne enestas la komputilan vortaron.\n",
			  &(new_words[i].letters[0]) );
			printw( "  Cxu gxi ja estas vorto (j/n)? " );
			refresh();
			do {
				c = get_key();
			} while( c != 'J' && c != 'N' );
			if( c == 'N' ) break;
			clear_rect( 21, 0, 22, 79 );
			printw( "  Enmetante %s en la vortaron...",
			  &(new_words[i].letters[0]) );
			refresh();
			add_dict( &(new_words[i].letters[0]) );
			dict_changed = 1;
		}
		clear_rect( 21, 0, 22, 79 );
		if( i == illword ) {
			illword = 0;
		} else {
			printw( "  Pro meti malgxustan vorton, vi ne gajnas poentojn cxi-foje.\n" );
			printw( "  Vi forprenu viajn literojn de la tabulo.\n" );
			for( j = 0; j < placed; j++ )
				plr_tiles[plr][((*newlet)[j]).tilepos] = ((*newlet)[j]).letter;
		}
	}
	if( illword == 0 ) {
		if( placed == 7 )
			printw( "  %s uzis cxiu sep literojn!", you[plr] );
		printw( "  %s poentoj cxi-vice estas %3d.\n", your[plr], score );
		plr_scores[plr] += score;
		for( i = 0; i < placed; i++ ) {
			x = ((*newlet)[i]).x;
			y = ((*newlet)[i]).y;
			tile = ((*newlet)[i]).letter;
			if( tile == CH_BL ) {
				tile = ((*newlet)[i]).blankchar;
				if( b1x == 0 ) {
					b1x = x;
					b1y = y;
				} else {
					b2x = x;
					b2y = y;
				}
			}
			board[y][x] = tile;
		}
		for( i = 0, shift = 0; i < 7; i++ ) {
			if( plr_tiles[plr][i] == 0 ) shift++;
			else if( shift > 0 ) {
				plr_tiles[plr][i - shift] = plr_tiles[plr][i];
				plr_tiles[plr][i] = 0;
			}
		}
		for( i = 7 - shift; i < 7; i++ ) {
			tile = draw_tile();
			if( tile == 0 ) break;
			plr_tiles[plr][i] = tile;
		}
		move( 22, 0 );
		if( tile == 0 && i == 7 - shift) {
			if( plr != human_player )
				printw( "  Ne plu estas literoj por %s preni.\n", you[plr] );
			else
				printw( "  Ne plu estas literoj por vi preni.\n" );
		} else {
			if( tile == 0 ) {
				printw( "  %s povas preni nur ", you[plr] );
				shift = i - ( 7 - shift );
			} else {
				printw( "  %s prenas ", you[plr]);
			}
			printw( "%d litero%s.\n", shift, ( shift == 1 ? "n" : "jn" ) );
		}
	}
	print_board();
	print_tiles();
	press_return();
}

add_dict( word )
  char *word;
{
	int i, l;
	long p1, p2;

	l = strlen( word );
	for( p1 = wlen[l];
		  p1 < wlen[l + 1] && strcmp( word, &(words[wptr[p1]]) ) > 0;
		  p1++ );
	for( p2 = dict_size - 1; p2 >= wptr[p1]; p2-- ) words[p2 + l + 1] = words[p2];
	for( p2 = wlen[16]; p2 > p1; p2-- ) wptr[p2] = wptr[p2 - 1] + l + 1;
	for( i = l + 1; i < 17; i++ ) wlen[i]++;
	strcpy( &(words[wptr[p1]]), word );
	dict_size += l + 1;
/*	printw( "\n  " );
	for( p2 = p1 - 2; p2 < p1 + 3; p2++ )
		printw( "%s  ", &(words[wptr[p2]]) );
	printw( "%s  %s", &(words[wptr[wlen[8]]]), &(words[wptr[wlen[16] - 1]]) );
	press_return(); */
}
