Inkorrekt Compilation von if und else

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Atze
Beiträge: 10
Registriert: So 30. Apr 2023, 19:22

Inkorrekt Compilation von if und else

Beitrag von Atze »

Das ist hier ein Spiel, bei dem man abwechselnd mit dem Computer Zahlen von 3-7 zum Zählerstand addiert. Wer die 100 trifft, hat gewonnen. Im Bereich bis 72 wird der Code richtig abgearbeitet. Sobald man in die oberen definierten If Bereiche kommt, wird vom Teilnehmer Computer (= Ich) das If ausgeführt aber zusätzlich das Else auch noch. Das ist unanständig und illegal... Es kommt dann zu einer doppelten Ausgabe. Nun, if und else sind entweder oder. Die Frage ist wo liegt der Fehler? Verträgt der Compiler keine gestaffelten If- Konditionen?
Wenn ich nur eine If- Kondition verwende, läuft der Code korrekt. Mit mehreren ist es buggy.

Man kann den Test abkürzen und den Zählerstand auf 70 setzen. Dann gewinnt der Computer.
Dateianhänge
Spiel2.zip
(12.09 KiB) 50-mal heruntergeladen
Zuletzt geändert von Atze am So 7. Mai 2023, 11:56, insgesamt 1-mal geändert.

Warf
Beiträge: 2118
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Inkorrekt Compilation von if und else

Beitrag von Warf »

Da eine LPI keinen code (dabei handelt es sich um die XML formatierte Projekt Datei) enthält kann man nur raten. Aber nein, gestaffelte if-then-else blöcke funktioneren sehr gut. Aber wenn du einzelstatement ifs (also ohne begin-end block) machst, kanns natürlich leicht vorkommen das man ausversehen im falschen if scope ist. Von daher immer einen begin end block starten. Ist zwar mehr tipparbeit, aber davon sind noch niemandem die Finger abgefallen und es kann viele dumme Fehler verhindern

Linkat
Lazarusforum e. V.
Beiträge: 559
Registriert: So 10. Sep 2006, 23:24
OS, Lazarus, FPC: Linux Mint 22; Lazarus 3.4 FPC 3.2.2; RaspiOS
CPU-Target: AMD 64, ARM 64
Wohnort: nr Stuttgart

Re: Inkorrekt Compilation von if und else

Beitrag von Linkat »

Hallo Atze,
herzlich willkommen im Lazarus-Forum.

Du musst deinen *.pas File anhängen. Mit dem .lpi kann man dir bei deinem Problem nicht helfen.

Gruß, Linkat
Linux Mint 21.3; Lazarus 3.4 FPC 3.2.2; RaspiOS

charlytango
Beiträge: 1061
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Inkorrekt Compilation von if und else

Beitrag von charlytango »

Linkat hat geschrieben: Sa 6. Mai 2023, 23:18 Du musst deinen *.pas File anhängen. Mit dem .lpi kann man dir bei deinem Problem nicht helfen.
Genau zu diesem Zweck kennt Lazarus die Anweisung "Publish Project" - zu finden im Menü unter "Project - Publish Project".
Damit werden alle relevanten Dateien eines Projekts in ein "Publish" Verzeichnis kopiert und bei Bedarf gleich gezippt

wennerer
Beiträge: 607
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: Inkorrekt Compilation von if und else

Beitrag von wennerer »

Hallo Atze,
deine else Abfrage bezieht sich nur auf die Abfrage zwischen 93 und 97. Ich würde deine Variable ok zur Abfrage hernehmen.

Code: Alles auswählen

program Spiel2;
var zStand,add,Du,differenz:integer;
     ok:boolean;

