// jack.c
// Black Jack card game

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <dos.h>
#include <ctype.h>
#include <time.h>

typedef struct {
	short suit;
	short value;
} card;

void Border();
void FillDeck();
void Shuffle();
void Line1(card* carte);
void Line2(card* carte);
void Line3(card* carte);
void Line4(card* carte);
void Line5(card* carte);
void Line6(card* carte);
void Line7(card* carte);
void PutCard(card* carte, short x, short y);
void ShowMsg(char msg[], short cursor);
void ShowStatus(char status[], int statuscolor);
void ResetPts();
void CalcPts();
void CalcSplitPts();
void ReShuffle();
void ShowScore();
void ClrView();
int  EscHandler();

const BLANK = 0;
const HEARTS = 3;
const DIAMONDS = 4;
const CLUBS = 5;
const SPADES = 6;
const JACK = 11;
const QUEEN = 12;
const KING = 13;
const ESC = 27;

const COLORSCREEN = 1;
const MONOCHROME = 2;
const LCD = 3;
short displaytype;
short white, black, blue, lightred, lightgreen, yellow, lightgray;

card structdeck[52];
card* deck[52];
card* dealer[6];
card* player[6];
short dealerpts, playerpts;
short split1pts, split2pts;
int score;
short hideflag;
short splitflag;
short playerdealt, dealerdealt;
short cardsdealt;

short cursorxdealer, cursorydealer;
short cursorxplayer, cursoryplayer;
short i;
short insuranceflag;
short doubledownflag;
short blackjackflag;
short bonusflag;
char answer;
card structblankcard;
card* blankcard = &structblankcard;
char coverstr[11 + 1];
char fullstr[11 + 1];
struct text_info screen;

