atarionline.pl Snake w ATALAN - Forum Atarum

Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

  • :
  • :

Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

    • 1: CommentAuthorJKR
    • CommentTime7 Aug 2010
     
    Witam wszystkich atarowiczów

    Jeśli ktoś ma ochotę pograć sobie w nowego snake'a to proszę bardzo.

    Program napisany w ATALAN'ie.
    Wiem, że pomysł mało oryginalny ale zawsze chciałem napisać sobie własnego snake'a.

    Kto pierwszy dojdzie do 9ego poziomu ?
    • 2: CommentAuthorJKR
    • CommentTime7 Aug 2010
     
    Tutaj sa źródła:
    • 3:
       
      CommentAuthorlarek
    • CommentTime7 Aug 2010
     
    Dodaj dźwięki i będzie fajna gierka.

    PS. Doszedłem tylko do 4-go ;)
    • 4:
       
      CommentAuthorWolfen
    • CommentTime7 Aug 2010 zmieniony
     
    Powiem tak :) mimo braku dzwieku (przydalby sie jak Larek slusznie zauwazyl :) gra coz... moze inaczje - opisze moja przygode z gierka ;>

    1. Odpalilem gierke - no... snake... eh... nudne...
    2. 5 minut pozniej no... w sumie poprawnie sie gra... bez fajerwerkow...
    3. 10 minut pozniej no... jeszcez kilka zer i koncze... ale gra sie fajnie no ale to prosta gra - nic ciekawego
    4. 15 minut pozniej ...no... jeszcze chwile pogram... ale gra no... nic specjalnego...
    5. 20 minut pozniej ...jeszcze tylko pare zerek zjem...
    6. 25 minut pozniej ...nie no ... taka sobie ta gierka i dzwieku nie ma... jeszcze tylko pare zer zjem i koniec...
    7. 30 minut pozniej... hmmm... jakby ta gra byla taka zla to bym 30 minut nie gral ot tak :P wiec postanowilem o tym napisac :D

    I z pewnoscia do gierki wroce :) jest... prosta... ale przez to zaje...sta! :D Czlowiem nie zauwaza nawet kiedy z tego "a jeszcze kilka zer" ;P robi sie nagle pol godziny ;)

    Good work! :) Swietna adaptacja Snake'a :) grywalnosc jak w Nokii :) (a to niemaly komplement! :)
    • 5: CommentAuthorw1k
    • CommentTime8 Aug 2010
     
    atalan is too hard to understand.. :/
    • 6:
       
      CommentAuthorCosi
    • CommentTime8 Aug 2010
     
    Brawo! Teraz czekamy na wbudowaną w ATALAN obsługę duszków :-)
    Btw. Rudla, how about adding module support (I mean importing modules, as in Python) to ATALAN?
    • 7:
       
      CommentAuthorjhusak
    • CommentTime8 Aug 2010
     
    I am impressed. New language quiet well working. Two playable classic games. The sources written in atalan are very clear and easy to manage.

    The only disadvantage (but not really, there is the Python language) is when you do not have the editor which helps you to make indentations easy way. Vim rules!

    Rudla, maybe you should think about syntax coloring for vim?
    please...
    • 8: CommentAuthorJKR
    • CommentTime8 Aug 2010
     
    Dzięki za komplementy.

    Dźwięki będą w wersji 0.2. (Muszę sobie przypomnieć jak się je generuje - to mój pierwszy program na Atari od 15 lat z górką. Coś mi się zdaje, że były tam jakieś 4 kanały, tak ? :-))

    Podpowiedź dla tych co nie czytali kodu źródłowego: Podczas gry, jak sie naciśnie fire, waż robi sie bardziej żwawy. Tego nawet w Nokii nie było :-)

    @w1k:
    Atalan is under development and still has some bugs and not yet implemented features.

    For instance I couldn't write:

    if ... and ... then ...

    I had to write:

    if ...
    if ... then
    ...

    Also nested 'if-else' statements didn't work yet and I had to do some workarounds.
    Let's keep fingers crossed for the author to continue the development.
    • 9:
       
      CommentAuthorKaz
    • CommentTime8 Aug 2010
     
    Gratulacje! Pierwszy po latach program i od razu w egzotycznym jezyku :).

    Jezeli bedziesz dodawal dzwiek to moze tez i postulowana przez kolegow muzyke? Muzykow kilku na scenie jest, mozna zrobic przetarg :)
    • 10: CommentAuthornosty
    • CommentTime8 Aug 2010
     
    Bardzo przyjemny gameplay (o ile to w snake mozliwe ;) i wyglad...

    Czy mi sie zdaje, czy "zera" do zjadania" jakos czesciej pojawiaja sie przy scianach i w katach, niz by to wynikalo z rachunku prawdopodobienstwa? :)
    • 11: CommentAuthorJKR
    • CommentTime8 Aug 2010
     
    @nosty
    Też mam takie wrażenie. Zastanowię się nad modyfikacją procedury losującej.
    Z drugiej strony, chociaż niezamierzony, to jednak ten efekt nie jest tak do końca niewłaściwy. Nieco utrudnia grę.
    • 12:
       
      CommentAuthorKaz
    • CommentTime9 Aug 2010 zmieniony
     
    Poniewaz zrodelka weza sa publicznie dostepne i niezle opisane, to pozwalam sobie nizej je przedstawic w formie bezposrednio czytelnej, przydadza sie do przekonywania niedowiarkow :D

    ; 'Atalan the Snake'
    ;---------------------------------------------------------------------
    ; Snake game implemented in ATALAN Programming language
    ; by Jakub Krzak
    ; Katowice, August 2010
    ;---------------------------------------------------------------------
    ; Compiled with Atalan compiler, ver. 05-08-2010


    ; SCREEN --------------------------------------------------------

    ;GR.0, 40 x 25 characters 
    ;We force it to address $8000 to make it aligned correctly.
    _scr@$8000:array(0..39, 0..24) of byte

    ;Display list 
    const dl:array = 2 times $70, $42, _scr, $10, 23 times $02, $10, $02, $41, dl

    ; CONSTANTS ------------------------------------------------------

    ;Font file
    const fontFileName:font = file "snake.fnt"

    ; Starting position of the snake on the screen 
    const 
        HSx = 22
        HSy = 10
        SLength = 7

    ;Characters 
    const 
        SNAKE_HEAD_l     = 72
        SNAKE_HEAD_r     = 69
        SNAKE_HEAD_u     = 70
        SNAKE_HEAD_d     = 71
        SNAKE_BODY_nw     = 75
        SNAKE_BODY_ws     = 77
        SNAKE_BODY_se    = 78
        SNAKE_BODY_en     = 76
        SNAKE_BODY_v     = 79
        SNAKE_BODY_h     = 80
        SNAKE_TAIL_l     = 66
        SNAKE_TAIL_r     = 68
        SNAKE_TAIL_u     = 65
        SNAKE_TAIL_d     = 67
        
        FRUIT            = 16
        
        WALL_CHR         = 73
        RWALL_CHR         = 74

    type bool:0..1

    ; some hardware registers
    out COL'BK@$d01a:byte
    out COL'PF1@$d017:byte
    out COL'PF2@$d018:byte
    in RTCLOCK@20:byte

    ; GLOBAL VARIABLES ------------------------------------------------

    ; Position of the snake on the screen 
    Hx:0..39
    Hy:0..24
    Tx:0..39
    Ty:0..24

    ;Snake's head direction 
    HDir:stick'state

    Score:0..10000
    Level:1..9
    LevDelay:0..10

    ; PROCEDURES ---------------------------------------

    initialize:proc =
        Score = 0
        Level = 1
        LevDelay = 10


    writeCredits:proc =
        _scr(3,7)   = "+--------------------------------+"
        _scr(3,8)   = "!                                !"
        _scr(3,9)   = "!       PROGRAMMED BY JKR        !"
        _scr(3,10)  = "!                                !"
        _scr(3,11)  = "! IN ATALAN PROGRAMMING LANGUAGE !"
        _scr(3,12)  = "!                                !"
        _scr(3,13)  = "!     KATOWICE, AUGUST 2010      !"
        _scr(3,14)  = "!                                !"
        _scr(3,15)  = "+--------------------------------+"

        
    erasePlayfield:proc =
        for yy:2..22 for xx:1..38 _scr(xx, yy) = 0

        
    drawSnakeBegin:proc(x y len) =
        Hx = x
        Hy = y
        Tx = x - len
        Ty = y

        xx = Tx
        until xx > Hx
            _scr(xx, Hy) = SNAKE_BODY_h
            inc xx

        _scr(Hx, Hy) = SNAKE_HEAD_r
        _scr(Tx, Ty) = SNAKE_TAIL_r

        HDir = right

        
    getNextHeadCoord:proc(>x:byte >y:byte) = 
        ; get next head's coordinates depending on its direction
        if HDir = right
            x = Hx + 1
            y = Hy
        else if HDir = up
            x = Hx 
            y = Hy - 1
        else if HDir = left
            x = Hx - 1
            y = Hy
        else
            x = Hx
            y = Hy + 1

            
    getNextTailCoord:proc(ss:byte >x:byte >y:byte) = 
        ; get next tail's coordinates depending on its direction
        if ss = SNAKE_TAIL_r
            x = Tx + 1
            y = Ty
        else if ss = SNAKE_TAIL_l
            x = Tx - 1
            y = Ty
        else if ss = SNAKE_TAIL_u
            x = Tx
            y = Ty - 1
        else if ss = SNAKE_TAIL_d
            x = Tx
            y = Ty + 1

            
    moveTail:proc =
        ts = _scr(Tx,Ty) ; current 'tail' character
        xx,yy = getNextTailCoord ts
        ns = _scr(xx,yy) ; snake's character next to the 'tail'
        
        _scr(Tx,Ty) = 0 ; erase the tail

        ; put a new 'tail' character (rotated, if needed)
        if ns = SNAKE_BODY_nw 
            if ts = SNAKE_TAIL_r then _scr(xx,yy) = SNAKE_TAIL_u else _scr(xx,yy) = SNAKE_TAIL_l
                
        else if ns = SNAKE_BODY_ws 
            if ts = SNAKE_TAIL_r _scr(xx,yy) = SNAKE_TAIL_d else _scr(xx,yy) = SNAKE_TAIL_l
                
        else if ns = SNAKE_BODY_se
            if ts = SNAKE_TAIL_u _scr(xx,yy) = SNAKE_TAIL_r else _scr(xx,yy) = SNAKE_TAIL_d
                
        else if ns = SNAKE_BODY_en
            if ts = SNAKE_TAIL_l _scr(xx,yy) = SNAKE_TAIL_u else _scr(xx,yy) = SNAKE_TAIL_r

        else
            _scr(xx,yy) = ts
            
        Tx = xx
        Ty = yy

            
    putNeck:proc(dir1:stick'state neck1 dir2:stick'state neck2 body) =
        ; put the 'neck1', 'neck2' or 'body' characters
        ; in the current head's position
        ; depending on the 'dir1' and 'dir2' arguments
        if HDir = dir1
            _scr(Hx,Hy) = neck1  
        else if HDir = dir2
            _scr(Hx,Hy) = neck2
        else 
            _scr(Hx,Hy) = body

            
    increaseLevel:proc =
        inc(Level)
        dec(LevDelay)

    eatFruit:proc =
        
        l:Level = 0                ; this was 'Score = Score + 10 * Level'
        while l < Level            ; but it didn't compile for some reason
            Score = Score + 10
            inc l
            
        if Score = 150 increaseLevel ; 15 * 10
        if Score = 450 increaseLevel ; + 15 * 20
        if Score = 900 increaseLevel ; + 15 * 30 
        if Score = 1500 increaseLevel ; + 15 * 40
        if Score = 2500 increaseLevel ; + 20 * 50
        if Score = 3700 increaseLevel ; + 20 * 60
        if Score = 5800 increaseLevel ; + 30 * 70
        if Score = 9000 increaseLevel ; + 40 * 80
            
        l = Level
        s:Score = Score      ; for some reason '"... SCORE: [Score]"' doesn't work
        _scr(0,24) = " LEVEL: [l]                   SCORE: [s]" 

        
    generateFruit:proc =
        ; generate random coordinates inside the playing area: 1..38, 2..22
        x = (RANDOM and 63) + 1
        y = (RANDOM and 31) + 2
        while x > 38 x = x - 38
        while y > 22 y = y - 22
        ; if this position is occupied, find a free one by increasing (and wrapping) x, then y
        while _scr(x,y) <> 0
            if x <> 38
                inc x
            else
                x = 1
                if y = 22 then 
                    y = 2
                else 
                    inc y
        ; put the fruit on the screen                
        _scr(x,y) = FRUIT

        
    moveHead:proc(>gotFruit:0..1) = 
        gotFruit = 0
        
        hs = _scr(Hx,Hy) ; current 'head' character
        xx,yy = getNextHeadCoord
        ns = _scr(xx,yy) ; character in front of the 'head'

        ; find a new 'head' character
        if HDir = right     
            nh = SNAKE_HEAD_r
        else if HDir = up
            nh = SNAKE_HEAD_u
        else if HDir = left
            nh = SNAKE_HEAD_l
        else
            nh = SNAKE_HEAD_d
            
        ; turn the head
        _scr(Hx,Hy) = nh
        
        ; check what is ahead and if the move is possible
        if ns = FRUIT
            gotFruit = 1 
        else if ns <> 0 
            goto game'over
        
        ; find and put the character next to the head
        if hs = SNAKE_HEAD_r 
            putNeck(up SNAKE_BODY_nw down SNAKE_BODY_ws SNAKE_BODY_h)
                
        if hs = SNAKE_HEAD_u 
            putNeck(left SNAKE_BODY_ws right SNAKE_BODY_se SNAKE_BODY_v)
            
        if hs = SNAKE_HEAD_l 
            putNeck(up SNAKE_BODY_en down SNAKE_BODY_se SNAKE_BODY_h)
            
        if hs = SNAKE_HEAD_d 
            putNeck(left SNAKE_BODY_nw right SNAKE_BODY_en SNAKE_BODY_v)

        ; put the head character in the new position
        _scr(xx,yy) = nh
        Hx = xx
        Hy = yy


    ; Random animation -------------------------

    drawSnakeAtRandomPosition:proc =
        rl = (RANDOM and 15) + 6
        while rl > 15 
            rl = rl - 9
        ry = (RANDOM and 15) + 2
        while ry > 13 
            ry = ry - 11
        if ry > 6 then ry = ry + 9
        rx = (RANDOM and 63) + (1 + rl)
        while rx > 38 
            rx = rx - 38 + (1 + rl)
            
        drawSnakeBegin(rx ry rl)

        
    changeDirection:proc =
        if _scr(Hx+1,Hy) <> 0
            if _scr(Hx-1,Hy) <> 0
                if _scr(Hx,Hy+1) <> 0
                    if _scr(Hx,Hy-1) <> 0
                        
                        ; no more move
                        timer = 0
                        while timer < 100
                            COL'BK = VCOUNT * 2 + RTCLOCK    ; do the Atari rainbow
                            if STRIG(0) = pressed  goto ex1

                        erasePlayfield
                        writeCredits
                        drawSnakeAtRandomPosition
                        goto ex1

        r = RANDOM 
        if r >= 128 goto turn'right
        
        turn'left@
        if HDir = right    
            HDir = up
        else if HDir = up
            HDir = left
        else if HDir = left
            HDir = down
        else
            HDir = right
        
        xx,yy = getNextHeadCoord
        if _scr(xx,yy) <> 0 
            goto turn'left
        moveHead
        goto ex1
        
        
        turn'right@
        if HDir = right    
            HDir = down
        else if HDir = up
            HDir = right
        else if HDir = left
            HDir = up
        else
            HDir = left

        xx,yy = getNextHeadCoord
        if _scr(xx,yy) <> 0 
            goto turn'right
        moveHead
        
        ex1@ ; exit

        
    animateSnake:proc =
        if timer >= 12

            moveTail

            xx,yy = getNextHeadCoord
            if _scr(xx,yy) <> 0
                changeDirection
                goto ex2

            r = (RANDOM and 15) 
            if r < 3 
                changeDirection
                goto ex2
                
            moveHead
            
            ex2@

            timer = 0

    ; -------------------------------------
            
    drawArea:proc =
        _scr(0,0)  = "       .-+  ATALAN THE SNAKE  +-.   V0.1"

        for xx:0..39
            _scr(xx, 1) = WALL_CHR
            _scr(xx, 23) = WALL_CHR
            
        for yy:2..22    
            _scr(0, yy) = WALL_CHR
            _scr(39, yy) = RWALL_CHR
            for xx:1..38
                _scr(xx, yy) = 0
        
        _scr(39, 1) = RWALL_CHR
        _scr(39, 23) = RWALL_CHR
        
        writeCredits
        
        _scr(0,24) = "     -+  PRESS TRIGGER TO START  +-     "

        timer = 0
        drawSnakeAtRandomPosition
        
        ; now, wait for trigger and animate the snake
        until STRIG(0) = pressed
            animateSnake

        erasePlayfield

        _scr(0,24) = " LEVEL: 1                   SCORE: 0    "

        ;  wait for the trigger to be released
        until STRIG(0) = not'pressed

        
    ; START -------------------------------------------

    ;Initialize graphics.
    sdlstl = dl
    COLOR0(2) = 0
    COLOR0(5) = 0
    set'font fontFileName

    start'game@

        initialize

        drawArea ; draws the playfield and waits for the trigger to start

        drawSnakeBegin(HSx HSy SLength)
        generateFruit ; put the first fruit

        grow:bool = 0
        delayCounter:0..20
        
    loop@    ; Main loop

        if STRIG(0) = pressed
            delayCntr = 2 ; if we push the trigger, the snake goes faster
        else
            delayCntr = LevDelay

        nDir = HDir
            
        while delayCntr > 0    ; delay loop

            ; wait for tick and check the stick in the meantime
            timer = 0
            while timer < 1
            
                ss:stick'state = STICK(0)
                if HDir = right then ss = ss or 8
                else if HDir = up then ss = ss or 1
                else if HDir = left then ss = ss or 4
                else if HDir = down then ss = ss or 2
                    
                if ss = right
                    if HDir = up then nDir = ss
                    if HDir = down then nDir = ss
                else if ss = left
                    if HDir = up then nDir = ss
                    if HDir = down then nDir = ss
                else if ss = up
                    if HDir = left then nDir = ss
                    if HDir = right then nDir = ss
                else if ss = down
                    if HDir = left then nDir = ss
                    if HDir = right then nDir = ss
            
            dec delayCntr
            
        HDir = nDir ; new direction

    ; move snake forward

        if grow = 0 
            moveTail ; only if the snake hasn't eaten a fruit before
        else 
            grow = 0
        
        if moveHead = 1
            eatFruit
            generateFruit
            grow = 1

    goto loop

    ;The game is over.
    ;Display message and wait for the player to press the button to play again.

    game'over@

    _scr(11,24) = "-+ GAME OVER +-"

    until STRIG(0) = not'pressed

    until STRIG(0) = pressed   
        COL'BK = VCOUNT * 2 + RTCLOCK    ; do the Atari rainbow

    until STRIG(0) = not'pressed

    goto start'game
    • 13: CommentAuthornosty
    • CommentTime9 Aug 2010 zmieniony
     
    Juz doszedlem.
    Generator wyznaczajacy pozycje nowego owocu jest zly.

    (sorki za takie wstawienie ale nie umiem cytowac :/ )

    generateFruit:proc =
    ; generate random coordinates inside the playing area: 1..38, 2..22
    x = (RANDOM and 63) + 1
    y = (RANDOM and 31) + 2
    while x > 38 x = x - 38
    while y > 22 y = y - 22
    ; if this position is occupied, find a free one by increasing (and wrapping) x, then y
    while _scr(x,y) <> 0
    if x <> 38
    inc x
    else
    x = 1
    if y = 22 then
    y = 2
    else
    inc y
    ; put the fruit on the screen
    _scr(x,y) = FRUIT


    Po losowaniu x jest od 1 do 64, a y od 2 do 33 ale potem jest robione obciecie przez odejmowanie.
    W wyniku tego x od 1 do 26 jest wybierany 2x czescien niz z zakresu 27 - 38.
    Co wiecej, w wyniku omijania zajetych pol szansa na X=1 jest jeszcze wieksza (bedzie tak zawsze kiedy wylosujemy X=38)

    Z Y jest podobnie ale jeszcze gorzej. Bo w wyniku dzialania "while y > 22 y = y - 22" moze pasc y =1 a wtedy zadziala omijanie zajetych pol i zostanie ustawione y=2. Jesli wylosujemy y = 22 to tez dostaniemy y=2.

    Czyli szansa wylosowania owocu przy gornej lub lewej bandzie jest _na poczatku gry_ okolo 3x wieksza niz przy dole planszy.

    To by bylo calkiem fajne, bo niechcacy troche utrudnia gre :)

    Ale z czasem, kiedy waz zajmuje coraz wiecej miejsca na planszy, coraz czesciej zaczyna dzialac omijanie zajetych pol. A ono nie losuje nowego pola, tylko przesuwa owoc zawsze w tym samym kierunku (w prawo i w dol) tuz obok weza. A to juz moze wkurzac.
    • 14:
       
      CommentAuthorKaz
    • CommentTime9 Aug 2010 zmieniony
     
    Nosty - dodalem znacznik [ code ] w Twoim poscie. Znaczniki byly opisane w tym watku: ->link<-
    • 15: CommentAuthorJKR
    • CommentTime9 Aug 2010
     
    Kaz, zrobiłeś mi miłą niespodziankę tym, że mój Snake trafił do nowinki na głównej stronie AtariOnline.

    Teraz to już muszę zrobić drugą ulepszoną wersję :-)
    (zwłaszcza, że trafiają się tu tacy goście jak Nosty, którzy od razu znajdą niedoskonałości)

    Co do samego języka:
    Myślę że przed autorem jeszcze długa droga. Nie działa jeszcze sporo rzeczy dość podstawowych.
    Nie jestem pewien czy warto, póki co, pisać coś większego w Atalanie (mój snake to właściwie tylko trochę rozbudowany programik zrobiony w oparciu o tetrisa z przykładów zamieszczonych przez Rudlę)
    Ale idea jest fajna i zachęcam wszystkich do prób w Atalanie żeby zdopingować autora do rozwoju kompilatora.
    • 16: CommentAuthorJKR
    • CommentTime9 Aug 2010
     
    Nosty, masz rację. Tam właśnie jest 'kruczek pogrzebany'.

    Chodziło mi o to, żeby wylosować dwie liczby z zakresów: 2..22 i 1..38 i jeśli wypadnie zajęte pole to nie powtarzać już losowania (to ma działać szybko nawet jak wąż jest już duży).

    Niestety funkcja (czy też makro) RANDOM zwraca po prostu bajt i nie bardzo mam pomysł jak w prosty sposób ograniczyć zakres tak, żeby rozkład prawdopodobieństwa był równomierny.

    Drugą część procedury można pewnie zmienić tak, żeby przesuwać się nie o 1 ale o jakiś losowo wybrany krok.

    Any ideas ?
    • 17:
       
      CommentAuthorKaz
    • CommentTime9 Aug 2010
     
    Moja idea opierala sie na tym, zeby napisac w tej sprawie do autora - wyslalem maila na jego adresy (ten forumowy i ten ze strony projektu). Moze cos zaradzi.
    • 18: CommentAuthorrudla
    • CommentTime9 Aug 2010
     
    You certainly did good job in giving me some more inspiration to improve the language.

    @cosi: module support is one of the planned features
    There will be keyword 'USE <filename> (that's going to be normal include file).
    Another will be 'platform:<platform>' at the beginning of the file. It will define, which platform is the application developed form and will include the right file for the platform (and check, that files from different platforms are not mixed together).
    'atari' is going to stay the default platform :-)
    but c64 is planned too.
    You may look into 'atari.atl' file to see, how the platform definition file looks.

    @jhusak: I'm not using Vim, but maybe you can try? I will send you list of keywords. However, if you do not like indent (or do not have appropriate editor :-), you may use blocks enclosed in ( ) - that should not require indentation.

    @JKR: The way may be long, but it will pass faster together:-) That's why I published Atalan in early stages and your achievement proves me right :-) Thank you one more.
    • 19: CommentAuthorrudla
    • CommentTime9 Aug 2010
     
    New version of ATALAN supports operator mod, which is basically the proper way of implementing integer range.

    2 + RANDOM mod 21

    However I believe the method used by you is correct too (it's modulo implemented by loop) and will be faster (as multiplication, division and modulo are slow operations on 6502).

    So problem is in finding the unoccupied one, which I think is more problem of an algorithm than the language.

    One method I can think of is managing array of unoccupied positions and choose randomly one of the positions in this array. As ordering of such array is not important, used position may be simply replaced by the last free position, new free position may be easily added to the end of the array. One dimensional array longer than 256 elements are supported by ATALAN :-)
    • 20: CommentAuthornosty
    • CommentTime9 Aug 2010 zmieniony
     
    @Kaz - szukalem, szukalem, bo liczylem ze opis znacznikow bedzie gdzies pod ręką , w jakiejs "pomocy" :P

    @JKR - uwzgledniajac ze RANDOM losuje z zakresu 0..255, cala procedure wyznaczajaca pozycje owocu POWINNO sie dac zapisac tak:

    x = RANDOM
    y = RANDOM
    while (x < 1) or (x > 38) or (y < 2) or (y > 22) or ( _scr(x,y) <> 0 )
    x = RANDOM
    y = RANDOM

    _scr(x,y) = FRUIT


    Niewydajne, ale pewnie wystarczy ;)

    Tyle ze to chyba nie zadziala :/

    Zrobilem experyment. To dziala:

    ;generate random x from 1 to 38
    ;WORKS

    x = RANDOM

    while x > 37 x = RANDOM
    x = x +1

    "x = [x]"


    Ale takie cos, kompiluje sie, ale juz NIE dziala :(

    ;should generate random x = 1 to 38
    ;but DONT WORK cause generate x = 0 to 255
    ;I dont know why

    x = RANDOM

    while (x < 1 ) or ( x > 38 ) x = RANDOM

    "x = [x]"


    Nie mam pojecia dlaczego, ale z eksperymentow mi wyszlo ze generuje x od 0 do 255.
    • 21: CommentAuthornosty
    • CommentTime9 Aug 2010 zmieniony
     
    A tak swoja droga: za nic nie moge wyczaic skad kompilator wie gdzie jest koniec bloku wykonywanego przy komendach while czy until??
    W opisie jezyka nie znalazlem. Z przykladow sie nie domyslilem. Raz jest to jedna komenda, innym razem kilka Zadnego znacznika konca nie ma...

    Moglby mnie ktos oswiecic?
    • 22: CommentAuthorrudla
    • CommentTime9 Aug 2010
     
    @nosty: there are three kinds of blocks:
    I will use optional 'then' after if.
    In all variants, "Hello" is not part of a block.

    1. one line (new line ends the block)
    if x = 10 then a=1 b=2
    "Hello"

    2. parentheses
    if x = 10 then ( a=1 b=2 ) "Hello"

    or
    if x = 10 then ( 
    a=1
    b=2
    )
    "Hello"


    3. indent

    if x = 10 then
    a=1
    b=2
    "Hello"


    In this case, any line, that is indented less than the first line of the block ends the block.
    • 23: CommentAuthornosty
    • CommentTime9 Aug 2010
     
    Thank you rudla.
    IMHO indent variant is risky. Cause people often uses code formatters.
    • 24: CommentAuthorrudla
    • CommentTime9 Aug 2010
     
    That is of course matter of taste (discussion on indent or not indent seems to take forever on Python mailing lists).

    However, I know from experience, that not taking indent into account leads to serious errors too.
    We, as people, suppose indent shows program structure, compiler should 'think' same way as we do.

    Following C snippet:

    if (x == 10)
    a = 1;
    b = 2;

    would misled anyone.

    if (x == 10) {
    a = 1;
    b = 2;
    }

    Is not readable at all.


    The only problem with indent (as I see it :-) is undefined size of tab character. Atalan fights this problem so, that you may use both tabs and spaces, but there must be first tabs and then spaces. Mixing tabs and spaces is forbidden.

    This somewhat minimizes the problem.

    However, if you do not like indent, feel free to use variant with parentheses. In this variant, indent is ignored.
    • 25: CommentAuthorScalak
    • CommentTime9 Aug 2010 zmieniony
     
    dla mnie losowanie do skutku nie jest najlepszym pomysłem bowiem im dłuższy wąż tym losowanie przebiega dłużej. Najlepiej losować z pól nie zajętych przez węża.

    Swoją drogą ciekaw jestem czy gra mocno zwolni (czy zwolni?) przy losowaniu do skutku gdy wąż zajmuje już prawie całe pole.
    • 26: CommentAuthornosty
    • CommentTime9 Aug 2010
     
    @rudla - do you have any idea why this code don't work properly?
    I expected x from 1 to 38, but I see x from 0 to 255. Why?

    x = RANDOM
    while (x < 1 ) or ( x > 38 ) x = RANDOM
    "x = [x]"
    • 27: CommentAuthorrudla
    • CommentTime9 Aug 2010
     
    Don't know. I will try to analyze it. Must be some error.
    • 28: CommentAuthornosty
    • CommentTime9 Aug 2010
     
    @Scalak - moje rozwiazanie bylo maksymalnie proste ale tez najbardziej nieoptymalne. Tak to zwykle jest :)
    To byl tylko przyklad.

    Jesli zapiszemy wszystkie warunki tak jak ja w jednej lini z OR, to prawdopodobienstwo udanego losowania wynosi:

    38/256 * 21/256 * ilosc_pol_zajetych/ilosc_wszystkich_pol

    Nie wiem jakie sa rekordy, ale jesli waz zajmuje 50% dostepnej powierzchni, to szansa na udane losowanie wynosi 0,006.

    Czyli musimy losowac srednio 164 razy zeby trafic. Biorac pod uwage, ze jak pisze autor, RANDOM, to po prostu odczyt z rejestru Atari, a warunki tez sie sprawdza banalnie, to chyba gracz nie zauwazy spowolnienia? Czyli bardzo nieeleganckie, ale pewnie skuteczne :)

    Ale skoro w ATALAN juz jest MOD, to sa to rozwazania akademickie :)
    • 29: CommentAuthornosty
    • CommentTime11 Aug 2010
     
    Sprobowalem skompilowac SNAKE i mam errora:

    error: no rule for translating instruction
    add _1001:-2147483648..2147483647, rl, 1
    jmp _lbl68
    snake.asm (1287) ERROR: Undeclared label _LBL68 (BANK=0)

    Dlaczemu?
    • 30: CommentAuthorJKR
    • CommentTime12 Aug 2010
     
    Nosty,
    Też mam ten błąd. Najnowsza wersja kompilatora nie akceptuje czegoś takiego:
    while rx > 38 
    rx = rx - 38 + (1 + rl)

    ale akceptuje już:
    while rx > 38 
    rx = rx - 37 + rl


    Jak już to wcześniej pisałem, przed Rudlą jeszcze długa droga. Trzeba dać chłopakowi czas i trzymać kciuki żeby nie stracił zapału.

    Dołączam na wszelki wypadek poprzednią wersję kompilatora na której kompilacja przechodzi.