/* JL == Jon Lundy     */
/* DG == David Gilliam */

#include "plateau.h" 
 
extern int captureno;
extern struct piece pieces[24];
extern struct square stack;
extern struct square board[4][4];
 
 
/*  User functions  */
 
struct gameinfo *select_game();
char *select_move();
void begin_game();
int endgame();
void finish_move();
int review();
void delete_game();
 
/*  Onboard functions  */
 
int onboard_piece();
 
/*  Move functions  */
 
int move_piece();
int select_initial_square();
int flip_check();
int select_final_square();
int middle_squares();
void in_between();
int final_square();
int capture_check();
int get_or_drop();
 
/*  Prisoner exchange functions */
 
int initial_offer();
int count_offer();
int counter_offer();
int must_offer();
void accept_exchange();
void reject_exchange();
int select_prisoners();
 
/* Functions from outside this module */
 
FILE *open_gamefile();
struct gameinfo *read_gameinfo();
 
main()
{   
    struct gameinfo game,tempgame;
    char move_so_far[80];
    char buffer[80];
    int counter,i;
    FILE *fptr,*gptr;
 
    initialize();   
    do
    {   do
	   list_gameinfo();
	while (select_game(&game) == NULL);
 
	fptr = open_gamefile(game.name);
	read_position(&game,fptr);
	cpstruct(game,&tempgame);
	
/*	boardinit();*/
 
	if (review(&tempgame,game,fptr) != 0)
	{   read_position(&game,fptr);
	    display(&game);
	   
	    if (game.status == 'o') 
	    {	counter = counter_offer(&game,move_so_far,count_offer());
		if (counter == 0)
		{   reject_exchange(move_so_far);
		    (game.moveno)--;
		    game.status = 'p';
		}
		else
		{   accept_exchange();
		    game.status = 'p';
		}
	    }
	    else if (game.status == 'p')
	    {	strcpy(move_so_far,"");
		captureno = 0;
		if (select_move(&game,move_so_far) != NULL)
		{   (game.moveno)++;
		    display(&game);
		    enterline("Do you wish to send this move? ",buffer);
		    if (tolower(*buffer) != 'y')
			game.status = 'c';
		    else
		    {   
			for (i=0;i<24;i++)
		        {   if (pieces[i].status == to_be_captured)
			        pieces[i].status = captured;
			    if (pieces[i].revealed == to_be_top)
			        pieces[i].revealed = top;
		        }
			captureno = 0;
			if (endgame(&game) == 1)
			{   scroll();
			    drawline("You won the game!");
			}
		    
		    }
		}
		else
		    game.status = 'c';
	    }
	
	    if (game.status != 'c')
	    {   display(&game);
		if (fseek(fptr,0L,2) == -1)
		{   scroll();
		    drawline("Error at end of file.");
		    exit(3);
		}
		enterline("Do you wish to send a message to the other player? ",buffer);
		if (tolower(*buffer) == 'y')
		{   if ((gptr = fopen("comments","w")) == NULL)
		    {   scroll();
			drawline("Cannot make comment file.");
			exit(0);
		    }
		    scroll();
		    drawline("Enter your comments--a blank line to end.");
		    scroll();
		    do
		    {   entercomment(buffer);
			if (strcmp(buffer,"") != 0)
			    fprintf(gptr,"Opp> %s\n",buffer);
		    } while (strcmp(buffer,"") != 0);
		    fprintf(gptr,"---\n");
		    fclose(gptr);
		}
		enterline("Do you wish to write a note to yourself? ",buffer);
		if (tolower(*buffer) == 'y')
		    game.comments = 'y';
		else
		    game.comments = 'n';	
		if (fprintf(fptr,"PLATEAU!%s:%d:%c:%c\n",game.name,
			game.moveno,game.status,game.comments) == EOF)
		{
			printf("Help me!!!!!!!!!!\n");
			exit(0);
		}
		fprintf(fptr,"-----\n");
		write_position(fptr);
		if (tolower(*buffer) == 'y')
		{ 
		    scroll();
		    drawline("Enter your comments--a blank line to end.");
		    scroll();
		    do
		    { 
			entercomment(buffer);
			if (strcmp(buffer,"") != 0)
			    fprintf(fptr,"Me> %s\n",buffer);
		    } while (strcmp(buffer,"") != 0);
		    fprintf(fptr,"---\n");
		}
		update_gameinfo(&game,0);
		generate_file(&game);
	    }
	    else
	    	game.status = 'p';
	}
	fclose(fptr);
/*    closegraph();*/
    } while (1);
}
				
