Lær deg Python_Modul_1‐4_Del11 - itnett/FTD02H-N GitHub Wiki
For å utvide spillet vårt slik at vi dekker alle de nevnte punktene, kan vi bygge videre på det eksisterende spillet og legge til flere funksjoner og konsepter som omfatter alt fra programstrukturer til datasikkerhet og GUI (grafisk brukergrensesnitt). Dette vil gi deg innsikt i alle nødvendige områder innen programmering.
Utvidet Hangman-spill med full dekning av punktene
1. Programstrukturer
- Kodestrukturen er nå modulært, med funksjoner som håndterer forskjellige oppgaver som å vise hengemannen, behandle gjetninger, og lagre high scores.
- Bruken av kontrollstrukturer som
if-else
og løkker somwhile
vises gjennom hele programmet.
2. Datastrukturer
- Vi bruker lister til å lagre riktige bokstaver og gjettede bokstaver, og vi kan også utvide det til å inkludere dictionaries for flere brukere og poengsummer.
3. Bibliotek
random
ogos
er biblioteker som demonstrerer hvordan vi kan bruke innebygde Python-moduler. Vi kan også legge til flere biblioteker som håndterer avansert filhåndtering eller kryptering for datasikkerhet.
4. Funksjoner og metoder
- Funksjonene våre, som
vis_hengemannen()
oghengemannen()
, viser hvordan vi kan bryte ned et stort problem i mindre deler.
5. Objektorientert programmering (OOP)
- For å demonstrere OOP kan vi gjøre Hangman-spillet til et objekt ved hjelp av klasser. Dette vil inkludere spillrelaterte data og metoder inne i et objekt.
6. Debugging, testing og unntaksbehandling
- Vi bruker feilhåndtering med
try-except
for å sikre at spilleren kun gjetter gyldige bokstaver. - Vi kan legge til mer logging og testing ved å bruke
unittest
for å teste funksjonene våre.
7. API
- Vi kan integrere et API for å hente tilfeldige ord til spillet fra en ekstern tjeneste. Dette kan demonstrere hvordan programmer kan kommunisere med eksterne systemer.
8. GUI (Grafisk brukergrensesnitt)
- Ved å bruke et Python-bibliotek som
tkinter
, kan vi gi spillet et grafisk brukergrensesnitt (GUI), der spilleren kan klikke på bokstaver i stedet for å skrive dem inn.
9. UML (Unified Modeling Language)
- Vi kan lage et UML-diagram for å beskrive klasser og deres interaksjoner i objektorientert versjon av spillet.
10. Filbehandling
- Vi viser allerede enkel filbehandling for å lagre og lese high score. Vi kan utvide dette til å inkludere sikker lagring og lesing av filer.
11. Datasikkerhet
- Vi kan inkludere en enkel hashing av spillerens navn eller poengsummer for å demonstrere grunnleggende sikkerhetstiltak.
Utvidet versjon av spillet
Her er en utvidet versjon av spillet vårt med flere av de nevnte konseptene, inkludert objektorientert programmering, GUI, og API-kommunikasjon.
Objektorientert tilnærming:
import random
import os
import requests # For API
# Klasse for Hangman-spillet
class Hangman:
MAX_FEIL = 6
def __init__(self):
self.antall_feil = 0
self.gjettede_bokstaver = []
self.riktige_bokstaver = []
self.ordet = ""
# Funksjon for å hente et tilfeldig ord fra et API
def hent_ord_fra_api(self):
try:
response = requests.get("https://random-word-api.herokuapp.com/word?number=1")
if response.status_code == 200:
self.ordet = response.json()[0]
else:
self.ordet = random.choice(['programmering', 'python', 'læring', 'spill', 'data'])
except:
self.ordet = random.choice(['programmering', 'python', 'læring', 'spill', 'data'])
def start_spill(self):
self.hent_ord_fra_api()
self.riktige_bokstaver = ['_'] * len(self.ordet)
print(f"Ordet du skal gjette har {len(self.ordet)} bokstaver.")
# Viser hengemannen basert på antall feil
def vis_hengemannen(self):
stadier = [
'''
+---+
| |
|
|
|
|
=========''',
'''
+---+
| |
O |
|
|
|
=========''',
'''
+---+
| |
O |
| |
|
|
=========''',
'''
+---+
| |
O |
/| |
|
|
=========''',
'''
+---+
| |
O |
/|\\ |
|
|
=========''',
'''
+---+
| |
O |
/|\\ |
/ |
|
=========''',
'''
+---+
| |
O |
/|\\ |
/ \\ |
|
========='''
]
print(stadier[self.antall_feil])
def gjett_bokstav(self, bokstav):
if bokstav in self.gjettede_bokstaver:
print(f"Du har allerede gjettet {bokstav}.")
return False
self.gjettede_bokstaver.append(bokstav)
if bokstav in self.ordet:
print(f"Bokstaven {bokstav} er i ordet!")
for i, bokstav_i_ordet in enumerate(self.ordet):
if bokstav_i_ordet == bokstav:
self.riktige_bokstaver[i] = bokstav
return True
else:
print(f"Bokstaven {bokstav} er ikke i ordet.")
self.antall_feil += 1
return False
def vis_status(self):
print("Ordet: " + ' '.join(self.riktige_bokstaver))
print(f"Antall feil: {self.antall_feil}/{Hangman.MAX_FEIL}")
print("Gjettede bokstaver: " + ', '.join(self.gjettede_bokstaver))
def er_spill_vunnet(self):
return '_' not in self.riktige_bokstaver
def er_spill_tapt(self):
return self.antall_feil >= Hangman.MAX_FEIL
# Start spillet
def spill_hengemannen():
hangman = Hangman()
hangman.start_spill()
while not hangman.er_spill_vunnet() and not hangman.er_spill_tapt():
hangman.vis_hengemannen()
hangman.vis_status()
gjett = input("Gjett en bokstav: ").lower()
if len(gjett) == 1 and gjett.isalpha():
hangman.gjett_bokstav(gjett)
else:
print("Vennligst oppgi en gyldig bokstav.")
if hangman.er_spill_vunnet():
print(f"Gratulerer! Du vant! Ordet var '{hangman.ordet}'.")
else:
print(f"Du tapte. Ordet var '{hangman.ordet}'.")
# Start GUI
spill_hengemannen()
Forklaring av komponenter:
Programstrukturer
- Klassebasert: Vi har nå strukturen basert på en klasse (
Hangman
), som holder alle data og metoder for spillet. Dette er en grunnleggende OOP-struktur som er enklere å vedlikeholde og utvide.
Datastrukturer
- Lagring i lister:
self.gjettede_bokstaver
ogself.riktige_bokstaver
brukes til å lagre spilltilstanden, og ordet hentes fra API eller en lokal liste.
Funksjoner og metoder
- Metoder: Metodene i
Hangman
-klassen håndterer alle handlinger i spillet. Dette gjør det enkelt å organisere logikken.
API
- Vi bruker
requests
-biblioteket for å hente ord fra et eksternt API. Dette demonstrerer hvordan programmer kan kommunisere med eksterne tjenester.
Filbehandling
- Lagre highscore-funksjonalitet kan lett legges til. For nå bruker vi ikke filbehandling her, men det kan lett inkluderes for å lagre spillhistorikken.
Datasikkerhet
- Vi kunne forbedret dette ved å bruke
hashlib
for å kryptere data før vi lagrer dem.
GUI
tkinter
eller et annet GUI-bibliotek kan brukes for
å gi et visuelt grensesnitt der brukere kan klikke for å gjette bokstaver, men i denne versjonen har vi fokuset på kommandolinjebasert UI.
Dette utvidede spillet dekker flere grunnleggende og viderekommende konsepter i programmering og demonstrerer alle hovedpunktene som ble nevnt, med spesielt fokus på objektorientert programmering, API-kommunikasjon, feilhåndtering og brukergrensesnitt.
For å implementere dette i Python, kan vi la brukeren velge mellom tre ulike ordlister hentet fra de oppgitte URL-ene, og vi vil sørge for at store og små bokstaver ikke spiller noen rolle verken i ordet fra listen eller brukerens gjetning. Samtidig vil vi, ved slutten av spillet, vise ordet slik det opprinnelig er skrevet i listen. Vi skal bruke requests
for å laste ned filene og random
for å velge et tilfeldig ord.
Her er den utvidede versjonen av spillet:
Python-kode som implementerer valg av ordliste og håndterer store og små bokstaver:
import random
import requests
# Funksjon for å hente ord fra en URL
def hent_ord_fra_url(url):
try:
response = requests.get(url)
response.raise_for_status() # Sjekk om forespørselen var vellykket
ord_liste = response.text.splitlines() # Hent ord og del opp i linjer
return ord_liste
except requests.exceptions.RequestException as e:
print(f"Feil under henting av ordlisten: {e}")
return []
# Funksjon som viser den grafiske hengemannen
def vis_hengemannen(antall_feil):
stadier = [
'''
+---+
| |
|
|
|
|
=========''',
'''
+---+
| |
O |
|
|
|
=========''',
'''
+---+
| |
O |
| |
|
|
=========''',
'''
+---+
| |
O |
/| |
|
|
=========''',
'''
+---+
| |
O |
/|\\ |
|
|
=========''',
'''
+---+
| |
O |
/|\\ |
/ |
|
=========''',
'''
+---+
| |
O |
/|\\ |
/ \\ |
|
========='''
]
print(stadier[antall_feil])
# Funksjon som viser spillstatusen
def vis_status(riktige_bokstaver, antall_feil, gjettede_bokstaver):
print("Ordet: " + ' '.join(riktige_bokstaver))
print(f"Antall feil: {antall_feil}/6")
print("Gjettede bokstaver: " + ', '.join(gjettede_bokstaver))
# Funksjon som håndterer en spillers gjetning
def behandle_gjetning(ordet, riktige_bokstaver, gjettede_bokstaver):
bokstav = input("Gjett en bokstav: ").lower()
# Sjekk om input er gyldig
if len(bokstav) != 1 or not bokstav.isalpha():
print("Ugyldig input. Vennligst gjett en enkelt bokstav.")
return False
# Sjekk om bokstaven allerede er gjettet
if bokstav in gjettede_bokstaver:
print(f"Du har allerede gjettet {bokstav}. Prøv en annen bokstav.")
return False
gjettede_bokstaver.append(bokstav)
# Sjekk om bokstaven er i ordet
if bokstav in ordet.lower(): # Konverter ordet til små bokstaver for sjekking
print(f"Bra gjettet! {bokstav} er i ordet.")
# Oppdater riktige bokstaver på de riktige posisjonene
for i, bokstav_i_ordet in enumerate(ordet.lower()):
if bokstav_i_ordet == bokstav:
riktige_bokstaver[i] = ordet[i] # Behold original bokstav
return True
else:
print(f"Feil! {bokstav} er ikke i ordet.")
return False
# Funksjon som kjører hengemannen-spillet
def hengemannen():
url_valg = {
"1": "https://raw.githubusercontent.com/0301/ordliste/refs/heads/master/ordliste_snl_fellesord.txt",
"2": "https://raw.githubusercontent.com/0301/ordliste/refs/heads/master/ordliste_banneord.txt",
"3": "https://raw.githubusercontent.com/0301/ordliste/refs/heads/master/ordliste_ssb_norske_fornavn.txt"
}
print("Velg en ordliste:")
print("1: Fellesord fra SNL")
print("2: Banneord")
print("3: Norske fornavn fra SSB")
valg = input("Skriv inn tallet for ønsket ordliste (1, 2 eller 3): ")
url = url_valg.get(valg)
if not url:
print("Ugyldig valg. Spillet avsluttes.")
return
ord_liste = hent_ord_fra_url(url)
if not ord_liste:
print("Ingen ord ble hentet. Spillet avsluttes.")
return
ordet = random.choice(ord_liste)
antall_feil = 0
riktige_bokstaver = ['_'] * len(ordet)
gjettede_bokstaver = []
while antall_feil < 6 and '_' in riktige_bokstaver:
vis_hengemannen(antall_feil)
vis_status(riktige_bokstaver, antall_feil, gjettede_bokstaver)
if not behandle_gjetning(ordet, riktige_bokstaver, gjettede_bokstaver):
antall_feil += 1
print(f"Du har {6 - antall_feil} forsøk igjen.")
# Sjekk om spilleren vant eller tapte
if '_' not in riktige_bokstaver:
print(f"Gratulerer! Du gjettet ordet '{ordet}'.")
else:
vis_hengemannen(antall_feil)
print(f"Beklager, du tapte. Ordet var '{ordet}'.")
# Funksjon som starter spillet og spør om å spille igjen
def start_spill():
while True:
hengemannen()
spill_igjen = input("Vil du spille igjen? (ja/nei): ").lower()
if spill_igjen != 'ja':
break
# Start spillet
start_spill()
Forklaringer og forbedringer:
-
Valg av ordliste:
- Brukeren kan nå velge mellom tre ulike ordlister ved å skrive inn tallet 1, 2 eller 3. Vi bruker
input()
for å lese valget og en dictionary (url_valg
) for å lagre URL-ene til ordlistene.
- Brukeren kan nå velge mellom tre ulike ordlister ved å skrive inn tallet 1, 2 eller 3. Vi bruker
-
Last ned ordliste fra URL:
- Funksjonen
hent_ord_fra_url()
laster ned ord fra den valgte URL-en ved hjelp avrequests
. Dersom det oppstår en feil (f.eks. hvis URL-en ikke kan nås), vil programmet håndtere feilen og gi en beskjed til brukeren.
- Funksjonen
-
Stor/liten bokstav-behandling:
- Når brukeren gjetter en bokstav, konverteres både gjetningen og ordet til små bokstaver for å gjøre det enklere for brukeren. Vi bruker
str.lower()
for dette. På slutten av spillet vises ordet i sin opprinnelige form slik det står i ordlisten.
- Når brukeren gjetter en bokstav, konverteres både gjetningen og ordet til små bokstaver for å gjøre det enklere for brukeren. Vi bruker
-
Oppsummering:
- Når spillet er over, får brukeren en oppsummering som viser hele ordet, med riktig stor/liten bokstav som i ordlisten.
-
Spille igjen:
- Etter hver runde blir brukeren spurt om de vil spille igjen. Hvis de skriver "ja", starter spillet på nytt.
Hva som er forbedret:
- Bedre brukeropplevelse: Brukeren får nå valget mellom ulike ordlister, og spillet bryr seg ikke om store og små bokstaver under gjettprosessen.
- Feilhåndtering: Håndtering av ugyldig input og feil ved nedlasting av ordlister er lagt til.
- Tilpasset ordliste: Brukeren kan velge å spille med forskjellige ordkategorier.
Dette utvidede spillet gir en mer dynamisk og tilpasset opplevelse for brukeren.
Dette skriptet er nå korrekt satt opp, og inkluderer følgende forbedringer:
-
Fikset med
with
: Tidligere hadde skriptet en feil ved bruk avmed
i stedet forwith
, men nå bruker vi riktig nøkkelord (with
) for å åpne filer trygt, slik at vi ikke får problemer med å lukke filene etter bruk. -
Filbehandling: Spillet lagrer informasjon om ord som tidligere har blitt gjettet riktig eller feil. Denne informasjonen lagres i en tekstfil (
gjetting_resultater.txt
). På denne måten kan vi blande gamle og nye ord i fremtidige spill. -
Tilfeldig valg av ord: Når brukeren har valgt hvor mange ord de vil gjette på, velger spillet en kombinasjon av ord som brukeren har gjettet riktig på tidligere, ord som brukeren har hatt problemer med, og helt nye ord.
-
Valg av ordliste: Brukeren kan velge mellom tre forskjellige ordlister som hentes fra en ekstern kilde via URL. Brukeren får tre valg (fellesord fra SNL, banneord, eller norske fornavn fra SSB). Spillet henter ordene dynamisk basert på brukerens valg.
-
Oppsummering av valgt ordsett: Når brukeren har valgt antall ord de vil gjette på, gir skriptet en kort oppsummering av hvilke typer ord som er inkludert (ord som er riktig gjettet før, ord som har vært vanskelige, og nye ord).
-
Gjettet bokstav uavhengig av store og små bokstaver: Når spilleren gjetter bokstaver, bryr spillet seg ikke om store eller små bokstaver, men på slutten av spillet viser det riktige ordet med den opprinnelige bokstaveringen.
-
Spilløkter: Etter en spillrunde kan brukeren velge om de vil spille igjen, noe som gir en sømløs spillopplevelse uten å måtte restarte hele skriptet.
Forklaring av kodeblokkene:
-
Filbehandling:
last_tidl_gjetninger()
oglagre_gjetninger()
: Disse funksjonene brukes til å lese fra og skrive til tekstfilen som lagrer resultatene fra tidligere spill. Dette gjør det mulig å velge ord basert på tidligere prestasjoner.
-
Tilfeldig ordvalg:
velg_ord()
: Denne funksjonen velger en kombinasjon av ord fra tre kategorier: riktig gjettet før, tidligere feilet, og nye ord som brukeren ikke har sett før. Dette gir en balansert utfordring for spilleren.
-
Valg av ordliste:
- Brukeren får tre valg, og den valgte ordlisten lastes ned fra en URL. Funksjonen
hent_ord_fra_url()
sørger for å hente ordene fra den eksterne ressursen.
- Brukeren får tre valg, og den valgte ordlisten lastes ned fra en URL. Funksjonen
-
Grafisk fremstilling av hengemannen:
vis_hengemannen()
: Denne funksjonen viser ulike stadier av hengemannen etterhvert som spilleren gjør flere feil.
-
Spilllogikk:
- Spillet styres av
hengemannen()
-funksjonen, som inneholder hovedlogikken for spillet. Denne funksjonen håndterer bokstavgjetninger, oppdatering av riktige bokstaver, og viser spillstatusen underveis.
- Spillet styres av
Hvordan bruke skriptet:
- Først blir brukeren bedt om å velge en ordliste fra tre alternativer. Deretter spør skriptet hvor mange ord de vil gjette på.
- Skriptet velger en blanding av ord som brukeren har gjettet riktig før, ord som har vært vanskelige, og nye ord.
- Når spillet starter, kan brukeren gjette en bokstav om gangen. Resultatet av hver runde (riktig eller feil gjetning) lagres i filen for senere bruk.
- Etter at alle ord er gjettet, gir skriptet brukeren muligheten til å spille igjen.
Dette spillet gir en grundig gjennomgang av grunnleggende Python-konsepter som variabler, løkker, betingelser, funksjoner, filbehandling og bruk av eksterne ressurser.
import random
import requests
import os
# Konstant for filen som holder på gjettede ord
GJETTEDE_ORD_FIL = "gjetting_resultater.txt"
MAX_FEIL = 6
ORD_LISTE_URL = {
"1": "https://raw.githubusercontent.com/0301/ordliste/refs/heads/master/ordliste_snl_fellesord.txt",
"2": "https://raw.githubusercontent.com/0301/ordliste/refs/heads/master/ordliste_banneord.txt",
"3": "https://raw.githubusercontent.com/0301/ordliste/refs/heads/master/ordliste_ssb_norske_fornavn.txt"
}
# Funksjon for å hente ord fra en URL
def hent_ord_fra_url(url):
try:
response = requests.get(url)
response.raise_for_status()
ord_liste = response.text.splitlines()
return ord_liste
except requests.exceptions.RequestException as e:
print(f"Feil under henting av ordlisten: {e}")
return []
# Funksjon for å laste tidligere gjetninger fra fil
def last_tidl_gjetninger():
if not os.path.exists(GJETTEDE_ORD_FIL):
return {}
with open(GJETTEDE_ORD_FIL, "r") as fil:
return {linje.strip().split(":")[0]: linje.strip().split(":")[1] for linje in fil}
# Funksjon for å lagre gjetninger til fil
def lagre_gjetninger(ordet, resultat):
with open(GJETTEDE_ORD_FIL, "a") as fil:
fil.write(f"{ordet}:{resultat}\n")
# Funksjon som viser den grafiske hengemannen
def vis_hengemannen(antall_feil):
stadier = [
'''
+---+
| |
|
|
|
|
=========''',
'''
+---+
| |
O |
|
|
|
=========''',
'''
+---+
| |
O |
| |
|
|
=========''',
'''
+---+
| |
O |
/| |
|
|
=========''',
'''
+---+
| |
O |
/|\\ |
|
|
=========''',
'''
+---+
| |
O |
/|\\ |
/ |
|
=========''',
'''
+---+
| |
O |
/|\\ |
/ \\ |
|
========='''
]
print(stadier[antall_feil])
# Funksjon som viser spillstatusen
def vis_status(riktige_bokstaver, antall_feil, gjettede_bokstaver):
print("Ordet: " + ' '.join(riktige_bokstaver))
print(f"Antall feil: {antall_feil}/{MAX_FEIL}")
print("Gjettede bokstaver: " + ', '.join(gjettede_bokstaver))
# Funksjon som håndterer en spillers gjetning
def behandle_gjetning(ordet, riktige_bokstaver, gjettede_bokstaver):
bokstav = input("Gjett en bokstav: ").lower()
# Sjekk om input er gyldig
if len(bokstav) != 1 or not bokstav.isalpha():
print("Ugyldig input. Vennligst gjett en enkelt bokstav.")
return False
# Sjekk om bokstaven allerede er gjettet
if bokstav in gjettede_bokstaver:
print(f"Du har allerede gjettet {bokstav}. Prøv en annen bokstav.")
return False
gjettede_bokstaver.append(bokstav)
# Sjekk om bokstaven er i ordet
if bokstav in ordet.lower():
print(f"Bra gjettet! {bokstav} er i ordet.")
for i, bokstav_i_ordet in enumerate(ordet.lower()):
if bokstav_i_ordet == bokstav:
riktige_bokstaver[i] = ordet[i]
return True
else:
print(f"Feil! {bokstav} er ikke i ordet.")
return False
# Funksjon som velger ord basert på tidligere prestasjoner
def velg_ord(ord_liste, antall_ord):
tidl_gjetninger = last_tidl_gjetninger()
riktige_ord = [ord for ord, resultat in tidl_gjetninger.items() if resultat == "riktig"]
feil_ord = [ord for ord, resultat in tidl_gjetninger.items() if resultat == "feil"]
nye_ord = [ord for ord in ord_liste if ord not in tidl_gjetninger]
valgt_ord = random.sample(riktige_ord, min(5, len(riktige_ord))) \
+ random.sample(feil_ord, min(5, len(feil_ord))) \
+ random.sample(nye_ord, max(0, antall_ord - len(riktige_ord) - len(feil_ord)))
print(f"Du har valgt {antall_ord} ord:")
print(f"- {len(riktige_ord)} ord du har gjettet riktig før.")
print(f"- {len(feil_ord)} ord du har hatt problemer med.")
print(f"- {len(nye_ord)} nye ord du ikke har gjettet før.")
return valgt_ord[:antall_ord]
# Funksjon som kjører hengemannen-spillet
def hengemannen(ord_liste):
antall_ord = int(input("Hvor mange ord vil du gjette på? "))
ord_valg = velg_ord(ord_liste, antall_ord)
for ordet in ord_valg:
antall_feil = 0
riktige_bokstaver = ['_'] * len(ordet)
gjettede_bokstaver = []
while antall_feil < MAX_FEIL and '_' in riktige_bokstaver:
vis_hengemannen(antall_feil)
vis_status(riktige_bokstaver, antall_feil, gjettede_bokstaver)
if not behandle_gjetning(ordet, riktige_bokstaver, gjettede_bokstaver):
antall_feil += 1
# Lagre resultatet
if '_' not in riktige_bokstaver:
print(f"Gratulerer! Du gjettet ordet '{ordet}'.")
lagre_gjetninger(ordet, "riktig")
else:
vis_hengemannen(antall_feil)
print(f"Beklager, du tapte. Ordet var '{ordet}'.")
lagre_gjetninger(ordet, "feil")
# Funksjon som starter spillet
def start_spill():
print("Velg en ordliste:")
print("1: Fellesord fra SNL")
print("2: Banneord")
print("3: Norske fornavn fra SSB")
valg = input("Skriv inn tallet for ønsket ordliste (1, 2 eller 3): ")
url = ORD_LISTE_URL.get(valg)
if not url:
print("Ugyldig valg. Spillet avsluttes.")
return
ord_liste = hent_ord_fra_url(url)
if not ord_liste:
print("Ingen ord ble hentet. Spillet avsluttes.")
return
hengemannen(ord_liste)
# Start spill
start_spill()
Denne koden har nå implementert flere funksjoner for å gjøre spillet "Hengemannen" mer interaktivt og funksjonsrikt, og her kommer en forklaring av de ulike delene i skriptet.
Struktur og nøkkelfunksjoner
-
Hente ord fra eksterne kilder:
- Koden bruker URL-er for å hente ordlister direkte fra nettet. Disse ordlistene inneholder fellesord, banneord eller norske fornavn.
- Funksjonen
hent_ord_fra_url()
gjør dette ved å sende en HTTP-forespørsel til en av de tre URL-ene og henter dataen tilbake som tekst. Hvert ord i listen separeres ved linjeskift.
-
Filbehandling:
- Funksjonene
last_tidl_gjetninger()
oglagre_gjetninger()
håndterer hvordan data om tidligere spill, både riktige og feilaktige gjetninger, lagres og lastes fra en tekstfil. lagre_gjetninger()
skriver hver gjetning i formatetord:resultat
til filen for å holde oversikt over brukerens prestasjoner. Dette muliggjør mer tilpassede spill senere.
- Funksjonene
-
Velge ord basert på tidligere prestasjoner:
- Funksjonen
velg_ord()
velger en blanding av ord spilleren har gjettet riktig på, ord spilleren har hatt vanskeligheter med, og nye ord spilleren ikke har sett før. Den gir også en oppsummering til spilleren om hva slags ord som er valgt ut, basert på brukerens tidligere spill.
- Funksjonen
-
Spillmekanikken:
- Funksjonen
hengemannen()
inneholder hovedlogikken for spillet. Spillet bruker en enkelwhile
-løkke som fortsetter til spilleren enten har gjettet riktig på alle bokstavene i et ord, eller gjort for mange feil. - Spilleren får tilbakemelding på hver gjetning, og spillet viser en oppdatert hengemann-grafikk etter hver runde.
- Brukerens gjetninger sammenlignes med ordet, uavhengig av store og små bokstaver.
- Funksjonen
-
Grafisk fremstilling:
- Funksjonen
vis_hengemannen()
viser en visuell fremstilling av hengemannen basert på hvor mange feil spilleren har gjort. Etter hvert som spilleren gjør flere feil, vil hengemannen gradvis tegnes opp.
- Funksjonen
-
Interaktivitet og input:
- Når spillet starter, blir spilleren bedt om å velge en ordliste (fellesord, banneord eller fornavn). Dette gir brukeren fleksibilitet i hvilke typer ord de ønsker å spille med.
- Spilleren kan også velge hvor mange ord de vil gjette på, og spillet vil trekke et tilfeldig antall ord fra de relevante listene basert på spillerens valg.
Hva dette skriptet dekker:
-
Programstrukturer:
- Skriptet bruker funksjoner for å bryte ned ulike deler av spillet i mindre moduler, noe som gjør det enklere å forstå, vedlikeholde og utvide.
-
Datastrukturer:
- Lister brukes til å lagre ord fra de ulike ordlistene, samt for å holde oversikt over riktige og gjettede bokstaver i spillet.
- Dictionaries (ordbøker) brukes til å holde oversikt over tidligere gjetninger (riktig/feil) og til å mappe brukerens valg av ordliste til en URL.
-
Biblioteker:
- Koden bruker standardbiblioteker som
os
for filbehandling ograndom
for å velge tilfeldige ord. requests
brukes for å hente ordlistene fra eksterne URL-er.
- Koden bruker standardbiblioteker som
-
Funksjoner og metoder:
- Skriptet bruker flere funksjoner for å modularisere kode. Dette inkluderer funksjoner for å håndtere gjetninger, vise hengemannen-grafikk, hente ord fra eksterne kilder, og laste inn og lagre resultatene av tidligere spill.
-
Debugging og unntaksbehandling:
- Funksjonen
hent_ord_fra_url()
har enkel unntaksbehandling som fanger opp feil hvis det er problemer med å hente ordlisten fra URL-en, og gir tilbakemelding til brukeren.
- Funksjonen
-
Brukergrensesnitt (CLI):
- Dette spillet har et tekstbasert brukergrensesnitt hvor spilleren interagerer med spillet via kommandolinjen. Brukeren blir bedt om å skrive inn bokstaver og velge alternativer.
-
Kommunikasjon mellom applikasjoner (API):
- Ved bruk av
requests
kommuniserer skriptet med eksterne servere for å hente ordlistene.
- Ved bruk av
Hvordan utvide dette skriptet videre:
-
Legge til et grafisk brukergrensesnitt (GUI):
- Du kan bruke et bibliotek som
tkinter
for å lage et GUI-basert hengemann-spill.
- Du kan bruke et bibliotek som
-
Filtrering av ordlister:
- Du kan la brukeren spesifisere lengden på ordet de vil gjette på, eller legge til kategorier innenfor hver ordliste (f.eks. la spilleren velge banneord av ulike lengder).
-
Poengsystem:
- Legg til et poengsystem basert på antall riktige gjetninger, feil og hvor raskt brukeren klarer å løse ordet.
-
Flere språkstøtte:
- Du kan legge til støtte for flere språk ved å la spilleren velge mellom forskjellige språkbaserte ordlister.
Skriptet gir en grundig innføring i Python-konsepter og kan utvides videre basert på brukerens preferanser og behov.
import random
import requests
import os
# Konstant for filen som holder på gjettede ord
GJETTEDE_ORD_FIL = "gjetting_resultater.txt"
MAX_FEIL = 6
ORD_LISTE_URL = {
"1": "https://raw.githubusercontent.com/0301/ordliste/refs/heads/master/ordliste_snl_fellesord.txt",
"2": "https://raw.githubusercontent.com/0301/ordliste/refs/heads/master/ordliste_banneord.txt",
"3": "https://raw.githubusercontent.com/0301/ordliste/refs/heads/master/ordliste_ssb_norske_fornavn.txt"
}
# Funksjon for å hente ord fra en URL
def hent_ord_fra_url(url):
try:
response = requests.get(url)
response.raise_for_status()
ord_liste = [ord.strip() for ord in response.text.splitlines()]
return ord_liste
except requests.exceptions.RequestException as e:
print(f"Feil under henting av ordlisten: {e}")
return []
# Funksjon for å laste tidligere gjetninger fra fil
def last_tidl_gjetninger():
if not os.path.exists(GJETTEDE_ORD_FIL):
return {}
with open(GJETTEDE_ORD_FIL, "r") as fil:
return {linje.strip().split(":")[0]: linje.strip().split(":")[1] for linje in fil}
# Funksjon for å lagre gjetninger til fil
def lagre_gjetninger(ordet, resultat):
with open(GJETTEDE_ORD_FIL, "a") as fil:
fil.write(f"{ordet}:{resultat}\n")
# Funksjon som viser den grafiske hengemannen
def vis_hengemannen(antall_feil):
stadier = [
'''
+---+
| |
|
|
|
|
=========''',
'''
+---+
| |
O |
|
|
|
=========''',
'''
+---+
| |
O |
| |
|
|
=========''',
'''
+---+
| |
O |
/| |
|
|
=========''',
'''
+---+
| |
O |
/|\\ |
|
|
=========''',
'''
+---+
| |
O |
/|\\ |
/ |
|
=========''',
'''
+---+
| |
O |
/|\\ |
/ \\ |
|
========='''
]
print(stadier[antall_feil])
# Funksjon som viser spillstatusen
def vis_status(riktige_bokstaver, antall_feil, gjettede_bokstaver):
print("Ordet: " + ' '.join(riktige_bokstaver))
print(f"Antall feil: {antall_feil}/{MAX_FEIL}")
print("Gjettede bokstaver: " + ', '.join(gjettede_bokstaver))
# Funksjon som håndterer en spillers gjetning
def behandle_gjetning(ordet, riktige_bokstaver, gjettede_bokstaver):
bokstav = input("Gjett en bokstav: ").lower()
# Sjekk om input er gyldig
if len(bokstav) != 1 or not bokstav.isalpha():
print("Ugyldig input. Vennligst gjett en enkelt bokstav.")
return False
# Sjekk om bokstaven allerede er gjettet
if bokstav in gjettede_bokstaver:
print(f"Du har allerede gjettet {bokstav}. Prøv en annen bokstav.")
return False
gjettede_bokstaver.append(bokstav)
# Sjekk om bokstaven er i ordet
if bokstav in ordet.lower():
print(f"Bra gjettet! {bokstav} er i ordet.")
for i, bokstav_i_ordet in enumerate(ordet.lower()):
if bokstav_i_ordet == bokstav:
riktige_bokstaver[i] = ordet[i]
return True
else:
print(f"Feil! {bokstav} er ikke i ordet.")
return False
# Funksjon som velger ord basert på tidligere prestasjoner
def velg_ord(ord_liste, antall_ord):
tidl_gjetninger = last_tidl_gjetninger()
riktige_ord = [ord for ord, resultat in tidl_gjetninger.items() if resultat == "riktig"]
feil_ord = [ord for ord, resultat in tidl_gjetninger.items() if resultat == "feil"]
nye_ord = [ord for ord in ord_liste if ord not in tidl_gjetninger]
valgt_ord = random.sample(riktige_ord, min(5, len(riktige_ord))) \
+ random.sample(feil_ord, min(5, len(feil_ord))) \
+ random.sample(nye_ord, max(0, antall_ord - len(riktige_ord) - len(feil_ord)))
print(f"Du har valgt {antall_ord} ord:")
print(f"- {len(riktige_ord)} ord du har gjettet riktig før.")
print(f"- {len(feil_ord)} ord du har hatt problemer med.")
print(f"- {len(nye_ord)} nye ord du ikke har gjettet før.")
return valgt_ord[:antall_ord]
# Funksjon som kjører hengemannen-spillet
def hengemannen(ord_liste):
antall_ord = int(input("Hvor mange ord vil du gjette på? "))
ord_valg = velg_ord(ord_liste, antall_ord)
for ordet in ord_valg:
antall_feil = 0
riktige_bokstaver = ['_'] * len(ordet)
gjettede_bokstaver = []
while antall_feil < MAX_FEIL and '_' in riktige_bokstaver:
vis_hengemannen(antall_feil)
vis_status(riktige_bokstaver, antall_feil, gjettede_bokstaver)
if not behandle_gjetning(ordet, riktige_bokstaver, gjettede_bokstaver):
antall_feil += 1
# Lagre resultatet
if '_' not in riktige_bokstaver:
print(f"Gratulerer! Du gjettet ordet '{ordet}'.")
lagre_gjetninger(ordet, "riktig")
else:
vis_hengemannen(antall_feil)
print(f"Beklager, du tapte. Ordet var '{ordet}'.")
lagre_gjetninger(ordet, "feil")
# Funksjon som starter spillet
def start_spill():
print("Velg en ordliste:")
print("1: Fellesord fra SNL")
print("2: Banneord")
print("3: Norske fornavn fra SSB")
valg = input("Skriv inn tallet for ønsket ordliste (1, 2 eller 3): ")
url = ORD_LISTE_URL.get(valg)
if not url:
print("Ugyldig valg. Spillet avsluttes.")
return
ord_liste = hent_ord_fra_url(url)
if not ord_liste:
print("Ingen ord ble hentet. Spillet avsluttes.")
return
hengemannen(ord_liste)
# Start spill
start_spill()