Kirjautuminen

Haku

Tehtävät

Opasarkisto: TI-89-peliohjelmointi: Osa 3 - Esimerkkipelejä

  1. Osa 1 - Basicin perusteet
  2. Osa 2 - Näppäimistö ja grafiikka
  3. Osa 3 - Esimerkkipelejä

Kirjoittaja: Antti Laaksonen (2003).

Tämä opassarjan viimeinen osa sisältää kaksi esimerkkipeliä, TI-JATSI ja TI-MATO, selitysten kera. Jos kirjoitat pelit laskimella, ota mukaan kaikki tasalevyisellä fontilla kirjoitetut rivit. Pelit ovat kuitenkin melko pitkiä, minkä vuoksi linkkikaapeli säästää reilusti aikaa ja paristoja; molemmat pelit TI-GRAPH LINK -yhteensopivassa muodossa löytyvät paketista ti89_pelit.zip (2,7 kt).

Huom: pelien latautuminen ensimmäisellä käynnistyskerralla kestää n. 5 sekuntia, myöhemmin ei viivettä juuri ole.

TI-JATSI

Ensimmäinen esimerkkipeli on kahden pelaajan noppapeli jatsi, tämän version nimi on TI-JATSI. Tarkoituksena on saada noppia heittämällä erilaisia yhdistelmiä, joita kerätään taulukkoon. Viidentoista kierroksen jälkeen se, jonka yhteenlaskettu pistemäärä on suurempi, on voittaja. Laskimen näytön pienen koon vuoksi pelin käyttöliittymä täytyi suunnitella huolellisesti. Pelin koko on 4176 tavua.

TI-JATSI

Pelin alussa määritellään joukko paikallisia muuttujia. tul on pelaajien heittotulokset sisältävä lista, nim-listassa on heittotulosten nimet, ak on kuvaajan akselien tila ja gr on kuvaajan ristikon tila. Seuraavan rivin muuttujat ovat noppien kuvia. Tämän jälkeen tulevat muuttujat heitetyille nopille, valituille nopille, tulossivulle (1 tai 2), painetulle näppäimelle ja heitosta tulleille pisteille. Viimeisen rivin muuttujia käytetään For-silmukoissa ja muissa väliaikaisissa tarkoituksissa.

jatsi()
Prgm
 Local tul,nim,ak,gr
 Local n1,n2,n3,n4,n5,n6,ty
 Local n,v,s,np,pi
 Local i,j,k,l,m

Seuraavaksi on vuorossa pelin ainoa aliohjelma, lis, joka näyttää valitun sivun heittotulokset. Sivulla 1 on saman nopan yhdistelmät, sivulla 2 loput. Jos tulos on char(4), se on heittämätön, jolloin listassa näkyy viiva. (Miksi juuri char(4)? Tämän merkin symboli sattuu olemaan ET, jonka voi selittää tarkoittavan "ei tulosta".) Tuloslistan rivien pituus on aina 13 merkkiä.

 Local lis
 Define lis(i,nim,tul)=Prgm
  Local j,k,t1,t2
  If i=1 Then
   For i,1,8
    For j,1,2
    "t"&string(j)→k
     If tul[i,j]=char(4) Then
      "  -"→#k
     Else
      right("  "&string(tul[i,j]),3)→#k
     EndIf
    EndFor
    PxlText string(i)&" "&left(nim[i]&"     ",9)&t1&t2,i*8-7,0
   EndFor
   PxlText "                 ",65,0
  Else
   For i,1,9
    For j,1,2
    "t"&string(j)→k
     If tul[i+8,j]=char(4) Then
      "  -"→#k
     Else
      right("  "&string(tul[i+8,j]),3)→#k
     EndIf
    EndFor
    PxlText string(i)&" "&left(nim[i+8]&"     ",9)&t1&t2,i*8-7,0
   EndFor
  EndIf
 EndPrgm