struct gameinfo *select_game(game)
struct gameinfo *game;
{   FILE *fptr;
    char buffer[80];
 
    printf("\nPlease enter the name of the game you would like to play. \n");
    printf("type 'begin' to begin a new game, or 'delete' to delete a game: ");
    gets(buffer);
 
    if (strcmp(buffer,"begin") == 0)
    {   begin_game();
	return (NULL);
    }
 
    if (strcmp(buffer,"exit") == 0)
	exit(1);
 
    if (strcmp(buffer,"delete") == 0)
    {   delete_game();
	return (NULL);
    }
 
 
    if ((fptr = fopen("board.cfg","r")) == NULL)
    {   fprintf(stderr,"Cannot open file for reading.\n");
	exit(5);
    }
 
 
    while (read_gameinfo(game,fptr) != (struct gameinfo *)NULL)
    {   if (strcmp(game->name,buffer) == 0)
	{   fclose(fptr);
	    return game;
	}
    }
    
    printf("I can't find that game on the disk.\n");
    fclose(fptr);
    return (NULL);
}                              
 
void delete_game()
{   char buffer[80];
    struct gameinfo *game;
    FILE *fptr;
 
    if ((fptr = fopen("board.cfg","r")) == NULL)
    {   printf("Cannot open 'board.cfg' file.\n");
	printf("Exiting...\n");
	exit(5);
    }
 
    printf("Which game would you like to delete? ");
    fgets(buffer,80,stdin);
    strtok(buffer,"\n");
    while (read_gameinfo(game,fptr) != (struct gameinfo *) NULL)
    {	if (strcmp(game->name,buffer) == 0)
	{   fclose(fptr);
	    printf("Are you sure? (y/n) ");
	    fgets(buffer,80,stdin);
	    if (tolower(*buffer) == 'y')
	    {   update_gameinfo(game,1);
		printf("Game removed from 'board.cfg' file.\n");
		return;
	    }
	    else
		return;
	}
    }
 
    printf("I can't find that game on the disk.\n");
    fclose(fptr);
    return;
}
 
void begin_game()
{   FILE *fptr;
    FILE *gptr;
    struct gameinfo newgame;
    char buffer[80];
    struct gameinfo game;
 
    do
    {	printf("Please enter name for new game: ");
	gets(buffer);
	if (strlen(buffer) >= 9)
	    printf("8 char maximum for file name.\n");
    } while (strlen(buffer) >= 9);
    strcpy(newgame.name,buffer);
 
    do
    {   printf("Enter opponent's name: ");
		gets(buffer);
	if (strlen(buffer) >= 49)
	    printf("49 char maximum for name.\n");
    } while (strlen(buffer) >= 49);
    strcpy(newgame.opp_address,buffer);
 
    do
    {   printf("Please enter color you will play (b or w): ");
		gets(buffer);
    } while ((tolower(*buffer) != 'b') && (tolower(*buffer) != 'w'));
 
    if (tolower(*buffer) == 'b')
		newgame.color = black;
	else
		newgame.color = white;
 
    newgame.moveno = 0;
    newgame.status = 'p';
 
    printf("Are you sure this is correct (y or n)? ");
    gets(buffer);
    if (tolower(*buffer) == 'y')
    {   if ((fptr = fopen("board.cfg","r")) == NULL)
		{   printf("Cannot open board file.\n");
			return;
		}
		else
		{       if ((gptr = fopen("board.cf2","w")) == NULL)
			{   printf("Cannot add game.\n");
			    return;
			}
			
			while ((read_gameinfo(&game,fptr) != NULL))
			   write_gameinfo(&game,gptr);
			fclose(fptr);
			write_gameinfo(&newgame,gptr);
			printf("\nThe new game has been opened.\n");
			fclose(gptr);
 
			if ((gptr = fopen(newgame.name,"w")) == NULL)
			{   printf("Cannot open new game file...\n");
				exit(4);
			}
			else
			{   fprintf(gptr,"PLATEAU!%s:0:p:n\n",newgame.name);
				fprintf(gptr,"-----\n");
				init_pos(gptr);
				fclose(gptr);
			}
			fclose(fptr);
/*
			system("copy board.cf2 board.cfg");
			system("del board.cf2");
*/
			system("mv board.cf2 board.cfg");
		}
    }
    return;
}
 