void main(int argc, char* argv[])
{
if (argc == 2
&& (strcmp(argv[1], "/MONO") == 0 || strcmp(argv[1], "/mono") == 0))
	displaytype = MONOCHROME;
else if (argc == 2
	  && (strcmp(argv[1], "/LCD") == 0 || strcmp(argv[1], "/lcd") == 0))
	displaytype = LCD;
else if (argc == 1)
	displaytype = COLORSCREEN;
else
{
	printf("\nYou entered an invalid option.\n");
	printf("\nThe valid options are:\n");
	printf("/MONO or /mono for a monochrome screen.\n");
	printf("/LCD or /lcd for an LCD screen.\n");
	printf("The default (no option) is for a color screen.\n\n");
	exit(1);
}

switch (displaytype)
{
	case COLORSCREEN:
		white = WHITE;
		black = BLACK;
		blue = BLUE;
		lightred = LIGHTRED;
		lightgreen = LIGHTGREEN;
		yellow = YELLOW;
		lightgray = LIGHTGRAY;
		break;
	case MONOCHROME:
		white = DARKGRAY;
		black = DARKGRAY;
		blue = GREEN;
		lightred = DARKGRAY;
		lightgreen = DARKGRAY;
		yellow = DARKGRAY;
		lightgray = WHITE;
		break;
	case LCD:
		white = GREEN;
		black = GREEN;
		blue = BLUE;
		lightred = GREEN;
		lightgreen = GREEN;
		yellow = GREEN;
		lightgray = BLACK;
		break;
}

// ² IS 178 0R xB2
for (i = 0; i < 11; i++) coverstr[i] = '\xB2';
coverstr[11] = '\0';
// Û IS 219 OR \xDB
for (i = 0; i < 11; i++) fullstr[i] = '\xDB';
fullstr[11] = '\0';

cardsdealt = 0;
score = 500;
blankcard->value = BLANK;
blankcard->suit = BLANK;

ctrlbrk(EscHandler);
setcbrk(1);
gettextinfo(&screen);
textmode(BW80);
_setcursortype(_NOCURSOR);
highvideo();
textbackground(blue);
_setcursortype(_NOCURSOR);
clrscr();
Border();
FillDeck();
ShowScore();
Shuffle();
ShowMsg("DEAL / QUIT (D/Q)? ", 1);
do
{   
	answer = toupper(getch());
	if (answer == ESC) EscHandler();
} while (!(answer == 'D' || answer == 'Q'));

while (answer == 'D' && score >= 20)
{
	dealerpts = 0;
	playerpts = 0;
	split1pts = 0;
	split2pts = 0;
	hideflag = 0;
	insuranceflag = 0;
	doubledownflag = 0;
	blackjackflag = 0;
	bonusflag = 0;
	splitflag = -1;
	dealerdealt = 0;
	playerdealt = 0;
	score -= 20;

	ClrView();
	ResetPts();
	CalcPts();
	ShowScore();
	sleep(1);

	cursorxplayer = 3;
	cursoryplayer = 14;
	if (cardsdealt == 52) ReShuffle();
	player[playerdealt] = deck[cardsdealt];
	PutCard(player[playerdealt], cursorxplayer, cursoryplayer);
	cardsdealt ++;
	playerdealt ++;
	CalcPts();
	ShowScore();
	sleep(1);

	cursorxdealer = 3;
	cursorydealer = 5;
	if (cardsdealt == 52) ReShuffle();
	dealer[dealerdealt] = deck[cardsdealt];
	PutCard(dealer[dealerdealt], cursorxdealer, cursorydealer);
	cardsdealt ++;
	dealerdealt ++;
	CalcPts();
	ShowScore();
	sleep(1);

	cursorxplayer += 13;
	if (cardsdealt == 52) ReShuffle();
	player[playerdealt] = deck[cardsdealt];
	PutCard(player[playerdealt], cursorxplayer, cursoryplayer);
	cardsdealt ++;
	playerdealt ++;
	CalcPts();
	ShowScore();
	if (playerpts == 21) blackjackflag = 1;
	sleep(1);
	if (cardsdealt == 52) ReShuffle();
	dealer[dealerdealt] = deck[cardsdealt];
	cardsdealt ++;
	PutCard(blankcard, cursorxdealer + 13, cursorydealer);
	hideflag = 1;

	if (dealer[0]->value == 1 && blackjackflag != 1)
	{
		ShowMsg("INSURE (Y/N)? ", 1);
		do
		{
			answer = toupper(getch());
			if (answer == ESC) EscHandler();
		} while (!(answer == 'Y' || answer == 'N'));
		switch(answer)
		{
		case 'Y':
			if (score >= 10)
			{
				ShowMsg("INSURED . . .", 0);
				score -= 10;
				ShowScore();
				hideflag = 0;
				sleep(1);
				CalcPts();
				if (dealerpts == 21)
				{
					ShowMsg("INSURANCE WIN ! ! !", 0);
					ShowStatus("INSURANCE WIN", lightgreen + BLINK);
					insuranceflag = 1;
					cursorxdealer += 13;
					PutCard(dealer[dealerdealt], cursorxdealer, cursorydealer);
					cardsdealt ++;
					dealerdealt ++;
					score += 30;
					CalcPts();
					ShowScore();
				}
				else
				{
					ShowMsg("FOR NOTHING . . .", 0);
					insuranceflag = 2;
				}
				hideflag = 1;
			}
			else
			{
				ShowMsg("NOT ENOUGH CREDIT !", 0);
				sleep(1);
				ShowMsg("NOT INSURED . . .", 0);
			}
			CalcPts();
			break;
		case 'N':
			ShowMsg("NOT INSURED . . .", 0);
			insuranceflag = 0;
			break;
		}
		sleep(1);
	}

	if (playerpts == 11 && insuranceflag != 1)
	{
		ShowMsg("DOUBLE DOWN (Y/N)? ", 1);
		do
		{
			answer = toupper(getch());
			if (answer == ESC) EscHandler();
		} while (!(answer == 'Y' || answer == 'N'));
		switch(answer)
		{
		case 'Y':
			if (score >= 20)
			{
				ShowMsg("DOUBLE DOWN . . .", 0);
				doubledownflag = 1;
				score -= 20;
				ShowScore();
			}
			else
			{
				ShowMsg("NOT ENOUGH CREDIT...", 0);
				sleep(1);
				ShowMsg("NORMAL WAGER . . .", 0);
			}
			break;
		case 'N':
			ShowMsg("NORMAL WAGER . . .", 0);
			break;
		}
		sleep(1);
	}
	if (player[0]->value == player[1]->value && insuranceflag != 1)
		splitflag = 1;
	if (splitflag == 1)
	{
		splitflag = 0;
		ShowMsg("SPLIT (Y/N)? ", 1);
		do
		{
			answer = toupper(getch());
			if (answer == ESC) EscHandler();
		} while (!(answer == 'Y' || answer == 'N'));
		switch(answer)
		{
		case 'Y':
			if (score >= 20)
			{
				ShowMsg("SPLITTING . . .", 0);
				splitflag = 1;
				score -= 20;
				ShowScore();
			}
			else
			{
				ShowMsg("NOT ENOUGH CREDIT...", 0);
				sleep(1);
				ShowMsg("NO SPLIT . . .", 0);
				splitflag = -1;
			}
			break;
		case 'N':
			ShowMsg("NO SPLIT . . .", 0);
			splitflag = -1;
			break;
		}
		sleep(1);
	}
	if (splitflag == 1 && insuranceflag != 1)
	{
		window(cursorxplayer, cursoryplayer + 1,
				 cursorxplayer + 10, cursoryplayer + 7);
		textbackground(blue);
		clrscr();
		window(screen.winleft, screen.wintop, screen.winright, screen.winbottom);
		PutCard(player[playerdealt - 1], cursorxplayer + 3 * 13, cursoryplayer);
		sleep(1);
		if (cardsdealt == 52) ReShuffle();
		player[playerdealt] = deck[cardsdealt];
		PutCard(player[playerdealt], cursorxplayer, cursoryplayer);
		cardsdealt ++;
		playerdealt ++;
		sleep(1);
		if (cardsdealt == 52) ReShuffle();
		player[playerdealt] = deck[cardsdealt];
		PutCard(player[playerdealt], cursorxplayer + 4 * 13, cursoryplayer);
		cardsdealt ++;
		playerdealt ++;
		sleep(1);
	}

	if (insuranceflag != 1 && splitflag != 1 && playerpts < 21)
	{
		ShowMsg("HIT / STAND (H/S)? ", 1);
		do
		{
			answer = toupper(getch());
			if (answer == ESC) EscHandler();
		} while (!(answer == 'H' || answer == 'S'));
		if (answer == 'H')
		{
			do
			{
				if (cardsdealt == 52) ReShuffle();
				player[playerdealt] = deck[cardsdealt];
				cursorxplayer += 13;
				PutCard(player[playerdealt], cursorxplayer, cursoryplayer);
				cardsdealt ++;
				playerdealt ++;
				CalcPts();
				ShowScore();
				if (playerdealt < 6 && playerpts < 21)
				{
					ShowMsg("HIT / STAND (H/S)? ", 1);
					do
					{
						answer = toupper(getch());
						if (answer == ESC) EscHandler();
					} while (!(answer == 'H' || answer == 'S'));
				}
				CalcPts();
				if (playerpts > 21)
				{
					ShowStatus("LOST", lightred + BLINK);
					ShowMsg("DEALER WINS . . .", 0);
					sleep(1);
				}
			} while (answer == 'H' && playerpts < 21 && playerdealt < 6);
		}
	}

	// BY NOW, "STAND" IS THE DEFAULT
	if (playerpts == 21) sleep(1);
	if (insuranceflag != 1)
	{
		cursorxdealer += 13;
		PutCard(dealer[dealerdealt], cursorxdealer, cursorydealer);
		dealerdealt ++;
	}
	hideflag = 0;
	CalcPts();
	ShowScore();
	ShowMsg("STAND . . .", 0);
	if ((playerpts <= 21 || splitflag == 1) && insuranceflag != 1)
	{
		sleep(1);
		if (blackjackflag != 1 && insuranceflag != 1)
		{
			while (dealerpts < 17 && dealerdealt < 6)
			{
				if (cardsdealt == 52) ReShuffle();
				dealer[dealerdealt] = deck[cardsdealt];
				cursorxdealer += 13;
				PutCard (dealer[dealerdealt], cursorxdealer, cursorydealer);
				cardsdealt ++;
				dealerdealt ++;
				CalcPts();
				ShowScore();
				sleep(1);
			}
		}
	}

	CalcPts();
	ShowScore();

	// RESULTS SECTION
	if (insuranceflag != 1 && splitflag != 1)
	{
		if (playerpts > dealerpts || dealerpts > 21)
		{
			if (playerpts <= 21)
			{
				ShowMsg("PLAYER WINS ! ! !", 0);
				if (doubledownflag == 1)
				{
					ShowStatus("DOUBLE DOWN", lightgreen + BLINK);
					score += 80;
					ShowScore();
				}
				else if (blackjackflag == 1)
				{
					ShowStatus("BLACK JACK", lightgreen + BLINK);
					score += 50;
					ShowScore();
				}
				else if (playerdealt == 3)
				{
					switch(player[0]->value)
					{
					case 6:
						if (player[1]->value == 7)
							if (player[2]->value == 8) bonusflag = 1;
						else if (player[1]->value == 8)
							if (player[2]->value == 7) bonusflag = 1;
						break;
					case 7:
						if (player[1]->value == 6)
							if (player[2]->value == 8) bonusflag = 1;
						else if (player[1]->value == 8)
							if (player[2]->value == 6) bonusflag = 1;
						break;
					case 8:
						if (player[1]->value == 6)
							if (player[2]->value == 7) bonusflag = 1;
						else if (player[1]->value == 7)
							if (player[2]->value == 6) bonusflag = 1;
						break;
					}
					if (bonusflag == 1)
					{
						ShowStatus("BONUS", lightgreen + BLINK);
						score += 50;
						ShowScore();
					}
					else
					{
						ShowStatus("WIN", lightgreen + BLINK);
						score += 40;
					}
				}
				else
				{
					ShowStatus("WIN", lightgreen + BLINK);
					score += 40;
					ShowScore();
				}
			sleep(1);
			}
      }
		else if (playerpts == dealerpts && playerpts <= 21)
		{
			ShowMsg("NOBODY WINS . . .", 0);
			ShowStatus("PUSH", yellow + BLINK);
			if (doubledownflag == 1) score += 40;
			else score += 20;
			ShowScore();
			sleep(1);
		}
		else
		{
			ShowMsg("DEALER WINS . . .", 0);
			ShowStatus("LOST", lightred + BLINK);
			sleep(1);
		}
	}
	else if (splitflag == 1)
	{
		CalcPts();
		CalcSplitPts();
		ShowScore();
		if (split1pts == 21)
			if (dealerpts == 21 && dealerdealt == 1)
			{
				ShowMsg("SPLIT 1 PUSH . . .", 0);
				score += 20;
			}
			else
			{
				ShowMsg("BLACK JACK ! ! !", 0);
				score += 50;
			}
		else if ((split1pts > dealerpts || dealerpts > 21) && split1pts <= 21)
		{
			ShowMsg("SPLIT 1 WINS ! ! !", 0);
			score += 40;
			ShowScore();
		}
		else if (split1pts < dealerpts)
		{
			ShowMsg("SPLIT 1 LOST . . .", 0);
			splitflag = 0;
		}
		else
		{
			ShowMsg("SPLIT 1 PUSH . . .", 0);
			score += 20;
			ShowScore();
			splitflag = 2;
		}
		sleep(1);
		if (split2pts == 21)
			if (dealerpts == 21 && dealerdealt == 1)
			{
				ShowMsg("SPLIT 2 PUSH . . .", 0);
				score += 20;
			}
			else
			{
				ShowMsg("BLACK JACK ! ! !", 0);
				score += 50;
			}
		else if ((split2pts > dealerpts || dealerpts > 21) && split2pts <= 21)
		{
			ShowMsg("SPLIT 2 WINS ! ! !", 0);
			score += 40;
			ShowScore();
			if (splitflag == 1)
			{
				ShowStatus("SPLIT WIN", lightgreen + BLINK);
			}
			else if (splitflag == 2)
			{
				ShowStatus("WIN", lightgreen + BLINK);
			}
			else
			{
				ShowStatus("PUSH", yellow + BLINK);
			}
		}
		else if (split2pts < dealerpts)
		{
			ShowMsg("SPLIT 2 LOST . . .", 0);
			if (splitflag == 1)
			{
				ShowStatus("PUSH", yellow + BLINK);
			}
			else
			{
				ShowStatus("SPLIT LOST", lightred + BLINK);
			}
		}
		else
		{
			ShowMsg("SPLIT 2 PUSH . . .", 0);
			score += 20;
			ShowScore();
			if (splitflag == 1)
			{
				ShowStatus("WIN", lightgreen + BLINK);
			}
			else if (splitflag == 0)
			{
				ShowStatus("SPLIT LOST", lightred + BLINK);
			}
			else
			{
				ShowStatus("SPLIT PUSH", yellow + BLINK);
			}
		}
		if (splitflag != 1) ShowScore();
		sleep(1);
	}

	ShowScore();
	ShowMsg("DEAL / QUIT (D/Q)? ", 1);
	do
	{
		if (splitflag != -1)
		{
			do
			{
				_setcursortype(_NOCURSOR);
				textcolor(yellow);
				gotoxy (77, 24);
				cprintf("%2d", split1pts);
				gotoxy(36, 24);
				_setcursortype(_NORMALCURSOR);
				textcolor(white);
				sleep(1);
				_setcursortype(_NOCURSOR);
				textcolor(yellow);
				gotoxy (77, 24);
				cprintf("%2d", split2pts);
				gotoxy(36, 24);
				_setcursortype(_NORMALCURSOR);
				textcolor(white);
				sleep(1);
			} while (!kbhit());
		}
		answer = toupper(getch());
		if (answer == ESC) EscHandler();
	} while (!(answer == 'D' || answer == 'Q'));

	if (score < 20)
	{
		ShowMsg("NOT ENOUGH CREDIT...", 0);
		sleep(1);
		answer = 'Q';
	}

	if (answer == 'Q')
	{
		ShowMsg("ANOTHER GAME (Y/N)? ", 1);
		do
		{
			answer = toupper(getch());
			if (answer == ESC) EscHandler();
		} while (!(answer == 'Y' || answer == 'N'));
		if (answer == 'Y')
		{
			ClrView();
			score = 500;
			cardsdealt = 0;
			ResetPts();
			CalcPts();
			ShowScore();
			FillDeck();
			Shuffle();
			sleep(1);
			answer = 'D';
		}
	}
} // end while

ClrView();
ShowMsg("GAME OVER . . .", 0);
sleep(1);

EscHandler();

} // end main