Tämän jälkeen tulee pelin aloitusikkuna, josta selviävät pelissä käytettävät näppäinkomennot. Jos käyttäjä painaa CANCEL-nappia, ok-erikoismuuttujan arvoksi tulee 0. Tällöin poistutaan pelistä välittömästi.

 Dialog
  Title "TI-JATSI"
  Text "Tervetuloa peliin!"
  Text ""
  Text "ENTER: Noppien heitto"
  Text "F1-F5: Nopan lukitus"
  Text "MODE: Tulossivun vaihto"
  Text "1-9: Tuloksen valinta"
  Text "ESC: Pelin keskeytys"
 EndDlog
 If ok=0
  Stop

Seuraavaksi määritellään pelin taulukot. nim-taulukko sisältää kaikkien heittotulosten nimet, ja tul-taulukosta löytyvät kummankin pelaajan heittotulokset. Kaikkien muiden tulosten arvo on aluksi char(4) (ei tulosta), paitsi 7:nnen ja 18:nnen, jotka sisältävät tulosten summan. s-muuttujan arvoksi laitetaan vielä 1, eli oletustulossivu on 1.
 {"Ykköset","Kakkoset","Kolmoset","Neloset","Viitoset","Kuutoset","Yhteensä","Bonus","Pari", "Kahdet parit","3 samaa","4 samaa","Suora 1-5","Suora2-6","Täyskäsi","Sattuma","Jatsi", "Yhteensä"}→nim

 newMat(18,2)→tul
 For i,1,17
  If i=7
   Cycle
  For j,1,2
   char(4)→tul[i,j]
  EndFor
 EndFor
 1→s

Nyt on vuorossa kuvien eli noppien luominen. Aluksi grafiikkanäytön kuvaajan akselit ja ruudukko otetaan pois häiritsemästä. Asetukset otetaan kuitenkin talteen muuttujiin, jotta ne voidaan palauttaa pelin lopuksi. Helpoin tapa muodostaa kuvat on piirtää ne ja kopioida StoPic-komennolla muuttujiin. Viimeinen kuva, ty, jota käytetään noppien poistamiseen, luodaan kuitenkin NewPic-komennolla.

 setGraph("Axes","Off")→ak
 setGraph("Grid","Off")→gr
 ClrDraw
 PxlLine 0,0,8,0
 PxlLine 0,0,0,8
 PxlLine 8,0,8,8
 PxlLine 0,8,8,8
 PxlOn 4,4
 StoPic n1,0,0,9,9
 PxlOn 2,4
 PxlOn 6,4
 StoPic n3,0,0,9,9
 PxlOff 4,4
 StoPic n2,0,0,9,9
 PxlOff 2,4
 PxlOff 6,4
 PxlOn 2,2
 PxlOn 6,2
 PxlOn 2,6
 PxlOn 6,6
 StoPic n4,0,0,9,9
 PxlOn 4,4
 StoPic n5,0,0,9,9
 PxlOff 4,4
 PxlOn 4,2
 PxlOn 4,6
 StoPic n6,0,0,9,9
 NewPic [1,1],ty,9,9

Tästä alkavat pelin pääsilmukat. Niitä ennen tuloslista piirretään ensimmäisen kerran ja tuloslistan oikealle puolelle piirretään pystysuora viiva. Ensimmäinen silmukka suoritetaan 15 kertaa, joka on pelin tulosten määrä. Toinen silmukka suoritetaan kaksi kertaa, ensimmäisen ja toisen pelaajan tulokset.

 ClrDraw
 lis(s,nim,tul)
 PxlVert 103
 For i,1,15
  For j,1,2

Silmukan alussa tulostetaan pelaajien yhteispistemäärä ja merkitään nuoli sen pelaajan kohdalle, joka on heittovuorossa.

   If j=1 Then
    PxlText "P1:"&right("  "&string(tul[18,1]),3)&" "&char(17),58,105
    PxlText "P2:"&right("  "&string(tul[18,2]),3)&"  ",68,105
   Else
    PxlText "P1:"&right("  "&string(tul[18,1]),3)&"  ",58,105
    PxlText "P2:"&right("  "&string(tul[18,2]),3)&" "&char(17),68,105
   EndIf

