Action! wie geht das?
1,
2Action! 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?
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?
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.
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...
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
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.
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...
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.
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.
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
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.
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=ACTIONRe: 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=716Buch "Starting Forth" zum Thema Fixed Math und Scaling
http://home.iae.nl/users/mhx/sf5/sf5.htmlWikipedia
http://de.wikipedia.org/wiki/Festkommazahl1,
2