Action! wie geht das?

1, 2

Action! wie geht das?

von Cash » Sa 30. Okt 2010, 10:15
Hi,
ich möchte gerne der Variablen Q den wert 100 zuweisen und anschließen mit Print ausgeben. Leider klappt das nicht wirklich. Das Programm gibt den Wert 98 aus.
Mein Programm:

Proc Acey()

byte Q=100
PrintE("Sie haben")
PrintB(Q)
PrintE(" Euro")
Return

Was hab ich falsch gemacht? :roll:

Re: Action! wie geht das?

von Tigerduck » Sa 30. Okt 2010, 10:38
Hallo Cash,

Ich glaube das gleichzeitige Dimensionieren einer Variablen und Zuweisen eines Wertes funktioniert so nicht.
Wenn du es so machst:

byte Q
Q=100

funktioniert es.

Vielleicht gibt's noch bessere Lösungen, hab's aber eben bei mir getestet und es geht.

Gruß

Tigerduck

Re: Action! wie geht das?

von Cash » Sa 30. Okt 2010, 17:09
Danke Tigerduck!
Habe gleich noch ne Frage, wie löse ich "Goto's" bzw. "Gosub's" in Action am praktikabelsten?

Re: Action! wie geht das?

von cas » Sa 30. Okt 2010, 18:43
Cash hat geschrieben:Hi,
ich möchte gerne der Variablen Q den wert 100 zuweisen und anschließen mit Print ausgeben. Leider klappt das nicht wirklich. Das Programm gibt den Wert 98 aus.
Mein Programm:

Proc Acey()

byte Q=100
PrintE("Sie haben")
PrintB(Q)
PrintE(" Euro")
Return

Was hab ich falsch gemacht? :roll:


Hallo Cash,
Code: Alles auswählen
BYTE Q=100


legt die Variable Q auf die Speicherstelle 100, aber initialisiert diese nicht.

Um die Speicherstelle zu initialisieren schreibst Du:
Code: Alles auswählen
BYTE Q=[100]

Re: Action! wie geht das?

von FlorianD » Sa 30. Okt 2010, 19:59
Cash hat geschrieben:Danke Tigerduck!
Habe gleich noch ne Frage, wie löse ich "Goto's" bzw. "Gosub's" in Action am praktikabelsten?


Basic
Code: Alles auswählen
100 ? "HALLO ";
110 GOSUB 1000
120 END
1000 ? "ABBUC-USER!"
1010 RETURN

ist nicht schön, weil keiner weiss, was "GOSUB 1000" bedeutet.

Turbobasic
Code: Alles auswählen
100 ? "HALLO ";
110 EXEC DRUCKEUSERGRUSS
120 END
1000 PROC DRUCKUSERGRUSS
1005 ? "ABBUC-USER!"
1010 RETURN

ist schon besser

In Action!
Code: Alles auswählen
PROC DRUCKEUSERGRUSS()
PRINTE("ABBUC-USER!")
RETURN

PROC MAIN()
PRINT("Hallo ")
DRUCKEUSERGRUSS() ; einfach die Routine ohne exec oder gosub aufrufen
RETURN


