•  Back 
  •  Ausfüllen der Prozeduren mit Leben 
  •  Index 
  •  Tree View 
  •  Cross references 
  •  ATOS Hilfe 
  •  Show info about hypertext 
  •  View a new file 
Topic       : Das ATOS-Magazin 3/99
Author      : Das ATOS-Team
Version     : 12.11.1999
Subject     : ATOS Diskettenmagazine
Nodes       : 214
Index Size  : 7926
HCP-Version : 5
Compiled on : Atari
@charset    : atarist
@lang       : 
@default    : 
@help       : ATOS Hilfe
@options    : -i -s -h+zz -t2
@width      : 70
View Ref-File      ATOS Programmierpraxis
         Moderne Zeiten
            Ausfüllen der Prozeduren mit Leben

Der Fußballspieler                               Das ATOS-Magazin 3/99

Konstruktor und Destruktor sind, wie oben schon auffiel, zweigeteilt. 
Der eine Teil (die Funktion @fussballspieler beim Konstruktor bzw. 
analog dazu die Prozedur @fussballspieler_free beim Destruktor) dient 
lediglich dem Anfordern und Freigeben des Objektspeichers. Dies wird 
dort mittels Aufruf der Bibliotheksfunktionen @ob_create bzw. 
@ob_free erledigt. Nach dem Anlegen und vor dem Freigeben von 
Objektspeichern müssen aber meist Initialisierungs- oder 
Aufräumaufgaben erledigt werden. Dies geschieht dann in den Prozeduren 
@fussballspieler_init bzw. @fussballspieler_exit, welche aus den 
beiden anderen Routinen heraus aufgerufen werden:

FUNCTION fussballspieler(name$,position&,staerke&)              !call
  '
  ' Diese Funktion legt ein Objekt des Typs fussballspieler an
  ' und gibt die Objektkennung zurück.
  '
  ' name$       => Name des Fußballspielers (bspw. "Lothar Matthäus")
  ' position&   => Position, auf der der Spieler besonders stark ist.
  '                     fussballspieler_position_tor_&
  '                     fussballspieler_position_abwehr_&
  '                     fussballspieler_position_mitte_&
  '                     fussballspieler_position_sturm_&
  ' staerke&    => Staerke des Spielers im Mittel.
  '                     (0 = sehr schlecht, 100 = sehr gut)
  '
  LOCAL ob#
  '
  ' *** Objektspeicher anfordern ***
  '
  LET ob#=@ob_create(fussballspieler_%)
  '
  ' *** Objektspeicher initialisieren ***
  '
  @fussballspieler_init(ob#,name$,position&,staerke&)
  '
  RETURN ob#
ENDFUNC
PROCEDURE fussballspieler_free(ob#)                             !call
  '
  ' Diese Prozedur entfernt ein Objekt des Typs fussballspieler aus
  ' dem Speicher.
  '
  '
  ' *** Objektintern "aufräumen" ***
  '
  @fussballspieler_exit(ob#)
  '
  ' *** Objektspeicher freigeben ***
  '
  @ob_free(ob#,fussballspieler_%)
  '
RETURN

Die beiden eben aufgeführten Routinen sehen bei allen Objekttypen 
gleich aus. Man muß lediglich stets die Typnamen und ggf. die 
Parameter anpassen.

Beim Initialisieren der Objektspeicher müssen zunächst alle konkreten 
Attributspeicher ihrerseits korrekt initialisiert werden. Dies 
geschieht durch Aufruf der zum jeweiligen Typ passenden init-Prozedur. 
An diese init-Prozedur muß nun dementsprechend auch die Objektkennung 
des konkreten Attributes übergeben werden. Diese Kennung wird über 
eine Bibliotheksfunktion, nämlich die Funktion @ob_attrib, unter 
Angabe der Typ- und der Attributkennung, ermittelt:

PROCEDURE fussballspieler_init(ob#,name$,position&,staerke&)    !call
  '
  ' *** konkrete Attribute initialisieren ***
  '
  @string_init(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_name_%))
  @word_init(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_tor_%))
  @word_init(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_abwehr_%))
  @word_init(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_mitte_%))
  @word_init(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_sturm_%))