void Border()
{   
	// É IS 201 OR xC9
	// Í IS 205 OR xCD
	// » IS 187 OR xBB
	// º IS 186 OR xBA
	// È IS 200 OR xC8
	// ¼ IS 188 OR xBC
	// Ì IS 204 OR xCC
	// ¹ IS 185 OR xB9
	// ³ IS 179 OR xB3
	// Ñ IS 209 OR xD1
	// Ï IS 207 OR xCF
	// Ë IS 203 OR xCB
	// Ê IS 202 OR xCA
	short i; 
	char buffer[3];
	textcolor(white);
	gotoxy (1, 1);
	putch('\xC9');
	for (i = 0; i < 78; i++) putch('\xCD');
	putch('\xBB');
	for (i = 2; i < 25; i++)
	{
		gotoxy (1, i);
		putch('\xBA');
		gotoxy (80, i);
		putch('\xBA');
	}
	gotoxy (1, 25);
	putch('\xC8');
	for (i = 0; i < 78; i++) putch('\xCD');
	// For outputing text to the very lower left corner of the screen
	gotoxy(79, 25);
	putch('\xBC');
	gettext(78, 25, 79, 25, buffer);
	puttext(79, 25, 80, 25, buffer);
	
	gotoxy (1, 4);
	putch('\xCC');
	for (i = 0; i < 78; i++) putch('\xCD');
	putch('\xB9');
	gotoxy (2, 2);
	cputs("BLACK JACK");
	gotoxy (2, 3);
	cputs("    21");
	gotoxy (12, 1);
	putch('\xCB');
	gotoxy (12, 2);
	putch('\xBA');
	gotoxy (12, 3);
	putch('\xBA');
	gotoxy (12, 4);
	putch('\xCA');
	gotoxy (14, 2);
	cputs("DOUBLE DOWN WIN  80");
	gotoxy (14, 3);
	cputs("BLACK JACK/BONUS 50");
	gotoxy (34, 1);
	putch('\xD1');
	gotoxy (34, 2);
	putch('\xB3');
	gotoxy (34, 3);
	putch('\xB3');
	gotoxy (34, 4);
	putch('\xCF');
	gotoxy (36, 2);
	cputs("WINNER HAND       40");
	gotoxy (36, 3);
	cputs("INSURANCE WIN     30");
	gotoxy (57, 1);
	putch('\xD1');
	gotoxy (57, 2);
	putch('\xB3');
	gotoxy (57, 3);
	putch('\xB3');
	gotoxy (57, 4);
	putch('\xCF');
	gotoxy (59, 2);
	cputs("PUSH              20");
	gotoxy (59, 3);
	cputs("DEALER STANDS ON  17");
	gotoxy (1, 23);
	putch('\xCC');
	for (i = 0; i < 78; i++) putch('\xCD');
	putch('\xB9');
	gotoxy (3, 24);
	cputs("SCORE:");
	gotoxy (15, 23);
	putch('\xD1');
	gotoxy (15, 24);
	putch('\xB3');
	gotoxy (15, 25);
	putch('\xCF');
	gotoxy (38, 23);
	putch('\xD1');
	gotoxy (38, 24);
	putch('\xB3');
	gotoxy (38, 25);
	putch('\xCF');
	gotoxy (54, 23);
	putch('\xD1');
	gotoxy (54, 24);
	putch('\xB3');
	gotoxy (54, 25);
	putch('\xCF');
	gotoxy (56, 24);
	cputs("DEALER:");
	gotoxy (67, 23);
	putch('\xD1');
	gotoxy (67, 24);
	putch('\xB3');
	gotoxy (67, 25);
	putch('\xCF');
	gotoxy (69, 24);
	cputs("PLAYER:");
}

