Gå till innehållet

Projekt – Sten, Sax, Påse (CLI), i små steg

Mål

  • Träna input() och print()
  • Slump med random.choice
  • If-satser, logiska uttryck och while-loop
  • Enkel poängräkning

Tips: Kör efter varje steg i denna sida. Om något krånglar, kör igen med små ändringar.

Så använder du denna sida

  • Varje “Steg” har en liten kodbit. Kopiera, spara, kör.
  • Testa förslag på inmatningar (t.ex. STEN, " påse ", felstavningar) och se vad som händer.
  • Om du fastnar: se “Felsökning” längst ner eller sidan “Felsökning” i menyn.

Steg 1: läs in ett val och skriv ut det

Kod:

Python
1
2
3
4
val = ("sten", "sax", "påse")

s = input("Välj sten/sax/påse: ")
print("Du valde:", s)

Rad för rad:

  • val = ("sten", "sax", "påse") – en tupel med giltiga val. (Som en liten lista som inte ska ändras.)
  • s = input(...) – frågar användaren och sparar texten i variabeln s.
  • print("Du valde:", s) – visar tillbaka vad användaren skrev.

Övning: låt eleven ändra prompten i input() och testa olika inmatningar.

Förväntad utdata (exempel):

Text Only
Välj sten/sax/påse: sten
Du valde: sten

Steg 2: städa inmatningen (småfel tolereras)

Kod:

Python
1
2
3
4
val = ("sten", "sax", "påse")

s = input("Välj sten/sax/påse: ").lower().strip()
print("Du valde:", s)

Rad för rad:

  • .lower() – gör all text till små bokstäver (tål STEN/Sax/…).
  • .strip() – tar bort mellanslag i början/slutet (tål ” sten ”).

Övning: skriv in SAX och se att det blir sax.

Steg 3: kontrollera att valet är giltigt

Kod:

Python
1
2
3
4
5
6
7
val = ("sten", "sax", "påse")

s = input("Välj sten/sax/påse: ").lower().strip()
if s not in val:
    print("Fel val! Välj sten, sax eller påse.")
else:
    print("Du valde:", s)

Rad för rad:

  • if s not in val: – kollar om texten inte finns i vår tupel.
  • print("Fel val!...") – ger tydlig felinfo.
  • else: – körs bara om valet var giltigt.

Steg 4: låt datorn slumpa ett val

Kod:

Python
import random

val = ("sten", "sax", "påse")

s = input("Välj sten/sax/påse: ").lower().strip()
if s not in val:
    print("Fel val! Välj sten, sax eller påse.")
else:
    d = random.choice(val)
    print("Datorn valde:", d)

Rad för rad:

  • import random – ger tillgång till slumpfunktioner.
  • random.choice(val) – väljer ett slumpmässigt element ur val.

Steg 5: avgör vinnaren (en runda)

Kod:

Python
import random

val = ("sten", "sax", "påse")

s = input("Välj sten/sax/påse: ").lower().strip()
if s not in val:
    print("Fel val! Välj sten, sax eller påse.")
else:
    d = random.choice(val)
    print("Datorn valde:", d)

    if s == d:
        print("Oavgjort!")
    elif (s == "sten" and d == "sax") or (s == "sax" and d == "påse") or (s == "påse" and d == "sten"):
        print("Du vinner!")
    else:
        print("Datorn vinner!")

Rad för rad:

  • if s == d: – samma val ⇒ ingen vinner.
  • elif (...) – tre vinnarsituationer för spelaren i ett logiskt uttryck.
  • else: – alla andra fall ⇒ datorn vinner.

Tips: låt eleverna skriva ut varför man vann: “sten krossar sax”, “sax klipper påse”, “påse täcker sten”.

Steg 6: spela många rundor tills man vill sluta

Kod:

Python
import random

val = ("sten", "sax", "påse")

while True:
    s = input("Välj sten/sax/påse eller q för att sluta: ").lower().strip()

    if s == "q":
        print("Tack för att du spelade!")
        break

    if s not in val:
        print("Fel val! Välj sten, sax eller påse.")
        continue

    d = random.choice(val)
    print("Datorn valde:", d)

    if s == d:
        print("Oavgjort!")
    elif (s == "sten" and d == "sax") or (s == "sax" and d == "påse") or (s == "påse" and d == "sten"):
        print("Du vinner!")
    else:
        print("Datorn vinner!")