char *select_move(gameptr,move_so_far)
struct gameinfo *gameptr;
char move_so_far[80];
{   char buffer[80];
    int o;
    
    if (gameptr->moveno < 2)
	initial_onboard(gameptr,move_so_far);
    else
    {   do
	{   strcpy(move_so_far,"");
	    scroll();
	    sprintf(buffer,"Game %s, Move %d:",gameptr->name,(gameptr->moveno)+1);
	    drawline(buffer);
	    scroll();
	    drawline("(O)nboard, (M)ove, (P)risoner Exchange, ");
	    get_input("or (C)hange games: ",gameptr,buffer,move_so_far);
	    switch (tolower(*buffer))
	    {   case 'o':  if (onboard_piece(gameptr,move_so_far) == -1)
				strcpy(buffer,"");
			   break;
		case 'm':  if (move_piece(gameptr,move_so_far) == -1)
				strcpy(buffer,"");
			   break;
		case 'p':  if ((o=initial_offer(gameptr,move_so_far)) == -1)
				strcpy(buffer,"");
			   else
			   {    gameptr->status = 'o';
				scroll();
				sprintf(buffer,"%d offered:",o);
				drawline(buffer);
			   }
			   break;
		case 'c':
		case 'q':  /*closegraph();*/
			   return NULL;
		default:   strcpy(buffer,"");
	    }
	} while (strcmp(buffer,"") == 0);
    }
    /*closegraph();*/
    return move_so_far;
}
	
int get_input(prompt,gameptr,buffer,move_so_far)
char *prompt;
struct gameinfo *gameptr;
char buffer[];
char move_so_far[];
{   enterline(prompt,buffer);
 
    if (strcmp(buffer,"display") == 0)
    {   display(gameptr);
    }
 
    if (strcmp(buffer,"cancel") == 0)
    	return -1;
 
    if (strcmp(buffer,"exit") == 0)
    {	/*closegraph();*/
	exit(0);
    }
 
    return 0;
}
 
int initial_onboard(gameptr,move_so_far)
struct gameinfo *gameptr;
char move_so_far[];
{   char buffer[80];
    char out_txt[80];
    int height;
    int column,row;
    enum weapons tside,bside;
    int pieceno;
    enum info known;
   
 
    strcpy(move_so_far,"");
 
    scroll();
    drawline("Initial stack onboard...");
    do
    {   scroll();
	if (get_input("Enter square for initial onboard: ",gameptr,buffer,move_so_far) == -1)
	    return -1;               
    } while ((parsesquare(buffer,&column,&row) == -1) ||
	((column > 0) && (row > 0) && (column < 3) && (row < 3)) ||
	(board[column][row].stackheight > 0));
 
    *(buffer+2) = '\0';
    strncat(move_so_far,buffer,2);
    strcat(move_so_far,"/");
    scroll();
 
    for (height = 1;height <= 2;height++)
    {
	do
	{   sprintf(out_txt,"Which piece would you like to onboard to position %d? ",
		height);
	    if (get_input(out_txt,gameptr,buffer,move_so_far) == -1)
		return -1;
	    if (parsepiece(buffer,&tside,&bside) != -1)
	    {   
	   	pieceno = findpiece(tside,bside,gameptr->color,offboard);
	    }
	    else
	    {   drawline("Can't parse piece.");
		scroll();
		pieceno = -1;
	    }
	} while (pieceno == -1);
 
  	*(buffer+2) = '\0';
	strncat(move_so_far,buffer,2);
	strcat(move_so_far,",");
 
 	known = ((height == 1) ? top : none);
 
	add_to_stack(column,row,height,pieceno,known);
    }
 
    return 0;
}
 