begin
 writeln('Spiele gegen mich');
 writeln('Wer zuerst 100 erreicht, hat gwewonnen.');
 writeln('Du darfst nur Werte von 3...7 hinzuzaehlen.');
 writeln('Ich starte.');
 writeln('1');
 zStand:= 1;
 add:= 6;

 while zStand < 100 Do
     Begin
     repeat
         writeln ('Du ' );
         readln(Du);
         //pruefe Eingabe, korrekt?
         differenz:= Du-zStand;

         if (differenz < 3) OR (differenz > 7) then
         begin
             writeln('Deine Eingabe war falsch!');
             ok:=false;
         end
         else
         // Eingabe korrekt
            Begin
            ok := true;
            zStand := Du;
            writeln ('Z Stand : ',zStand);
            if zStand = 100 then
                writeln ('Du hast gewonnen!');
            end;
       until ok=true;

        //Computer macht Eingabe

        if zStand <100  then
           begin

           // Bereich 73...77
              if (zStand >= 73) AND (zStand <=77) then
                begin
                 zStand := 80;
                 writeln('Ich:',zStand);
                 ok:= false;
                end;//73..77
           // Bereich 83...87  ?

              if (zStand >= 83) AND (zStand <=87) then
                begin
                 zStand := 90;
                 writeln('Ich:',zStand);
                 ok:= false;
                end;//83..87

           // Bereich 93...97 ?

              if (zStand>= 93 )AND (zStand <= 97 ) then
                begin
                 zStand := 100;
                 writeln('Ich: ',zStand);
                 writeln('Ich habe gewonnen!');
                 ok:= false;
                end;//93..97
                
           // das else bezieht sich nur auf das letzte if .. then!
           
            // Restbereiche
              if ok then
                begin
                  zStand := zStand + add;
                  writeln ('Ich*: ',zStand);
                  ok:= false;
                  add:= add + 1;
                        if add >7 then
                        add := 3;
                 end;//if ok

          end;//<100
     END;//<100
 readln;
end.
Viele Grüße
Bernd
Dateianhänge
Spiel2.zip
(1.79 KiB) 37-mal heruntergeladen

Atze
Beiträge: 10
Registriert: So 30. Apr 2023, 19:22

Re: Inkorrekt Compilation von if und else

Beitrag von Atze »

Dankeschön. Ich hatte das Problem auch schon auf diese Weise gelöst. Jedoch ist das nur ein Umgehen des eigentlichen Problems. Wieso bezieht sich das Else nur auf das letzte If? Dann kann man ja keine gestaffelten If Bedingungen mit else einsetzen. Ich bin es von anderen Sprachen gewöhnt, dass ein Else sich auf alle vorherigen Bedingungen bezieht. Wie aber kann man das in Pascal schaffen?
Grüße

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Re: Inkorrekt Compilation von if und else

Beitrag von theo »

Warum schmeisst du deine ganze Codesammlung in das Zip?
Ein Snippet (wie unten) hätte übrigens auch gereicht.
Atze hat geschrieben: Di 9. Mai 2023, 10:32 Wie aber kann man das in Pascal schaffen?
Meinst du so?

Code: Alles auswählen

  if (zStand >= 73) and (zStand <= 77) then
  begin

  end
  else if (zStand >= 83) and (zStand <= 87) then
  begin

  end
  else if (zStand >= 93) and (zStand <= 97) then
  begin

  end
  else
  begin

  end; 

Atze
Beiträge: 10
Registriert: So 30. Apr 2023, 19:22

Re: Inkorrekt Compilation von if und else

Beitrag von Atze »

Genau. In MatLab hat man dazu elseif !
Ich teste es mal, ob es korrekt läuft. Danke. Ich muss mich in Pascal einarbeiten...

Atze
Beiträge: 10
Registriert: So 30. Apr 2023, 19:22

Re: Inkorrekt Compilation von if und else

Beitrag von Atze »

Nun das Zippen hat charlytango empfohlen. Ich hatte noch nicht den Code Button im Menü entdeckt... Ich dachte, die lpi Datei beinhaltet den Text Code... wie in Matlab..

charlytango
Beiträge: 1061
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Inkorrekt Compilation von if und else

Beitrag von charlytango »

Atze hat geschrieben: Di 9. Mai 2023, 17:49 Nun das Zippen hat charlytango empfohlen.
Ja, aber erst nachdem du es nicht geschafft hast ein relevantes Code Snippet zu zeigen.
Dann sichert meine vorgeschlagene Methode dass alle Teile eines Projektes (und nicht nur die *.lpi-Datei) in ein Verzeichnis kopiert werden. Dass auch gezippet werden kann ist nur ein Zusatzgoodie.
Atze hat geschrieben: Di 9. Mai 2023, 17:49 ... wie in Matlab..
If/elseif/else scheint in Mathlab genauso zu funktionieren wie in vielen anderen Sprachen. Was für mich historisch gesehen auch kein Wunder ist ;-)

Wenn man aber mehrere If-Statements verschachtelt muss man aufpassen welches else dann zum Zuge kommt.

Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 1196
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Manjaro Linux, Mint und Windows 10 ,Lazarus 3.99, FPC-Version: 3.3.1
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

Re: Inkorrekt Compilation von if und else

Beitrag von kralle »

Moin,