GOTO sollte man gar nicht benutzen, dass mach alles nur unübersichtlich und schlecht nachvollziehbar. Braucht man in Action! auch nicht, das geht im Zweifelsfall auch ohne.
(siehe Edsger Dijkstra, "GOTO considered harmful" http://en.wikipedia.org/wiki/Considered_harmful )

Re: Action! wie geht das?

von Cash » Sa 30. Okt 2010, 21:49
Danke an alle für die schnelle hilfe.
@carsten: wenn ich z.b. "Q=[100]" eingebe kommt bei mir die Fehlermeldung "17"
@all: ich stehe vor dem nächsten problem, ich habe am anfang des Spieles Q=100€€ und möchte jetzt eine Abfrage starten wieviel Geld der spieler einsetzten möchte mit M=Input(), M soll dann von Q abgezogen werden so etwa-> "Q==-M". So dass man dann den Betrag in Q weniger hat. Leider bekoome ich immer ein ERROR "7" bei der input abfrage, ich verstehe nicht warum? Vielleicht wisst ihr ja eine lösung. Im ersten Proc hatte ich das Byte M initialisiert sonst gäbe es ein fehler. im nächsten proc ist dann die abfrage, dann musste ich nochmals byte M initialisieren und habe auch noch einen wert von "M=200" eingetragen. Danach dann die abfrage M=Input.

so in etwa:

Proc A()
byte M,Q
Q=100
Q==-M

printe("du hast jetzt")
printb(Q)
printe("Euro")

Return

Proc d()
byte M
M=200

printe("wieviel wettest du")
M=Input()
...
...

Re: Action! wie geht das?

von Dietrich » Sa 30. Okt 2010, 23:12
Action! funktioniert hier anders als andere Sprachen: Bei der Deklaration einer Variablen definiert =100 die Adresse der Variablen (wenn angegeben) und mit =[100] wird der Wert zugewiesen. Im Programmcode ist =100 eine Wertzuweisung und =[100] geht nicht. Beispiele:

BYTE Q=100 deklariert eine Variable Q, die auf Speicherstelle 100 liegt
BYTE Q=[100] deklariert eine Variable Q irgendwo im ACTION!-Variablenspeicher, die mit 100 initialisiert wird

PROC ...
Q=100 schreibt 100 in die Variable Q

Input() gibt es nicht. Benutze stattdessen InputB(), InputC() oder InputI() je nachdem, ob Du ein BYTE, CARD oder INT einlesen willst, z.B.

BYTE Q

PROC ...
Q=InputB()

Re: Action! wie geht das?

von Cash » So 31. Okt 2010, 11:38
@Dietrich danke, das mit Input funktioniert nun auch prima. :beer:

Allerdings habe ich immer noch ein Problem mit der Byte Funktion und den Variablen.
Wenn ich mehrere Unterprogramme erstelle also z.B. Proc 1(), Proc 2() usw. und in Proc 1() die Byte Funktionen deklariere z.b. Byte B und habe dann in Proc 2() eine Funktion die auf diese Byte B Variable die in Proc 1() festgelegt wurde zurückgreifen will, wird vom Unterprogramm schlicht und einfach "vergessen".
Deshal meine Frage wie lege ich die Byte Variablen in Proc 1() so fest das ich auch in den Unterprogrammen auf den Inhalt der Byte Variablen zurückgreifen kann?

Ps: Ich hoffe ich nerve euch nicht zu doll... :mrgreen:

gruß
Alex

Re: Action! wie geht das?

von Tigerduck » So 31. Okt 2010, 12:22
Hihihi,

find' ich gut das du die Fragen stellst, dann kann ich schön mitlesen und so machen als wüßte ich das Alles :wink:

Nee, im Ernst, als ACTION!-Neuling helfen deine Fragen (und natürlich die Antworten von unseren Experten) auch mir um mich einzuarbeiten.

Gruß

Tigerduck (Der jetzt gleich auf Arbeit muß :( )

Re: Action! wie geht das?

von FlorianD » So 31. Okt 2010, 16:02
Cash hat geschrieben:@Dietrich danke, das mit Input funktioniert nun auch prima. :beer:
Allerdings habe ich immer noch ein Problem mit der Byte Funktion und den Variablen.
Wenn ich mehrere Unterprogramme erstelle also z.B. Proc 1(), Proc 2() usw. und in Proc 1() die Byte Funktionen deklariere z.b. Byte B und habe dann in Proc 2() eine Funktion die auf diese Byte B Variable die in Proc 1() festgelegt wurde zurückgreifen will, wird vom Unterprogramm schlicht und einfach "vergessen".
Deshal meine Frage wie lege ich die Byte Variablen in Proc 1() so fest das ich auch in den Unterprogrammen auf den Inhalt der Byte Variablen zurückgreifen kann?

Ps: Ich hoffe ich nerve euch nicht zu doll... :mrgreen:
gruß
Alex


Hallo,

entweder Du definierst dir die Variable global (so wie in BASIC, d.h. die kann überall, in jeder Funktion/Procedure "gesehen" und genutzt werden.
Das geht so:
Code: Alles auswählen
MODULE
BYTE B ; globale Variable. Alle Variablen, die VOR der ersten PROC oder FUNC definiert werden, sind global
; oder man setzt im Code ein MODULE davor, dann sind alle Variablen zwischen MODULE und
; dem nächsten FUNC/PROC global

PROC EINS()
B=1
RETURN

PROC ZWEI()
B=2
RETURN

PROC MAIN() ; Hauptroutine, immer die letzte im Programmcode
  B=0 ;B gleich null setzen, definieren mit BYTE nicht nötig, da ganz oben global definiert
  PRINTB("B ist gleich=")
  PRINTBE(B) ; printbe heißt drucke byte und CR

  EINS()
  PRINTB("B ist gleich=")
  PRINTBE(B)

  ZWEI()
  PRINTB("B ist gleich=")
  PRINTBE(B)
RETURN


Ausgabe ist dann
B ist gleich=0
B ist gleich=1
B ist gleich=2



ooooder Du nutzt lokale Definitionen (soll solls mans "richtig" machen, guter Stil)
Code: Alles auswählen
MODULE
; keine globalen Variable definiert

BYTE FUNC EINS()
; wir müssen jetzt FUNCtionen nehmen, da PROCedure keine Werte zurückliefern können.
; wir berechnen hier nichts, sondern geben einen festen Wert mit "RETURN(Wert)" zurück
RETURN(1)

BYTE FUNC ZWEI()
 BYTE B ; dieses B ist nur lokal, d.h. in der FUNC ZWEI() sichtbar
 B=7000 ; wir setzen es auf 7000, das globale B wird davon nicht betroffen
RETURN(2)

PROC MAIN() ; Hauptroutine, immer die letzte im Programmcode
  BYTE B
  B=0 ;B gleich null setzen
  PRINTB("B ist gleich=")
  PRINTBE(B)

  B=EINS()
  PRINTB("B ist gleich=")
  PRINTBE(B)

  B=ZWEI()
  PRINTB("B ist gleich=")
  PRINTBE(B)
RETURN


Ausgabe ist dann
B ist gleich=0
B ist gleich=1
B ist gleich=2

Re: Action! wie geht das?

von cas » So 31. Okt 2010, 17:11
Hi,

wie Florian schon angemerkt hat kann man das Verhalten von BASIC in ACTION! mit globalen Variablen "emulieren", aber damit würde man eines der guten Funktionen von ACTION! nicht nutzen. Das Variablen in PROC/FUNC nur innerhalb der Prozedur/Function "sichtbar" sind ist eine wirklich gute Sache.

Die regel für gut-strukturierte Programme ist:

* alle Daten, die in einer Prozedur/Funktion benötigt werden, werden über die Parameter übergeben (in Klammern)
* alle Daten, die von einer Funktion berechnet werden, werden über den RETURN-Wert zurückgegeben
* eine Prozedur/Function sollte im Idealfall nicht länger sein als eine Bildschirmseite (das kann unser Gehirn gut erfassen). Längere Prozeduren/Funktionen können in kleinere aufgeteilt werden

Der RETURN-Wert eine Funktion kann nur einen Wert zurüclgeben. Dieser Wert kann aber ein Zeiger (Pointer) auf eine Datenstruktur (Array, Record) sein, so das damit beliebig komplexe Daten aus einer Funktion zurückgegeben werden können.

Zur Sichtbarkeit von Variablen (Scope) aus Wikipedia
http://de.wikipedia.org/wiki/Variable_% ... 28Scope.29

-- Carsten

Re: Action! wie geht das?

von FlorianD » So 31. Okt 2010, 17:15
im Action! Handbuch (deutsch) ist ab Seite 97 der Sachverhalt auch ganz gut erklärt in Kapitel 6.3, 6.4, 6.5

Re: Action! wie geht das?

von Cash » Mo 1. Nov 2010, 10:01
Danke für die Tipps! So langsam geht es bei mir voran.
Aber etwas hab ich noch, wenn ich ein hauptprogramm habe und ein Unterprogramm das "über" dem hauptprogramm liegt gelingt mir der sprung zwar von unten nach oben aber nicht von oben nach unten. Im Unterprogramm ist das Ende des Programms und es soll wieder neu gestartet werden indem ich ins hauptprogramm springe. Aber das klappt wie gesagt nicht. :coffee

Re: Action! wie geht das?

von eda70 » Mo 1. Nov 2010, 10:07
Das könnte daran liegen, dass Action! ein single-pass-compiler ist.
D.h. erst muss die Funktion im Programm liegen. Der Aufruf muss danach kommen.
Also einfach die Funktion nach oben kopieren.
Die "main" proc sollte/muss immer die letzte im Code sein.
Code: Alles auswählen
proc vor()
return

Proc main()
    vor()  ; geht
    nach() ; geht nicht, da der Compiler diese Proc noch nicht "kennt"
return

proc nach()
return

Re: Action! wie geht das?

von FlorianD » Mo 1. Nov 2010, 10:23
Cash hat geschrieben:Danke für die Tipps! So langsam geht es bei mir voran.
Aber etwas hab ich noch, wenn ich ein hauptprogramm habe und ein Unterprogramm das "über" dem hauptprogramm liegt gelingt mir der sprung zwar von unten nach oben aber nicht von oben nach unten. Im Unterprogramm ist das Ende des Programms und es soll wieder neu gestartet werden indem ich ins hauptprogramm springe. Aber das klappt wie gesagt nicht. :coffee


Hi,

das ist dann nicht gut programmiert. Probiers mal so:
Code: Alles auswählen
MODULE
  ;globale Variablen
  BYTE VERSUCHE

PROC INIT()
  ;hier werden alle Vars auf Anfangswerte gesetzt
  VERSUCHE=0
RETURN

PROC MACHSPIEL()
  ;spielt oder macht was auch immer
  BYTE EINGABE
  BYTE GEHEIMEZAHL
  ;
  GEHEIMEZAHL=RAND(100)
  DO
    INPUTBE(EINGABE)
    VERSUCHE==+1
    IF EINGABE<GEHEIMEZAHL THEN
       PRINTE("zu klein")
    ELSE IF EINGABE>GEHEIMEZAHL THEN
       PRINTE("zu gross")
    ELSE
       PRINTE("richtig!!!!")
    FI
   UNTIL EINGABE=GEHEIMEZAHL
  OD
RETURN

PROC SCHLUSS()
  ;endbildschirm
  PRINT("Du hast ")
  PRINTB(VERSUCHE)
  PRINTE("Versuche gebraucht.")
RETURN

PROC MAIN() ;Hauptroutine
BYTE CONSOL=53279 ; Funktionstasten
;
DO  ; DO Schleife wiederholt Initialisieren-spielen-Ergebnisanzeigen solange bis SELECT im Schlußbildschirm gedrückt wird
  INIT()
  MACHSPIEL()
  SCHLUSS()
  PRINTE("Nochmal? START Ende=SELECT")
  DO
   UNTIL CONSOL<>7 ;warten bis eine CONSOL Taste gedrückt wird
  OD
  UNTIL CONSOL=5 ; Abfrage ob "SELECT" gedrückt
OD
RETURN

Re: Action! wie geht das?

von Cash » So 9. Jan 2011, 12:57
Hi leute,
ich bleibe mal in meinem alten Thread weil ich mal wieder auf dem Schlauch stehe.

Ich habe folgende Schleife gebastelt:

Proc Sound()

Byte S

For S=1 to 250 step 10 do
Sound (0,S,12,10)od

Return

Leider bekomme ich einen Fehler "7",(nicht zulässige Argumentenlist. Zu viele Argumente) was hab ich falsch gemacht?

Re: Action! wie geht das?

von FlorianD » So 9. Jan 2011, 16:55
...da muss man erstmal drauf kommen...war nicht leicht den Fehler zu finden...

Ich habe es getestet, die PROC allerdings MAIN() genannt. Ging einwandfrei. Hatte erst vermutet, dass es STEP nicht gibt, wars aber nicht. Der Soundeffekt klingt im übrigen SEHR spacig!!!

Dein Fehler war, dass Du die PROC "SOUND" genannt hast. Da kommt der Compiler natürlich durcheinander. Erst gibts Du SOUND() ohne Parameter an, das frisst er auch (er nimmt an, Du wolltest jetzt die eingebaute Procedure Sound umdefinieren, macht er auch und zwar in PROC SOUND() ohne Parameter). Paar Zeilen weiter rufst Du nun Sound mit 4 Parametern auf (0,S,12,10). Und nun ist er verwirrt und meckert über die Anzahl der Parameter (zu recht) ;-)

mach mal so:
Code: Alles auswählen
PROC MAIN()
  BYTE S
  FOR S=0 to 255 DO ;erstmal ohne STEP
    SOUND(0,S,10,10) ;10,10 für reine Töne bei 12,10 klingt es schräg
  OD
RETURN


ohne Step sehr spacig, mit step 5 ähnlich Boulder Dash

Re: Action! wie geht das?

von Cash » So 9. Jan 2011, 19:54
Danke Florian! Jetzt geht's :beer:

Dann hab ich gleich die nächsten Fragen.

1) Ich möchte gern eine Sinusfunktion haben, gibt es das schon in Action? Wenn nein wie soll ich die am sinnvolsten programmieren (bin eine Null in Mathe), also bitte nicht auslachen. :oops:

2) Kann man bei der Step funktion (in der for do Schleife) auch irgendwie z.b. ".833333" eingeben oder gehen nur ganze Zahlen?