int move_piece(gameptr,move_so_far)
struct gameinfo *gameptr;
char move_so_far[80];
{   char buffer[80];
    int icolumn,irow;
    int fcolumn,frow;
    int dist,maxdist;
    int number;
 
    stack.stackheight = 0;
 
    if (select_initial_square(gameptr,move_so_far,&icolumn,&irow,&maxdist)==-1)
	return -1;
 
    if (flip_check(gameptr,icolumn,irow,move_so_far) == -1)
	return -1;
 
    pickup(gameptr,icolumn,irow,maxdist);
    do
    {   get_input("How many pieces do you wish to leave behind? ",gameptr,buffer,move_so_far);
	number = atoi(buffer);
    } while (number < 0 || number > stack.stackheight || !isdigit(*buffer));
 
    if (number > 0)
    {  
  	sprintf(move_so_far+strlen(move_so_far),"(-%d)",number);
	drop_off(gameptr,icolumn,irow,number,1);
    }
    strcat(move_so_far,",");
  
    dist = select_final_square(gameptr,move_so_far,&fcolumn,&frow,icolumn,irow,
	maxdist);
    if (dist == -1)
	return -1;
 
    middle_squares(gameptr,move_so_far,icolumn,irow,fcolumn,frow,dist);
    final_square(gameptr,fcolumn,frow,move_so_far);
 
    return 0;
}
 
int select_initial_square(gameptr,move_so_far,icptr,irptr,maxdistptr)
struct gameinfo *gameptr;
char move_so_far[];
int *icptr,*irptr;
int *maxdistptr;
{   char buffer[80];
    int pieceno;
 
    do
    {   
	if (get_input("Please enter initial square: ",gameptr,buffer,move_so_far) == -1)
	    return -1;
    } while (init_sq_verify(gameptr,buffer,icptr,irptr,&pieceno) == -1);
 
    *maxdistptr = 0;
 
    do
    {   (*maxdistptr)++;
	pieceno = pieces[pieceno].link;
    } while (COLOR(pieceno) == gameptr->color && pieceno != -1);
 
    *(buffer+2) = '\0';
    strncat(move_so_far,buffer,3);
 
    return 0;
}
 
int flip_check(gameptr,icolumn,irow,move_so_far)
struct gameinfo *gameptr;
int icolumn,irow;
char move_so_far[80];
{   char tempstr[80];
    char buffer[80];
    int pieceno;
 
    pieceno = board[icolumn][irow].link;
 
 
    do
    {   
	if (get_input("Flip top piece? (Y/N): ",gameptr,buffer,move_so_far) == -1)
	    return -1;
	if (tolower(*buffer) == 'y')
	{   flip(pieceno);
	    strcpy(tempstr,"^");
	    strcat(tempstr,move_so_far);
	    strcpy(move_so_far,tempstr);
	
	    return 0;
	}
    } while (tolower(*buffer) != 'n' && tolower(*buffer) != 'y');
 
    return 0;
}
	
int select_final_square(gameptr,move_so_far,fcptr,frptr,icolumn,irow,maxdist)
struct gameinfo *gameptr;
char move_so_far[];
int *fcptr,*frptr;
int icolumn,irow;
int maxdist;
{   char buffer[80];
    int dist;
 
    do
    {   
	if (get_input("Please enter final square: ",gameptr,buffer,move_so_far) == -1)
	    return -1;
    } while ((dist = final_sq_verify(gameptr,buffer,icolumn,irow,
	fcptr,frptr,maxdist)) == -1);
 
    *(buffer+2) = '\0';
    strcat(move_so_far,"...,");
    strncat(move_so_far,buffer,3);
    return dist;
}
 