void CalcPts()
{
	short i ;
	short dealeraceflag , playeraceflag;
	dealeraceflag = 0;
	playeraceflag = 0;
	dealerpts = 0;
	playerpts = 0;
	for (i = 0; i < 6; i++)
	{
		if (!(i == 1 && hideflag == 1))
		{
			switch(dealer[i]->value)
			{
			case JACK: 
			case QUEEN:
			case KING:
				dealerpts += 10;
				break;
			case 1:
				if (dealeraceflag == 0) dealeraceflag = 1;
				// if there is an ace already, the new ace is only worth 1
				else dealerpts ++;
				break;
			default:
				dealerpts += dealer[i]->value;
				break;
			}
		}
		switch(player[i]->value)
		{
		case JACK: 
		case QUEEN:
		case KING:
			playerpts += 10;
			break;
		case 1:
			if (playeraceflag == 0) playeraceflag = 1;
			// if there is an ace already, the new ace is only worth 1
			else playerpts ++;
			break;
		default:
			playerpts += player[i]->value;
			break;
		}
	}
	if (dealeraceflag == 1)
	{
		if (dealerpts <= 10) dealerpts += 11;
		else dealerpts ++;
	}
	if (playeraceflag == 1)
	{
		if (playerpts <= 10) playerpts += 11;
		else playerpts ++;
	}
}

