workshop12

Top  Zurück  Weiter

Workshop 12: If - Else Verzweigung

Falls meine Ausgaben über 1500 US-Dollar liegen, muss ich mir einen neuen Job suchen, sonst behalte ich meinen derzeitigen Job.


Ja, mein Hirn funktioniert noch, danke der Nachfrage. Das ist nur ein Beispiel für eine "if" (falls) - 'else' (sonst)-Verzweigung. Den entsprechenden Code sehen Sie unten:

if (my_bills > 1500) // falls (meine_rechnungen > 1500)
  find_new_job( ); /
/ finde_neuen_job()
else
// sonst
  keep_existing_job( ); // behalte_derzeitigen_job()

Wenn Sie wollen, dass sich Ihr Programm, je nach bestimmten Bedingungen wie z. B. Anwender-Eingabe, einer Zufallszahl, dem Ergebnis einer mathematischen Gleichung etc. unterschiedlich verhält, benutzen Sie "if"-Anweisungen. Hier die Grundlage einer "if"-Anweisung:

if (eine Bedingung ist wahr)
  do_something(); // tu etwas, führe diese Anweisung (eine einzige Anweisung!) durch

oder

if (eine Bedingung ist wahr)
{

// führe die Anweisungen innerhalb der geschweiften Klammern aus
}

Die komplexere Form einer "if"-Anweisung ist folgende:

if (eine Bedingung ist wahr)
{
  // führe eine oder mehrere Anweisungen innerhalb dieser geschweiften Klammern aus
}

else
{
   // führe eine oder mehrere Anweisungen innerhalb dieser geschweiften Klammern aus
}

Die Anweisungen innerhalb der "else"-Schweifklammern wird nur dann ausgeführt, wenn die verlangte "if"-Bedingung nicht erfüllt, also nicht wahr ist. Hier ein praktisches Beispiel:

if (mein_Alter > 65)
  Einkommen = 2000;
else // Alter niedriger oder gleich 65?
  Einkommen = 3000;

Es ist ziemlich eindeutig, dass "Einkommen" entweder 2000 oder 3000 sein kann, denn es wird nur eine der Verzweigungen ausgeführt ("Einkommen = 2000" oder "Einkommen = 3000", nicht beides).

Ziehen wir einige Schlüsse:

- "if"-Verzweigungen fangen mit dem Schlüsselwort "if" an und dann folgt ein Klammerpaar:
- zwischen den beiden Klammern steht ein Vergleich, eine Ausdruck (eine Bedingung), die wahr oder falsch sein kann;
- ist die Ausdruck wahr, wird die folgende Anweisung oder der Satz von Anweisungen, der innerhalb des ersten Paares geschweifter Klammern steht, ausgeführt;
- ist die Ausdruck falsch und wir verwenden kein "else", werden die Anweisungen innerhalb der geschweiften Klammern übersprungen (also nicht ausgeführt);
- ist die Ausdruck falsch und wir verwenden zusätzlich die "else"-Verzweigung, werden die Anweisungen innerhalb der ersten geschweiften Klammern übersprungen und die Anweisungen innerhalb des zweiten Paares von geschweiften Klammern ausgeführt.

Diese Verzweigungstechnik haben Sie ruck zuck im Griff, glauben Sie mir! Öffnen wir die Datei script12:

////////////////////////////////////////////////////////////////////
#include 
#include 

////////////////////////////////////////////////////////////////////
var weight = 300;

STRING* fluffy_str = "Fluffy!";
STRING* skinny_str = "Skinny!";

////////////////////////////////////////////////////////////////////
TEXT* weight_txt =
{
	pos_x = 300;
	pos_y = 230;
	flags = SHOW;
}

/////////////////////////////////////////////////////////////////////
function main()
{	
	video_mode = 7; // erstelle ein Programmfenster von 800x600 Pixels
	screen_color.blue = 1; // und einen dunklen Hintergrund
	while (1)
	{
		if (weight > 200)
			(weight_txt.pstring)[0] = fluffy_str;
		else
			(weight_txt.pstring)[0] = skinny_str;
		wait (1);
	}
}        
Der Code sieht nicht allzu schwierig aus: wir haben eine var namens weight (Gewicht), die einen Anfangswert von 300 bekommt und zwei Strings: "Fluffy!" ('flaumig') und "Skinny!" ('dünn'). Mithilfe des eingebauten Fonts werden wir einen Text anzeigen. Das Interessante an dem Code ist der while (1) -Loop innerhalb der main-Funktion:

while (1)
{
   if  (weight > 200)
      (weight_txt.pstring)[0] = fluffy_str;
  else
     (weight_txt.pstring)[0] = skinny_str;
  wait (1);
}

Ich hoffe, Sie haben die "wait (1);"-Anweisung im while-Loop bemerkt. Diese Anweisung unterbricht jeden Framezyklus die Schleife und gibt anderen Aktionen und Funktionen die Möglichkeit, gleichzeitig zu laufen. Der Rest des Codes ist einfach: falls weight größer als 200 ist, setzen wir (mithilfe der Punkt-Methode) fluffy_str auf den Text namens weight_txt. Ist weight kleiner oder gleich 200, setzen stattdessen skinny_str als von weight_txt benutzten String. Die oben erwähnten geschweiften if / else-Klammern können wir weglassen, da ihr Inhalt lediglich aus einer einzigen Codezeile besteht.

Wie Sie sich vielleicht gedacht haben, ist pstring die Texteigenschaft, die es uns (per Punkt-Methode) ermöglicht, die für unsere Texte verwendeten Strings zu (er)setzen. Da jeder Text einen oder mehrere Strings benutzen kann (erinnern Sie sich an den 7. Workshop?), wird (weight_txt.pstring)[0] auf den ersten String unseres Textes weight_txt zugreifen, (weight_txt.pstring)[1] auf den zweiten String des Textes usw.. Mehrheitlich werden wir wir Texte mit einem einzigen String verwenden, daher wird "(some_txt.pstring)[0] = some_string;" den meisten unserer Ansprüche genügen.

Starten Sie das Skript und Sie sehen folgenden Text in der Mitte des Bildschirms:

w12_02

Drücken Sie jetzt die [Tab]-Taste und tippen Sie folgenden Text in die Konsole:

weight = 100;

Sobald Sie auf [Eingabe] gedrückt haben, ändert sich der Text von "Fluffy!" zu "Skinny!", denn sobald weight weniger oder gleich 200 ist, wird die Anweisung der "else"-Verzweigung ausgeführt:

w12_03

Damit wir, sobald der Anwender einen neuen Wert eingibt, auch den passenden Text anzeigen können, müssen wir den Wert von weight ständig überprüfen und brauchen daher eine while-Schleife

Nehmen wir an, Sie wollen das Programm herunterfahren wenn der Anwender diese Zeile in die Konsole eingibt:

weight = 0;
 
Wie bewerkstelligen Sie das? Sie müssen ein weiteres "if", welches weight mit Null vergleicht, hinzufügen. Kopieren Sie den folgenden Code und fügen Sie ihn innerhalb der while-Schleife ein:

if (weight == 0)

sys_exit(NULL);

So sollte der Code nun aussehen:  

////////////////////////////////////////////////////////////////////
#include 
#include 

////////////////////////////////////////////////////////////////////
var weight = 300;

STRING* fluffy_str = "Fluffy!";
STRING* skinny_str = "Skinny!";

////////////////////////////////////////////////////////////////////
TEXT* weight_txt =
{
	pos_x = 300;
	pos_y = 230;
	flags = SHOW;
}

/////////////////////////////////////////////////////////////////////
function main()
{	
	video_mode = 7; // erstelle ein Programmfenster von 800x600 Pixeln
	screen_color.blue = 1; // und einen dunklen Hintergrund
	while (1)
	{
		if (weight == 0)
		   sys_exit (NULL);
		if (weight >200)
		   (weight_txt.pstring)[0] = fluffy_str;
		else
		   (weight_txt.pstring)[0] = skinny_str;
		wait (1);
	}
}      

Der neue Code sieht wieder nicht allzu kompliziert aus; ist weight Null, wird die Engine herunterfahren ("sys_exit" sollten Sie noch aus dem 6. Workshop kennen). Starten Sie das Skript und tippen Sie:

weight = 0;

in die Konsole. Die Engine wird herunterfahren, denn das neue "if" hat seinen Job erledigt.

Moment mal! Was soll dieses "==" in der ersten der beiden Codezeilen? Nein, das ist kein Tippfehler. Immer, wenn Sie zwei Ausdrücke (Gewicht und Null in diesem Fall) miteinander vergleichen, müssen Sie"==" anstelle von "=" verwenden. Eine Code-Zeile, die so aussieht:

if (weight = 0)
{
    // tu irgendwas
}

