/* WARBIRD, the tic-tac-toe app for LCARS 24 */
/* Powered by a school assignment by Alastair Francis */
/* No copyright stated */
/* The opponent is always X, displayed as a Romulan Warbird. */

/* This program is free software. You may redistribute and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License or
 * (at your option) any later version.
 *
 * Refer to the file C:\LCARS24\DATA\COPYING.TXT for details.
 */


#include "warbird.h"


void Wb5GrayMessage(char *message)
{
	rectfill(screen,799-100-12, 461, 799-12, 480, LILAC);
	PutsLuna(799-96-12,465, BLACK,LILAC, message);
}
void Wb5PrimeCursor()
{
	blit(screen, bmp1, 86-52+(BoardX*WbSqSize),66-26+(BoardY*WbSqSize), 0, 0, bmp1->w,bmp1->h);
}
void Wb5EraseCursor()
{
/*
	EnterSymbol(86+(BoardX*WbSqSize),66+(BoardY*WbSqSize),1,ORANGE4);
	return;
*/
	blit(bmp1, screen, 0,0, 86-52+(BoardX*WbSqSize),66-26+(BoardY*WbSqSize),bmp1->w,bmp1->h);
}
void Wb5DrawCursor()
{
	EnterSymbol(86+(BoardX*WbSqSize),66+(BoardY*WbSqSize),1,NAPLES);
}
void Wb5UnparkCursor()
{
	EnterSymbol(86+(5*WbSqSize),66+(2*WbSqSize),1,BLACK);
}
int Wb5ParkCursor()
{
	BoardX=5;
	BoardY=2;
	Wb5DrawCursor();
	return(0);
}
int Wb5MarkPlayerSpot()
{
	int x,y;

	if(BoardX > 4) return(86); /* cursor parked */

/* Trap any FALSE input, independently of the TTT engine */
	if(Scratchpad25[BoardX+(BoardY*5)] !=(null)) return(86);
	Scratchpad25[BoardX+(BoardY*5)] = 'O';
	Wb5HumanMove=BoardX+(BoardY*5);

	Wb5EraseCursor();

	x=86+(BoardX*WbSqSize)-50;
	y=66+(BoardY*WbSqSize)-10;
	masked_blit(voy, screen, 0, 0, x, y, voy->w, voy->h);
	Wb5ParkCursor();
	Wb5GrayMessage("THINKING");
	CheckBeep();
	return(0);
}
int Wb5MarkOpponenSpot()
{
	int x,y;

	if(BoardX > 4) return(86); /* cursor parked */

/* Trap any FALSE input, independently of the TTT engine */
/* if(Scratchpad25[BoardX+(BoardY*5)] !=(null)) return(86); */
	Scratchpad25[BoardX+(BoardY*5)] = 'X';

	Wb5EraseCursor();

	x=86+(BoardX*WbSqSize)-50;
	y=66+(BoardY*WbSqSize)-10;
	masked_blit(rom, screen, 0, 0, x, y, rom->w, rom->h);
	Wb5ParkCursor();
	Wb5GrayMessage("");
	CheckBeep();
	return(0);
}
void Wb5CursorLeft()
{
	if(BoardX < 1) return;
	if(BoardX==5 && BoardY==2) Wb5UnparkCursor();
		else Wb5EraseCursor();
	--BoardX;
	Wb5PrimeCursor();
	Wb5DrawCursor();
}
void Wb5CursorRight()
{
	if(BoardX > 3) return;
	Wb5EraseCursor();
	++BoardX;
	Wb5PrimeCursor();
	Wb5DrawCursor();
}
void Wb5CursorUp()
{
	if(BoardY < 1) return;
	if(BoardX==5 && BoardY==2) Wb5UnparkCursor();
		else Wb5EraseCursor();
	--BoardY;
	Wb5PrimeCursor();
	Wb5DrawCursor();
}
void Wb5CursorDown()
{
	if(BoardY > 3) return;
	if(BoardX==5 && BoardY==2) Wb5UnparkCursor();
		else Wb5EraseCursor();
	++BoardY;
	Wb5PrimeCursor();
	Wb5DrawCursor();
}