void CalcSplitPts()
{
	short i; 
	short split1aceflag , split2aceflag ;
	split1aceflag = 0;
	split2aceflag = 0;
	split1pts = 0;
	split2pts = 0;
	for (i = 0; i < 4; i++)
	{
		switch(i)
		{
		case 0:
		case 2:
			switch(player[i]->value)
			{
			case JACK: 
			case QUEEN: 
			case KING:
				split1pts += 10;
				break;
			case 1:
				if (split1aceflag == 0) split1aceflag = 1;
				// if there is an ace already, the new ace is only worth 1
				else split1pts ++;
				break;
			default:
				split1pts += player[i]->value;
				break;
			}
			break;
		case 1:
		case 3:
			switch(player[i]->value)
			{
			case JACK:
			case QUEEN:
			case KING:
				split2pts += 10;
				break;
			case 1:
				if (split2aceflag == 0) split2aceflag = 1;
				// if there is an ace already, the new ace is only worth 1
				else split2pts ++;
				break;
			default:
				split2pts += player[i]->value;
				break;
			}
			break;
		}
	}
	if (split1aceflag == 1)
	{
		if (split1pts <= 10) split1pts += 11;
		else split1pts ++;
	}
	if (split2aceflag == 1)
	{
		if (split2pts <= 10) split2pts += 11;
		else split2pts ++;
	}
}