Jetzt können die Attributspeicher benutzt und insbesondere mit 
vernünftigen Werten vorbelegt werden. Im vorliegenden Fall wird der 
Name des Fußballspielers gesetzt, und es werden die Spielerstärken je 
nach übergebener Position und Durchschnittsstärke unter Einfluß von 
etwas Zufall voreingestellt:


  '
  ' *** Spieler einrichten ***
  '
  ' +++ Name setzen +++
  '
  @fussballspieler_name_set(ob#,name$)
  '
  ' +++ Stärke in Tor, Abwehr, Mitte und Sturm festlegen +++
  '     (der Zufall spielt mit)
  '
  SELECT position&
  CASE fussballspieler_position_tor_&      ! Torwart => im Tor gut
    @fussballspieler_tor_set(ob#,RANDOM(20)+staerke&-10)
    @fussballspieler_abwehr_set(ob#,RANDOM(10))
    @fussballspieler_mitte_set(ob#,RANDOM(10))
    @fussballspieler_sturm_set(ob#,RANDOM(10))
  CASE fussballspieler_position_abwehr_&   ! Abwehr => hinten gut
    @fussballspieler_tor_set(ob#,RANDOM(10))
    @fussballspieler_abwehr_set(ob#,RANDOM(20)+staerke&-10)
    @fussballspieler_mitte_set(ob#,RANDOM(staerke& DIV 3))
    @fussballspieler_sturm_set(ob#,RANDOM(staerke& DIV 3))
  CASE fussballspieler_position_mitte_&    ! Mitte => mitte gut
    @fussballspieler_tor_set(ob#,RANDOM(10))
    @fussballspieler_abwehr_set(ob#,RANDOM(staerke& DIV 3))
    @fussballspieler_mitte_set(ob#,RANDOM(20)+staerke&-10)
    @fussballspieler_sturm_set(ob#,RANDOM(staerke& DIV 3))
  CASE fussballspieler_position_sturm_&    ! Stürmer => vorne gut
    @fussballspieler_tor_set(ob#,RANDOM(10))
    @fussballspieler_abwehr_set(ob#,RANDOM(staerke& DIV 3))
    @fussballspieler_mitte_set(ob#,RANDOM(staerke& DIV 3))
    @fussballspieler_sturm_set(ob#,RANDOM(20)+staerke&-10)
  ENDSELECT
  '
RETURN

In der init-Prozedur können auch -- wie oben erwähnt -- Dateien 
geöffnet werden oder Internetverbindungen aufgebaut werden, falls sich 
die tatsächlichen Informationspeicher (oder Teile davon) an entfernten 
Orten befinden. Diese Dateien und Verbindungen kann man in der exit- 
Prozedur wieder schließen bzw. abbauen.

Anschließend muß man (umgekehrt wie beim Initvorgang) jeden einzelnen 
konkreten Attributspeicher ebenfalls sauber "herunterfahren", denn es 
könnte ja sein, daß ein solcher noch Resourcen belegt und diese 
seinerseits erst freigeben muß.

PROCEDURE fussballspieler_exit(ob#)                             !call
  '
  ' *** konkrete Attribute freigeben ***
  '
  @string_exit(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_name_%))
  @word_exit(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_tor_%))
  @word_exit(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_abwehr_%))
  @word_exit(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_mitte_%))
  @word_exit(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_sturm_%))
  '
RETURN

Das Ausfüllen der Abfragefunktionen und der Operationen gestaltet sich 
recht monoton. Zu jedem Objekttyp stehen üblicherweise eine xxx_set- 
Prozedur sowie eine xxx_get-Funktion zur Verfügung, über die die Werte 
in die Objektspeicher eingeschrieben bzw. von dort wieder 
herausgelesen werden können:

FUNCTION fussballspieler_name$(ob#)                             !call
  '
  ' Ermittelt den Spielernamen.
  '
  RETURN @string_get$(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_name_%))
ENDFUNC
FUNCTION fussballspieler_tor(ob#)                               !call
  $F%
  '
  ' Ermittelt die Tor-Stärke des Spielers.
  '
  RETURN @word_get(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_tor_%))
ENDFUNC
FUNCTION fussballspieler_abwehr(ob#)                            !call
  $F%
  '
  ' Ermittelt die Abwehr-Stärke des Spielers.
  '
  RETURN @word_get(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_abwehr_%))
ENDFUNC
FUNCTION fussballspieler_mitte(ob#)                             !call
  $F%
  '
  ' Ermittelt die Stärke im Mittelfeld des Spielers.
  '
  RETURN @word_get(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_mitte_%))
ENDFUNC
FUNCTION fussballspieler_sturm(ob#)                             !call
  $F%
  '
  ' Ermittelt die Sturm-Stärke des Spielers.
  '
  RETURN @word_get(@ob_attrib(ob#,fussballspieler_%,
                                        fussballspieler_sturm_%))
ENDFUNC
PROCEDURE fussballspieler_name_set(ob#,name$)
  @string_set(@ob_attrib(ob#,fussballspieler_%,
                                   fussballspieler_name_%),name$)
RETURN
PROCEDURE fussballspieler_tor_set(ob#,staerke&)                 !call
  '
  ' Setzt die Tor-Stärke des Spielers. Die Werte werden auf den
  ' Breich 0..100 gestutzt.
  '
  LET staerke&=MAX(0,MIN(100,staerke&))
  @word_set(@ob_attrib(ob#,fussballspieler_%,
                                  fussballspieler_tor_%),staerke&)
RETURN
PROCEDURE fussballspieler_abwehr_set(ob#,staerke&)              !call
  '
  ' Setzt die Abwehr-Stärke des Spielers. Die Werte werden auf den
  ' Breich 0..100 gestutzt.
  '
  LET staerke&=MAX(0,MIN(100,staerke&))
  @word_set(@ob_attrib(ob#,fussballspieler_%,
                                 fussballspieler_abwehr_%),staerke&)
RETURN
PROCEDURE fussballspieler_mitte_set(ob#,staerke&)               !call
  '
  ' Setzt die Stärke im Mittelfeld des Spielers. Die Werte werden
  ' auf den Breich 0..100 gestutzt.
  '
  LET staerke&=MAX(0,MIN(100,staerke&))
  @word_set(@ob_attrib(ob#,fussballspieler_%,
                                 fussballspieler_mitte_%),staerke&)
RETURN
PROCEDURE fussballspieler_sturm_set(ob#,staerke&)               !call
  '
  ' Setzt die Sturm-Stärke des Spielers. Die Werte werden auf den
  ' Breich 0..100 gestutzt.
  '
  LET staerke&=MAX(0,MIN(100,staerke&))
  @word_set(@ob_attrib(ob#,fussballspieler_%,
                                 fussballspieler_sturm_%),staerke&)
RETURN

Daß dies hier so monoton aussieht, ist eine Folge der oben gemachten 
1:1-Kodierung. Bei Optimierungen oder bei der Verwendung externer 
Speicher gestaltet sich die Ermittlung und das Ändern der abstrakten 
Attribute dann entsprechend der gewählten Kodierung aufwendiger.





Der Verein