Sitten alkaa noppien heittäminen. n-lista sisältää noppien arvot ja v-lista valitut nopat. Noppia on luvallista heittää kolme kertaa, minkä vuoksi For-silmukka suoritetaan kolmesti. Ainoastaan ne nopat, joita ei ole valittu, heitetään ja piirretään uudelleen. Noppien heiton jälkeen seuraa silmukka, jossa luetaan pelaajan näppäinpainalluksia. ESC lopettaa pelin, MODE vaihtaa tulossivua ja F1-F5 valitsevat tai poistavat noppien valinnan.

   {0,0,0,0,0}→n
   {0,0,0,0,0}→v
   pxlText "        ",11,107
   For m,1,3
    PxlText string(m)&"/3",38,105
    For l,1,5
     If v[l]=0 Then
      rand(6)→n[l]
      "n"&string(n[l])→k
      AndPic ty,1,97+l*10
      RclPic #k,1,97+l*10
     EndIf
    EndFor
    If m≠3 Then
     Loop
      getKey()→np
      If np=264 Then
       Goto loppu
      ElseIf np=266 Then
       If s=1 Then
        2→s
       Else
        1→s
       EndIf
       lis(s,nim,tul)
      ElseIf np>267 and np<273 Then
       np-267→l
       If v[l]=0 Then
        1→v[l]
        pxlText char(15),11,97+l*10
       Else
        0→v[l]
        pxlText " ",11,97+l*10
       EndIf
      ElseIf np=13 Then
       Exit
      EndIf
     EndLoop
    EndIf
   EndFor

Kun nopat on heitetty, on aika valita, mikä yhdistelmä nopista muodostetaan. Tämä tapahtuu ensimmäisellä sivulla näppäimillä 1 - 8 ja toisella sivulla näppäimillä 1 - 9. Pelaaja voi myös keskeyttää pelin ESCillä ja vaihtaa tulossivua MODElla.

   If s=1 Then
    PxlText "1-8",38,105
   Else
    PxlText "1-9",38,105
   EndIf
   Loop
    getKey()→np
    If np=264 Then
     Goto loppu
    ElseIf np=266 Then
     If s=1 Then
      2→s
      PxlText "1-9",38,105
     Else
      1→s
      PxlText "1-8",38,105
     EndIf
     lis(s,nim,tul)
    ElseIf np>48 and np<58 Then
       np-48→l
       If s=2
        l+8→l
       If tul[l,j]=char(4) and l≠7 and l≠8 Then
        Exit
       EndIf
    EndIf
   EndLoop