void ClrView()
{
	window(2, 5, 78, 22);
	textbackground(blue);
	clrscr();
	window(screen.winleft, screen.wintop, screen.winright, screen.winbottom);
	textbackground(blue);
	ShowMsg("", 0);
	ShowStatus("", white);
	gotoxy (64, 24);
	cputs("  ");
	gotoxy (77, 24);
	cputs("  ");
	textcolor(white);
}

void FillDeck()
{
	short ctr , i , j;
	ctr = 0;
	for (j = HEARTS; j <= SPADES; j++)
	{
		for (i = 1; i <= KING; i++)
		{
			structdeck[ctr].value = i;
			structdeck[ctr].suit = j;
			deck[ctr] = &structdeck[ctr];
			ctr ++;
		}
	}
}

void Line1(card* carte)
{
	char face;
	switch(carte->value)
	{
	case 1:
		face = 'A';
		break;
	case JACK:
		face = 'J';
		break;
	case QUEEN:
		face = 'Q';
		break;
	case KING:
		face = 'K';
		break;
	}
	switch(carte->value)
	{
	case BLANK:
		cputs(coverstr);
		break;
	case 1: 
	case JACK: 
	case QUEEN: 
	case KING:
		cprintf(" %c         ", face);
		break;
	case 4: 
	case 5:
	case 6: 
	case 7:
	case 8: 
	case 9:
	case 10:
		cprintf(" %c       %c ", carte->suit, carte->suit);
		break;
	default:
		cputs("           ");
		break;
	}
}

