Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Python: Arvauspelin tekeminen

Sivun loppuun

Rintsi [04.08.2017 21:35:48]

#

Olen päivän pari harjoitellut pythonin parissa lukien python 3 - ohjelmointiopasta jonka jostain kaivoin esiin. Tossa oli tutoriaali kuinka tehdään numeronarvauspeli jota lähdin soveltamaan.

Halusin että ohjelma arpoo randomin numeron arvattavaksi johon pelaaja valitsee haluamansa maksimin kokonaisluvulle.

tämä yritelmä antaa aina tulosteen: Numero on pienempi kuin arvaus.

# _*_ coding: utf-8 _*_
# Tiedosto: demo.py
# Numeronarvauspeli while-rakenteen avulla

import random

a = 1
b = int(raw_input("Kerro vaikeusaste: "))
oikea_numero = random.randint(a, b)

while True: # aloittaa while silmukan
    arvaus = raw_input("Anna kokonaisluku: ")
    if arvaus == "lopeta":
        break # lopettaa while silmukan
    if arvaus == oikea_numero:
        print("Arvasit oikein!")
        print("Peli paattyy tahan.")
        break # lopettaa while silmukan
    elif arvaus < oikea_numero:
        print("Numero on suurempi kuin arvaus")
    else:
        print("Numero on pienempi kuin arvaus")

Auttakaas nyt reppanaa oikealle polulle.

-Rintsi

Chiman [04.08.2017 23:23:09]

#

raw_input palauttaa merkkijonon. Et voi onnistuneesti verrata merkkijonoa kokonaislukuun. Niinpä käytä int(arvaus) -muunnosta ennen vertailua kokonaislukuun.

qwerty12302 [05.08.2017 15:14:45]

#

Jos käytät Python 3:a, ei pitäisi käyttää raw_inputia vaan inputia.

Rintsi [06.08.2017 01:11:43]

#

qwerty12302 kirjoitti:

Jos käytät Python 3:a, ei pitäisi käyttää raw_inputia vaan inputia.

mulla on versio 2.7 käyössä, luin vaan uudempaa opasta kun vaikutti kattavalta, en huomannut asiaa mainita aloituksessa.

ja kiitos vastauksesta Chiman

aloitin homman uusiksi ja sain raavittua jotain kasaan.

# _*_ coding: utf-8 _*_
# Tiedosto:

# Numeron arvauspeli

import random
helppo = random.randint (1,100)
normaali = random.randint (1,1000)
vaikea = random.randint (1,1000000)

vastaus_laskuri = 0
nimi = raw_input("Kuka pelaa?")
vaikeus = raw_input("Kerroppas "+ nimi + ". Minka vaikeustason haluat ottaa? helppo, normaali vai vaikea? ")
if vaikeus.lower() == "helppo": # .lower() muuttaa annetut merkit pieniksi.
    numero = helppo
    print ("Okei, " + nimi + ". Pelaat siis kuin nynny! Mietin numeroa 1-100")
    print ("Sulla on 20 arvausta")
if vaikeus.lower() == "normaali":
    numero = normaali
    print ("Okei, " + nimi + ". Hyva valinta! Ajattelen numeroa 1-1000")
    print ("Sulla on 20 arvausta")
if vaikeus.lower() == "vaikea":
    numero = vaikea
    print ("Okei, " + nimi + ". Haluat siis painia isojen poikien sarjassa.")
    print ("Numero jota ajattelen on valilta 1-1000000 (Miljoona)")
    print ("Sulla on 20 arvausta")
while vastaus_laskuri < 20:# Määrittää arvauksien max määrän
    vastaus = int(raw_input("Anna vastaus:" ))
    vastaus_laskuri = vastaus_laskuri + 1
    if vastaus < numero:
        print("Vastauksesi meni alakanttiin.")
    if vastaus > numero:
        print("vastauksesi meni yläkanttiin.")
    if vastaus == numero:
        break

def tee_kyltti(teksti):
    plakaatti = "*" * (len(teksti) + 4) + "\n"
    plakaatti = plakaatti + "* " + teksti + " *\n"
    plakaatti = plakaatti + "*" * (len(teksti) + 4) + "\n"
    return plakaatti

if vastaus == numero:
    vastaus_laskuri = str (vastaus_laskuri)
    syote = ("Onnee " + nimi + "! Selvitit arvaukseni " + vastaus_laskuri+ " yrityksella!")
    taulu = tee_kyltti(syote)
    print(taulu)
if vastaus != numero:
    numero = str (numero)
    print("Ei.. Numero jota mietin on " + numero)

ehkä kokeilen laittaa viellä score taulun tohon

Chiman [06.08.2017 12:54:35]

#