int middle_squares(gameptr,move_so_far,icolumn,irow,fcolumn,frow,dist)
struct gameinfo *gameptr;
char move_so_far[];
int icolumn,irow,fcolumn,frow;
int dist;
{   int i,j;
    char tempstr[80];
    char *cptr;
 
    if (pieces[stack.link].top == orange)
    {   
        if (abs(fcolumn - icolumn) == 1)
/* JL:  added abs to allow the twister to move down and left (ex: c4-b2) */
	{   i = icolumn;
	    j = (frow+irow)/2;
	}
	else
	{ 
            i = (fcolumn+icolumn) / 2;
	    j = irow;
	}
	in_between(gameptr,i,j,move_so_far);
    }
    else
    {   i = icolumn+((dist > 0) ? ((fcolumn-icolumn)/dist) : 0);
	j = irow + ((dist > 0) ? ((frow-irow)/dist) : 0);
    
  	while (i != fcolumn || j != frow)
	{   in_between(gameptr,i,j,move_so_far);
	    i += (fcolumn-icolumn)/dist;
	    j += (frow-irow) / dist;
	}
    }
 
    cptr = strchr(move_so_far,'.');
    strcpy(tempstr,cptr+4);
    *cptr = '\0';
 
    if (fcolumn == icolumn && frow == irow)
    {	strcpy(tempstr,"");
	cptr = strchr(move_so_far,',');
	*cptr = '\0';
    }
 
    strcat(move_so_far,tempstr);
    return 0;
}
 
void in_between(gameptr,column,row,move_so_far)
struct gameinfo *gameptr;
int column,row;
char move_so_far[80];
{   char *cptr;
    char tempstr[80];
    char square[3];
    char out_txt[80];
 
    cptr = strchr(move_so_far,'.');
    strcpy(tempstr,cptr);
    *cptr = '\0';
 
    sprintf(out_txt,"%c%d:  ",column+97,row+1);
    scroll();
    drawline(out_txt);
    sprintf(square,"%c%d",column+97,row+1);
 
    strcat(move_so_far,square);
    strcat(move_so_far,tempstr);
 
    if (get_or_drop(gameptr,column,row,move_so_far) == 0)
	move_so_far[strlen(move_so_far)-9] = '\0';
 
    strcat(move_so_far,",");
    strcat(move_so_far,tempstr);
}
 
int final_square(gameptr,column,row,move_so_far)
struct gameinfo *gameptr;
int column,row;
char move_so_far[80];
{   int lastlink;
 
    lastlink = board[column][row].link;
 
    while (COLOR(lastlink) == gameptr->color)
    {	lastlink = pieces[lastlink].link;
	pickup(gameptr,column,row,1);
    }
 
    if (COLOR(board[column][row].link) == 1-(gameptr->color))
    {	if ((capture_check(gameptr,column,row,move_so_far)) == -1)
	    return -1;
    }
 
    drop_off(gameptr,column,row,stack.stackheight,1);
    return 0;
}
 
int capture_check(gameptr,column,row,move_so_far)
struct gameinfo *gameptr;
int column,row;
char move_so_far[80];
{   char buffer[80];
    int number;
    
    do
    {	
	if (get_input("How many pieces do you wish to capture? ",gameptr,buffer,move_so_far) == -1)
	    return -1;
	number = atoi(buffer);
    } while (isalpha(*buffer) || number > stack.stackheight ||
	capture(gameptr,column,row,move_so_far,number) == -1);
    return 0;
}
 