void Line2(card* carte)
{
	switch(carte->value)
	{
	case BLANK:
		cputs(coverstr);
		break;
	case 1:
	case JACK: 
	case QUEEN: 
	case KING:
		cprintf(" %c         ", carte->suit);
		break;
	case 2 :
	case 3: 
	case 10:
		cprintf("     %c     ", carte->suit);
		break;
	default:
		cputs("           ");
		break;
	}
}

void Line3(card* carte)
{
	switch(carte->value)
	{
	case BLANK:
		cputs(coverstr);
		break;
	case 8:
	case 9:
	case 10:
		cprintf(" %c       %c ", carte->suit, carte->suit);
		break;
	default:
		cputs("           ");
		break;
	}
}

void Line4(card* carte)
{
	switch(carte->value)
	{
	case BLANK:
		cputs(coverstr);
		break;
	case 1:
	case 3:
	case 5:
		cprintf("     %c     ", carte->suit);
		break;
	case 6:
	case 7:
		cprintf(" %c       %c ", carte->suit, carte->suit);
		break;
	default:
		cputs("           ");
		break;
	}
}

void Line5(card* carte)
{
	switch(carte->value)
	{
	case BLANK:
		cputs(coverstr);
		break;
	case 8: 
	case 9: 
	case 10:
		cprintf(" %c       %c ", carte->suit, carte->suit);
		break;
	default:
		cputs("           ");
		break;
	}
}

void Line6(card* carte)
{
	char face ;
	switch(carte->value)
	{
	case 1:
		face = 'A';
		break;
	case JACK:
		face = 'J';
		break;
	case QUEEN:
		face = 'Q';
		break;
	case KING:
		face = 'K';
		break;
	}
	switch(carte->value)
	{
	case BLANK:
		cputs(coverstr);
		break;
	case 1:
	case JACK: 
	case QUEEN: 
	case KING:
		cprintf("         %c ", face);
		break;
	case 2: 
	case 3: 
	case 7:
	case 9: 
	case 10:
		cprintf("     %c     ", carte->suit);
		break;
	default:
		cputs("           ");
		break;
	}
}

