Yatzy 🎲

Ett terminalbaserat Yatzyspel byggt i Python.

🎯 Syfte och mål

Jag ville öva på Python och lär mig bäst genom att ha konkreta projekt att jobba med. Vid tillfället hade jag snöat in mig på Yatzy och tänkte att det verkade som ett görbart projekt.

🤔 Utmaningar och lösningar

Att bygga ett spel

Jag hade aldrig tidigare byggt ett spel så jag visste inte om det fanns något speciellt “speltänk” att förhålla sig till. Jag tänkte dock att en enda stor loop nog skulle passa för denna typ av spel.

Genom att bygga hela spelet som en stor loop var det enkelt att hålla koll på vems tur det var och hur många rundor som hade körts.

För varje runda kunde alla spelare loopas igenom, och för varje spelare kunde jag hålla koll på

  • hur många kast spelaren hade gjort
  • vilka tärningar som en spelare hade valt att spara
  • hur många poäng spelaren fick från rundan.

Tärningar

Något som inte var kritiskt för spelet i sig men som gjorde det mer visuellt tilltalade var hur tärningarna visades på skärmen. Till en början skrev jag bara ut siffrorna som 123456 men efter ett tag ville jag göra något roligare.

Jag testade lite olika idéer och landade i att jag ville få det att se ut så här:

| ..... | 2.... | 3.... | 4...4 | 5...5 | 6...6 |
| ..1.. | ..... | ..3.. | ..... | ..5.. | 6...6 |
| ..... | ....2 | ....3 | 4...4 | 5...5 | 6...6 |

Utmaningen låg i hur jag skulle skriva ut ovanstående i terminalen eftersom att jag bara kan skriva ut en rad i taget (tänkte annars att jag ville skriva ut en hel tärning i taget).

Jag klurade en stund på problemet och landade sedan i följande lösning:

def print_dice(self, dice):

  number = {
    "1": {0: " ..... ", 1: " ..1.. ", 2: " ..... "},
    "2": {0: " 2.... ", 1: " ..... ", 2: " ....2 "},
    "3": {0: " 3.... ", 1: " ..3.. ", 2: " ....3 "},
    "4": {0: " 4...4 ", 1: " ..... ", 2: " 4...4 "},
    "5": {0: " 5...5 ", 1: " ..5.. ", 2: " 5...5 "},
    "6": {0: " 6...6 ", 1: " 6...6 ", 2: " 6...6 "},
    "-": {0: "       ", 1: " ..... ", 2: "       "},
  }

  output = ""

  for i in range(3):
      output += "\n"
      for di, d in enumerate(dice):
          if di == 0:
              output += "|"
          output += number[str(d)][i]+"|"
  output += "\n"

  print(output)

Det jag gör är helt enkelt att först definiera hur varje rad för respektive siffra (tärning) ska se ut. Sedan skapar jag en loop på tre varv (eftersom att det är tre rader ska ska skrivas ut). För varje varv hämtar jag sedan aktuell rad för respektive siffra.

Så, om jag skulle skicka in 35462 skulle respektive rad per varv se ut så här:

| 3.... | 5...5 | 4...4 | 6...6 | 2.... |
| ..3.. | ..5.. | ..... | 6...6 | ..... |
| ....3 | 5...5 | 4...4 | 6...6 | ....2 |

🥇 Resultat

Tre tärningar kastas ut från ett terminalfönster på en datorskärm

Efter några timmar (utspritt på några dagar) så hade jag ett fullt fungerade Yatzyspel som går lika bra att spela själv som tillsammans med andra.

Fun fact: Jag spelade spelet tillsammans med två kollegor när det var nybyggt. När jag vann blev de lite fundersamma och frågade om det eventuellt fanns en bugg i systemet. Jag förklarade att det med största sannolikhet inte fanns någon bugg utan att jag bara var en skicklig Yatzy-spelare (a.k.a. hade tur). När jag senare skulle vidareutveckla spelet insåg jag att det faktiskt fanns en bugg i poängräkningen. Hoppsan…

🤓 Lärdomar och reflektioner

Hantera Exceptions

Förutom att lära mig mer om Python och hur man bygger ett spel så lärde jag mig att hantera Exceptions (och hur viktigt det är). Jag upptäckte att är väldigt tråkigt att hela spelet kraschar när du är på väg att slå ditt egna rekord, bara för att du råkade ange en felaktigt input 🤥.

Nya bibliotek

Jag blev bekant med två nya Python-bibliotek:

  • tabulate gör det enkelt att skriva ut data som tabeller i terminalen
  • colorama gör att du kan sätta färger på text i terminalen.

Exempel på hur biblioteken används:

En terminal-output som visar hur pyhton-biblioteken tabulate och colorama används i Yatzyspelet

Spelregler & tärningar

Vissa saker reflektera man inte riktigt över.. förrän man gör det. Jag visste t.ex inte att varje motsatt sida av en tärning tillsammans blir 7 🤯.

Detta lärde jag mig när jag skulle illustrera omslaget till spelet som skulle innehålla tärningar. Jag ställde mig då frågan; “Finns det några siffror på tärningen som aldrig kan synas tillsammans?” – Ja, t.ex 1 och 6 visade det sig. Hur du än vrider och vänder på tärningen kommer du aldrig kunna se de samtidigt.

Jag lärde mig även att det finns lite olika varianter av spelreglerna för Yatzy. T.ex. att om Yatzy är det enda du har kvar på slutet av spelet så får du slå 5 slag istället för 3. Jag kanske väljer att implementera detta i en kommande uppdatering av spelet.

Slutord

Källkod och instruktioner om hur du spelar finns på min GitHub. Happy playing 🥳.