PROGRAM RandomNumber;
Var rand,count,guess : integer;
LABEL correct, loop, wrong, end1;
begin
{Initialization, so that random numbers are drawn}
Randomize;
count :=0;
repeat
loop:
count := count+1;
{Random(i) Creates random numbers between 0 and i.}
rand := Random(10);
guess := Random(10);
if rand=guess
then
goto correct
else
goto wrong;
until count > 10;
goto end1;
correct :
WriteLn('Correct');
goto end1;
wrong :
WriteLn('False Guess');
goto loop;
end1 :
WriteLn;
end.
The goal of the program is to find a random number in 10 tries. I managed to compile it with Free Pascal IDE and the problem then is that the program does not stop until the number is found. However, when I tried to compile it with an online compile it gives this error:
prog.pas: In main program:
prog.pas:26: error: `goto' to invalid target
Is it because labels/goto can`t jump right away in loops?
The proximate "why does't it work?!" answer is exactly as lamas shaikh says: A missing semicolon.
Don't feel bad. It's an easy thing to miss. Pascal allows either a single line of code after after a conditional or loop structure, or a begin
/end
sequence as a virtual statement. That choice interacts badly with Pascal's use of semicolons as statement separators rather than terminators (a fine distinction to parser designers but one that over the years has proven subtle and error-prone, especially for those new to the language. Beware both missing and extra semicolons!
Two things that can help: Always, always, always use strong, consistent, disciplined indentation to help show you the logical structure of the code. And you may find it easier to just always use begin
/end
blocks in any context that either a statement or a multi-statement block might fit (even if the block contains contains a single line). That may seem goofy at first, but as you start adding statements to programs (including temporary debugging print statements), working with a single construct that works in all cases really helps.
The less immediate reason that your program fails isn't the semicolon. It's that you're using a completely unstructured approach to control flow in your program. You're GOTO
ing all over the place, even when you don't need to, and even though there are simpler, cleaner, better structured alternatives. For example, consider:
PROGRAM RandomNumber;
Var rand, count, guess, MaxGuesses : integer;
begin
{Initialization, so that random numbers are drawn}
Randomize;
MaxGuesses := 10;
count := 0;
repeat
count := count + 1;
{Random(i) Creates random numbers between 0 and i.}
rand := Random(10);
guess := Random(10);
if rand = guess
then begin
WriteLn('Correct');
break
end
else
WriteLn('False Guess');
until count >= MaxGuesses;
WriteLn;
if (rand = guess)
then
WriteLn('We had a winner (', guess, ') in ', count, ' tries.')
else
WriteLn('Sorry! No winner in ', MaxGuesses, ' tries.');
WriteLn;
end.
Compiled and run a few times, it looks like:
$ ./guess
False Guess
Correct
We had a winner (1) in 2 tries.
$ ./guess
False Guess
False Guess
False Guess
False Guess
False Guess
False Guess
False Guess
False Guess
False Guess
False Guess
Sorry! No winner in 10 tries.
$ ./guess
False Guess
Correct
We had a winner (8) in 2 tries.
Pascal was part and parcel of the revolution in programming in the 1960s and 1970s that brought "structured programming" into widespread use. Don't use lower-level goto
-laden code when better structures are so eagerly available.