Re: Action! wie geht das?

von FlorianD » So 9. Jan 2011, 23:42
Sinus (und Cosinus) sind Funktionen, die Werte von -1 bis 1 liefern. "Zahlen mit Nachkommastellen" werden Fließkommazahlen genannt. Action! kann von Haus aus nur ganze Zahlen.
Man kann das z.B. umgehen, in dem man sich eine Tabelle mit möglichen Werten anlegt, also z.B. die Sinuswerte von 0° bis 90° (die anderen 3 Viertel sind die gleichen Werte, nur gespiegelt bzw negativ) jeweils multipliziert mit 100 in 5° Schritten. Dann hat man abgerundete ganze Zahlen, mit denen man für Grafik o.ä. operieren kann. Spätestens bei PLOTten von Pixeln muss man ja eh auf ganze Zahlen runden.
Kreise kann man auch ohne Sinus malen, wenn man Quadrieren und Wurzeln ziehen kann

STEP kann auch nur ganze Zahlen, weil Action! nur ganze Zahlen kann.

Vielleicht gibts ja irgendwo ein FP-Pack (Floating Point Pack) zum INCLUDEn. Guck doch mal im ATARI-Wiki http://wiki.strotmann.de/wiki/Wiki.jsp?page=ACTION

Re: Action! wie geht das?

von cas » Mo 10. Jan 2011, 11:34
Hi Cash,

generell sollte man bei Grafikprogrammierung auf 8-bit Rechnern (oder generell bei Rechnern ohne extra Fliesskomma-Unterstützung in Hardware) auf Fliesskommazahlen verzichten und mit ganzen Zahlen arbeiten.

Um das zu machen "skaliert" man die Zahlen hoch.

Wenn man z.B. rechnen will:

Code: Alles auswählen
 10.456
+ 5.123


dann macht man daraus eine Ganzzahl und "verschiebt" das Komma erst nachdem man den entgültigen Wert errechnet hat:

Code: Alles auswählen
 10456
+ 5123
= 15597
/1000
=16 (gerundet)


Hier sind ein paar Weiterführende Quellen zum Thema

Aus dem 6502 Forum:
http://forum.6502.org/viewtopic.php?t=716

Buch "Starting Forth" zum Thema Fixed Math und Scaling
http://home.iae.nl/users/mhx/sf5/sf5.html

Wikipedia
http://de.wikipedia.org/wiki/Festkommazahl
1, 2