Recent

Author Topic: Can I use multiple conditions in case statements?  (Read 16169 times)

JoshM

  • Jr. Member
  • **
  • Posts: 57
Can I use multiple conditions in case statements?
« on: July 08, 2013, 10:23:42 pm »
...or do I need to use if statements. So for example case A & B = true then [do something]. I'm trying to make a SUVAT solver and these calculations will then be the basis to simulate projectile motion. If you don't know what SUVAT is, basically each letter corresponds to a variable (eg A = accelation & T = time). To work out other values, you always need a minimum of 3 values. I've got the 4 SUVAT equations:

v = u + at
s = (tu + tv)/2
v^2 = u^2 + 2as
s = ut + (at^2)/2

So once the user enters 3 valid integers, then I need the program to solve the remaining 2 values. Let's say we get values for t, u, & s. To work out v we can use the re-arranged equation v = (2s-tu)/t. My question is would I have to type something like:
Code: [Select]
if (t.valid = true) && (u.valid = true) && (s.valid = true) then
v := (2s-tu)/t;

Bear in mind there will be 10 different combinations of 3 the user could enter (5C3 = 10). Would I have to use 10 different if statements, or could I somehow do it in a case statement/something more advanced? This is as much me learning about Pascal rather than the practical application of it.

Thanks

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Can I use multiple conditions in case statements?
« Reply #1 on: July 08, 2013, 11:04:11 pm »
Try this:
Code: [Select]
Value:=0;
if a.valid then inc(Value);
if s.valid then inc(Value, 2);
if t.valid then inc(Value, 4);
if u.valid then inc(Value, 8);
if v.valid then inc(Value, 16);
case Value of
  7: //code when a, s, t is set
  11: //when a, t, u is set
 etc... //all possible (or reasonable) combinations
end;

EDIT: Of course, you can even increase readability:
Code: [Select]
var Value: Integer;
const ca = 1;
      cs = 2;
      ct = 4;
      cu = 8;
      cv = 16;
begin
  ....
  case Value of
    ca + cs + ct: ;
    ca + cs + cu: ;
    ....
  end;