wird "weight" auf Null setzen anstatt es mit Null zu vergleichen. Dies ist einer der häufigsten Fehler, selbst einem erfahrenen Programmierer kann es passieren, aus Versehen eine Variable auf einen bestimmten Wert zu setzen, anstatt sie mit diesem Wert zu vergleichen.

Wichtiger Hinweis:
Das Verwenden eines anstelle von zwei Gleichheitszeichen zum Vergleich zweier Ausdrücke innerhalb einer while-Schleife, if-Verzweigung usw. ist ein sehr häufig gemachter Fehler. Denken Sie also bitte daran:

if (a == 3) // korrekt
{
    tu_irgend_was
}

if (a = 3) // falsch!
{
    tu_irgend_was
}

Dieser Fehler läßt sich vermeiden, wenn Sie es sich zur Gewohnheit machen, den konstanten Wert auf die linke Seite des Vergleichs zu schrieben und die Variable auf die Linke. Die Anweisung zum Vergleich von weight würde demnach so aussehen:

if (0 == weight) // correct

sys_exit(NULL);

Wenn Sie hier anstelle von '==' versehentlich ein einzelnes '=' reinschreiben, wird der Compiler einen Fehler melden, denn er weiß, daß 0 nicht auf einen anderen Wert gesetzt werden kann.

Wir haben soviel über Ausdrücke gesprochen aber was ist eigentlich eine Ausdruck? Ein (arithmetischer) Ausdruck ist eine Folge von miteinander verknüpften Variablen, Zahlen, Operatoren etc.Während es ganz nett ist, so einfache Ausdrücke wie diese zu haben:

if (energy < 50) // einfache Ausdruck innerhalb der Klammern
{
    health = health - 10;
}

... ist es aber auch absolut möglich, mit komplizierteren Ausdrücke zu operieren, die dann in etwa so aussehen können:

if ((armor + energy * 0.25) > (health * (1 - class / 3))) // etwas komplizierterer Ausdruck
{
  health += 5;
}

Wichtiger Hinweis:
Unter Verwendung von Klammern, lassen sich so viele Ausdrücke kombinieren wie Sie haben wollen. Es gelten dieselben Regeln wie im Mathematikunterricht. Leider muss man ein wenig Mathematik können, wenn man ein guter Programmierer sein will.

Die folgende Tabelle veranschaulicht das Vergleichen zweier verschiedener Ausdrücke (dieselbe Tabelle lässt sich auch auf "if"-, "while" usw. anwenden):

w12_05

SITUATION
OPERATOR
PRAKTISCHES BEISPIEL
Ausdruck1 = Ausdruck2
==
if (a == b)
Ausdruck1 ist größer als Ausdruck2
>
if (a > b)
Ausdruck1 ist größer als oder gleich wie Ausdruck2
>=
if (a >= b)
Ausdruck1 ist kleiner als Ausdruck2
<
if (a < b)
Ausdruck1 ist kleiner als oder gleich wie Ausdruck2
<=
if (a <= b)
Ausdruck1 ist ungleich Ausdruck2
!=
if (a != b)

Manchmal müssen Sie überprüfen, ob verschiedene Bedingungen auf einmal zutreffen. Nehmen wir an, Sie wollen eine Kugel abfeuern. Der dafür zuständige Code sollte feststellen ob:

a) Ihr Gesundheits-Wert ("health") über Null ist (tote Spieler sollten keine Kugeln abfeuern können),
b) Ihre Munition ("ammo") mehr als Null beträgt (um damit irgendwas oder irgendjemanden zu beschießen, brauchen Sie mindestens eine Kugel).

Es gibt verschiedene Methoden, dieses Problem zu lösen aber nur eine verwendet verschachtelte "if"-Verzweigungen. Das bedeutet soviel wie "if" Verzweigungen innerhalb der geschweiften Klammern anderer "If"-Verzweigungen. Betrachten wir das anhand eines klaren, einfachen Beispiels:

if (player_health > 0)
{
   if (ammo > 0)
  {
    fire_bullets();
  }
}

Was geschieht hier? Zuallererst wird die Gesundheit des Spielers mit Null verglichen. Falls player_health <= 0, wird der Rest des Codes ignoriert. Ist der Player lebendig (player_health > 0), machen wir weiter und prüfen ob "ammo" größer als Null ist. Hat der Spieler nicht genug Munition (ammo <= 0), wird der Rest des Codes ignoriert. Andernfalls, wenn ammo > 0, wird die Funktion fire_bullets gestartet.

 Weiter: Die Tastatur