Matopeli Pythonilla

empty 15.04.03 21:46

Simppeli, perinteinen matopeli Pythonilla tekstigrafiikoilla.

 Tekstiversio  Arvo: 5 (5 ääntä)  Äänestä: +  -
# Ajamiseen tarvitset Console-moduulin, jonka saa täältä
# http://effbot.org/zone/console-handbook.htm
#
# Tai tarkemmin ottaen täältä:
# http://effbot.org/downloads/
#
# Tarvitset myös Python version 2.2 tai uudemman (luulisin)
#
# Matoa ohjataan napeista w,s,a,d. q lopettaa pelin.
#
# Taas tämmöinen ylikommentoitu pätkä. Toivottavasti jotain
# kiinnostaa.
#
# Hannu Kankaanpää

import Console
import time
import string
import random

def wormgame():
    # Luodaan eka konsoli
    c = Console.getconsole()
    c.title("Matopeli")
   
    # Kuvaruudun leveys ja korkeus
    width, height = c.size()
   
    # Tämä kertoo miten tietty näppäimistön näppäin muuttuu
    # suunnaksi. Esim 'w'-kirjain => (0, -1), mikä vastaa yhden ruudun
    # liikkumista ylöspäin
    dirmap = { 'w': (0, -1), 's': (0, 1), 'a': (-1, 0), 'd': (1, 0) }
   
    # Mitkä suunnat ovat toistensa vastakohtia? Tätä käytetään
    # varmistamaan ettei pelaaja tee täyskäännöstä ja kuole suoraan
    opposites = { 'w': 's', 's': 'w', 'a': 'd', 'd': 'a' }
   
    # Pelikenttä, eli 2-ulotteinen taulukko joka sisältää kirjaimia.
    # Käyttö tähän tapaan: area[x][y] = '1'
    # Numeroilla merkataan bonuksia, kirjaimilla w,s,a,d madon
    # liikesuuntia eri ruuduissa.
    area = [ [' ' for e in range(height)] for i in range(width)]
   
    # Luodaan pelialueen reunat. Käydään härskisti koko ruutu läpi
    # ja piirretään seinää vain silloin kun ollaan reunoilla.
    # Siis kun x == 0 tai y == 0 jne.
    for y in range(height):
        for x in range(width):
            if x == 0 or y == 0 or \
               x == width - 1 or y == height - 1:
                c.text(x, y, '#')
                area[x][y] = '#'
   
    # Kuinka kauan häntä odottaa alussa, ennenkuin lähtee seuraamaan?
    # Eli madon alkupituus.
    trailWait = 10
   
    # Aloituskoordinaatit
    x = 10; y = 10
   
    # Hännän aloituskoordinaatit
    tx = x; ty = y
   
    # Pisteet nollille
    points = 0
   
    # Lähtösuunta ('d' on oikealle)
    dir = 'd'

    # makebonus tekee bonuksen satunnaiseen paikkaan ruudulla.
    # Huomaa että funktioita voi määritellä kätevästi täällä
    # toisen funktion sisällä. makebonuksella onkin pääsy main-
    # funktion muuttujiin, kuten konsoliin c ja pelialueeseen area
    def makebonus():
        while 1:
            # arvo satunnainen paikka ruudulta
            x = random.randint(0, width - 1)
            y = random.randint(0, height - 1)
            # varmista että siinä on tyhjää
            if area[x][y] == ' ':
                # bonuksen arvo on luku 0-4
                bonus = random.randint(0, 4)
                # merkitse karttaan bonuksen arvo numerona 1-5
                area[x][y] = chr(bonus + ord('1'))
                # piirrä ruudulle bonus
                c.text(x, y, 'X', 15 + 16 * (bonus + 9))
                return
   
    # Tehdään aluksi 1 bonus ruudulle
    makebonus()
   
    # Tästä alkaa itse peli
    while 1:
        # Hidastetaan hieman pelin kulkua. Tämä on simppelein tapa.
        time.sleep(0.08)
       
        # Luetaan näppis
        if c.peek() is not None:
            # event on tapahtuma (esim. hiiren liikahdus ruudulla)
            event = c.get()
            # Mutta me välitetään vain napin painalluksista ('KeyPress')
            if event.type == 'KeyPress':
                # Katso onko painettu nappi suunta (w,s,a,d) ja ettei
                # se ole vastakkaiseen kuin aiempi liike
                if event.char in dirmap and opposites[event.char] != dir:
                    dir = event.char
               
                # Lopeta luuppi jos painettiin nappia 'q'
                if event.char == 'q':
                    break
       
        # Merkitään karttaan mihin suuntaan oltiin matkalla
        # Häntä voi sitten seurata tätä suuntaa
        area[x][y] = dir
        # Liikutetaan madon päätä...
        x += dirmap[dir][0]
        y += dirmap[dir][1]
        # ...ja piirretään se.
        c.text(x, y, 'O')

        # Jos uudessa sijainnissamme ei ole tyhjää,
        # siinä on jotain erikoista (bonus, seinä tai häntä)
        if area[x][y] != ' ':
            # Jos siinä on numero, on kyseessä bonus
            if area[x][y] in string.digits:
                # Muuta numero-merkki numeroksi
                bonusAmount = int(area[x][y]) * 5
                # Lisää pojoja
                points += bonusAmount
                # Ja pistä häntä venaamaan
                trailWait += bonusAmount
                # Sekä lisää uusi bonus ruudulle
                makebonus()
            else:
                # Muuten kuolema
                break
       
        # Katotaan pitääkö hännän odotella
        if trailWait > 0:
            trailWait -= 1
        else:
            # Häntä lukee merkin pelialueelta ja liikkuu
            # vastaavaan suuntaan. Muista että silloin kun madon pää
            # liikkui eteenpäin, se merkitsi suuntansa pelialueelle
            trailDir = dirmap[area[tx][ty]]
            # Pyyhi häntä ruudulta ja pelialueelta
            area[tx][ty] = ' '
            c.text(tx, ty, ' ')
            # Ja liikuttele häntää
            tx += trailDir[0]
            ty += trailDir[1]
   
    # Peli loppui, näytä pisteet ruudulla.
    c.text(9, 10, "+" + "-" * 24 + "+")
    c.text(9, 11, "|" + ("You got %s points" % points).center(24) + '|')
    c.text(9, 12, "|" + "Press 'q' to quit".center(24) + '|')
    c.text(9, 13, "+" + "-" * 24 + "+")
    # Odottele että näppikseltä painetaan 'q'
    while 1:
        event = c.get()
        if event.type == 'KeyPress' and event.char == 'q':
            break

# Käynnistä peli suoraan vain jos ohjelma on käynnistetty
# tästä python-tiedostosta.
if __name__ == '__main__':
    wormgame()
 

empty 21:55 15.4.03 
Ei tässä muuten ole kuin 72 riviä koodia jos kommentit ja tyhjät rivit poistetaan ;)
thefox 09:36 16.4.03 
Pythonia en itse osaa, mutta vaikuttaisi mainiolta esimerkiltä Pythonin opiskelun juuri aloittaneille.
pikkumyy 09:38 16.4.03 
Tuon vastakkaisen suunnan tarkastuksen olisi voinut tehdä vähän hienomminkin, mutta kommentoinnin laajuudesta, selkeästä koodista yms kiitoksia :)
empty 00:28 17.4.03 
No joo, jos olisi joku vektoriluokka käytössä niin vois kirjoittaa

if event.char in dirmap and dirmap[event.char] != -dirmap[dic]:

mutta en tiedä miten sen perustyypeillä saisi nätimmin.
editoitu: 02:15 1.8.04
Kinnala 02:13 1.8.04 
Jotain erroria heitti. En vaivautunut katsomaan mitä. Python 2.3 käytössä. Mukava esimerkki kylläkin. :)

Edit: Pitäis lukea tarkemmin ennenkuin kirjoittaa mitään. Tämä teksti siis mitätöity. :)
sakke13 20:42 17.10.05 
Mainion oloinen pätkä. Tähän pitää tutustua paremmalla ajalla ja ajatuksen kanssa. Meille alkajille hyvä ja mukavan konkreettinenkin esimerkki.
mwandishi 09:05 20.7.06 
Saattaa olla, että teen vaan jotain väärin, mutta Console tuntuu olevan todella epävakaa moduuli. :/