void WbClearBottom()
{
	rectfill(screen,120,241,800,600,BLACK);
}
void Wb5Clear()
{
	rectfill(screen,0,50,677,550,BLACK);
}
void WbPrimeCursor()
{
	blit(screen, bmp1, 243-52+(BoardX*WbSqSize),304-26+(BoardY*WbSqSize), 0, 0, bmp1->w,bmp1->h);
}
void WbEraseCursor()
{
	blit(bmp1, screen, 0,0, 243-52+(BoardX*WbSqSize),304-26+(BoardY*WbSqSize),bmp1->w,bmp1->h);
}
void WbDrawCursor()
{
	EnterSymbol(243+(BoardX*WbSqSize),304+(BoardY*WbSqSize),1,NAPLES);
}
void Wb3UnparkCursor()
{
	EnterSymbol(243+(3*WbSqSize),304+(WbSqSize),1,BLACK);
}
int WbParkCursor()
{
	BoardX=3;
	BoardY=1;
	WbDrawCursor();
	return(0);
}
int WbMarkPlayerSpot()
{
	int x,y;

	if(BoardX > 2) return(86); /* cursor parked */

/* Trap any FALSE input, independently of the TTT engine */
	if(Scratchpad9[BoardX+(BoardY*3)] !=(null)) return(86);
	Scratchpad9[BoardX+(BoardY*3)] = 'O';
	HumanMove=BoardX+(BoardY*3);

	WbEraseCursor();

	x=243+(BoardX*WbSqSize)-50;
	y=304+(BoardY*WbSqSize)-10;
	masked_blit(voy, screen, 0, 0, x, y, voy->w, voy->h);
	WbParkCursor();
	return(0);
}
int WbMarkOpponenSpot()
{
	int x,y;

/* Trap any FALSE input, independently of the TTT engine */
/* if(Scratchpad9[BoardX+(BoardY*3)] !=(null)) return(86); */
	Scratchpad9[BoardX+(BoardY*3)] = 'X';

	WbEraseCursor();

	x=243+(BoardX*WbSqSize)-50;
	y=304+(BoardY*WbSqSize)-10;
	masked_blit(rom, screen, 0, 0, x, y, rom->w, rom->h);
	WbParkCursor();
	return(0);
}
void WbCursorLeft()
{
	if(BoardX < 1) return;
	if(BoardX==3 && BoardY==1) Wb3UnparkCursor();
		else WbEraseCursor();
	--BoardX;
	WbPrimeCursor();
	WbDrawCursor();
}
void WbCursorRight()
{
	if(BoardX > 1) return;
	WbEraseCursor();
	++BoardX;
	WbPrimeCursor();
	WbDrawCursor();
}
void WbCursorUp()
{
	if(BoardY < 1) return;
	if(BoardX==3 && BoardY==1) Wb3UnparkCursor();
		else WbEraseCursor();
	--BoardY;
	WbPrimeCursor();
	WbDrawCursor();
}
void WbCursorDown()
{
	if(BoardY > 1) return;
	if(BoardX==3 && BoardY==1) Wb3UnparkCursor();
		else WbEraseCursor();
	++BoardY;
	WbPrimeCursor();
	WbDrawCursor();
}
void WbBox1a(int Hue)
{
	int boxtop;

	boxtop=10;
	rectfill(screen,10,boxtop,110,boxtop+54,Hue);
	PutsLuna(14,boxtop + 37, BLACK,Hue, "CLOSE");
	PutsLuna(91,boxtop + 37, BLACK,Hue, "F12");
}
void WbBox2a(int Hue)
{
	int boxtop;

	boxtop=68;
	rectfill(screen,10,boxtop,110,boxtop+54,Hue);
}
void WbBox1b(int Hue, char *Str1, char *Str2)
{
	int boxtop;

	boxtop=590 - 54;
	rectfill(screen,10,boxtop,110,boxtop+53,Hue);
	PutsLuna(14,boxtop + 4, BLACK,Hue, Str1);
	PutsLuna(96,boxtop + 4, BLACK,Hue, Str2);
}
void WbBox2b(int Hue, char *Str1, char *Str2)
{
	int boxtop;

	boxtop=590 - (54*2) - 3;
	rectfill(screen,10,boxtop,110,boxtop+53,Hue);
	PutsLuna(14,boxtop + 4, BLACK,Hue, Str1);
	PutsLuna(96,boxtop + 4, BLACK,Hue, Str2);
}
void WbBox3b(int Hue, char *Str1, char *Str2)
{
	int boxtop;

	boxtop=590 - (54*3) - 6;
	rectfill(screen,10,boxtop,110,boxtop+53,Hue);
	PutsLuna(14,boxtop + 4, BLACK,Hue, Str1);
	PutsLuna(96,boxtop + 4, BLACK,Hue, Str2);
}
void WbBox4b(int Hue, char *Str1, char *Str2)
{
	int boxtop;

	boxtop=590 - (54*4) - 9;
	rectfill(screen,10,boxtop,110,boxtop+53,Hue);
	PutsLuna(14,boxtop + 4, BLACK,Hue, Str1);
	PutsLuna(96,boxtop + 4, BLACK,Hue, Str2);
}
void WbBox5b(int Hue, char *Str1, char *Str2)
{
	int boxtop;

	boxtop=590 - (54*5) - 12;
	rectfill(screen,10,boxtop,110,boxtop+53,Hue);
	PutsLuna(14,boxtop + 4, BLACK,Hue, Str1);
	PutsLuna(96,boxtop + 4, BLACK,Hue, Str2);
}
int WbBoxBlank(int Hue)
{
	int boxtop, boxbottom;

	boxtop=590 - (54*5) - 12;
	boxbottom=590 - (54*3) - 6+53;
	rectfill(screen,10,boxtop,110,boxbottom,Hue);
	return(0);
}
void WbElbowSignage(int Hue1, int Hue2)
{
	int boxtop;

	boxtop=148;
	PutsLuna(14,boxtop + 6 -24, BLACK,Hue1, "MARK");
	PutsLuna(80,boxtop + 6 -24, BLACK,Hue1, "ENTER");

	boxtop=590 - (54*6) - 16;
	PutsLuna(14,boxtop + 28 +9, BLACK,Hue2, "HELP");
	PutsLuna(91,boxtop + 28 +9, BLACK,Hue2, "F11");
}
void WbBoxes()
{
	WbBox1a(LILAC);
	WbBox2a(PALEBLUE);
	WbBoxBlank(BLACK);					/* ## */
	WbBox1b(BIGBLUE,"NEW GAME","F1");
	WbBox2b(PALEBLUE,"","");
	WbBox3b(SKYBLUE,"GRID SIZE","F3");
	WbBox4b(BIGBLUE,"FIRST","F4");
	WbBox5b(BIGBLUE,"LEVEL","F5");
	WbElbowSignage(BIGBLUE, PALEBLUE);
/* rectfill(screen,10,365,110,532,PALEBLUE); */
}
void WbPostTieGame()
{
	rectfill(screen,120,100,200,160,BLACK);
	PutsFont21(120,100, BRICK, "STANDOFF");
	PutsFont21(120,132, BRICK, "NO LOSER");
	WbBoxes();
	PanelBeep();
}
void Wb5PostTieGame()
{
	rectfill(screen,360,13,600,39,LILAC);
	PutsLuna(360,20, BLACK,LILAC, "STANDOFF--NO LOSER");
	Wb5GrayMessage("GAME OVER");
	PanelBeep();
}
void Wb3PostWinner(int Winner)
{
	rectfill(screen,120,100,200,160,BLACK);
	if(Winner==1) {
		PutsFont21(120,100, BRICK, "LOSER:");
		PutsFont21(120,132, ORANGE, "WINNER:");
	} else {
		PutsFont21(120,100, ORANGE, "WINNER:");
		PutsFont21(120,132, BRICK, "LOSER:");
	}
	WbBoxes();
	PanelBeep();
}
void Wb5PostWinner(int Winner)
{
	rectfill(screen,360,13,600,39,LILAC);
	if(Winner==1) PutsLuna(360,20, BLACK,LILAC, "WINNER: ROMULAN STAR EMPIRE");
		else PutsLuna(360,20, BLACK,LILAC, "WINNER: STARFLEET");
	Wb5GrayMessage("GAME OVER");
	PanelBeep();
}
void Wb5NewGame()
{
	memset(Scratchpad25,(null),25);
	rectfill(screen,0,50,677,550,BLACK);

	rectfill(screen,360,13,600,39,LILAC);
	PutsLuna(360,20, BLACK,LILAC, "PLAYER: STARFLEET   OPPONENT: ROMULANS");

	Wb5DrawGrid();
	Wb5GrayMessage("");
	BeepSet=TRUE;
}
void Wb3NewGame()
{
	memset(Scratchpad9,(null),9);
	rectfill(screen,120,100,200,160,BLACK);
	PutsFont21(120,100, BIGBLUE, "PLAYER:");
	masked_blit(voy, screen, 0, 0, 200, 100, voy->w, voy->h);
	PutsFont21(120,132, BIGBLUE, "OPPONENT:");
	masked_blit(rom, screen, 0, 0, 200, 126, rom->w, rom->h);

	WbDrawGrid();
	WbBoxes();
	BeepSet=TRUE;
}
void Wb5GetPlayerTypeX(Wb5PlayerType* a_Wb5Player)
{ /* replaces original console routine, but only for
	  Wb5Player 1 (the computer) */

	a_Wb5Player->Wb5Computer=TRUE;	  /* R = Romulans, the AI here */
	a_Wb5Player->Wb5SkillLevel=Wb5Level; /* Level LCARS selectable */
}
void Wb5GetPlayerTypeO(Wb5PlayerType* a_Wb5Player)
{ /* same as above, for Wb5Player 2 (the user) */

	a_Wb5Player->Wb5Computer=FALSE;	  /* S = Starfleet, the user here */
	a_Wb5Player->Wb5SkillLevel=Wb5Level; /* repeat of above */
}
void Wb3GetPlayerTypeX(Wb3PlayerType* a_Wb3Player)
{ /* replaces original console routine, but only for
	  Wb3Player 1 (the computer) */

	a_Wb3Player->Wb3Computer=TRUE;	  /* X = Romulans, the AI here */
	a_Wb3Player->Wb3SkillLevel=Wb3Level; /* Level LCARS selectable */
}
void Wb3GetPlayerTypeO(Wb3PlayerType* a_Wb3Player)
{ /* same as above, for Wb3Player 2 (the user) */

	a_Wb3Player->Wb3Computer=FALSE;	  /* O = Starfleet, the user here */
	a_Wb3Player->Wb3SkillLevel=Wb3Level; /* repeat of above */
}
int WbSetWhoGoesFirst()
{
	int x,y;

	if(WbPlayMode==3) {
		WbClearBottom();
		x=508;
					 y=235;
	} else {
		Wb5Clear();
		x=358;
		y=85;
	}

	PutsFont21(x-268,y+47+7, ORANGE, "WHO SHALL GO FIRST?");
	ButtonType2(x, y+47, ORANGE, LILAC, "STARFLEET");
	ButtonType2(x, y+(47*2), MANGO, PALEBLUE, "ROMULANS");
	ButtonType3(x, y+(47*3), BIGBLUE, ORANGE, "BACK");

	F36_1(x+140, y+47+1, MANGO, BLACK);
	F36_2(x+140, y+(47*2)+1, SKYBLUE, BLACK);
	EscSymbol(x+117, y+(47*3)+1,2, NAPLES);

loopback:
	do {
		if(WbPlayMode==3) SolPutTime();
			else T24PutTime();
	} while(!keypressed());
	c=GetKey();
	switch(c)
		{
			case F10: return(0);
			case ESC: return(1);
			case 49: OpponentGoesFirst=FALSE;
					if(WbPlayMode==3) Wb3NewGame();
						else Wb5NewGame();
					return(1);
			case 50: OpponentGoesFirst=TRUE;
					if(WbPlayMode==3) Wb3NewGame();
						else Wb5NewGame();
					return(1);
			case CTRL_F1: Screenshot792("Warbd8.bmp");
					PanelBeep();
					goto loopback;
			case CTRL_F2: Screenshot1024("Warbd10.bmp");
					PanelBeep();
					goto loopback;
			default: goto loopback;
		}
	return(0);
}
void WbPostSkillLevel()
{
	char LevelStr[3];

	if(WbPlayMode==3) {
		rectfill(screen,465,153,530,178,BLACK);
		PutsFont21(465,153, ORANGE, "LEVEL:");
		itoa(Wb3Level,LevelStr,10);
		PutsFont21(465+52,153, ORANGE, LevelStr);
	} else {
		rectfill(screen,260,13,356,39,LILAC);
		PutsLuna(260,20, BLACK,LILAC, "LEVEL:");
		itoa(Wb5Level,LevelStr,10);
		PutsLuna(302,20, BLACK,LILAC, LevelStr);
	}
}
int Wb5SetSkillLevel()
{
	char LevelStr[4];

	Wb5Clear();
	PutsFont21(240,85, ORANGE, "SPECIFY DIFFICULTY LEVEL:");
	PutsLuna(240,85+32,PURPLE,BLACK,"RANGE: 1 TO 7"); /* 1 to 23 possible */
	PutsLuna(240,85+52,PURPLE,BLACK,"USE ARROW KEYS PLUS ENTER, OR ESC");
	UpArrowHead(427, 110, ORANGE);
loopback:
	itoa(Wb5Level,LevelStr,10);
	rectfill(screen,431,85,448,106,BLACK); /* was 440, but at double-digit */
	PutsFont21(432,85, ORANGE, LevelStr);  /* levels the AI is too slow */
	clear_keybuf();

	do {
		T24PutTime();
	} while(!keypressed());
	c=GetKey();
	switch(c)
		{
			case F10: return(0);
			case ESC: return(1);
			case UPARROW: if(Wb5Level >6) goto loopback;
				++Wb5Level;
				goto loopback;
			case DOWNARROW: if(Wb5Level < 2) goto loopback;
				--Wb5Level;
				goto loopback;
			case 13: return(1);
			default: goto loopback;
		}
	return(0);
}
int WbSetSkillLevel()
{
	char LevelStr[3];

	WbClearBottom();
	PutsFont21(240,289, ORANGE, "SPECIFY DIFFICULTY LEVEL:");
	PutsLuna(240,321,PURPLE,BLACK,"RANGE: 1 TO 7");
	PutsLuna(240,341,PURPLE,BLACK,"USE ARROW KEYS PLUS ENTER,");
	PutsLuna(240,361,PURPLE,BLACK,"A NUMERIC KEY, OR ESC");
	UpArrowHead(428, 314, ORANGE);
loopback:
	itoa(Wb3Level,LevelStr,10); 
	rectfill(screen,432,289,448,310,BLACK);
	PutsFont21(434,289, ORANGE, LevelStr); 
	clear_keybuf();

	do {
		SolPutTime(); 
	} while(!keypressed());
	c=GetKey();
	switch(c)
		{
			case F10: return(0);
			case ESC: return(1);
			case UPARROW: if(Wb3Level >6) goto loopback;
				++Wb3Level;
				goto loopback;
			case DOWNARROW: if(Wb3Level < 2) goto loopback;
				--Wb3Level;
				goto loopback;
			case 13: return(1);
			case 49: Wb3Level=1;
				return(1);
			case 50: Wb3Level=2;
				return(1);
			case 51: Wb3Level=3;
				return(1);
			case 52: Wb3Level=4;
				return(1);
			case 53: Wb3Level=5;
				return(1);
			case 54: Wb3Level=6;
				return(1);
			case 55: Wb3Level=7;
				return(1);
			default: goto loopback;
		}
	return(1);
}
Wb5GamePiece Wb5GetWhoGoesFirst()
{
	Wb5GamePiece result;

	if(OpponentGoesFirst==TRUE) result = R; /* default */
		else result = S;
	return(result);
}
Wb3GamePiece WbGetWhoGoesFirst()
{
	Wb3GamePiece result;

	if(OpponentGoesFirst==TRUE) result = X; /* default */
		else result = O;
	return(result);
}
void WbDoHelp()
{
	char HelpPath[80];

	strcpy(HelpPath, LcarsPath);
	strcat(HelpPath,"\\LC24APPS\\WARBIRD\\WARBIRD.TXT");
	OpenHelp(HelpPath);
	min_old=70;
}

