Pascal Ausgabe in Variable speichern

Derbysieger

Cadet 3rd Year
Registriert
Nov. 2009
Beiträge
54
Hi, also ich hänge hier ein wenig!

Wie bekomme ich denn die Zufallsausgabe der 2 Zahlen(muss eine Funktion sein) in eine Variable gespeichert?

Ich soll das Spiel Meier programmieren!

Hier mein Ansatz:
PHP:
PROGRAM P1_meiern;
USES WinCrt;
VAR zahl                       : ARRAY [1..2] OF Integer;
       i                             : Integer;
       wuerfelergebnis    : Integer;

Function wuerfeln(zahl1, zahl2 : Integer) : Integer;
BEGIN
  ClrScr;
  Randomize;   (* Generator initialisieren *)
   i := 1;  (* Index; die wievielte Zahl *)
   REPEAT
    zahl[i] := (Random(5)+1);   (* eine Zahl erzeugen und zuweisen *)
    inc (i);   (* i erhoehen *)
  UNTIL i > 2;

  if zahl[1] > zahl[2] then
     begin
        Write(zahl[1],zahl[2], '');
     end  
  else
     begin
        write(zahl[2],zahl[1], '');
     end;

  ReadKey;
END;

BEGIN
  ClrScr;
  Writeln ('Folgende Augenzahlen wurden erzeugt:   ', wuerfeln(zahl[1],zahl[2]));
   END.
 
Zum einen halt ich es für unglücklich, bei jedem Funktionsaufruf "randomize;" anzugeben, weil du dann im unglücklichsten Fall jedes mal die selben Zufallszahlen bekommst. Zum anderen ist dir (denke ich) inzwischen klar, dass eine Funktion nur einen Rückgabewert hat.

Wenn du alst mehr als einen Wert durch eine Funktion zurückgeben lassen willst, bleibt dir eigentlich nur die Variante, einen Datentyp zu erzeugen, der alle Werte aufnehmen kann, die du zurückgeben willst.
Im einfachen Fall haben all diese Werte den gleichen Datentyp. Dann kannst du mit einem Array arbeiten. Wobei ich nicht weiß, ob deine alte pascal-Version Arrays als Rückgabewerte von Funktionen unterstützt.

Wenn die Werte hingegen verschiedene Datentypen haben, musst du zwangsweise entweder als VAR-Parameter zurückgeben oder ein Record aufbauen (ggf. empfiehlt sich auch eine Klasse), das die benötigten Werte enthält.

Du solltest dir übrigens folgende Dinge angewöhnen:
1. Funktionen greifen nicht auf Globale Variablen zu, sondern bekommen alles, was sie benötigen, als Parameter übergeben.
2. Funktionen zur Benutzerinteraktion (Ein- und Ausgabe) und Funktionen mit Berechnungs-/Programmlogik sollten nicht gemischt werden.
3. Wenn der Compiler sagt "Variable "Würfelergebnis wurde in Zeile 4 deklariert, aber in "P1_meiern" nicht verwendet, ist die Variable überflüssig und sollte nicht im Programm sein.

Und nebenbei:
für "i:=1;Repeat ... inc(i); Until i=x" gibt es formschöner in der variante "For i:=1 to x do begin ... end;"
 
Gibt es denn einen "Random-Befehl" der mit eine zweistellige Zahl ausgibt, aus einer bestimmten folge die ich vorher festlege?
also beim meiern steht ja die höhere Augenzahl vorne!
 
randomize brauchst du nur einmal aufrufen und dann nie wieder. Die Funktion generiert einen Wert, der aus der Systemzeit bebildet wird und speichert diesen in eine globale Variable. Die Funktion random() greift dann auf diesen Wert zu.
Wenn du z.B. eine Schleife erzeugst, die mehrer Zufallszahlen generieren soll und du jedes Mal wieder Randomize aufrufst, dann kann es passieren, dass die globale Variable immer den selben Wert besitzt und somit würde random() immer die gleiche Zahl ausgeben.

edit:
Random() beitzt einen Parameter, indem man angeben kann, wie groß die Zufallszahl sein kann.
Random(100) sagt also, dass er eine Zufallszahl zwischen 0 und 99 erzeugt.
Durch einfache Addition kann man auch die untere Grenze bestimmen. Random(91) + 10 erzeugt eine Zufallszahl zwischen 10 und 100.