int get_or_drop(gameptr,column,row,move_so_far)
struct gameinfo *gameptr;
int column,row;
char move_so_far[80];
{  
    int number=0;  /* DG:  (Allow the user to drop pieces, I don't know
                      why this wasn't noticed before */
    char buffer[80],tempstr[80];
    char *cptr;
 
    
       
/*	if (get_input("Enter # of pieces to pick upor drop: ",gameptr,buffer,move_so_far) == -1)*/
	if (COLOR(board[column][row].link) == gameptr->color)
	{   do
	    {   if (get_input("Enter # of pieces to pick up: ",gameptr,buffer,move_so_far) == -1)
		    return -1;
		if (!isdigit(*buffer))
		    *buffer = '\0';
		number = atoi(buffer);
		if (number > 0)
		{   if (pickup(gameptr,column,row,number) == -1)
			strcpy(buffer,"");
		    
		}
	    } while (strcmp(buffer,"") == 0);
	}
	if ((number == 0) && (stack.stackheight > 1))
	{   do
	    {   if (get_input("Enter # of pieces to drop off: ",gameptr,buffer,move_so_far) == -1)
		    return -1;
		if (!isdigit(*buffer))
		    *buffer = '\0';
		number = atoi(buffer);
		if (number > 0)
		{   if (drop_off(gameptr,column,row,number,0) == -1)
			strcpy(buffer,"");
		}
	    } while (strcmp(buffer,"") == 0);
	}
	    
/*	switch(*buffer)
	{   case '+': if (pickup(gameptr,column,row,number) == -1)
			strcpy(buffer,"");
		      break;
	    case '-': if (drop_off(gameptr,column,row,number,0) == -1)
			strcpy(buffer,"");
		      break;
	    case '0': return 0;
	    default:  strcpy(buffer,"");
	}
*/
    
    cptr = strchr(move_so_far,'.');
    strcpy(tempstr,cptr);
    *cptr = '\0';
 
    *(buffer+2) = '\0';
    strcat(move_so_far,"(");
    strncat(move_so_far,buffer,2);
    strcat(move_so_far,")");
    return 0;
}
     
int onboard_piece(gameptr,move_so_far)
struct gameinfo *gameptr;
char move_so_far[];
{   char buffer[80];
    int column,row;
    int height;
    int pieceno;
    enum weapons tside,bside;
 
    do
    {   
	if (get_input("Which square would you like to onboard to? ",gameptr,buffer,move_so_far) == -1)
	    return -1;
    } while (parsesquare(buffer,&column,&row) == -1);
 
    *(buffer+2) = '\0';
    strncat(move_so_far,buffer,2);
    strcat(move_so_far,"/");
    
    if (board[column][row].stackheight > 0)
    {
      do
      {   if (get_input("At which location in the stack? ",gameptr,buffer,move_so_far) == -1)
	    return -1;
	  height = atoi(buffer);
      } while (onboard_verify(gameptr,height,column,row) == -1);
    }
    else
	height = 1;
      
 
    *(buffer+1) = '\0';
    strncat(move_so_far,buffer,1);
 
    do 
    {   
	if (get_input("Which piece would you like to onboard? ",gameptr,buffer,move_so_far) == -1)
	    return -1;
	if (parsepiece(buffer,&tside,&bside) != -1)
	    pieceno = findpiece(tside,bside,gameptr->color,offboard);
	else
	    pieceno = -1;
    } while (pieceno == -1);
 
    *(buffer+2) = '\0';
    strcat(move_so_far," ");
    strncat(move_so_far,buffer,2);
 
    add_to_stack(column,row,height,pieceno,top);
 
    return 0;
}
 
int initial_offer(gameptr,move_so_far)
struct gameinfo *gameptr;
char move_so_far[80];
{   int offer;
    
    strcat(move_so_far,"(");
    offer = select_prisoners(gameptr,move_so_far);
    strcat(move_so_far,")");
 
    return offer;
}
 
