[comp.sources.games] v02i052: mastrm - Master Mind in C

games-request@tekred.TEK.COM (09/18/87)

Submitted by: granger@cg-atla.UUCP (Peter Granger )
Comp.sources.games: Volume 2, Issue 52
Archive-name: mastrm

	[Compiled and ran OK on our 4.3bsd Vax.  No other gaurantees.
		-br]

#! /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 shell archive."
# Contents:  README mastrm.c
# Wrapped by billr@tekred on Thu Sep 17 17:03:50 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(679 characters\)
sed "s/^X//" >README <<'END_OF_README'
X  This game, Master Mind, was written by Peter E. Granger and released to
X  the public domain via Usenet on Sept. 1, 1987.  Master Mind is based on
X  the game by the same name which is  marketed by Invicta Plastics.  This
X  game has not been licensed or recognized in anyway by Invicta Plastics.
X  Master Mind, as presented here, is intended solely for the enjoyment of
X  the public, and is not to be used for profit.  Recipients are permitted
X  to redistribute this  code as long as  they do not  attempt to gain any
X  profit from it, and may edit this code as they see fit.
X
X                                                      - Pete Granger
X						      granger@cg-atla.UUCP
END_OF_README
if test 679 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mastrm.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"mastrm.c\"
else
echo shar: Extracting \"mastrm.c\" \(18986 characters\)
sed "s/^X//" >mastrm.c <<'END_OF_mastrm.c'
X/*****************************************************************************
X
X  This game, Master Mind, was written by Peter E. Granger and released to
X  the public domain via Usenet on Sept. 1, 1987.  Master Mind is based on
X  the game by the same name which is  marketed by Invicta Plastics.  This
X  game has not been licensed or recognized in anyway by Invicta Plastics.
X  Master Mind, as presented here, is intended solely for the enjoyment of
X  the public, and is not to be used for profit.  Recipients are permitted
X  to redistribute this  code as long as  they do not  attempt to gain any
X  profit from it, and may edit this code as they see fit.
X
X                                                      - Pete Granger
X
X ***************************************************************************/
X
X#include <stdio.h>
X
X#define FALSE 0
X#define TRUE 1
X#define NONE 0
X#define WHITE 1
X#define BLACK 2
X#define BAD_COLOR -1
X
X	struct peg { int color;
X				 int used   };
X
X	struct guess { struct peg pegs[4];
X				   int blacks, whites  };
X				   
X	static char *col[6] = { "white",
X                            "black",
X                            "red",
X                            "green",
X                            "yellow",
X                            "blue"    };
X	int dig[6];
X	int cur;
X	struct guess guesses[18];
X	struct guess dummy[18];
X	struct guess code;
X	int game_won, player, check, cons;
X
Xsetcolors()
X{
X	extern int dig[];
X	int x, val, y;
X	int digit_found, place_found;
X
X	for (x = 0; x < 6; x++)
X		dig[x] = BAD_COLOR;
X	for (x = 6; x > 1; x--)
X	{
X		val = rand() % x;
X		place_found = FALSE;
X		while (!place_found)
X		{
X			digit_found = FALSE;
X			for (y = 0; y < (6 - x); y++)
X				if (val == dig[y])
X					digit_found = TRUE;
X			if (!digit_found)
X			{
X				dig[y] = val;
X				place_found = TRUE;
X			}
X			else
X				val = (val + 5) % 6;
X		}
X	}
X	dig[5] = 15 - dig[4] - dig[3] - dig[2] - dig[1] - dig[0];
X}
X
Xset_dummy()
X{
X	extern struct guess guesses[];
X	extern struct guess dummy[];
X	extern int cur;
X
X	int x;
X
X		dummy[cur].blacks = dummy[cur].whites = 0;
X		for (x = 0; x < 4; x++)
X		{
X			dummy[cur].pegs[x].used = NONE;
X			dummy[cur].pegs[x].color = guesses[cur].pegs[x].color;
X		}
X}
X
Xmake_code(ges)
X
Xstruct guess *ges;
X{
X	int x, temp;
X
X	for (x = 0; x < 4; x++)
X	{
X		temp = ges->pegs[x].color = rand() % 6;
X		ges->blacks = 0;
X		ges->whites = 0;
X	}
X}
X
Xfind_digit(col_name)
X
Xchar col_name[7];
X{
X	extern int dig[];
X
X	int s;
X
X	for (s = 0; s < 6; s++)
X		if (strlen(col_name) == strlen(col[dig[s]]) && 
X			!(strncmp(col[dig[s]],col_name,strlen(col_name))))
X				return(s);
X	return(BAD_COLOR);
X}
X
Xget_code(kode)
X
Xstruct guess *kode;
X
X{
X	extern int cur;
X
X	char c[4][7];
X	int bad_in, code_valid;
X	int x;
X
X	code_valid = bad_in = FALSE;
X	kode->blacks = kode->whites = 0;
X	while (!code_valid)
X	{
X		code_valid = TRUE;
X		if (bad_in)
X			printf("Previous code contained invalid color.\n");
X		if (player)
X			printf("\nPlease enter guess #%d -> ",cur + 1);
X		else
X			printf("Please enter the correct code -> ");
X		scanf("%s %s %s %s",c[0],c[1],c[2],c[3]);
X		while (getchar() != '\n');
X		if (!player)
X			printf("\n");
X		for (x = 0; x < 4; x++)
X		{
X			kode->pegs[x].used = NONE;
X			kode->pegs[x].color = find_digit(c[x]); 
X			if (kode->pegs[x].color == BAD_COLOR)
X			{
X				code_valid = FALSE;
X				bad_in = TRUE;
X			}
X		}
X	}
X}
X
Xscore()
X{
X	extern struct guess code;
X	extern struct guess guesses[];
X	extern int game_won;
X
X	int x, y;
X
X	for (x = 0; x < 4; x++)
X		guesses[cur].pegs[x].used = code.pegs[x].used = NONE;
X	for (x = 0; x < 4; x++)
X		if (guesses[cur].pegs[x].color == code.pegs[x].color)
X		{
X			code.pegs[x].used = guesses[cur].pegs[x].used = BLACK;
X			guesses[cur].blacks++;
X			if (player)
X				printf("b");
X		}
X	if (guesses[cur].blacks != 4)
X	{
X		for (x = 0; x < 4; x++)
X			for (y = 0; y < 4; y++)
X				if (guesses[cur].pegs[x].color == code.pegs[y].color &&
X				    !code.pegs[y].used && !guesses[cur].pegs[x].used)
X				{
X					code.pegs[y].used = guesses[cur].pegs[x].used = WHITE;
X					guesses[cur].whites++;
X					if (player)
X						printf("w");
X				}
X	}
X	else
X		game_won = TRUE;
X	if (player)
X		if (guesses[cur].blacks != 0 || guesses[cur].whites != 0)
X			printf("\n\n");
X		else
X			printf("No score.\n\n");
X}
X
Xrest()
X{
X	printf("\n-- More --   ");
X	while (getchar() != '\n');
X}
X
Xprint_instructions()
X{
Xprintf ("\n\n                    Instructions for Master Mind\n");
Xprintf ("                                  by\n");
Xprintf ("                             Pete Granger\n\n");
Xprintf ("OBJECT: To match the four color code set by your opponent, using\n");
Xprintf ("        clues from previous guesses.\n\n");
Xprintf ("METHOD: Begin by telling the computer whether you wish to guess,\n");
Xprintf ("        or to create the code which it will guess.  It is usually\n");
Xprintf ("        more interesting to be the guesser, but I wanted you to \n");
Xprintf ("        have the option.\n\n");
Xprintf ("        First, we will cover how to play if you are guessing:\n\n");
Xprintf ("        You will be asked to specify whether you want 'coaching'.\n");
Xprintf ("        This means, the computer will tell you whether your guess\n");
Xprintf ("        is inconsistent with information from previous guesses (it\n");
Xprintf ("        is considered inconsistent if it cannot be the correct\n");
Xprintf ("        code, and you could deduce this).\n\n");
Xrest();
Xprintf ("        You will then be asked for your first guess.  A guess is\n");
Xprintf ("        a set of four colors, separated by at least one space. \n");
Xprintf ("        The valid colors are:\n\n");
Xprintf ("            black    blue    green    red    white    yellow\n\n");
Xprintf ("        Note that these spellings must be used exactly.  If you\n");
Xprintf ("        make a mistake the machine will let you know, and give\n");
Xprintf ("        another chance.\n\n");
Xprintf ("        The machine will then return your score for that guess.\n");
Xprintf ("        Score is given in black and white pegs (b and w).  A black\n");
Xprintf ("        score peg means that one of your guessed colors is in the\n");
Xprintf ("        correct place.  A white score peg means that one of your\n");
Xprintf ("        guessed colors appears in the correct code, but not in\n");
Xprintf ("        the same location. (If you have selected coaching, that\n");
Xprintf ("        will occur at this time also.)\n\n");
Xprintf ("        You will now be given a choice of 'guess, refresh, hint\n");
Xprintf ("        or quit'.  Enter your choice.  Either first letter or the\n");
Xprintf ("        entire word is okay, case is ignored.  If you just hit\n");
Xprintf ("        return, this is taken as meaning 'guess'.\n");
Xrest();
Xprintf ("        GUESS: Make another guess, same as before, using the\n");
Xprintf ("               score from previous guesses to make deductions.\n");
Xprintf ("               You have 18 chances to find the right code.\n\n");
Xprintf ("        REFRESH: Shows all your previous guesses and scores.\n\n"); 
Xprintf ("        HINT: By entering the number of  a previous guess, and one\n");
Xprintf ("              of the pegs in that guess, you may find out what \n");
Xprintf ("              score that particular peg received.  Note:  If you\n");
Xprintf ("              have a color in your guess twice, and it is only in\n");
Xprintf ("              the code once, or vice-versa, it will only receive\n");
Xprintf ("              one scoring peg, black taking precedence over white.\n");
Xprintf ("              Hence, it may sometimes be in your best interest to\n");
Xprintf ("              ask for the hint on the first instance of the color\n");
Xprintf ("              in your guess.\n\n");
Xprintf ("        QUIT: You don't want to play anymore.  Remember, the code\n");
Xprintf ("              will not be revealed if you quit.\n\n");
Xprintf ("        When you find the correct sequence, the computer will let\n");
Xprintf ("        you know, and ask if you wish to begin another game.  The\n");
Xprintf ("        default value for this is 'no'.\n");
Xrest();
Xprintf ("        Now we will consider how to play if you wish to make up\n");
Xprintf ("        the code and have the computer guess:\n\n");
Xprintf ("        You will be asked whether you want the computer to double\n");
Xprintf ("        your scoring of its guesses.  If you desire this, each \n");
Xprintf ("        time you give the computer a score, it score the guess\n");
Xprintf ("        itself.  If the two scores are different, it will inform\n");
Xprintf ("        you of your mistake, and the score it generates will re-\n");
Xprintf ("        place the one you gave.  If you wish your scores checked,\n");
Xprintf ("        you must enter the correct code, so that the computer has\n");
Xprintf ("        data to check the scores you give.  Don't worry, I haven't\n");
Xprintf ("        designed this game to cheat.  The code you enter will be\n");
Xprintf ("        ignored when the computer makes its guess.\n\n");
Xprintf ("        If you do not want double checking, you can refuse it.\n");
Xprintf ("        In this case, any valid score you give will be accepted.\n");
Xprintf ("        The default value for checking is 'yes'.\n");
Xprintf ("        The computer will now make its first guess.  You will be\n");
Xprintf ("        asked for the number of black pegs the guess receives (for\n");
Xprintf ("        each instance of the right color in the right position),\n");
Xprintf ("        up to four.  If you do not give a valid answer (0-4), you\n");
Xprintf ("        will be queried until you do.\n");
Xrest();
Xprintf ("\n\n");
Xprintf ("        If you give three or four black pegs, it is not possible\n");
Xprintf ("        for any white pegs to be given.  Otherwise, you will be\n");
Xprintf ("        asked for the number of white pegs until you give a valid\n");
Xprintf ("        valid answer, zero to (4 - blacks).\n\n");
Xprintf ("        At this point, if you requested it, your scoring will be\n");
Xprintf ("        checked by the computer.\n\n");
Xprintf ("        The computer will continue to guess in this manner, making\n");
Xprintf ("        certain that each guess is consistent with all previous\n");
Xprintf ("        information, until it receives a score of four black pegs.\n");
Xprintf ("        This will generally take from four to seven guesses, but\n");
Xprintf ("        the machine has been known to get lucky, and break the \n");
Xprintf ("        code on the second guess.  If at any point the computer\n");
Xprintf ("        has exhausted all possible guesses, and found none to be\n");
Xprintf ("        consistent with the information you have given, it will \n");
Xprintf ("        report this error and end the game.\n\n");
Xprintf ("        Good luck, and enjoy Master Mind!\n\n");
Xrest();
Xsystem("clear");
X}
X
Xconsistent()
X{
X	extern int player, cons;
X	extern int cur;
X	extern struct guess dummy[];
X	extern struct guess guesses[];
X
X	int x, y, z;
X
X	for (z = 0; z < cur; z++)
X	{
X		dummy[z].blacks = dummy[z].whites = 0;
X		for (x = 0; x < 4; x++)
X			guesses[cur].pegs[x].used = dummy[z].pegs[x].used = NONE;
X		for (x = 0; x < 4; x++)
X			if (guesses[cur].pegs[x].color == dummy[z].pegs[x].color)
X			{
X				dummy[z].pegs[x].used = guesses[cur].pegs[x].used = BLACK;
X				dummy[z].blacks++;
X			}
X		if (dummy[z].blacks != 4)
X		{
X			for (x = 0; x < 4; x++)
X				for (y = 0; y < 4; y++)
X					if (guesses[cur].pegs[x].color == dummy[z].pegs[y].color &&
X					    !dummy[z].pegs[y].used && !guesses[cur].pegs[x].used)
X					{
X						dummy[z].pegs[y].used = guesses[cur].pegs[x].used = 
X							WHITE;
X						dummy[z].whites++;
X					}
X		}
X	}
X	cons = TRUE;
X	for (z = 0; z < cur; z++)
X	{
X		if (dummy[z].blacks != guesses[z].blacks ||
X			dummy[z].whites != guesses[z].whites)
X		{
X			if (cons)
X			{
X				cons = FALSE;
X				if (player)
X					printf("Inconsistent guess.  If this were correct:\n");
X			}
X			if (player)
X			{
X			printf("    guess #%d would have gotten ",z + 1);
X			printf("%d black and %d white.\n",dummy[z].blacks,dummy[z].whites);
X			}
X		}
X	}
X	if (cons && player)
X		printf("This guess is consistent with all previous clues.\n");
X}
X
Xrefresh()
X{
X	extern struct guess guesses[];
X	int x, y;
X
X	system("clear");
X	if (!player && check)
X	{
X		printf("Your correct sequence:  ");
X		for (y = 0; y < 4; y++)
X			printf("%-8s",col[dig[code.pegs[y].color]]);
X		printf("\n\n");
X	}
X	for (x = 0; x < cur; x++)
X	{
X		printf("%2d.  ",x + 1);
X		for (y = 0; y < 4; y++)
X			printf("%-8s",col[dig[guesses[x].pegs[y].color]]);
X		for (y = 0; y < guesses[x].blacks; y++)
X			printf("b");
X		for (y = 0; y < guesses[x].whites; y++)
X			printf("w");
X		printf("\n");
X	}
X	printf("\n");
X}
X
Xplayer_plays()
X{
X	extern int game_won;
X	extern struct guess code;
X	extern struct guess guesses[];
X	extern int dig[];
X	extern int cur;
X
X	char inst, action;
X	int coach, quit;
X	int t, w, x, y, z;
X
X	coach = quit = FALSE;
X	printf("Do you want coaching, y/n [default is n] -> ");
X	if ((inst = getchar()) != '\n')
X		while (getchar() != '\n');
X	if (inst == 'y' || inst == 'Y')
X		coach = TRUE;
X	printf("\nChoosing a code for you to guess.\n");
X	t = rand() % 3 + 2;
X	sleep(t);
X	make_code(&code);
X	for (cur = 0; cur < 18 && !game_won;)
X	{
X		if (cur)
X		{
X			printf("guess, refresh, hint, or quit [default is guess] -> ");
X			if ((action = getchar()) != '\n')
X				while (getchar() != '\n');
X		}
X		else
X			action = 'g';
X		switch (action)
X		{
X			case 'q':
X			case 'Q':
X				cur = 18;
X				quit = TRUE;
X				break;
X			case 'r':
X			case 'R':
X				refresh();
X				break;
X			case 'h':
X			case 'H':
X				printf("\n");
X				z = 0;
X				while (z < 1 || z > cur)
X				{
X					z = 0;
X					printf("Enter the guess you need the hint for -> ");
X					while((t = getchar()) != '\n')
X						z = z * 10 + t - '0';
X				}
X				w = 0;
X				while (w < 1 || w > 4)
X				{
X					w = 0;
X					printf("Which peg of guess #%d -> ",z);
X					while((t = getchar()) != '\n')
X						w = w * 10 + t - '0';
X				}
X				printf("In guess #%d, peg #%d received ",z,w);
X				if (guesses[z - 1].pegs[w - 1].used == BLACK)
X					printf("a black peg.\n");
X				if (guesses[z - 1].pegs[w - 1].used == WHITE)
X					printf("a white peg.\n");
X				if (guesses[z - 1].pegs[w - 1].used == NONE)
X					printf("no peg.\n");
X				printf("\n");
X				break;
X			default:
X 				get_code(&guesses[cur]);
X				set_dummy();
X				if (coach && cur)
X					consistent();
X				score();
X				cur++;
X				break;
X		}
X	}
X	if (game_won)
X	{
X		printf("    Congratulations, human!  You broke the code in %d",cur);
X		if (cur != 1)
X			printf(" guesses.\n");
X		else
X			printf(" guess.  What luck!\n");
X	}
X	else if (!quit)
X	{
X		printf("    Sorry.  You've run out of guesses.\n");
X		printf("    The correct code was:   %-8s %-8s %-8s %-8s\n",
X				col[dig[code.pegs[0].color]],
X				col[dig[code.pegs[1].color]],
X				col[dig[code.pegs[2].color]],
X				col[dig[code.pegs[3].color]]);
X	}
X	else
X		printf("Was that too tough for you?  I'll be nicer next time.\n");
X}
X
Xtell_guess()
X{
X	extern int cur;
X	extern struct guess guesses[];
X	extern int dig[];
X
X	if (!check)
X		printf("\n");
X	if (cur < 10)
X		printf(" ");
X	printf("    Guess #%d:   %-8s %-8s %-8s %-8s\n\n",cur + 1,
X			col[dig[guesses[cur].pegs[0].color]],
X			col[dig[guesses[cur].pegs[1].color]],
X			col[dig[guesses[cur].pegs[2].color]],
X			col[dig[guesses[cur].pegs[3].color]]);
X}
X
Xget_score()
X{
X	extern struct guess guesses[];
X	extern int cur;
X	extern int check;
X
X	int t, w, x;
X
X	w = -1;
X	while (w < 0 || w > 4)
X	{
X		w = 0;
X		printf("How many black pegs do I get -> ");
X		while((t = getchar()) != '\n')
X			w = w * 10 + t - '0';
X	}
X	if (w == 4 || w == 3)
X		x = 0;
X	else
X		x = -1;
X	while (x < 0 || x > 4 - w)
X	{
X		x = 0;
X		printf("How many white pegs do I get -> ");
X		while((t = getchar()) != '\n')
X			x = x * 10 + t - '0';
X	}
X	if (check)
X	{
X		score();
X		if (guesses[cur].blacks != w || guesses[cur].whites != x)
X		{
X			printf("You seem to have made a mistake.  ");
X			printf("My correct score is %d black",guesses[cur].blacks);
X			if (guesses[cur].blacks != 1)
X				printf("s");
X			printf(" and %d white",guesses[cur].whites);
X			if (guesses[cur].whites != 1)
X				printf("s");
X			printf(".\n\n");
X		}
X		else
X			printf("\n");
X	}
X	else
X	{
X		guesses[cur].blacks = w;
X		guesses[cur].whites = x;
X		if (guesses[cur].blacks == 4)
X			game_won = TRUE;
X	}
X}
X
Xmachine_plays()
X{
X	extern struct guess code;
X	extern struct guess guesses[];
X	extern int cur;
X	extern int check, game_won;
X
X	int w, x, y, z;
X	int randomizing = TRUE;
X	int quit = FALSE;
X	int refreshed;
X	char ans;
X
X	check = TRUE;
X	printf("Do you want me to double check you, y/n [default is y] -> ");
X	if ((ans = getchar()) != '\n')
X		while (getchar() != '\n');
X	if (ans == 'n' || ans == 'N')
X		check = FALSE;
X	if (check)
X		get_code(&code);
X	cur = 0;
X	make_code(&guesses[cur]);
X	set_dummy();
X	tell_guess();
X	get_score();
X	for (++cur; cur < 6 && !game_won && randomizing && !quit;)
X	{
X		refreshed = FALSE;
X		if (!(cur % 2) && cur > 3)
X		{
X			refresh();
X			refreshed = TRUE;
X		}
X		x = 0;
X		cons = FALSE;
X		while (!cons && x < 1200)
X		{
X			x++;
X			make_code(&guesses[cur]);
X			consistent();
X		}
X		if (cons)
X		{
X			set_dummy();
X			tell_guess();
X			get_score();
X			cur++;
X		}
X		else
X			randomizing = FALSE;
X	}
X	if (!game_won)
X		for (cur; cur < 18 && !game_won && !quit; cur++)
X		{
X			if (!(cur % 2) && cur > 3 && !refreshed)
X				refresh();
X			cons = FALSE;
X			for (w = 0; w < 6 && !cons; w++)
X			for (x = 0; x < 6 && !cons; x++)
X			for (y = 0; y < 6 && !cons; y++)
X			for (z = 0; z < 6 && !cons; z++)
X			{
X				guesses[cur].pegs[0].color = w;
X				guesses[cur].pegs[1].color = x;
X				guesses[cur].pegs[2].color = y;
X				guesses[cur].pegs[3].color = z;
X				guesses[cur].blacks = guesses[cur].whites = 0;
X				consistent();
X			}
X			if (cons)
X			{
X				set_dummy();
X				tell_guess();
X				get_score();
X			}
X			else
X			{
X				printf("No guess is consistent.  You must have cheated!\n");
X				printf("Can't recover from this.  Goodbye!\n");
X				quit = TRUE;
X			}
X		}
X	if (game_won)
X	{
X		printf("I broke your code in %d ",cur);
X		if (cur != 1)
X			printf("guesses.\n");
X		else
X			printf("guess.  Machines can get lucky, too!\n");
X	}
X	else if (!quit)
X		printf("I didn't break your code.  You win this time!\n");
X}
X
Xmain()
X{
X	extern int cur, game_won, player;
X	extern int dig[];
X	extern struct guess code;
X	extern struct guess guesses[];
X
X	char more, inst;
X	int play_game = TRUE;
X	int z;
X
X	system("clear");
X	z=time();
X	srand(z);
X	printf("Would you like instructions, y/n [default is n] -> ");
X	if ((inst = getchar()) != '\n')
X		while (getchar() != '\n');
X	if (inst == 'y' || inst == 'Y')
X		print_instructions();
X	while (play_game)
X	{
X		player = TRUE;
X		game_won = FALSE;
X		printf("Do you want to guess, or make the code,");
X		printf(" g/m [default is g] -> ");
X		if ((inst = getchar()) != '\n')
X			while (getchar() != '\n');
X		if (inst == 'm' || inst == 'M')
X			player = FALSE;
X		setcolors();
X		if (player)
X			player_plays();
X		else
X			machine_plays();
X		printf("\nWould you like to play again, y/n [default is n] -> ");
X		if ((more = getchar()) != '\n')
X			while (getchar() != '\n');
X		if (more != 'y' && more != 'Y')
X			play_game = FALSE;
X		system("clear");
X	}
X}
END_OF_mastrm.c
if test 18986 -ne `wc -c <mastrm.c`; then
    echo shar: \"mastrm.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0