Sieht ein bisschen komisch aus, aber daraus kann man sich eine eigene Funktio basteln, die etwas sprechender ist.
Code:
// Funktioniert nur mit positiven Zahlen!
function getRandom(min, max : Integer) : Integer;
begin
  getRandom := random(max - min + 1) + min;
end;
 
Zuletzt bearbeitet:
abgesehen von den Codeoptimierungen, hier mal, wie es aussehen könnte:
Code:
PROGRAM P1_meiern;
USES Crt;
type tZahlen = array[1..2] of integer;
var Zahlen : tZahlen;

Function wuerfeln : tZahlen;
VAR zahl                       : ARRAY [1..2] OF Integer;
       i                             : Integer;

BEGIN
  ClrScr;
  Randomize;   (* Generator initialisieren *)
   i := 1;  (* Index; die wievielte Zahl *)
   REPEAT
    zahl[i] := (Random(5)+1);   (* eine Zahl erzeugen und zuweisen *)
    inc (i);   (* i erhoehen *)
  UNTIL i > 2;

  if zahl[1] > zahl[2] then
     begin
        result[1] := zahl[1];
        result[2] := zahl[2];
     end
  else
     begin
        result[1] := zahl[2];
        result[2] := zahl[1];
     end;
{
  ReadKey;}
END;

BEGIN
  ClrScr;
  Zahlen := wuerfeln();
  Writeln ('Folgende Augenzahlen wurden erzeugt:   ', Zahlen[1],Zahlen[2]);
  ReadKey;
   END.
 
Ich bekomme das nicht zum laufen!Kann leider auch kein CRT nutzen!

PHP:
PROGRAM P1_meiern;
USES WinCrt;
type tZahlen = array[1..2] of integer;
var Zahlen : tZahlen;

Function wuerfeln(tZahlen1,tZahlen2 : Integer) : Integer;
VAR zahl                       : ARRAY [1..2] OF Integer;
    result                     : ARRAY [1..2] OF Integer;
       i                             : Integer;

BEGIN
  ClrScr;
  Randomize;   (* Generator initialisieren *)
   i := 1;  (* Index; die wievielte Zahl *)
   REPEAT
    zahl[i] := (Random(5)+1);   (* eine Zahl erzeugen und zuweisen *)
    inc (i);   (* i erhoehen *)
  UNTIL i > 2;

  if zahl[1] > zahl[2] then
     begin
        result[1] := zahl[1];
        result[2] := zahl[2];
     end
  else
     begin
        result[1] := zahl[2];
        result[2] := zahl[1];
     end;
{
  ReadKey;}
END;

BEGIN
  ClrScr;
  Zahlen := wuerfeln(tZahlen1,tZahlen2);
  Writeln ('Folgende Augenzahlen wurden erzeugt:   ', Zahlen[1],Zahlen[2]);
  ReadKey;
   END.

Also so müste doch in result[1] die größere Zahl gespeichert sein und in result [2] die kleinere oder?
wie kriege ich nun beide zu einer auf eine variable???
 
Code:
PROGRAM P1_meiern;

USES 
  Crt;

type 
  TNumbers = array[0..1] of integer;

  function getRandom(min, max : Integer) : Integer;
  begin
    getRandom := random(max - min + 1) + min;
  end;

  procedure swap (VAR zahlen : TNumbers);
  var
    temp : integer;
  begin
    temp := zahlen[0];
    zahlen[0] := zahlen[1];
    zahlen[1] := temp;
  end;

  function dice() : TNumbers;
  var
    zahlen : TNumbers;
    i : Integer;
  begin
    for i := 0 to 1 do
      zahlen[i] := getRandom(1, 6);	

    if zahlen[1] > zahlen[0]
      swap(zahlen);
  
     dice := zahlen; 
  end;

var 
  Zahlen : TNumbers;
begin
  ClrScr;
  randomize;
  zahlen := dice();
  Writeln ('Folgende Augenzahlen wurden erzeugt: ', zahlen[0],zahlen[1]);
end.
habs nicht getestet aber so sollte es funktionieren.
 
Achso, hatte vergessen, daß ich Lazarus benutzt habe. Crt habe ich nur verwendet, weil es ClrScr beinhaltet.

