3
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$
  • 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 the case statement instead.
  • pascal do not use camelCase but PascalCase.
  • you should use const for constants, and name them like PASCAL_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 variables
    • S 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 a begin 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.
\$\endgroup\$
  • \$\begingroup\$ FTA is common in Pascal, Free Pascal and Delphi. For local variables there are no standards, but you will frequently find S for local strings and I for loop integers. IS is an extension considering that fact. \$\endgroup\$ – cpicanco Nov 13 '15 at 2:58
  • \$\begingroup\$ @holroy, after all, the point is not getting lost. Works for me :) \$\endgroup\$ – cpicanco Nov 13 '15 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 Nov 13 '15 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 Nov 13 '15 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 Nov 13 '15 at 7:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.