(I tested it now, I wasn't sure if FPC can do it.)
« Last Edit: July 08, 2013, 11:30:06 pm by Blaazen »
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Can I use multiple conditions in case statements?
« Reply #2 on: July 09, 2013, 12:51:49 am »
As interesting as the syntax of legal case statements in fpc is the question of how to design a UI to provide for entry of several variables when several equations using those values overlap.
Here's one approach (which you can extend) which solves for V when S, U, A or T change.

Code: [Select]
unit uMain;

{$mode objfpc}{$H+}

interface

uses
  Classes, Spin, StdCtrls, Forms, Graphics;

type
  TSpinEdits = (S, U, V, A, T);

  TSpinEditsArray = array[TSpinEdits] of TSpinEdit;

  { TForm1 }

  TForm1 = class(TForm)
   procedure FormCreate(Sender: TObject);
  private
   FEdits: TSpinEditsArray;
   procedure seChange(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
const titleChars: string = 'SUVAT';
var s: TSpinEdits;
    i, tp: integer;
    lbl: TLabel;

  function NewLabel(aTop: integer): TLabel;
  begin
    Result := TLabel.Create(Self);
    Result.Parent := Self;
    Result.Top := aTop;
    Result.Left := 10;
    Result.Layout := tlCenter;
    Result.Alignment := taCenter;
    Result.AutoSize := False;
    Result.Width := 23;
    Result.Height := 23;
  end;

  function newSpinEdit(aTop: integer): TSpinEdit;
  begin
    Result := TSpinEdit.Create(Self);
    Result.Parent := Self;
    Result.Top := aTop;
    Result.Left := 38;
    Result.Caption := '';
    Result.MaxValue := 1000;
    Result.OnChange := @seChange;
  end;

begin
  for s in TSpinEdits do
    begin
     i := integer(s);
     tp := 10 + i*30;
     lbl := NewLabel(tp);
     lbl.Caption := titleChars[Succ(i)];
     FEdits[s] := newSpinEdit(tp);
     FEdits[s].Name := titleChars[Succ(i)];
    end;
  FEdits[T].MinValue := 1;
end;

procedure TForm1.seChange(Sender: TObject);
var
    se: TSpinEdit;
begin
  if (Sender is TSpinEdit) then
  begin
   se := TSpinEdit(Sender);
   case se.Name of
    'S': FEdits[V].Value :=
           trunc((2*FEdits[S].Value - FEdits[T].Value*FEdits[U].Value)
                  div FEdits[T].Value);
    'U': FEdits[V].Value := FEdits[U].Value + FEdits[A].Value*FEdits[T].Value;
    'V': FEdits[U].Value := FEdits[V].Value - FEdits[A].Value*FEdits[T].Value;
    'A': FEdits[V].Value := FEdits[U].Value + FEdits[A].Value*FEdits[T].Value;
    'T': FEdits[V].Value := (2*FEdits[S].Value - FEdits[T].Value*FEdits[U].Value)
                             div FEdits[T].Value;
   end;
  end;
end;

end.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Can I use multiple conditions in case statements?
« Reply #3 on: July 09, 2013, 01:27:53 am »
Just the case's sake yes case can check for multiple values at the same time but not combined eg if any of the values is correct then it will that brunch.

eg
Code: [Select]
case aCh of
  'A' : Write('Grats');
  'B' : write ('Not Bad');
  'C' : Write('What? too much beer?')
  'E','F' : Write('I hope you are good at sports');
end;

a single value must appear in one and only place otherwise it should not compile.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Can I use multiple conditions in case statements?
« Reply #4 on: July 09, 2013, 02:51:54 am »
t. My question is would I have to type something like:
Code: [Select]
if (t.valid = true) && (u.valid = true) && (s.valid = true) then
Actually in pascal you can clean that up nicer
Code: [Select]
if t.valid and u.valid and s.valid then

bmy92

  • New Member
  • *
  • Posts: 11
Re: Can I use multiple conditions in case statements?
« Reply #5 on: July 09, 2013, 08:57:59 pm »
I had a similar problem with a small application where the user inputs 2 parameters and asks for the value of the third parameter. My solution :

Parameter1 : TEditButton
Parameter2 : TEditButton
Parameter3 : TEditButton

The user fills two of the edit boxes and then clicks the button of the remaining box. Each button click starts a specific routine.
No need for Case statement !

kpeters58

  • Sr. Member
  • ****
  • Posts: 267
Re: Can I use multiple conditions in case statements?
« Reply #6 on: July 10, 2013, 12:37:38 am »
This is what I typically use to avoid IF-ladders.

Cheers,
Kai


Code: [Select]

procedure MakeDecision(Hungry, Tired, Angry: Boolean);
var
  i: Integer;

begin
  i := Ord(Hungry) or (Ord(Tired) shl 1) or (Ord(Angry) shl 2);
  case i of
    0:  DoNothing;
    1:  JustEat;
    2:  TakeANap;            //Tired so rest
    3:  OrderPizza;          //Tired and hungry
    4:  CalmDown;             
    5:  SnackThenCalmDown;  // Hungry and angry
    6:  GoToBed;            // Tired and angry
    7:  EatThenSleep;       // Hungry, tired and angry
  end;
end;

Lazarus 2.0.4/FPC 3.0.4/Win 64

ludob

  • Hero Member
  • *****
  • Posts: 1173
Re: Can I use multiple conditions in case statements?
« Reply #7 on: July 10, 2013, 08:12:03 am »
This is what I typically use to avoid IF-ladders.
To make this a bit more easy to write you can use the binary notation and reorder the booleans so that they are listed most significant bit to the left:
Code: [Select]
procedure MakeDecision(Hungry, Tired, Angry: Boolean);
var
  i: Integer;

begin
  i := (Ord(Angry) shl 2) or (Ord(Tired) shl 1) or Ord(Hungry);
  case i of
    %000:  DoNothing;
    %001:  JustEat;
    %010:  TakeANap;            //Tired so rest
    %011:  OrderPizza;          //Tired and hungry
    %100:  CalmDown;
    %101:  SnackThenCalmDown;  // Hungry and angry
    %110:  GoToBed;            // Tired and angry
    %111:  EatThenSleep;       // Hungry, tired and angry
  end;
end;

 

TinyPortal © 2005-2018