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
raw_input palauttaa merkkijonon. Et voi onnistuneesti verrata merkkijonoa kokonaislukuun. Niinpä käytä int(arvaus) -muunnosta ennen vertailua kokonaislukuun.
Jos käytät Python 3:a, ei pitäisi käyttää raw_inputia vaan inputia.
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
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
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.
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.
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
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()
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ä.
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
Aihe on jo aika vanha, joten et voi enää vastata siihen.