int select_prisoners(gameptr,move_so_far)
struct gameinfo *gameptr;
char move_so_far[80];
{   char buffer[80];
    int value_offered=0;
    int pieceno;
    enum weapons tside,bside;
    char out_txt[80];
 
    do
    {   
	drawline("Which piece do you wish to offer for exchange? ");
	if (get_input("\"done\" to conclude offer: ",gameptr,buffer,move_so_far) == -1)
	    return -1;
 
	if (parsepiece(buffer,&tside,&bside) == 0)
	    pieceno = findpiece(tside,bside,1-(gameptr->color),captured);
	else
	    pieceno = -1;
 
	if (pieceno > -1)
	{   value_offered += pieces[pieceno].value;
	    *(buffer+2) = '\0';
	    sprintf(out_txt,"%s offered.",buffer);
	    drawline(out_txt);
	    scroll();
	    strncat(move_so_far,buffer,3);
	    strcat(move_so_far,",");
	    pieces[pieceno].status = offered;
	}
   	else
	{   if (strcmp(buffer,"done") != 0 &&
		strcmp(buffer,"display") != 0)
		{   scroll();
		    drawline("You don't have one of those to exchange!");
		}
	}
    } while (strcmp(buffer,"done") != 0);
    *(move_so_far+strlen(move_so_far) - 1) = '\0';
    return value_offered;
}
 
int counter_offer(gameptr,move_so_far,offer)
struct gameinfo *gameptr;
char move_so_far[80];
int offer;
{   int counter,min_offer;
    int i,begin;
    char tempstr[80];
    char out_txt[80];
 
    strcpy(tempstr,"");
 
    if (gameptr->color == white)
	begin = 0;
    else
	begin = 12;
 
   min_offer = must_offer(0,offer,begin,begin+12);
   sprintf(out_txt,"Your opponent offered %d.  You must offer at least %d.",
	offer,min_offer);
    scroll();
    drawline(out_txt);
    scroll();
    if (min_offer == 0)
    {
	if (get_input("Do you wish to exchange prisoners? (y/n)",gameptr,tempstr,move_so_far) == -1)
	    return -1;
	if (tolower(*tempstr) == 'n')
	    return 0;
    }
	
    strcat(move_so_far,"(");
 
    do
    {   counter = select_prisoners(gameptr,move_so_far);   
	if (counter < min_offer)
	{   for (i=0;i<12;i++)
	   	if (pieces[begin+i].status == offered)
		    pieces[begin+i].status = captured;
	
	    sprintf(out_txt,"You only offered %d points.",counter);
	    scroll();
	    drawline(out_txt);
	}
    } while (counter < min_offer);
 
    if (counter > 0)
	strcat(move_so_far,")");
    else
	strcat(move_so_far,"()");
 
    return counter;
}
 
int must_offer(points,offer,pieceno,limit)
int points,offer,pieceno,limit;
{   int with,without;
 
    while (pieceno < limit && pieces[pieceno].status != captured)
	pieceno++;
 
    if (pieceno < limit)
    {	if ((with = points + pieces[pieceno].value) <= offer)
	    with = must_offer(with,offer,pieceno+1,limit);
	else
	    with = 0;
	without = must_offer(points,offer,pieceno+1,limit);
	if (with > without)
	    return with;
	else
	    return without;
    }
    else
	return points;
}
 
int count_offer()
{   int i,offer = 0;
 
    for (i=0;i<24;i++)
	if (pieces[i].status == offered)
	    offer += pieces[i].value;
    
    return offer;
}
 
void accept_exchange()
{   int i;
 
    for(i=0;i<24;i++)
	if (pieces[i].status == offered)
	    pieces[i].status = offboard;
}
 
void reject_exchange(move_so_far)
char move_so_far[80];
{   int i;
 
    for (i=0;i<24;i++)
	if (pieces[i].status == offered)
	    pieces[i].status = captured;
 
    strcpy(move_so_far,"REJECT");
}
 
int endgame(gameptr)
struct gameinfo *gameptr;
{   int i,j,pieceno,cheight,no_captured;
    enum colors color;
 
    no_captured = 0;
 