Hyvin näyttää edistyvän. Jatkokehitysehdotuksia:
- virheensieto väärille syötteille (tarkistukset, try-except)
- tulosta lukuväli, jolla numeron on oltava kunkin arvauksen jälkeen
- siirrä enemmän yksittäisiä toimintoja omaan funktioonsa, esim. arvauksen kysyminen

The Alchemist [07.08.2017 18:28:16]

#

Eikä kommentteja tarvitse tuhlata triviaaleihin asioihin. Vakiokirjaston funktioiden käyttöä on turha kommentoida samoin kuin silmukan kierrosten rajoittamista; sen näkee suoraan koodista. Järkevämpää olisi sen sijaan esimerkiksi kertoa silmukan alussa, mikä kyseisen silmukan tarkoitus on. Kuitenkaan yksinkertaisessa koodissa sillä ei vielä tee mitään.

Rintsi [07.08.2017 20:35:24]

#

Käytin tota try - except virheensiedoksi vastaukselle mutta se soimii jostain syystä x niin että kun syötän inputtiin ensimmäisellä kerralla aakkosia niin ohjelma päättyyy virheeseen "NameError: name 'vastaus' is not defined"

Mutta jos syötän inputtiin ensin numeron ja vasta seuraavaalla kerralla aakkosen niin saan silloin tulostuksen:
Annoit kirjaimia numeroiden sijaan!

En nyt ihan käsitä kuinka saisin ton ongelman korjattua.?

while vastaus_laskuri < 20:# Määrittää arvauksien max määrän
    try:
        vastaus = int(raw_input("Anna vastaus:" ))
        vastaus_laskuri = vastaus_laskuri + 1
    except ValueError:
        print "Annoit kirjaimia numeroiden sijaan!"
    if vastaus < numero:
        print("Vastauksesi meni alakanttiin.")
    if vastaus > numero:
        print("vastauksesi meni yläkanttiin.")
    if vastaus == numero:
        break

The Alchemist kirjoitti:

Eikä kommentteja tarvitse tuhlata triviaaleihin asioihin.

Laitoin kommentteja lähinnä itseäni varten musistilapuiksi kun tässä tullut mulle jo paljon uutta.

Chiman [07.08.2017 21:49:03]

#

Rintsi kirjoitti:

Käytin tota try - except virheensiedoksi vastaukselle mutta se soimii jostain syystä x niin että kun syötän inputtiin ensimmäisellä kerralla aakkosia niin ohjelma päättyyy virheeseen "NameError: name 'vastaus' is not defined"

Tuo johtuu siitä, että rivillä

vastaus = int(raw_input("Anna vastaus:" ))

int-muunnos keskeytyy virheeseen, eikä int ehdi palauttaa mitään arvoa, joten saman rivin =-sijoitusoperaattoria ei suoriteta sillä kerralla. Siten vastaus-muuttujaa (nimeä) ei määritellä. Kun kysyt olemattoman nimen arvoa alempana, saat mainitun virheen.

Näin:

while vastaus_laskuri < 20:  # Määrittää arvauksien max määrän
    try:
        vastaus = int(raw_input("Anna vastaus:" ))
    except ValueError:
        print "Annoit kirjaimia numeroiden sijaan!"
        continue  # kysy uudestaan eli palaa whilen alkuun

    # arvo ok, jatketaan
    vastaus_laskuri += 1
    if vastaus < numero:
        print("Vastauksesi meni alakanttiin.")
    elif vastaus > numero:
        print("vastauksesi meni yläkanttiin.")
    else:
        # arvaus meni oikein
        break

Rintsi [10.08.2017 18:47:52]

#

Nyt taas pieniä lisäyksiä koodissa mm. ajanotto sekä virheensieto..

Työn alla on tällähetkellä toimintojen siirtäminen omiin funktioihinsa. taidan viettää pari välipäivää sen osalta kun ei yritykset tuota toimivaa tulosta ja ajatukset menee ristiin..

tässä toimiva koodi tällähetkellä, siinä työnalla olevassa riittää varmasti hupia osaavalle koodarille ;D

# _*_ coding: utf-8 _*_
# Tiedosto:

# Numeron arvauspeli

import time
import random
helppo = random.randint (1,100)
normaali = random.randint (1,1000)
vaikea = random.randint (1,1000000)
vastaus_laskuri = 0

nimi = raw_input("Kuka pelaa?")

def uusi_peli():
    ehdotus = raw_input("haluatko pelata uudelleen vai lopettaa, uudelleen, lopeta? ").lower()
    if ehdotus == "uudelleen":
        exit()
    elif ehdotus == "lopeta":
        exit()
    else:
        print
        syote = ("kirjoita uusi jos haluat uuden pelin. kirjoita lopeta jos haluat lopettaa!")
        taulu = tee_virhe(syote)
        print(taulu)
        uusi_peli()