Warum mit vielen IF-Abfragen arbeiten?
Nehme CASE.
https://wiki.freepascal.org/Case/de

Gruß Heiko
OS: Manjaro Linux, Linux Mint und Windows 10
FPC-Version: 3.3.1 , Lazarus 3.99
+ Delphi XE7SP1

Atze
Beiträge: 10
Registriert: So 30. Apr 2023, 19:22

Re: Inkorrekt Compilation von if und else

Beitrag von Atze »

Es läuft jetzt korrekt.
Ich habe das für meinen Enkel geschrieben, falls er Pascal lernen muss. So dachte ich, ich bereite mich mal auf Pascal vor...
Habt ihr schon rausgekriegt, wie man dieses Spiel sicher gewinnt?

Code: Alles auswählen

program Spiel2;
var zStand,add,Du,differenz:integer;
     ok:boolean;

begin
 writeln('Spiele gegen mich');
 writeln('Wer zuerst 100 erreicht, hat gwewonnen.');
 writeln('Du darfst nur Werte von 3...7 hinzuzaehlen.');
 writeln('Ich starte.');
 writeln('1');
 zStand:= 1;
 add:= 6;

 while zStand < 100 Do
     Begin
     repeat
         writeln ('Du ' );
         readln(Du);
         //pruefe Eingabe, korrekt?
         differenz:= Du-zStand;

         if (differenz < 3) OR (differenz > 7) then
         begin
             writeln('Deine Eingabe war falsch!');
             ok:=false;
         end
         else
         // Eingabe korrekt
            Begin
            ok := true;
            zStand := Du;
            writeln ('Z Stand : ',zStand);
            if zStand = 100 then
                writeln ('Du hast gewonnen!');
            end;
       until ok=true;

        //Computer macht Eingabe

        if zStand <100  then
           begin

           // Bereich 73...77
              if (zStand >= 73) AND (zStand <=77) then
                begin
                zStand := 80;
                writeln('Ich:',zStand);
                ok:= false;
                end
           // Bereich 83...87  ?
              else
              if (zStand >= 83) AND (zStand <=87) then
                begin
                zStand := 90;
                writeln('Ich:',zStand);
                ok:= false;
                end

           // Bereich 93...97 ?
              else
              if (zStand>= 93 )AND (zStand <= 97 ) then
                begin
                zStand := 100;
                writeln('Ich: ',zStand);
                writeln('Ich habe gewonnen!');
                end
          // Restbereiche
              else
                  begin
                  zStand := zStand + add;
                  writeln ('Ich: ',zStand);
                  ok:= false;
                  add:= add + 1;
                        if add >7 then
                        add := 3;
                  end;
          end;
     END;
 readln;
end.
[code]

Atze
Beiträge: 10
Registriert: So 30. Apr 2023, 19:22

Re: Inkorrekt Compilation von if und else

Beitrag von Atze »

Warum mit vielen IF-Abfragen arbeiten?
Nun, soweit ich das sehe, verlangt case einen einfachen Integer. Da ist nix mit >73 and <77 drin!

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Re: Inkorrekt Compilation von if und else

Beitrag von theo »

Atze hat geschrieben: Do 11. Mai 2023, 15:07
Warum mit vielen IF-Abfragen arbeiten?
Nun, soweit ich das sehe, verlangt case einen einfachen Integer. Da ist nix mit >73 and <77 drin!
Mit Integer geht das schon. Nur bei Fliesskommazahlen afaik nicht.

Code: Alles auswählen

  case zStand of
    73 .. 77: tuwas;
    83 .. 87: tuwas;
    93 .. 97: tuwas;
    else
      tuwas;
  end;     

Warf
Beiträge: 2118
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Inkorrekt Compilation von if und else

Beitrag von Warf »

Atze hat geschrieben: Do 11. Mai 2023, 15:07 Nun, soweit ich das sehe, verlangt case einen einfachen Integer. Da ist nix mit >73 and <77 drin!
Doch klar, Case kann nicht nur einfache werte, sondern auch mehrere werte oder sogar die Möglichkeit einen ganzen Zahlenraum zwischen start und ende anzugeben:

Code: Alles auswählen

  case i of
  3, 7: WriteLn('3 oder 7');
  74..76:
    WriteLn('>73 und <77'); 
  80, 83..85, 89:
    WriteLn('80 oder >82 und <86 oder 89');
  end;  
Aber nur mit Ordinalen typen (Integers, Enums und Chars)

Antworten