void Line7(card* carte)
{
	switch(carte->value)
	{
	case BLANK:
		cputs(coverstr);
		break;
	case 1:
	case JACK: 
	case QUEEN:
	case KING:
		cprintf("         %c ", carte->suit);
		break;
	case 4: 
	case 5:
	case 6: 
	case 7:
	case 8: 
	case 9:
	case 10:
		cprintf(" %c       %c ", carte->suit, carte->suit);
		break;
	default:
		cputs("           ");
		break;
	}
}

void PutCard(card* carte, short x, short y)
{
	window(x, y + 1, x + 10, y + 7);
	textbackground(lightgray);
	clrscr();
	window(screen.winleft, screen.wintop, screen.winright, screen.winbottom);
	switch(carte->suit)
	{
	case BLANK:
	case HEARTS: 
	case DIAMONDS:
		textcolor(lightred);
		break;
	default:
		textcolor(black);
		break;
	}
	gotoxy (x, y + 1);
	Line1(carte);
	gotoxy (x, y + 2);
	Line2(carte);
	gotoxy (x, y + 3);
	Line3(carte);
	gotoxy (x, y + 4);
	Line4(carte);
	gotoxy (x, y + 5);
	Line5(carte);
	gotoxy (x, y + 6);
	Line6(carte);
	gotoxy (x, y + 7);
	Line7(carte);
	textbackground(blue);
}

void ResetPts()
{
	short i ;
	for (i = 0; i < 6; i++) dealer[i] = player[i] = blankcard;
}

void ReShuffle()
{
	short i , j;
	card* temp;
	Shuffle();
	cardsdealt = 0;
	for (j = 0; j < 52; j++)
	{
		for (i = 0; i < dealerdealt; i++)
		{
			if (deck[cardsdealt]->value == dealer[dealerdealt]->value)
			{
				temp = deck[dealerdealt];
				deck[dealerdealt] = deck[cardsdealt];
				deck[cardsdealt] = temp;
				cardsdealt ++;
			}
		}
		for (i = 0; i < playerdealt; i++)
		{
			if (deck[cardsdealt]->value == player[playerdealt]->value)
			{
				temp = deck[playerdealt];
				deck[playerdealt] = deck[cardsdealt];
				deck[cardsdealt] = temp;
				cardsdealt ++;
			}
		}
	}
	ShowMsg("", 0);
}

void ShowMsg(char msg[], short cursor)
{
	textcolor(white);
	gotoxy (17, 24);
	cputs("                   ");
	if (cursor == 2) textcolor(white + BLINK);
	else textcolor(white);
	gotoxy (17, 24);
	cputs(msg);
	cputs(" ");
	gotoxy (17 + strlen(msg), 24);
	if (cursor == 1) _setcursortype(_NORMALCURSOR);
	else _setcursortype(_NOCURSOR);
}

void ShowScore()
{
	_setcursortype(_NOCURSOR);
	textcolor(yellow);
	gotoxy (9, 24);
	cprintf("%5d", score);
	if (dealerpts != 0)
	{
		gotoxy (64, 24);
		cprintf("%2d", dealerpts);
	}
	gotoxy (77, 24);
	if (playerpts != 0 && splitflag == -1)
		cprintf("%2d", playerpts);
	else
	{
		cputs("  ");
	}
}

void ShowStatus(char status[], int statuscolor)
{
	_setcursortype(_NOCURSOR);
	gotoxy(40, 24);
	textcolor(white);
	cputs("              ");
	textcolor(statuscolor);
	gotoxy(40, 24);
	cputs(status);
}

void Shuffle()
{
	short i, j ;
	card* temp;
	ShowMsg("SHUFFLING . . .", 2);
	sleep(1);
	randomize();
	for (i = 0; i < 52; i++)
	{
		j = random(52);
		temp = deck[i];
		deck[i] = deck[j];
		deck[j] = temp;
	}
}

int EscHandler()
{
	_setcursortype(_NORMALCURSOR);
	textmode(screen.currmode);
	clrscr();
	exit(1);
	return 0;
}