Wo klemmt es denn bei meinem Listing? Kannst Du keine Arrays als Rückgabewerte benutzen?
 
Also bei Turbo Pascal gibt es mir einen Compilerfehler bei
PHP:
function dice() : TNumbers;
aus!
Das Problem ist vor allem das ich nicht ganz so fit bin im Programmieren.
Ich muss es leider machen obwohl es so garnichts mit meinem Wirtschaftsstudium zu tun hat!
Und das ganze hat auch mit einer Einführung nichts mehr zu tun meiner Meinung nach.
Da schießt unser Prof ein wenig über das Ziel hinaus!
 
Ich nehme an das liegt dann wirklich daran, dass du keine Arrays als Rückgabeparameter verwenden darfst (TNumbers ist ja ein Array of Integer).

Versuch mal einen Record, solange die Anzahl der Elemente immer gleich bleibt.
 
pcw schrieb:
Ich nehme an das liegt dann wirklich daran, dass du keine Arrays als Rückgabeparameter verwenden darfst (TNumbers ist ja ein Array of Integer).

Das sollte normalerweise gehen, da TNumbers ein deklarierter Datentyp ist und diese kann man zurückgeben. Anders ist es, wenn ich
Code:
function tuWas() : Array[0..1] of Integer;
begin
[...]
end;

mache. Das funktioniert nicht.
Siehe hier

Ein String ist ja auch nichts weiter als Array[0..n] of Char.
 
Zuletzt bearbeitet:
Danke für die Antworten. Ich bekomme es nur nicht hin die ausgegebene Datei in eine Variable zu speichern!
Würfeln und ausgeben funktioniert ja gut. Ist zu hoch für mich einfach!
PHP:
PROGRAM P1_meiern;
USES WinCrt;
 
VAR zahl               : ARRAY [1..2] OF Integer;
    i                  : Integer;
    
Function wuerfeln(zahl1, zahl2 : Integer) : Integer;

BEGIN

  ClrScr;
  i := 1;  (* Index; die wievielte Zahl *)
 
  FOR i:=1 TO 2 DO
     BEGIN
        zahl[i] := (Random(5)+1);   (* eine Zahl erzeugen und zuweisen *)
     END;
  
  if zahl[1] > zahl[2] then

  begin
    Write(zahl[1],zahl[2], '');
  end

  else

  begin
    write(zahl[2],zahl[1], '');
  end;

  ReadKey;

END;

BEGIN

  ClrScr;
  Randomize;   (* Generator initialisieren *)
  Writeln ('Folgende Augenzahlen wurden erzeugt:   ', wuerfeln(zahl[1],zahl[2]));
  writeln;

END.

Das ist mein Ansatz bis jetzt!
 
Wir reden hier aber von TurboPascal und nicht von Delphi-Pascal. Das ist ein Unterschied. Turbo-Pascal unterstützt unter anderem auch keine Dynamischen Array- und Stringlängen.

und nur weil du ein TNumber definierst, ist es immernoch ein Array. Der einzige unterschied ist, dass der Compiler es in Funktion und aufrufendem Programmcode als "gleichen Variablentyp" erkennt und nicht als "zwei Variablentypen gleichen Aussehens".

Turbo-Pascal Umgehung für Array als Rückgabewert wäre ein:
PNumber = ^TNumber;
MypNumber: pNumber;
new(MypNumber);
MypNumber^[0] := X;
MypNumber^[1] := Y;
result := MypNumber;

und
pNr := blubb(1,6);
global_X := pNr^[0];
global_Y := pNr^[1];
dispose(pNr);


Ansonsten steht es dir natürlich frei, mittels Turbo Pascal eine schönere Version zu schreiben bzw. zu demonstrieren, wie Arrays als Funktionsresult verwendet werden können.
 
Du vermischst Berechnungen mit Ausgaben. Das sollte man unter allen Umständen vermeiden.
Es ist ein sehr schlechter Programmierstil und führt zu Problemen.

