A few things.
First off, you missed a section. The game is supposed to allow ONLY letters. Currently I can enter digits, apostrophes, etc.
When all characters have been guessed, the user is not told. You must enter the phrase in for it to say correct guess! After entering the last letter, it should say complete and no longer let you guess more letters.
If you accidentally type in a letter at the menu, it creates an error.
Don't set Choice as an INTEGER, set it as a CHAR and then use CHOICE:=READKEY();
This way you will not have to press enter after and you won't crash your program.
If you try to guess the phrase and fail, it un-sets the phrase. You need a BEGIN..END statement:
end else
begin
inc(badguesses);
if badguesses > 10 then
begin
lineDisplay := 'You have ran out of guesses';
Phrasehasbeenset:= False;
end;
end;
***** BELOW IS NOT ABOUT ERRORS, BUT HOW TO MAKE YOUR UI BETTER *****
Also, the layout is confusing. I just did some research and found Delphi does not support CLRSCR() or GOTOXY(), but use this code at the top of your program:
//-----------------------------------------
// Position cursor to X, Y
//-----------------------------------------
procedure GotoXY(X, Y : Word);
begin
Coord.X := X; Coord.Y := Y;
SetConsoleCursorPosition(ConHandle, Coord);
end;
//-----------------------------------------
// Clear Screen - fill it with spaces
//-----------------------------------------
procedure ClrScr;
begin
Coord.X := 0; Coord.Y := 0;
FillConsoleOutputCharacter(ConHandle, ' ', MaxX*MaxY, Coord, NOAW);
GotoXY(0, 0);
end;
and then you can do a little more visual formatting.
Here's an example that doesn't require many changes and makes the program alot smoother to use.
First, in your main procedure at the start of your loop, change the first few lines to :
{ Main program block starts here }
begin
PhraseHasBeenSet := False;
Repeat
clrscr;
DisplayCurrentStatus(Length(NewPhrase), GuessStatusArray);
DisplayMenu;
GotoXY(1,23); WriteLn(lineDisplay);
GotoXY(1,22); Write('Choice? ');
Readln(Choice);
lineDisplay := '';
Add the lineDisplay variable to your global variables as a STRING. Since we clear the screen everytime, we need a way to write the error information to the screen.
So change the following lines from WriteLn() to:
lineDisplay := 'You have ran out of guesses';
lineDisplay := 'You have guessed correctly';
lineDisplay := 'The setter has not specified the word/phrase ..';
Your display menu needs a start point:
procedure DisplayMenu;
Begin
GotoXY(1,10);
Writeln('__________________________________');
Writeln;
Writeln('1. SETTER - Makes new word/phrase');
and so does your DisplayCurrentStatus:
procedure DisplayCurrentStatus(PhraseLength : byte; GuessStatusArray : TGuessStatusArray);
var
Position : integer;
begin
GotoXY(1,1); WriteLn('Phrase:');
for Position := 1 to PhraseLength do
Write(GuessStatusArray[Position]);
Writeln; Writeln;
Writeln('Letters used so far:');
For position := 1 to length(letters) do
begin
Write(Lettersguessedarray[Position]);
end;
Writeln;WriteLn;
Writeln('Number of guesses so far :- ',guesses, ' Number of bad guesses :- ', badguesses);
Writeln('Bad guesses remaining :- ', 10-Badguesses)
end;
This will always display your coded phrase at the top of the screen as well as the letters guessed, right & wrong guesses and the number of guesses left. You can now remove all other calls to DisplayCurrentStatus() in the rest of your code.
The last suggestion I would make is to change the letters already guessed from '*' to something that makes the letters easier to see, such as '.'
In your SetUpGuessStatusArray() procedure:
For position := 1 to length(letters) do
begin
Lettersguessedarray[position] := '.';
end;
Well, my wife is calling me to bed now, so I hope this helps you out a bit more ;)