Rad för rad:

  • while True: – en oändlig loop tills vi bryter.
  • if s == "q": break – användaren kan avsluta.
  • continue – hoppa till nästa varv vid felaktig inmatning.

Exempel på körning:

Text Only
1
2
3
4
5
6
7
8
Välj sten/sax/påse eller q för att sluta: sax
Datorn valde: påse
Du vinner!
Välj sten/sax/påse eller q för att sluta: sten
Datorn valde: sten
Oavgjort!
Välj sten/sax/påse eller q för att sluta: q
Tack för att du spelade!

Steg 7: lägg till poängräkning

Kod:

Python
import random

val = ("sten", "sax", "påse")
poang_spelare = 0
poang_dator = 0

while True:
    s = input("Välj sten/sax/påse eller q för att sluta: ").lower().strip()

    if s == "q":
        break
    if s not in val:
        print("Fel val! Välj sten, sax eller påse.")
        continue

    d = random.choice(val)
    print("Datorn valde:", d)

    if s == d:
        print("Oavgjort!")
    elif (s == "sten" and d == "sax") or (s == "sax" and d == "påse") or (s == "påse" and d == "sten"):
        print("Du vinner!")
        poang_spelare += 1
    else:
        print("Datorn vinner!")
        poang_dator += 1

    print(f"Ställning: Du {poang_spelare} – Dator {poang_dator}\n")

print("Tack för matchen!")

Rad för rad:

  • poang_spelare = 0 / poang_dator = 0 – startpoäng.
  • += 1 – öka poäng för vinnaren.
  • f"Ställning: ..." – f-sträng för snygg utskrift.

Steg 8: visa ASCII-bilder för valen

Kod (läggs ovanför loopen och används inuti loopen vid utskrift):

Python
bilder = {
    "sten": """
    _______
---'  ____/
     / __/
    / /_
   /___/
    """,
    "sax": """
    _______
---'  ___ )
     (___ )
     (___ )
      (__ )
---.__(___)
    """,
    "påse": """
     _______
---'   ____)____
          ______)
          _______)
         _______)
---.__________)
    """,
}

Användning (inuti loopen, efter att du vet s och d):

Python
1
2
3
4
print("Du valde:")
print(bilder[s])
print("Datorn valde:")
print(bilder[d])

Rad för rad:

  • bilder = { ... } – en ordbok (dictionary) som kopplar ordet till en ASCII-sträng.
  • bilder[s] – hämta rätt bild utifrån nyckeln.

Tips: ASCII-bilder kan “glida” om man blandar tabbar och mellanslag. Be eleverna att bara använda mellanslag.


Steg 9: “först till N” (bästa av)

Kod (idé):

Python
vinn_poang = 3  # ändra till 5 för “bästa av 9” (först till 5)

poang_spelare = 0
poang_dator = 0

while poang_spelare < vinn_poang and poang_dator < vinn_poang:
    # samma runda-logik som tidigare ...
    # uppdatera poäng
    # skriv ut ställning

if poang_spelare == vinn_poang:
    print("Grattis! Du vann matchen.")
else:
    print("Datorn vann matchen.")

Rad för rad:

  • while poang_spelare < vinn_poang and poang_dator < vinn_poang: – loopen fortsätter tills någon nått målet.
  • Efter loopen avgör vi vem som nådde gränsen.

Kopiera & kör: Bästa av 3 (minimal kod)

Python
import random

val = ("sten", "sax", "påse")
poang_spelare = 0
poang_dator = 0
vinn_poang = 3

while poang_spelare < vinn_poang and poang_dator < vinn_poang:
    s = input("Välj sten/sax/påse eller q för att sluta: ").lower().strip()
    if s == "q":
        print("Du avbröt matchen.")
        break
    if s not in val:
        print("Fel val! Välj sten, sax eller påse.")
        continue
    d = random.choice(val)
    if s == d:
        print("Oavgjort!")
    elif (s == "sten" and d == "sax") or (s == "sax" and d == "påse") or (s == "påse" and d == "sten"):
        print("Du vinner rundan!")
        poang_spelare += 1
    else:
        print("Datorn vinner rundan!")
        poang_dator += 1
    print(f"Ställning: Du {poang_spelare} – Dator {poang_dator}")