    for (i=0;i<12;i++)
    	if (pieces[i].status == captured)
	    no_captured++;
 
    if (no_captured >= 6)
    {   (gameptr->status) = 'w';
	scroll();
	drawline("White wins by capturing.");
	return 1;
    }
    no_captured = 0;
 
    for (i=12;i<24;i++)
	if (pieces[i].status == captured)
	    no_captured++;
 
    if (no_captured >= 6)
    {   (gameptr->status) = 'b';
	scroll();
	drawline("Black wins by capturing.");
	return 1;
    }
 
    for (i=0;i<4;i++)
	for (j=0;j<4;j++)
	{   if (board[i][j].stackheight >= 6)
	    {	pieceno = board[i][j].link;
		color = COLOR(pieceno);
		do
		{   cheight = 0;
		    color = COLOR(pieceno);
		    while (COLOR(pieceno) == color)
		    {	cheight++;
			if (cheight == 6)
			{   (gameptr->status) = ((color == black) ? 'b' : 'w');
			    return 1;
			}
		        pieceno = pieces[pieceno].link;
		    }
		} while (COLOR(pieceno) != empty);
	    }
	}
    
    return 0;
}
 
int review(tgameptr,game,fptr)
struct gameinfo *tgameptr;
struct gameinfo game;
FILE *fptr;
{   char buffer[80];                      
    int m;
    char out_txt[80];
    FILE *gptr;
 
  do
  {
    display(tgameptr);
    if (tgameptr->comments == 'y')
    {   if ((gptr = fopen("comfile","r")) == NULL)
	{   scroll();
	    drawline("No comment file found.");
	}
	else
	{   while(fgets(out_txt,80,gptr) != NULL)
	    {	strtok(out_txt,"\n");
		drawline(out_txt);
	    }
	    fclose (gptr);
	}
    }
    sprintf(out_txt,"Game %s: Move %d of %d",game.name,tgameptr->moveno,
	game.moveno);
    scroll();
    drawline(out_txt);
    scroll();
    if (moveable(*tgameptr,game) == 1)
	drawline("(F)orward, (B)ackward, (G)o to move #, (M)ove,");
    else
	drawline("(F)orward, (B)ackward, (G)o to move #,");
    scroll();
    enterline("or (C)hange games? ",buffer);
    scroll();
    scroll();
    if (strstr(buffer,"exit") != NULL)
    {   if (tgameptr->comments == 'y')
	    system("rm comfile"); 
/* For DOS
        system("del comfile");
*/

/*	closegraph(); */

	exit(0);
    }
 
    switch (tolower(*buffer))
    {   case 'f':   if (tgameptr->moveno < game.moveno)
		    {   if (tgameptr->comments == 'y')
			{   /* system("del comfile");*/
			    system("rm comfile");
		  	}
			tgameptr->moveno++;
			read_position(tgameptr,fptr);
		    }
		    break;
	case 'b':   if (tgameptr->moveno > 0)
		    {	if (tgameptr->comments == 'y')
			{
			  /*  system("del comfile");*/
			    system("rm comfile");
			}
			tgameptr->moveno--;
			read_position(tgameptr,fptr);
		    }
		    break;
	case 'g':   do
		    {   scroll();
			enterline("Which move #? ",buffer);
		    } while (!isdigit(*buffer) || (m=atoi(buffer)) < 0 ||
			m > game.moveno);
		    if (tgameptr->comments == 'y')
		    {
		/*	system("del comfile");*/
			system("rm comfile");
		    }
		        tgameptr->moveno = m;
		    read_position(tgameptr,fptr);
		    break;
	case 'm':   if (tgameptr->comments == 'y')
		    	system("rm comfile");
			/*system("del comfile");*/
		    return (1);
	case 'c':   if (tgameptr->comments == 'y')
		    	system("rm comfile");
			/*system("del comfile");*/
		    /*closegraph();*/
		    return (0);
	default :   *buffer = ' ';
   	
    }
  } while (tolower(*buffer) != 'q');
  return (0);
}