def tee_kyltti(teksti):
    plakaatti = "*" * (len(teksti) + 4) + "\n"
    plakaatti = plakaatti + "* " + teksti + " *\n"
    plakaatti = plakaatti + "*" * (len(teksti) + 4) + "\n"
    return plakaatti

def tee_virhe(virhe):
    plakaatti_virhe = "!" * (len(virhe) + 4) + "\n"
    plakaatti_virhe = plakaatti_virhe + "! " + virhe + " !\n"
    plakaatti_virhe = plakaatti_virhe + "!" * (len(virhe) + 4) + "\n"
    return plakaatti_virhe

while True:

    vaikeus = raw_input("Kerroppas "+ nimi + ". Minka vaikeustason haluat ottaa? helppo, normaali vai vaikea? ").lower()
    if vaikeus == "helppo":
        numero = helppo
        print
        print ("Okei, " + nimi + ". Pelaat siis kuin nynny! Mietin numeroa 1-100 Ja sulla on 20 arvausta")
        print
        start = time.time()
        break
    elif vaikeus == "normaali":
        numero = normaali
        print
        print ("Okei, " + nimi + ". Hyva valinta! Ajattelen numeroa 1-1000 Ja sulla on 20 arvausta")
        print
        start = time.time()
        break
    elif vaikeus == "vaikea":
        numero = vaikea
        print
        print ("Okei, " + nimi + ". Haluat siis painia isojen poikien sarjassa.")
        print ("Numero jota ajattelen on valilta 1-1000000 (Miljoona) Ja sulla on 20 arvausta")
        print
        vastaus = int(raw_input("Anna vastaus:" ))
    except ValueError:
        print
        syote = ("Annoit kirjaimia numeroiden sijaan!")
        taulu = tee_virhe(syote)
        print(taulu)
        continue
    vastaus_laskuri += 1
    if vastaus < numero:
        print("Vastauksesi meni alakanttiin.")
    if vastaus > numero:
        print("vastauksesi meni ylakanttiin.")
    if vastaus == numero:
        break

if vastaus == numero:
    stop = time.time()
    aika = (stop - start)
    aika = round(aika, 5)
    aika = str (aika)
    vastaus_laskuri = str (vastaus_laskuri)
    syote = ("Onnee " + nimi + "! Selvitit numeroni " + aika + " Sekunnissa, " + vastaus_laskuri+ " yrityksella! ")
    taulu = tee_kyltti(syote)
    print(taulu)
    uusi_peli()
if vastaus != numero:
    numero = str (numero)
    print("Ei.. Numero jota mietin on " + numero)
    uusi_peli()
        start = time.time()
        break
    else:
        print
        syote = ("Sinun taytyy valita vaikeustaso kirjoittamalla joko: helppo, normaali tai vaikea!")
        taulu = tee_virhe(syote)
        print(taulu)

while vastaus_laskuri < 20:
    try:
        vastaus = int(raw_input("Anna vastaus:" ))
    except ValueError:
        print
        syote = ("Annoit kirjaimia numeroiden sijaan!")
        taulu = tee_virhe(syote)
        print(taulu)
        continue
    vastaus_laskuri += 1
    if vastaus < numero:
        print("Vastauksesi meni alakanttiin.")
    if vastaus > numero:
        print("vastauksesi meni ylakanttiin.")
    if vastaus == numero:
        break

if vastaus == numero:
    stop = time.time()
    aika = (stop - start)
    aika = round(aika, 5)
    aika = str (aika)
    vastaus_laskuri = str (vastaus_laskuri)
    syote = ("Onnee " + nimi + "! Selvitit numeroni " + aika + " Sekunnissa, " + vastaus_laskuri+ " yrityksella! ")
    taulu = tee_kyltti(syote)
    print(taulu)
    uusi_peli()
if vastaus != numero:
    numero = str (numero)
    print("Ei.. Numero jota mietin on " + numero)
    uusi_peli()

Laitan tähän viellä sen "työn alla" olevan koodin jos vaikka saisin hieman ohjausta oikeaan suuntaan. ja isot Kiitokset, Chiman! Pelastit mut yhdeltä veritulpalta!

# _*_ coding: utf-8 _*_
# Tiedosto:

# Numeron arvauspeli

import time
import random
helppo = random.randint (1,100)
normaali = random.randint (1,1000)
vaikea = random.randint (1,1000000)
vastaus_laskuri = 0



def uusi_peli():
    ehdotus = raw_input("haluatko pelata uudelleen vai lopettaa, uudelleen, lopeta? ").lower()
    if ehdotus == "uudelleen":
        anna_nimi()
    elif ehdotus == "lopeta":
        exit()
    else:
        print
        syote = ("kirjoita uusi jos haluat uuden pelin. kirjoita lopeta jos haluat lopettaa!")
        taulu = tee_virhe(syote)
        print(taulu)
        uusi_peli()

def anna_nimi():
    global nimi
    nimi = raw_input("Kuka pelaa?")
    anna_vaikeus()