Tämän jälkeen lasketaan pelaajan saamat pisteet valitulla heittoyhdistelmällä. Heittojen analysoiminen on kuvattu yksityiskohtaisesti esim. täällä. Heittotulos sekä tulosten yhteissummat tallennetaan lopuksi tul-listaan. Tämän jälkeen palataan silmukan alkuun, ja tulee kakkospelaajan vuoro heittää tai uusi kierros.

   SortA n
   0→pi
   If l>0 and l<7 Then
    For m,1,5
     If n[m]=l
      pi+l→pi
    EndFor
    tul[7,j]+pi→tul[7,j]
    If tul[7,j]>62 and tul[8,j]=char(4) Then
     50→tul[8,j]
     50+tul[18,j]→tul[18,j]
    EndIf
   ElseIf l=9 Then
    For i,4,1,ª1
     If n[i]=n[i+1] Then
      n[i]*2→pi
      Exit
     EndIf
    EndFor
   ElseIf l=10 Then
    If n[4]=n[5] and n[2]=n[3] and n[2]≠n[5] Then
     n[4]*2+n[2]*2→pi
    ElseIf n[4]=n[5] and n[1]=n[2] and n[1]≠n[5] Then
     n[4]*2+n[1]*2→pi
    ElseIf n[3]=n[4] and n[1]=n[2] and n[1]≠n[4] Then
     n[3]*2+n[1]*2→pi
    EndIf
   ElseIf l=11 Then
    For i,3,1,ª1
     If n[i]=n[i+2] Then
      n[i]*3→pi
      Exit
     EndIf
    EndFor
   ElseIf l=12 Then
    For i,2,1,ª1
     If n[i]=n[i+3] Then
      n[i]*4→pi
      Exit
     EndIf
    EndFor
   ElseIf l=13 Then
    If n[1]=1 and n[2]=2 and n[3]=3 and n[4]=4 and n[5]=5
     15→pi
   ElseIf l=14 Then
    If n[1]=2 and n[2]=3 and n[3]=4 and n[4]=5 and n[5]=6
     20→pi
   ElseIf l=15 Then
    If n[3]=n[5] and n[1]=n[2] and n[1]≠n[5] Then
     n[5]*3+n[1]*2→pi
    ElseIf n[4]=n[5] and n[1]=n[3] and n[1]≠n[5] Then
     n[5]*2+n[1]*3→pi
    EndIf
   ElseIf l=16 Then
    n[1]+n[2]+n[3]+n[4]+n[5]→pi
   Elseif l=17 Then
    If n[1]=n[5]
     50→pi
   EndIf
   pi→tul[l,j]
   tul[18,j]+pi→tul[18,j]
   Text nim[l]& " pelaaja "&string(j)&":lle, "&string(pi)&" pistettä!"
   lis(s,nim,tul)
  EndFor
 EndFor

Ja tässä on pelin päättyminen 15 kierroksen tai ESCin painalluksen jälkeen. Poikkeuksellisesti on jouduttu käyttämään Goto- ja Lbl-komentoja hyppäämään loppu-nimiöön, koska TI-89:n Basic ei tunnu sisältävän keinoa poistua usemmasta kuin yhdestä silmukasta. Lopuksi ilmoitetaan, kumpi pelaajista voitti, vai tuliko tasapeli, minkä jälkeen kuvaajan asetukset palautetaan alkuperäisiksi ja peli palaa perusnäyttöön.

 Lbl loppu
 If tul[18,1]>tul[18,2] Then
  Text "Peli päättyi - pelaaja 1 voitti!"
 ElseIf tul[18,1]<tul[18,2] Then
  Text "Peli päättyi - pelaaja 2 voitti!"
 Else
  Text "Peli päättyi - tasapeli!"
 EndIf
 setGraph ("Axes",ak)
 setGraph ("Grid",gr)
 DispHome
EndPrgm

TI-MATO

Toisen esimerkkipelin nimi on TI-MATO. Se on nimensä mukaisesti vanhan kunnon matopelin laskinversio. Nuolinäppäimillä ohjattavan madon tehtävä on kerätä kentän satunnaisiin kolkkiin ilmestyviä aarteita, joista saa pisteitä. Ja jos mato osuu seinään tai itseensä, peli päättyy. Pelin koko on huomattavasti pienempi kuin jatsin, 1431 tavua.

TI-MATO

Ohjelman alussa määritellään joukko paikallisia muuttujia:

aaarteen kuva
akgrafiikkaikkunan akselit-asetus
axaarteen x-koordinaatti
ayaarteen y-koordinaatti
grgrafiikkaikkunan ristikko-asetus
lxlista, jossa on madon palojen x-koordinaatit
lylista, jossa on madon palojen y-koordinaatit
mpmadon pituus
npainettu näppäin
pmadon palan kuva
pipisteet
smadon suunta
ttyhjä kuva
xnykyinen x-koordinaatti
ynykyinen y-koordinaatti
mato()
Prgm
 Local a,ak,ax,ay,gr,lx,ly,mp,n,p,pi,s,t,x,y

Tämän jälkeen luodaan kolme kuvaa: madon pala, aarre ja tyhjä kuva, jota käytetään kuvien poistamiseen.

 NewPic [1,1;1,2;1,3;1,4;1,5;2,1;3,1;4,1;2,5;3,5;4,5;5,1;5,2;5,3;5,4;5,5],p
 NewPic [1,3;2,2;2,4;3,1;3,5;4,2;4,4;5,3],a
 NewPic [3,3],t,5,5

Sitten siirrytään grafiikkanäyttöön, mitä ennen kuvaajan mahdolliset akselit ja ruudukko otetaan pois. Asetusten arvot kuitenkin tallennetaan muuttujiin, jotta ne voidaan palauttaa pelin päätyttyä.

 setGraph("Axes","Off")→ak
 setGraph("Grid","Off")→gr
 ClrDraw

Seuraavaksi piirretään ruudun kehykset. Ruudun ylälaidassa näkyy aina pelin nimi ja pistemäärä. Pistemäärä näkyy aina nelinumeroisena, alussa on tarvittaessa ylimääräisiä nollia. Tämä onnistuu right-funktiolla, joka palauttaa annetun määrän merkkejä merkkijonon lopusta.

 0→pi
 PxlText "TI-MATO",0,0
 PxlHorz 9
 PxlVert 156
 PxlText right("000"&string(pi),4),0,135

Tämän jälkeen määritetään madon aloituskoordinaatit ja -nopeus. Madon kaikkien palojen koordinaatit tallennetaan listaan, jossa on aluksi viisi alkiota. Lisäksi arvotaan madon suunta (1 = vasemmalle, 2 = ylös, 3 = oikealle, 4 = alas) ja ensimmäisen aarteen sijainti. Lopuksi aarre ja madon ensimmäinen pala piirretään näytölle.

 75→x
 40→y
 5→mp
 {x,x,x,x,x}→lx
 {y,y,y,y,y}→ly
 rand(4)→s
 rand(30)*5→ax
 rand(12)*5+10→ay
 RclPic a,ay,ax
 RclPic p,y,x

Nyt alkaa varsinainen pelisilmukka. Silmukan alussa luetaan näppäimistöä. Jos painettu näppäin on ESC, poistutaan välittömästi silmukasta. Jos painettu näppäin on joku nuolinäppäimistä, madon suunta muuttuu. Kuitenkaan mato ei saa lähteä vastakkaiseen suuntaan.

 Loop
  getKey()→n
  If n=264 Then
   Exit
  ElseIf n=337 and s≠3 Then
   1→s
  ElseIf n=338 and s≠4 Then
   2→s
  ElseIf n=340 and s≠1 Then
   3→s
  ElseIf n=344 and s≠2 Then
   4→s
  EndIf

Seuraavaksi muutetaan madon koordinaatteja suunnan mukaan. Samalla tarkistetaan, ettei mato mene alueen rajojen yli. Jos näin käy, poistutaan silmukasta.

  If s=1 Then
   x-5→x
   If x<0
    Exit
  ElseIf s=2 Then
   y-5→y
   If y<10
    Exit
  ElseIf s=3 Then
   x+5→x
   If x>150
    Exit
  ElseIf s=4 Then
   y+5→y
   If y>70
    Exit
  EndIf

Jos madon ja aarteen koordinaatit ovat samat, mato on onnistunut saamaan aarteen. Tällöin pisteitä lisätään kymmenellä ja aarteelle arvotaan uusi paikka, jonne se myös piirretään. Madon pituutta myös lisätään yhdellä, jotta peli ei olisi liian helppo.

  If x=ax and y=ay Then
   pi+10→pi
   PxlText right("000"&string(pi),4),0,135
   AndPic t,ay,ax
   Loop
    rand(30)*5→ax
    rand(12)*5+10→ay
    If not PxlTest(ay+1,ax+1)
     Exit
   EndLoop
   RclPic a,ay,ax
   mp+1→mp
   lx[1]→lx[mp]
   ly[1]→ly[mp]
   rotate(lx)→lx
   rotate(ly)→ly
  EndIf

Tässä osassa liikutetaan matoa ja piirretään se. X- ja y-koordinaattien listat sisältävät madon jokaisen palikan paikan niin, että uusin on ensimmäisenä ja vanhin viimeisenä. Vanhin palikka pitäisi saada pois. rotate-funktio on kuin luotu tähän tarkoitukseen: se tuo listan viimeisen palikan ensimmäiseksi ja siirtää muita yhden edemmäs. Nyt vanha palikka voi vaihtaa osia uuden kanssa. PxlTest-funktion avulla tarkistetaan, ettei mato osu itsensä päälle.

  rotate(lx)→lx
  rotate(ly)→ly
  AndPic t,ly[1],lx[1]
  x→lx[1]
  y→ly[1]
  If PxlTest(y+1,x+1)
   Exit
  RclPic p,y,x
 EndLoop

Jos silmukasta joudutaan pois, peli on keskeytetty tai mato on törmännyt seinään tai itseensä. Siksi tähän kohtaan kuuluu pelin loppu. Ensin grafiikkanäytön kuvaaja-asetukset palautetaan entiselleen. Tämän jälkeen ohjelmanäyttöön tulostetaan ilmoitus pelin päättymisestä ja pelaajan saavuttama pistemäärä. Ja kun pelaaja painaa ENTERiä, ohjelma palaa perusnäyttöön.

 setGraph("Axes",ak)
 setGraph("Grid",gr)
 ClrIO
 Disp "Peli päättyi!"
 Disp ""
 Disp "Pisteet: "&string(pi)
 Pause
 DispHome
EndPrgm

Loppusanat

Tässäpä se sitten oli. Opassarjan lopuksi TI-89:lle pelejä ohjelmoivan "yhdeksän käskyä":

Lähetä toki sähköpostia, ja kerro, mitä pidit oppaasta. Voit myös kysyä apua ongelmiin ja kertoa omista peleistäsi.

Antti Laaksonen, 30.7.2003


Kommentit

Gwaur [31.07.2003 03:21:38]

#

Jollain on vähän liian paljon aikaa :D ei pahalla

Ilmuri [01.08.2003 22:55:47]

#

varsin mukava opas... oikun omistaisinkin tommosen laskimen...

Sami [03.08.2003 14:38:42]

#

Vielä kun olisi tuollainen laskin tai samanlainen opas Sharpin el-9900 laskimelle (tai joku sinnepäin se ainakin oli...)

Ilmuri [07.08.2003 19:59:42]

#

aattelin hommata sellasen casio laskinpömpelin... en vaan tuu tarvihtemaan ees prosenttia sen toiminnoista piitkään aikaan!

Heikki [29.06.2004 14:21:53]

#

TI-86 pitää hommata tossa kun koulut alkavat, saa sitten nähdä kuinka hyvin nämä ti-89:n pelit/käskyt siinä toimivat...

Puhveli [29.01.2005 16:57:11]

#

Älkää ihmiset ostako casioita koodaamista varten, ainakin mun FX 1.0 Plus on hiiiiiiiidas! Tästä TI:stä en tiedä, kuulemma paljon nopeempi.

tsuriga [19.01.2006 21:58:44]

#

TI-86:ssa ei ole mielestäni läheskään näin hienostunutta kieltä, mikälie basicci siinä pyörii, mutta sekin on hidas kuin syväjäädytetty virtahepo. Kannattaa sillä ASMilla tehdä ne ohjelmat ja siirtää laskimeen. Tein itse Venttiä, Numeronarvausta ja yritinpä jopa moninpeliä väsätä, vaan meni hankalaksi käskyjen lähetys. Ja Ventti toimi jo kymmenen pelin jälkeen toivottoman hitaasti.

Väpä [17.03.2009 20:21:11]

#

jollakin lailla soveltamalla toimii myös ainakin TI-84+ laskimessa, vaikka ei olekaan tuollaista Program Editoria, on vain PRGM napin takana oleva ohjelman luonti (lähes sama)

Kirjoita kommentti

Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.

Muista lukea kirjoitusohjeet.
Tietoa sivustosta