Deine Funktion würfeln() berechnet die Zahlen und gibt sie gleich auf dem Bildschirm aus, ohne dass jemals eine andere Funktion auf die Zahlen zugreifen kann, da sie gleich wieder gelöscht werden, wenn die Funktion beendet wurde. was machst du denn, wenn du das Programm erweitern willst?
Dann stehst du schon auf den Schlauch.
Du brauchst also 3 Funktionen:
- eine, die dir die Zahlen generiert
- eine, die dir die Zahlen auf den Bildschirm ausgibt
- eine, die dir die Zahlen in eine Datei schreibt

Sowas nennt man auch Abkapselung, oder auch EVA-Prinzip (Eingabe, Verarbeitung, Ausgabe) genannt.

pcw schrieb:
Wir reden hier aber von TurboPascal und nicht von Delphi-Pascal. Das ist ein Unterschied. Turbo-Pascal unterstützt unter anderem auch keine Dynamischen Array- und Stringlängen.

In meiner Ausbildung haben wir auch Turbo Pascal verwendet und da ging es auch. Vermutlich muss da noch was am Compiler einstellen, aber das weiß ich jetzt nicht mehr so ganz.
 
Zuletzt bearbeitet:
Ich hab jetzt extra Turbo Pascal 5.5 runtergeladen um das zu testen.
Ergebnis: Arrays und Records sind "Error 34: Invalid function result type".

Deswegen sieht meine Lösung wie folgt aus:
Code:
PROGRAM MEIER;
uses CRT;
const
  TNUMBER_COUNT = 7;
type
  TNumber = Array [1..TNUMBER_COUNT] of Byte;
  PNumber = ^TNumber;

function dice(Min,Max:Byte):PNumber;
var
  myNumber:PNumber;
  i: Integer;
begin
  New(myNumber);
  for i := 1 to TNUMBER_COUNT do
  begin
    myNumber^[i] := random(Max-Min)+1;
  end;
  dice := myNumber;
end;

VAR
  gNumber:PNumber;
  i:Integer;
BEGIN
  randomize;
  clrscr;
  gNumber := dice(1,6);
  for i:=1 to TNUMBER_COUNT do
  begin
    writeln('Zahl ',i,' ist ',gNumber^[i]);
  end;
  Dispose(gNumber);
  readln;
END.

Der komplette Code deswegen, weil ich es für einen Anfänger mit Problemen, Schleifen zu benutzen für äußerst unfair halte, wenn man von ihm verlangt, sich mit den Besonderheiten veralteter Compiler und Zeigern auszukennen.

Wobei ich ja immer mehr daran zweifel, dass die Aufgabenstellung tatsächlich verlangt, dass eine Funktion alle Zahlen auf einmal zurückgibt, sondern ich vielmehr davon ausgehe, dass die selbe Funktion für jede Zahl einmal aufgerufen werden sollte.
 
Hi,
ich probiere darauf aufzubauen!Danke erstmal für deine Mühe!!!!!!
Hier aber nochmal die genaue Aufgabenstellung:

Und ehrlich gesagt, finde ich es schon ziemlich komplex wenn man sowas nach 6 Wochen Vorlesung können soll. Bin halt kein Informatiker!

Zur Version P1 – nur einmal w¨urfeln:

• Zur Umsetzung des Wurfes zweier W¨urfel muss eine Funktion mit dem Namen Wuerfeln verwendet werden,
die f¨ur unseren Zweck das W¨urfeln ¨ubernimmt, Zehner- und Einerstelle kombiniert und eine zweistellige
Zahl ausgibt. Tritt ein M¨axchen auf, soll dieses als 77 ausgegeben werden.

! P1: Entwickeln Sie das Programm P1, das die Funktion Wuerfeln deklariert und im Hauptprogramm aufruft.
Der Funktionswert – das W¨urfelergebnis – soll auf eine Variable mit geeignetem Namen zugewiesen und
auf dem Bildschirm ausgegeben werden.

Zur Version P2 – nur einmal w¨urfeln und ggf. l¨ugen:

• Die Umsetzung des L¨ugens oder des Nichtl¨ugens soll durch eine Prozedur (LuegeOderWahrheit) unterst¨utzt
werden. Diese Prozedur zeigt dem Spieler die zu ¨uberbietende Ansage sowie das W¨urfelergebnis und ermittelt,
ob der Spieler l¨ugen m¨ochte oder wegen eines zu schlechten W¨urfelergebnisses l¨ugen muss. Ist das der
Fall, erfragt die Prozedur die gew¨unschte Ansage (in Form einer zweistelligen Zahl). Nach dieser Kl¨arung
wird die neue Ansage gespeichert. Wir unterstellen zur Vereinfachung, dass kein Spieler auf die Idee kommt,
eine nicht erlaubte Zahl einzugeben.

