\$\begingroup\$
\$\endgroup\$
This is a code written is Pascal (Delphi). It asks the user to think of a number between min_
and max_
and then guesses the number using either a Binary or a Linear method.
program BandLSearch;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
var
min_, max_: integer; // set the max and min to check between the two (inclusive)
BinorLin: string; // Get user input as to which method they wish to use
procedure Linear();
{
This uses a linear search technique to guess the number.
It will ask min_ then min_ +1 etc up to max_. e.g. 1, 2, 3, ... , 99, 100
}
var
input: string;
count: integer; // For the foor loop
begin
for count := min_ to max_ do // loop from min to max and ask if the number is corect, one by one
begin
write('Is your number ',count,'? Y or N? > ');
readln(input);
if (input = 'Y') or (input = 'y') then
begin
writeln('Found your number, it is ',count);
readln; // Prevent the code ending without being able to read the output.
break
end
else
begin
if count = max_ then //If they have reached max and not said yes, they are lying
begin
writeln('You have cheated');
readln;
end;
end;
end;
end;
procedure Binary();
{
This uses a linear search technique to guess the number
It will ask (min_ + max_)/2 and the user says too high or too low.
Depending on the response, it will set either min_ or max_ to the guessed number
Eventually it narrows down, eg:
50, 75, 62, 68, 65, 63, 64
L H L H H L C
}
var
input: string;
guess, preGuess: integer; // For the current computer guess
goesTaken : integer; // To monitor the guesses needed
end_: integer; // Will increase for each guess that max_ = min_
begin
preGuess := -1; // Will not be the guess.
goesTaken := 0;
end_ := 0;
while end_ < 2 do //when it is 2, it will have guessed all the numbers.
begin
inc(goesTaken);
guess := (max_ + min_) div 2;
writeln('Is your number ',guess,'?');
writeln('If guess is too high enter H, if it''s too low, enter L.');
write('If the guess is corect, enter C > ');
readln(input);
if input = 'H' then // Number is too high, so guess lower
max_ := guess - 1
else
if input = 'L' then // Number is too low, so guess higher
min_ := guess + 1
else // Number is correct
begin
writeln('Found your number, it is ',guess);
writeln('It took me ',goesTaken,' goes.');
readln;
break
end;
if guess = preGuess then // If the computer asks the same number two times in a row, the user has cheated.
begin
writeln('You have cheated');
readln;
break
end
else
preGuess := guess;
if (max_ = min_) then // If min is the same as max, then 1 go later the code can exit.
begin
end_ := end_ + 1;
end;
end;
end;
begin
min_ := 0;
max_ := 100;
writeln('Think of a number between ',min_, ' and ', max_, '. I will guess it.');
write('Do you want to use a (l)inear or a (b)inary search? > ');
readln(BinorLin);
if BinorLin = 'l' then // User input comparison
begin
writeln('Starting Linear Search...');
Linear();
end
else;
begin
if BinorLin = 'b' then
begin
writeln('Starting Binary Search...');
Binary();
end
else // didn't enter 'l' or 'b'
begin
exit
end;
end;
end.
This is a high school assignment, however I have already handed it in (today) for marking. I'd be interested in the opinion of more than my teacher.
1 Answer 1
\$\begingroup\$
\$\endgroup\$
9
- I would rather use Free Pascal than Delphi, makes code more promptly editable;
- You should avoid nested
if
's, specially in pascal, where you can easily get lost otherwise. Use thecase
statement instead. - pascal do not use
camelCase
butPascalCase
. - you should use
const
for constants, and name them likePASCAL_CONSTANT
. - you should prefix your own variables to avoid getting lost in terms of scope and variables types:
F
for class fields;T
for objects;A
for property (generic) values;I
for integers, for local variablesS
for strings, for local variables- and so on
starting code
messages should be put at the starting of the code, i.e., first line after abegin
statement of the corresponding procedure, function or program.- It is not necessary to write the
()
for methods that does not require entries. - Pascal is case insensitive. However, it does not mean you should not be consistent with existing code: you should use WriteLn, instead writeln, for example.
Putting all together:
program BandLSearch;
uses SysUtils;
var
SInput: string; // Get user input as to which method they wish to use
const // set the max and min to check between the two (inclusive)
MIN_VALUE : integer = 0;
MAX_VALUE : integer = 100;
{ This uses a linear search technique to guess the number.
It will ask MIN_VALUE then MIN_VALUE +1 up to MAX_VALUE. e.g. 1, 2, 3, ... , 99, 100 }
procedure Linear;
var
ICount: integer; // For the foor loop
begin
WriteLn('Starting Linear Search...');
for ICount := MIN_VALUE to MAX_VALUE do // loop from min to max and ask if the number is corect, one by one
begin
Write('Is your number ',ICount,'? Y or N? > ');
ReadLn(SInput);
SInput := UpperCase(SInput);
if SInput = 'Y' then
begin
WriteLn('Found your number, it is ',ICount);
ReadLn; // Prevent the code ending without being able to read the output.
Break
end;
if ICount = MAX_VALUE then //If they have reached max and not said yes, they are lying
begin
WriteLn('You have cheated.');
ReadLn;
end;
end;
end;
{ This uses a binary search technique to guess the number
It will ask (MIN_VALUE + MAX_VALUE)/2 and the user says too high or too low.
Depending on the response, it will set either MIN_VALUE or MAX_VALUE to the guessed number
Eventually it narrows down, eg:
50, 75, 62, 68, 65, 63, 64
L H L H H L C }
procedure Binary;
var
IGuess, IPreGuess, // For the current computer guess
IGoesTaken, // To monitor the guesses needed
IEnd: integer; // Will increase for each guess that MAX_VALUE = MIN_VALUE
begin
WriteLn('Starting Binary Search...');
IPreGuess := -1; // Will not be the guess.
IGoesTaken := 0;
IEnd := 0;
repeat
Inc(IGoesTaken);
IGuess := (MAX_VALUE + MIN_VALUE) div 2;
WriteLn('Is your number ',IGuess,'?');
WriteLn('If guess is too high enter H, if it''s too low, enter L.');
Write('If the guess is correct, enter C or Y > ');
ReadLn(SInput);
SInput := UpperCase(SInput);
case SInput of
'H': MAX_VALUE := IGuess - 1; // Number is too high, so guess lower
'L': MIN_VALUE := IGuess + 1; // Number is too low, so guess higher
'C', 'Y':
begin
WriteLn('Found your number, it is ',IGuess);
WriteLn('It took me ',IGoesTaken,' goes.');
ReadLn;
Break;
end;
else // Number is correct
end;
if IGuess = IPreGuess then // If the computer asks the same number two times in a row, the user has cheated.
begin
WriteLn('Sorry, I did not undertand you (or you have cheated).');
ReadLn;
Break;
end
else
IPreGuess := IGuess;
if MAX_VALUE = MIN_VALUE then
IEnd := IEnd + 1; // If min is the same as max, then 1 go later the code can exit.
until IEnd >= 2;
end;
begin
WriteLn('Think of a number between ',MIN_VALUE, ' and ', MAX_VALUE, '. I will guess it.');
Write('Do you want to use a (l)inear or a (b)inary search? > ');
ReadLn(SInput);
SInput := LowerCase(SInput);
case SInput of // User input comparison
'l': Linear;
'b': Binary;
else
Exit;
end;
end.
answered Nov 13, 2015 at 1:03
-
\$\begingroup\$
FTA
is common in Pascal, Free Pascal and Delphi. For local variables there are no standards, but you will frequently findS
for local strings andI
for loop integers.IS
is an extension considering that fact. \$\endgroup\$cpicanco– cpicanco2015年11月13日 02:58:23 +00:00Commented Nov 13, 2015 at 2:58 -
\$\begingroup\$ @holroy, after all, the point is not getting lost. Works for me :) \$\endgroup\$cpicanco– cpicanco2015年11月13日 03:01:03 +00:00Commented Nov 13, 2015 at 3:01
-
1\$\begingroup\$ I'm all for clarity in naming, but in C# or Python naming standards is used where you don't need prefixes, but rather use variations on camelCase or PascalCase or snake_case. And you should normally not have a problem knowing the type of a variable as that should be given by the name/context. The same applies for scope, as if your code is so long you don't have control of the scope you should add some procedures/methods/functions to narrow down the scope. But YMMV... \$\endgroup\$holroy– holroy2015年11月13日 03:05:38 +00:00Commented Nov 13, 2015 at 3:05
-
\$\begingroup\$ For me works like that,
PascalMethod
,LPascalLocalVariable
,AMethodValue
,FFieldAttribute
,TAbstractObject
. As you can see, methods are not prefixed. But, again, for local variables there are no standards as far as I know. \$\endgroup\$cpicanco– cpicanco2015年11月13日 03:16:27 +00:00Commented Nov 13, 2015 at 3:16 -
\$\begingroup\$ I will think about these. I essentially have to use Delphi but I'll consider the others. I especially like the use of case statements but I'm unsure the variable prefix is needed, and some of the other naming conventions seem strange. Thanks though. \$\endgroup\$Tim– Tim2015年11月13日 07:55:54 +00:00Commented Nov 13, 2015 at 7:55
Explore related questions
See similar questions with these tags.
lang-pascal