if poang_spelare >= vinn_poang or poang_dator >= vinn_poang:
    print("Grattis! Du vann matchen." if poang_spelare > poang_dator else "Datorn vann matchen.")

Samlad lösning med kommentarer (rad för rad)

Klistra in detta som facit eller stödkommentarer:

Python
import random  # 1) Ger tillgång till slumpfunktioner som random.choice

val = ("sten", "sax", "påse")  # 2) Giltiga val i spelet – tuple ändras inte

# 3) Poäng räknas över flera rundor
poang_spelare = 0
poang_dator = 0

# 4) (Valfritt) ASCII-bilder för att göra det roligare
bilder = {
    "sten": """
    _______
---'  ____/
     / __/
    / /_
   /___/
    """,
    "sax": """
    _______
---'  ___ )
     (___ )
     (___ )
      (__ )
---.__(___)
    """,
    "påse": """
     _______
---'   ____)____
          ______)
          _______)
         _______)
---.__________)
    """,
}

# 5) Välj matchformat – först till N poäng
vinn_poang = 3

# 6) Spelloop: kör nya rundor tills någon nått målet
while poang_spelare < vinn_poang and poang_dator < vinn_poang:
    # 7) Läs in val och städa texten
    s = input("Välj sten/sax/påse eller q för att sluta: ").lower().strip()

    # 8) Avsluta om spelaren skriver q
    if s == "q":
        print("Du avbröt matchen.")
        break

    # 9) Kontrollera giltigt val
    if s not in val:
        print("Fel val! Välj sten, sax eller påse.")
        continue  # hoppa till nästa runda

    # 10) Datorn väljer slumpmässigt
    d = random.choice(val)

    # 11) Visa bådas val med ASCII (kan kommenteras bort)
    print("Du valde:")
    print(bilder[s])
    print("Datorn valde:")
    print(bilder[d])

    # 12) Avgör rundan
    if s == d:
        print("Oavgjort!")
    elif (s == "sten" and d == "sax") or (s == "sax" and d == "påse") or (s == "påse" and d == "sten"):
        print("Du vinner rundan!")
        poang_spelare += 1  # 13) Öka spelarens poäng
    else:
        print("Datorn vinner rundan!")
        poang_dator += 1  # 14) Öka datorns poäng

    # 15) Visa ställningen efter varje runda
    print(f"Ställning: Du {poang_spelare} – Dator {poang_dator}\n")

# 16) Matchresultat om ingen avbröt
if poang_spelare >= vinn_poang or poang_dator >= vinn_poang:
    if poang_spelare > poang_dator:
        print("Grattis! Du vann matchen.")
    else:
        print("Datorn vann matchen. Bra kämpat!")

print("Tack för matchen!")

Utmaningar (progression)

  1. tillåt flera stavningar Skapa en “översättning”:

    Python
    1
    2
    3
    alias = {"pase": "påse", "saxen": "sax", "rock": "sten", "p": "påse", "s": "sten", "x": "sax"}
    s = input(...).lower().strip()
    s = alias.get(s, s)  # översätt om möjligt
    
    2. förklara vinsten Lägg till en text som beskriver varför: orsak = {("sten","sax"):"Sten krossar sax", ("sax","påse"):"Sax klipper påse", ("påse","sten"):"Påse täcker sten"} 3. turnering Läs in flera spelarnamn i en lista och låt turordningen rotera. 4. poängbonus 2 poäng vid tre raka vinster i rad.

Felsökning (checklista för elever)

  • Tom inmatning? Använd .strip() och kontrollera längden: if not s: continue.
  • Felstavning av “påse”? Lägg till alias/normalisering (se utmaning 1).
  • ASCII-bilder hoppar? Använd endast mellanslag i trippelcitat, undvik tabbar.
  • Oändlig loop? Kontrollera break vid s == "q" och villkoret i “först till N”.

Lärartips

  • Låt eleverna köra efter varje litet steg innan ni går vidare.
  • Använd “förutsäg resultatet” innan körning: vad händer om s == "sax" och d == "påse"?
  • Låt dem skriva egna testfall: mata in STEN, påse, q, felord.