! P2: Entwickeln Sie im zweiten Schritt aus P1 das Programm P2, in dessen Hauptprogramm einmal Wuerfeln
und danach LuegeOderWahrheit aufgerufen wird. Zum Schluss wird die Ansage ¨uber den Bildschirm ausgegeben.
Offensichtlich werden f¨ur P2 zwei ganz zentrale Variablen ben¨otigt, um das W¨urfelergebnis und
die Spieleransage aufzubewahren.
Zur Version P3 – w¨urfeln, ggf. l¨ugen und sich hochsteigern:

• F¨ur die Abbildung des Hochbietens soll in dieser Version eine Schleife verwendet werden.
! P3: Entwickeln Sie in einem dritten Schritt P2 zu dem Programm P3 weiter, mit dem man wiederholt w¨urfeln
und ggf. immer h¨ohere Gebote eingeben kann. Die Schleife soll abgebrochen werden, wenn eine Ansage
gr¨oßer 77 eingegeben wird.

Zur Version P4: – w¨urfeln / l¨ugen, hochsteigern mit 3 Spielern:
• F¨ur ein richtiges Spiel sind drei Spieler erforderlich. W¨ahrend des Ablaufes muss das Programm also mitteilen,
welcher Spieler am Zuge ist. Hierf¨ur ist eine Variable erforderlich, die den aktuellen Spieler anzeigt.

! P4: Erstellen Sie auf Basis von P3 das Programm P4, bei dem drei Personen abwechselnd w¨urfeln und ggf.
Ansagen machen k¨onnen. Das Spiel soll wieder enden, wenn die Ansage 77 (unsere Kodierung f¨ur M¨axchen)
¨uberschritten wird.

Zur Version P5: – Zweifeln einbauen:
• Entwickeln Sie eine Prozedur mit dem Namen ZweifelnSimple, in der einige Handlungen umgesetzt werden,
die im Falle eines Anzweifelns zu erledigen sind: Anzeige der letzten Ansage, Anzeige des letzten Wurfes,
R¨ucksetzung der Ansage auf 0 sowie eine Textausgabe dar¨uber, ob der Zweifler oder der letzte Ansager
bestraft werden muss.
! P5: Erstellen Sie das Programm P5, bei dem drei Personen abwechselnd w¨urfeln und Ansagen machen k¨onnen.
Jeder Spieler soll aber nun die letzte Ansage anzweifeln d¨urfen. Im Falle des Zweifelns wird die Prozedur
ZweifelnSimple aufgerufen. Das Spiel soll enden, wenn die Ansage 77 (unsere interne Kodierung f¨ur
M¨axchen) ¨uberschritten wird.

Zur Version P6: – Punkteverwaltung hinzuf¨ugen:
• Die Punkte der Spieler sollen auf einem Vektor verwaltet werden. Dieser muss deklariert und mit Anfangspunkten
initialisiert werden. In der Prozedur Zweifeln als Erweiterung von ZweifelnSimple wird dem zu
bestrafenden Spieler ein Punkt von seinem Konto abgezogen und der aktuelle Punktestand ausgegeben.
! P6: Erstellen Sie das Programm P6, das gegen¨uber P5 zus¨atzlich mit Hilfe der verbesserten Zweifel-Prozedur
die Punkte der Spieler verwaltet und das Spiel erst beendet, wenn ein Spieler die Punktegrenze 0 erreicht
hat. Zum Spielen sollten an passender Stelle ¨ubrigens die Ausgaben vom Bildschirm entfernt werden.
 
zu P1:
funktion würfeln:
x sei eine Zufallszahl zwischen 1 und 6
y sei eine Zufallszahl zwischen 1 und 6
wenn x > y, dann x und y vertauschen
der Rückgabewert der Funktion sei (y * 10) + x
wenn der Rückgabewert der Funktion 21 ist, dann sei der Rückgabewert der Funktion 77
funktion ende