def anna_vaikeus():
    while True:
        vaikeus = raw_input("Kerroppas "+ nimi + ". Minka vaikeustason haluat ottaa? helppo, normaali vai vaikea? ").lower()
        if vaikeus == "helppo":
            numero = helppo
            print
            print ("Okei, " + nimi + ". Pelaat siis kuin nynny! Mietin numeroa 1-100 Ja sulla on 20 arvausta")
            anna_vastaus()
            start = time.time()
            break
        elif vaikeus == "normaali":
            numero = normaali
            print
            print ("Okei, " + nimi + ". Hyva valinta! Ajattelen numeroa 1-1000 Ja sulla on 20 arvausta")
            print
            start = time.time()
            break
        elif vaikeus == "vaikea":
            numero = vaikea
            print
            print ("Okei, " + nimi + ". Haluat siis painia isojen poikien sarjassa.")
            print ("Numero jota ajattelen on valilta 1-1000000 (Miljoona) Ja sulla on 20 arvausta")
            print
            start = time.time()
            break
        else:
            print
            syote = ("Sinun taytyy valita vaikeustaso kirjoittamalla joko: helppo, normaali tai vaikea!")
            taulu = tee_virhe(syote)
            print(taulu)

def anna_vastaus():
    while vastaus_laskuri < 20:
        try:
            vastaus = int(raw_input("Anna vastaus:" ))
        except ValueError:
            print
            syote = ("Annoit kirjaimia numeroiden sijaan!")
            taulu = tee_virhe(syote)
            print(taulu)
            continue
        vastaus_laskuri += 1
        if vastaus < numero:
            print("Vastauksesi meni alakanttiin.")
        if vastaus > numero:
            print("vastauksesi meni ylakanttiin.")
        if vastaus == numero:
            break

def tee_kyltti(teksti):
    plakaatti = "*" * (len(teksti) + 4) + "\n"
    plakaatti = plakaatti + "* " + teksti + " *\n"
    plakaatti = plakaatti + "*" * (len(teksti) + 4) + "\n"
    return plakaatti

def tee_virhe(virhe):
    plakaatti_virhe = "!" * (len(virhe) + 4) + "\n"
    plakaatti_virhe = plakaatti_virhe + "! " + virhe + " !\n"
    plakaatti_virhe = plakaatti_virhe + "!" * (len(virhe) + 4) + "\n"
    return plakaatti_virhe

anna_nimi()

Jaska [11.08.2017 16:27:42]

#

Minusta koodia ei kannata koettaa kirjoittaa kerralla kuntoon vaan pieninä paloina, jotka testataan kunnolla. Esimerkiksi minä tekisin ekasta versiosta ihan raakaversion:

def jatketaanko():
    vaihtoehdot = ["kyllä", "ei"]
    x = ""
    while x not in vaihtoehdot:
        x = input("Pelataanko vielä? ")
    if x == vaihtoehdot[0]:
        return True
    else:
        return False

def pelaa_kierros():
    print("Pelattiin kierros")

if __name__ == '__main__':
    pelataan = True
    while pelataan:
        pelaa_kierros()
        pelataan = jatketaanko()

Kun tuon on testannut kuntoon, voi miettiä mitä yhdellä kierroksella tapahtuu ja voiko pelaaja vaihtua eri kierrosten välillä.

Chiman [13.08.2017 13:34:21]

#

Rintsi kirjoitti:

Laitan tähän viellä sen "työn alla" olevan koodin jos vaikka saisin hieman ohjausta oikeaan suuntaan.

Välttäisin globaaleja muuttujia. Nyt kohta "vastaus_laskuri += 1" ei toimi funktion sisältä sellaisenaan, eikä global-avainsanan käyttö lisäisi selkeyttä. Kun käytät muuttujaa vain yhden funktion sisällä, on parasta määritellä se vain siellä.

syote-muuttujan sijoitukset sisältävät turhia sulkuja.

anna_vastaus-funktion if-ehdot ovat toisensa poissulkevia eli vain yksi voi olla tosi. Tällöin on fiksuinta käyttää if-elif-else-rakennetta.

Yksi pikkuviilauksen paikka vielä pisti silmään: anna_vaikeus-funktio sisältää toisteisuutta, jonka voisi poistaa esim. laittamalla eriävät kohdat sanakirjaan, jonka avaimina olisi käyttäjän syötevaihtoehdot.

Enkä malta olla näyttämättä omaa vaihtoehtoani Jaskan funktiolle:

def kysy_jatko():
    vaihtoehdot = {'kyllä': True, 'ei': False}
    while True:
        vastaus = input('Pelataanko vielä (%s)? ' % '/'.join(vaihtoehdot))
        try:
            return vaihtoehdot[vastaus]
        except KeyError:
            continue

Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta