Steg 5: spis epler og bli stor

forrige steg
oversikt
neste steg

I dette steget skal vi implementere funksjonalitet som gjør at slangen vokser når den spiser et eple.

Tilstand før Tilstand etter
før spising etter spising

I før/etter -bildene over, legg merke til at når slangen spiser:

  • økes verdien app.snake_size fra 3 til 4,
  • posisjonen hvor hodet flytter til (1, 6) endrer verdi fra -1 til 4, som er den nye verdien til app.snake_size, og
  • ingen verdier tilhørende slangen (positive verdier) i app.board synker.

For å gjennomføre dette steget, må vi modifisere koden vi skrev i move_snake tidligere:

import random

# Et tilfeldig tall mellom 0 og 10 (ikke inkludert 10)
print(random.choice(range(10)))

# Et tilfeldig element i en liste
print(random.choice(["a", "b", "c"]))

Test hjelpefunksjonen din ved å kopiere denne testen inn i snake.py (legg testen inn før kallet til run_app, men etter at funksjonen add_apple_at_random_location er definert)

print("Tester add_apple_at_random_location...", end="")
for _ in range(100):
    a = [[2, 3, -1, 0], [1, 0, 0, 0]]
    add_apple_at_random_location(a)
    legal_results = [
        [[2, 3, -1, -1], [1, 0, 0, 0]],
        [[2, 3, -1, 0], [1, -1, 0, 0]],
        [[2, 3, -1, 0], [1, 0, -1, 0]],
        [[2, 3, -1, 0], [1, 0, 0, -1]],
    ]
    assert(a in legal_results)
print("OK")

Legg merke til at funksjonen kun skal opprette epler på steder som er ledige, altså har verdien 0. Siden vi her tester en funksjon som produserer tilfeldige resultater, sjekker vi i assert-setningen at resultatet er ett av de fire lovlige resultatene for test-casen vår. Vi kjører også testen mange ganger slik at vi ikke bare passerer testen på grunn av flaks.

Det finnes i hovedsak to måter å løse add_apple_at_random_location på. Velg selv hvilken strategi du ønsker å bruke.

Alternativ A. Denne tilnærmingen er som regel rask og effektiv så lenge slangen er relativt kort, men man har ingen øvre grense for hvor lang tid som kreves i verste fall.

  • Velg en tilfeldig rad mellom 0 og antall rader i grid
  • Velg en tilfeldig kolonne mellom 0 og antall kolonner i grid
  • Sjekk om det er ledig plass (altså verdien 0) i grid på den gitte posisjonen:
    • Hvis ja, legg inn et eple (verdien -1) i posisjonen og avslutt så funksjonen med return
    • Hvis ikke, begynn på nytt (f. eks. ha all koden inn i en while True -løkke)

Alternativ B. Denne tilnærmingen er ikke spesielt effektiv i gjennomsnitt, men har en øvre grense for hvor lang tid den tar. Dersom det ikke er plass til et nytt eple i det hele tatt vil denne algoritmen kunne avsløre det (f. eks. ved å krasje, eller håndtere det på annen måte), mens alternativ A aldri vil terminere, og programmet vil fryse (som tross alt er et dårligere alternativ).

  • Opprett først en liste med alle posisjonene hvor det er mulig å opprette et eple.
  • Velg en tilfeldig posisjon fra listen over muligheter.
  • Legg inn et eple i den valgte posisjonen

For de ambisiøse: det er mulig å kombinere alternativene A og B ved å prøve alternativ A noen få iterasjoner først, og deretter hoppe over til alternativ B dersom ingen gode alternativer ble funnet. Da får vi det beste fra begge verdener.


Guide til snake av Torstein Strømme er lisensiert under CC-NC-SA 4.0.