Hauptprogramm:
Würfelergebnis sei der Rückgabewert der Funktion würfeln
Ausgabe von Würfelergebnis auf dem Bildschirm.

zu P2:
funktion Frage(Text):
wiederhole:
Ausgabe von Text + '(y/n)'
Eingabe von EingabeStr
bis EingabeStr = y oder EingabeStr = n
Rückgabewert der Funktion sei das ergebnis des boolschen Ausdrücks "EingabeStr = y"
funktion ende

funktion ErfrageZahl:
wiederhole
Ausgabe von 'Geben sie eine zweistellige Zahl ein: '
Eingabe von EingabeStr
EingabeStr in Zahlwert EingabeZahl unter Berücksichtigung von Fehlerstelle FS umwandeln
bis FS = 0 und EingabeZahl > 9 und EingabeZahl < 100
Rückgabewert der Funktion sei EingabeZahl

Prozedur LuegeOderWahrheit(var Ansage):
Würfelergebis sei Rückgabewert der Funktion Würfeln
wenn nicht Ansage kleiner als Würfelergebnis, dann sei Lügen = Rückgabewert der Funktion Frage('Wollen Sie lügen?')
sonst sei Lügen = true
Wenn Lügen = true, dann sei Ansage der Rückgabewert der Funktion ErfrageZahl
sonst sei Ansage = Würfelergebnis
prozedur Ende

Hauptprogramm:
AktuelleAnsage sei der Rückgabewert der Funktion Würfeln
Aufruf der Prozedur LuegeOderWahrheit mit AktuelleAnsage als Parameter
Ausgabe von AktuelleAnsage


Für 3. Baust du um das Hauptprogramm ne schleife
Für 4. kommt in die Schleife eine Zählvariable, die du jede Runde um eins höchzählst und immer den Rets der Ganzzahligen Division durch 3 ermittelst, um so rauszufinden, welcher Spieler grade dran ist.

Damit solltest du genug Wissen angesammelt haben, um den Rest auch noch zu erledigen.
 
Ja vielen Dank erstmal!Setze mich morgen früh direkt dran!
Also soweit bin ich im moment:

Wie beende ich das programm,zB wenn ich einen Meier habe???? !!!

PHP:
PROGRAM P1_meiern;
USES WinCrt;
 
VAR     i,w                  : Integer;
    
Function wuerfeln : Integer;

Var      x,y        : Integer;

BEGIN

  x := (random(6)+1);  {Generiert ein Zufallszahl zwischen 1 und 6}
  y := (random(6)+1);

  IF x > y THEN        {Schleife die Zehner- und Einerstelle kombiniert}

     BEGIN
        w := x*10+y    
     END
  ELSE
     BEGIN
        w := y*10+x
     END;

  IF w = 21 THEN       {Meier, 21, ist hier die 77}
    BEGIN
       w := 77;
       writeln(' ',w);
       writeln;
       writeln('Meier! Der Spieler hat gewonnen!');

    END;    
    wuerfeln:=w;

END; 

Procedure luegeoderwahrheit;

var zeichen : char;
    n : integer;

Begin  
   writeln;
   writeln('Ihr Wurf ist: ',wuerfeln, '   (weiter mit beliebiger Taste...)');
   zeichen:=Readkey; 
   writeln;
   writeln('Moechten Sie luegen? (j/n)');
   readln(zeichen);
   writeln;
If zeichen = 'j' then

   BEGIN                                                 
     
      writeln;
      Writeln ('Welche Augenzahl moechten Sie eingeben?  ');
      readln(n);
      writeln;
      write('Meine Ansage ist ',n);
   END
ELSE
   BEGIN
      zeichen:='n';    
      writeln;
      writeln('Ihre Augenzahl ist: ',w);
   End;

End;


{Hauptprogramm}

BEGIN

  ClrScr;
  Randomize;            {Zufallsgenerator}
  Writeln ('Folgende Augenzahlen wurden gewürfelt:  ',wuerfeln);
  luegeoderwahrheit;
  writeln;

END.

Vlt kann jemand helfen!
 
Zuletzt bearbeitet:

Ähnliche Themen

T
Antworten
12
Aufrufe
1.197
Antworten
7
Aufrufe
3.605
R
T
  • Gesperrt
Antworten
14
Aufrufe
1.391
Zurück
Oben