int Warbird3WindowActive(int redraw)
{
	Wb3GamePiece first_turn;
	Wb3PlayerType Wb3Players [3];	 /* index used is of type Wb3GamePiece */
	Wb3PlayerType Wb3Player;
	Wb3BoardType the_board;
	int x,y, position;
	Wb3GamePiece current_turn;
	Wb3Boolean game_finished;

	if(redraw==1) Wb3Screen();

restart: Wb3NewGame();
	game_finished = Wb3False;
	WbGameOver=FALSE;

	Wb3GetPlayerTypeX(&Wb3Player); /* Romulans (opponent, the Wb3Computer) */
	Wb3Players[X]=Wb3Player;
	Wb3GetPlayerTypeO(&Wb3Player); /* Starfleet (human Wb3Player) */
	Wb3Players[O]=Wb3Player;
	first_turn=WbGetWhoGoesFirst();

	Wb3InitBoard(&the_board);
	current_turn = first_turn;

	while (! game_finished)  {
		if (Wb3Players[current_turn].Wb3Computer)  {
	/* Wb3Computers turn */
			Wb3MaxDepth = Wb3Players[current_turn].Wb3SkillLevel;
			position = Wb3FindBestMove (the_board, current_turn);
	/* column, row format */
			x = (position % Wb3BOARD_WIDTH) + 1;
			y = (position / Wb3BOARD_WIDTH) + 1;
			 Wb3PlacePiece (&the_board, position, current_turn);
			BoardX=x-1;
			BoardY=y-1;
			WbMarkOpponenSpot();
			Wb3Players_piece = O;
			Wb3Players_piece = X;
		}
		else  {
	/* human's turn */
			if (the_board.Wb3Elements_occupied == (Wb3BOARD_SIZE - 1))  {
	/* automatically fill last game position */
				WbPostTieGame();
				position = 0;
				while (the_board.Wb3Element[position] != Wb3empty) ++position;
		}
		else  {
	/* get the move and jump back to the label human_move */
			goto loopback;
human_move:	 position = HumanMove;
		}  /* end if else */
			Wb3PlacePiece (&the_board, position, current_turn);
		} /* end if else - which type of Wb3Player */

		if (Wb3IsWinner (the_board))  {
			WbGameOver=TRUE;
			Wb3PostWinner(current_turn);
			game_finished = TRUE;
			goto loopback;
		}  /* end if - winner */
		else  {
		if (Wb3IsFull (the_board))  {
			WbGameOver=TRUE;
			WbPostTieGame();
			game_finished = TRUE;
			goto loopback;
		}  /* end if - game board full */
		else  {
	/* Toggle current turn */
			current_turn = ((current_turn == X) ? O : X);
		}  /* end if else */
		}	/* end if else - check if game board is full or there is a winner */
	}  /* end while - game in progress */


loopback:
	do {
		SolPutTime();
	} while(!keypressed());
	c=GetKey();
	switch(c)
		{
			case F1: 	Wb3NewGame();
					InProgress=FALSE;
					game_finished = TRUE;
					goto restart;
			case F3: 	game_finished = TRUE;
					BeepSet=TRUE;
					if(Warbird5WindowActive()==0) return(0);
			case F4:	 BeepSet=TRUE;
					if(WbSetWhoGoesFirst()==0) return(0);
						else goto restart;
			case F5:  	game_finished = TRUE;
/*					BeepSet=TRUE; */
					if(WbSetSkillLevel()==0) return(0);
					WbPostSkillLevel();
					goto restart;
			case F11: 	WbDoHelp();
					min_old=70;
					PanelBeep();
					goto loopback;
			case F12:	game_finished = TRUE;
					return(0);
			case 13:	if(WbGameOver==TRUE) goto loopback;
					if(WbMarkPlayerSpot()==0) goto human_move;
					else goto loopback;
			case UPARROW: 	if(WbGameOver==TRUE) goto loopback;
					WbCursorUp();
					goto loopback;
			case DOWNARROW: if(WbGameOver==TRUE) goto loopback;
					WbCursorDown();
					goto loopback;
			case LEFTARROW: if(WbGameOver==TRUE) goto loopback;
					WbCursorLeft();
					goto loopback;
			case RIGHTARROW: if(WbGameOver==TRUE) goto loopback;
					WbCursorRight();
					goto loopback;
			case CTRL_F1: Screenshot792("Warbd8.bmp");
					goto loopback;
			case CTRL_F2: Screenshot1024("Warbd10.bmp");
					goto loopback;
			default: goto loopback;
		}
	return(0);
}
int Warbird5WindowActive()
{
	Wb5GamePiece first_turn;
	Wb5PlayerType Wb5Players[3];	 /* index used is of type Wb5GamePiece */
	Wb5PlayerType Wb5Player;
	Wb5BoardType the_board;
	int x,y, position;
	Wb5GamePiece current_turn;
	Wb5Boolean game_finished;

	Wb5Screen();

restart: Wb5NewGame();
	game_finished = Wb5False;
	WbGameOver=Wb5False;

	Wb5GetPlayerTypeX(&Wb5Player); /* Romulans (opponent, the computer) */
	Wb5Players[R]=Wb5Player;
	Wb5GetPlayerTypeO(&Wb5Player); /* Starfleet (human player) */
	Wb5Players[S]=Wb5Player;
	first_turn=Wb5GetWhoGoesFirst();

	Wb5InitBoard(&the_board);
	current_turn = first_turn;

	while (! game_finished)  {
		if (Wb5Players[current_turn].Wb5Computer)  {
	/* Wb5Computers turn */
			Wb5MaxDepth = Wb5Players[current_turn].Wb5SkillLevel;
			position = Wb5FindBestMove (the_board, current_turn);
	/* column, row format */
			x = (position % Wb5BOARD_WIDTH) + 1;
			y = (position / Wb5BOARD_WIDTH) + 1;
			 Wb5PlacePiece (&the_board, position, current_turn);
			BoardX=x-1;
			BoardY=y-1;
			Wb5MarkOpponenSpot();
			Wb5Players_piece = S;
			Wb5Players_piece = R;
		}
		else  {
	/* human's turn */
			if (the_board.Wb5Elements_occupied == (Wb5BOARD_SIZE - 1))  {
	/* automatically fill last game position */
				Wb5PostTieGame();
				position = 0;
				while (the_board.Wb5Element[position] != Wb5empty) ++position;
		}
		else  {
	/* get the move and jump back to the label human_move */
			goto loopback;
human_move:	 position = Wb5HumanMove;
		}  /* end if else */
			Wb5PlacePiece (&the_board, position, current_turn);
		} /* end if else - which type of Wb5Player */

		if (Wb5IsWinner (the_board))  {
			WbGameOver=TRUE;
			Wb5PostWinner(current_turn);
			game_finished = TRUE;
			goto loopback;
		}  /* end if - winner */
		else  {
		if (Wb5IsFull (the_board))  {
			WbGameOver=TRUE;
			Wb5PostTieGame();
			game_finished = TRUE;
			goto loopback;
		}  /* end if - game board full */
		else  {
	/* Toggle current turn */
			current_turn = ((current_turn == R) ? S : R);
		}  /* end if else */
		}	/* end if else - check if game board is full or there is a winner */
	}  /* end while - game in progress */

loopback:
	do {
		T24PutTime();
	} while(!keypressed());
	c = GetKey();
	switch( c )
		{
			case 13: if(WbGameOver==TRUE) goto loopback;
					if(Wb5MarkPlayerSpot()==0) goto human_move;
					else goto loopback;
			case F1:  BeepSet=TRUE;
					Wb5NewGame();
					InProgress=FALSE;
					game_finished = TRUE;
					goto restart;
			case F3:	 game_finished = TRUE;
								 BeepSet=TRUE;
					if(Warbird3WindowActive(1)==0) return(0);
			case F4:  BeepSet=TRUE;
					if(WbSetWhoGoesFirst()==0) return(0);
					else goto restart;
			case F5:		  game_finished = TRUE;
/*					 BeepSet=TRUE; */
					if(Wb5SetSkillLevel()==0) return(0);
					WbPostSkillLevel();
					goto restart;
			case F11: 	WbDoHelp();
					min_old=70;
					PanelBeep();
					goto loopback;
			case F12:	game_finished = TRUE;
					return(0);
			case LEFTARROW: if(WbGameOver==TRUE) goto loopback;
					Wb5CursorLeft();
					goto loopback;
			case RIGHTARROW: if(WbGameOver==TRUE) goto loopback;
					Wb5CursorRight();
					goto loopback;
			case UPARROW:	if(WbGameOver==TRUE) goto loopback;
					Wb5CursorUp();
					goto loopback;
			case DOWNARROW: if(WbGameOver==TRUE) goto loopback;
					Wb5CursorDown();
					goto loopback;
			case CTRL_F1: Screenshot792("Wb5.bmp");
					PanelBeep();
					goto loopback;
			default:	 goto loopback;
		}
	return(0);
}
void Wb5ShowStars()
{
	int x,y,i,c;
	int PaintBox[6];

	PaintBox[0]=makecol(102,102,102);
	PaintBox[1]=makecol(58,58,58);
	PaintBox[2]=makecol(80,80,80);
	PaintBox[3]=makecol(58,58,58);
	PaintBox[4]=makecol(90,90,90);
	PaintBox[5]=makecol(58,58,58);

	srand( (unsigned int)time( NULL ) );

	for(i=0; i < 2400; ++i) {
		x = rand() % 667;
		y = rand() % 500;
		c = rand() % 6;
		putpixel(screen,x+10,y+50,PaintBox[c]);
	}
}
void WbShowStars()
{
	int x,y,i,c;
	int PaintBox[6];

	PaintBox[0]=makecol(102,102,102);
	PaintBox[1]=makecol(58,58,58);
	PaintBox[2]=makecol(80,80,80);
	PaintBox[3]=makecol(58,58,58);
	PaintBox[4]=makecol(90,90,90);
	PaintBox[5]=makecol(58,58,58);

	srand( (unsigned int)time( NULL ) );

	for(i=0; i < 2400; ++i) {
		x = rand() % 670;
		y = rand() % 350;
		c = rand() % 6;
		putpixel(screen,x+120,y+239,PaintBox[c]);
	}
}
int WbDrawGrid()
{
	int h0,h1, h2, h3, GRIDGRAY;

	WbClearBottom();
	WbShowStars();
	GRIDGRAY=makecol(58,58,58);

	h1=358;
	h0=h1-WbSqSize;
	h2=h1+WbSqSize;
	h3=h2+WbSqSize;

	vline(screen,300-WbSqSize,ly+22,589,GRIDGRAY);
	vline(screen,300,ly+22,589,GRIDGRAY);
	vline(screen,300+WbSqSize,ly+22,589,GRIDGRAY);
	vline(screen,300+(WbSqSize*2),ly+22,589,GRIDGRAY);
	vline(screen,300+(WbSqSize*3),ly+22,589,GRIDGRAY);
	vline(screen,300+(WbSqSize*4),ly+22,589,GRIDGRAY);
/* WHITE to emphasize the part of the grid for the game */
	vline(screen,300,h0+1,h3-1,WHITE);
	vline(screen,300+WbSqSize,h0+1,h3-1,WHITE);

	hline(screen,120,h0,790,GRIDGRAY);
	hline(screen,120,h1,790,GRIDGRAY);
	hline(screen,120,h2,790,GRIDGRAY);
	hline(screen,120,h3,790,GRIDGRAY);
/* WHITE to emphasize the part of the grid for the game */
	hline(screen,301-WbSqSize,h1,299+(WbSqSize*2),WHITE);
	hline(screen,301-WbSqSize,h2,299+(WbSqSize*2),WHITE);

/* label only the squares in play */
	PutsLuna(277,h1-18,LAVENDER,BLACK, "045");
	PutsLuna(277+WbSqSize,h1-18,LAVENDER,BLACK, "046");
	PutsLuna(277+(WbSqSize*2),h1-18,LAVENDER,BLACK, "047");

	PutsLuna(277,h2-18,LAVENDER,BLACK, "055");
	PutsLuna(277+WbSqSize,h2-18,LAVENDER,BLACK, "056");
	PutsLuna(277+(WbSqSize*2),h2-18,LAVENDER,BLACK, "057");

	PutsLuna(277,h3-18,LAVENDER,BLACK, "065");
	PutsLuna(277+WbSqSize,h3-18,LAVENDER,BLACK, "066");
	PutsLuna(277+(WbSqSize*2),h3-18,LAVENDER,BLACK, "067");

	WbParkCursor();
	return(0);
}
int Wb5DrawGrid()
{
	int s, GRIDGRAY;

	Wb5ShowStars();
	s=WbSqSize;
	GRIDGRAY=makecol(58,58,58);

	hline(screen,10,20+s,677,GRIDGRAY);
	hline(screen,10,20+(s*2),677,GRIDGRAY);
	hline(screen,10,20+(s*3),677,GRIDGRAY);
	hline(screen,10,20+(s*4),677,GRIDGRAY);
/* WHITE to emphasize the part of the grid for the game */
	hline(screen,31,20+s,29+(s*5),WHITE);
	hline(screen,31,20+(s*2),29+(s*5),WHITE);
	hline(screen,31,20+(s*3),29+(s*5),WHITE);
	hline(screen,31,20+(s*4),29+(s*5),WHITE);

	vline(screen,30,50,550,GRIDGRAY);
/* WHITE to emphasize the part of the grid for the game */
	vline(screen,30+(s*1),50,550,WHITE);
	vline(screen,30+(s*2),50,550,WHITE);
	vline(screen,30+(s*3),50,550,WHITE);
	vline(screen,30+(s*4),50,550,WHITE);
	vline(screen,30+(s*5),50,550,GRIDGRAY);


	PutsLuna((s*1)+7,20+(s*1)-18,LAVENDER,BLACK, "212");
	PutsLuna((s*2)+7,20+(s*1)-18,LAVENDER,BLACK, "213");
	PutsLuna((s*3)+7,20+(s*1)-18,LAVENDER,BLACK, "214");
	PutsLuna((s*4)+7,20+(s*1)-18,LAVENDER,BLACK, "215");
	PutsLuna((s*5)+7,20+(s*1)-18,LAVENDER,BLACK, "216");

	PutsLuna((s*1)+7,20+(s*2)-18,LAVENDER,BLACK, "222");
	PutsLuna((s*2)+7,20+(s*2)-18,LAVENDER,BLACK, "223");
	PutsLuna((s*3)+7,20+(s*2)-18,LAVENDER,BLACK, "224");
	PutsLuna((s*4)+7,20+(s*2)-18,LAVENDER,BLACK, "225");
	PutsLuna((s*5)+7,20+(s*2)-18,LAVENDER,BLACK, "226");

	PutsLuna((s*1)+7,20+(s*3)-18,LAVENDER,BLACK, "232");
	PutsLuna((s*2)+7,20+(s*3)-18,LAVENDER,BLACK, "233");
	PutsLuna((s*3)+7,20+(s*3)-18,LAVENDER,BLACK, "234");
	PutsLuna((s*4)+7,20+(s*3)-18,LAVENDER,BLACK, "235");
	PutsLuna((s*5)+7,20+(s*3)-18,LAVENDER,BLACK, "236");

	PutsLuna((s*1)+7,20+(s*4)-18,LAVENDER,BLACK, "242");
	PutsLuna((s*2)+7,20+(s*4)-18,LAVENDER,BLACK, "243");
	PutsLuna((s*3)+7,20+(s*4)-18,LAVENDER,BLACK, "244");
	PutsLuna((s*4)+7,20+(s*4)-18,LAVENDER,BLACK, "245");
	PutsLuna((s*5)+7,20+(s*4)-18,LAVENDER,BLACK, "246");

	Wb5ParkCursor();
	return(0);
}
int Wb3Screen()
{
	rectfill(screen,0,0,800,600,BLACK);
	Brackets1(BIGBLUE,PALEBLUE);
	WbBoxes();
	MarsF(465,10,2, ORANGE,BLACK,"WARBIRD STANDOFF");
	PutsLuna(465,78,PURPLE,BLACK,"TIC-TAC-TOE IN THE NEUTRAL ZONE");
	PutsLuna(465,102,LAVENDER,BLACK,"GRID SIZE, AI LEVEL, WHO GOES FIRST SELECTABLE");
	ButtonType1(500+62,144,BRICK,"ARROW KEYS");
	ButtonType1(620+62,144,NAPLES,"ENTER");
/* vline(screen,792,13, 300, BORG); alignment check */
	WbPlayMode=3;
	WbPostSkillLevel();
	WbGameOver=TRUE;
	min_old=70;
	return(0);
}
void Wb5Brackets()
{
	NortheastElbow(662,13,LILAC);
	rectfill(screen,12,13,799-12-126,39,LILAC);
	SoutheastElbow(662,MaxY-12,LILAC);
	rectfill(screen,12, MaxY-26-12, 799-12-126, MaxY-12, LILAC);
/* extra filler--no boxes for F11, F12 */
	rectfill(screen,799-100-12, 461, 799-12, 542, LILAC);

	min_old=70;
	T24PutTime();
	Title("WARBIRD STANDOFF");
}
void Wb5Box(int Hue, int Pos, char *Label1, char *Label2)
{
	int boxtop;

	boxtop=(39*Pos)+12+17;	/* was 48 */
	rectfill(screen,799-100-12,boxtop,799-12,boxtop+35,Hue);
	PutsLuna(799-96-12,boxtop+4, BLACK,Hue, Label1);
	PutsLuna(799-2-StrLenLuna(Label2)-12,boxtop+4,BLACK,Hue,Label2);
}
void Wb5MessageBoxes()
{	 /* position range: 1 to 10 */
	Wb5Box(MANGO, 1, "NEW GAME","F1");
	Wb5Box(MANGO, 2, "","");
	Wb5Box(NAPLES, 3, "GRID SIZE","F3");
	Wb5Box(MANGO, 4, "FIRST","F4");
	Wb5Box(PURPLE, 5, "LEVEL","F5");
	Wb5Box(PALEBLUE, 6, "HELP","F11");
/* Wb5Box(BRICK, 9, "","F9"); */
}
void Wb5LowerMessageBoxes()
{
	Wb5Box(ORANGE, 10, "CLOSE","F12");
/* Wb5Box(ORANGE, 11, "","");	  */
/* Wb5Box(ORANGE, 12, "","");	  */
}
int Wb5Screen()
{
	rectfill(screen,0,0,800,600,BLACK);
	Wb5Brackets();
	Wb5MessageBoxes();
	Wb5LowerMessageBoxes();
	WbPlayMode=5;
	WbPostSkillLevel();
	WbGameOver=TRUE;
	WbPlayMode=5;
	min_old=70;
	return(0);
}
int WarbirdMode()
{
	Wb3Level=3;
	Wb5Level=3;
	WbSqSize=112;
	InProgress=FALSE;
	MaxY=599;
	Wb3Screen(); /* draw screen before accessing disk */

	bmp1 = create_bitmap(106,52); /* to erase the cursor */
	clear_to_color(bmp1,BLACK); /* better for 256-color machines than clear_bitmap() */

	/* Romulan Warbird and Intrepid-class starship */
	SetCurrentFile("\\LC24APPS\\WARBIRD\\ROMWB.BMP");
	rom=load_bitmap(CurrentFile, the_palette);
	if (!rom) {
		destroy_bitmap(bmp1);
		NormalLoadError("\\LCARS24\\LC24APPS\\WARBIRD\\ROMWB.BMP, VOY.BMP");
		return(86);
	}
	SetCurrentFile("\\LC24APPS\\WARBIRD\\VOY.BMP");
	voy=load_bitmap(CurrentFile, the_palette);
	if (!rom) {
		destroy_bitmap(bmp1);
		NormalLoadError("\\LCARS24\\LC24APPS\\WARBIRD\\ROMWB.BMP, VOY.BMP");
		return(86);
	}
	OpponentGoesFirst=TRUE;
	Warbird3WindowActive(0);	/* play; 0 not to redraw the screen */
	destroy_bitmap(rom);
	destroy_bitmap(voy);
	destroy_bitmap(bmp1);
	return(0);
}
/* eof */

