Gra papier, kamień, nożyce

0

Witajcie. Niedawno zacząłem naukę, i niestety wykładam się na jednym z pierwszych zadań. Zrobiłem grę papier kamień nożyce, działało do czasu dodania pętli while.Tak wygląda cały kod:

wynik_gracz1 = 0
wynik_gracz2 = 0

opcje_gracza = ["kamien", "papier", "nozyczki"]

while wynik_gracz1 != 3 and wynik_gracz2 != 3:
    wybor_gracza_jest_poprawny = True
    while wybor_gracza_jest_poprawny:
        wybor_gracza1 = input("gracz1 podaj swoj wybor: ")
        if wybor_gracza1 in opcje_gracza:
            wybor_gracza_jest_poprawny = False
    while wybor_gracza_jest_poprawny:
        wybor_gracza2 = input("gracz2 podaj swoj wybor: ")
        if wybor_gracza2 in opcje_gracza:
            wybor_gracza_jest_poprawny = False

    if wybor_gracza1 == "kamien" and wybor_gracza2 == "nozyczki" \
    or wybor_gracza1 == "papier" and wybor_gracza2 == "kamien" \
    or wybor_gracza1 == "nozyczki" and wybor_gracza2 == "papier":
        print("gracz1 wygral")
        wynik_gracz1 += 1
    elif wybor_gracza1 == wybor_gracza2:
        print("remis")
    else:
        print("gracz2 wygral")
        wynik_gracz2 += 1
if wynik_gracz1 > wynik_gracz2:
    print("Cala gre wygral gracz 1")
else:
    print("Cala gre wygral gracz 2")

Problem polega na tym że przed dodaniem pętli while sprawdzającej zgodność tego co wpiszę z listą funkcja input działała mi normalnie, zapisywało zmienną. W tym momencie w linii 17 dostaję

NameError: name 'wybor_gracza2' is not defined. Did you mean: 'wybor_gracza1'?

Odrzuca mi gdy wpiszę cokolwiek spoza listy, ale gdy wpiszę rzecz z listy automatycznie wyrzuca mi ten błąd.
Rozumiem że problem jest ze zmienną, ale nie rozumiem dlaczego

1

Rozpisz sobie program na kartce. Bo chyba tyłu pętli nie potrzeba.

while wybor_gracza_jest_poprawny:
        wybor_gracza1 = input("gracz1 podaj swoj wybor: ")
        if wybor_gracza1 in opcje_gracza:
            wybor_gracza_jest_poprawny = False

Tu ustawiasz wybor_gracza_jest_poprawny = False tym samym druga pętla chyba nie jest uruchamiana? Program nie pyta o wprowadzenie danych dla drugiego gracza i problematyczna zmienna nigdy nie jest inicjalizowana.

Na wstępnym etapie nauki warto jeszcze przepływ sobie rozrysować i dopiero pisać program. Jak rozrysujesz to wyjdzie Ci pewnie, że te pętlę do wpisywania jednego wyboru są zbędne. Gracze raz w rundzie dokonują wyboru. Natomiast liczba rund może być większa od jednej.

0

Bo ta pętla ma sprawdzać czy zostało wpisane poprawne słowo z listy, jeśli nie to ma wywoływać tak długo aż je wpiszemy. Więc powinno to wyglądać tak że po tym false przechodzi do kolejnego

while wybor_gracza_jest_poprawny

i sprawdza to co wpisze gracz2

i dopiero gdy w obu przypadkach mamy wpisane poprawne hasła z listy to przechodzi dalej

    if wybor_gracza1 == "kamien" and wybor_gracza2 == "nozyczki" \
    or wybor_gracza1 == "papier" and wybor_gracza2 == "kamien" \
    or wybor_gracza1 == "nozyczki" and wybor_gracza2 == "papier":

Więc chyba faktycznie po zakończeniu tej pierwszej pętli chce jechać dalej bez zrobienia drugiej, i przy porównywaniu wyrzuca błąd bo nie ma do czego porównać gdyż to

and wybor_gracza2 == "nozyczki"

nie istnieje

Mniej więcej wiem już co i jak, będę kombinował jak to naprawić, dzieki

1

Jeżeli wybor_gracza1 w 1 pętli jest zgodny z tym co jest w liście opcje_gracza to druga pętla prosząca o input od gracza 2 nie jest juz wykonywana.

50
scores = {
    "papier":{"papier": 0, "nozyce": 0, "kamien": 1},
    "kamien":{"papier": 0, "nozyce": 1, "kamien": 0},
    "nozyce":{"papier": 1, "nozyce": 0, "kamien": 0}
}

gracz1: int = 0
gracz2: int = 0

while gracz1 != 3 and gracz2 !=3:
    g1 = input("Gracz 1: ")
    g2 = input("Gracz 2: ")

    gracz1 += scores[g1][g2]
    gracz2 += scores[g2][g1]

Wersja bez ifologi. Logikę określa słownik.

3

Czemu nie zrobić zwyczajnie:

if opcje_gracza.index(wybor_gracza1)==(opcje_gracza.index(wybor_gracza2)+1)%3:
  print("gracz1 wygral")
elif opcje_gracza.index(wybor_gracza2)==(opcje_gracza.index(wybor_gracza1)+1)%3:
  print("gracz2 wygral")
else:
  print("remis")
0

Słowników jeszcze nie ruszyłem, natomiast znalazłem już dlaczego nie chciało mi to działać.

    wybor_gracza_jest_poprawny = True
    while wybor_gracza_jest_poprawny:
        wybor_gracza1 = input("gracz1 podaj swoj wybor: ")
        if wybor_gracza1 in opcje_gracza:
            wybor_gracza_jest_poprawny = False
    while wybor_gracza_jest_poprawny:
        wybor_gracza2 = input("gracz2 podaj swoj wybor: ")
        if wybor_gracza2 in opcje_gracza:
            wybor_gracza_jest_poprawny = False

po zakończeniu tej pierwszej pętli poprzez False powinienem wrzucić drugi raz

wybor_gracza_jest_poprawny = True

i wtedy druga pętla while się odpali
wiem że nie wygląda to najlepiej jeśli chodzi o jakość kodu, ale na dniach jak poznam więcej rzeczy to skrócę

_13th_Dragon napisał(a):

Czemu nie zrobić zwyczajnie:

if opcje_gracza.index(wybor_gracza1)==(opcje_gracza.index(wybor_gracza2)+1)%3:
  print("gracz1 wygral")
elif opcje_gracza.index(wybor_gracza2)==(opcje_gracza.index(wybor_gracza1)+1)%3:
  print("gracz2 wygral")
else:
  print("remis")

po skopiowaniu mi działa i wygląda o wiele lepiej, z 13 linii robi się 6, siadam dalej żeby to rozkminić
wielkie dzięki

0

W sumie wystarczy tyle:

GameTill=3
ResultPlayer1=0
ResultPlayer2=0

Options=["kamien","papier","nozyczki"]

def PlayerChoise(who):
    while True:
        choise=input(who+" podaj swoj wybor: ").lower()
        if choise in Options:
            return Options.index(choise)

while ResultPlayer1<GameTill and ResultPlayer2<GameTill:
    pc1=PlayerChoise("Gracz1")
    pc2=PlayerChoise("Gracz2")
    if pc1==(pc2+1)%3:
        print("gracz1 wygral")
        ResultPlayer1+=1
    elif pc2==(pc1+1)%3:
        print("gracz2 wygral")
        ResultPlayer1+=1
    else:
        print("remis")
if ResultPlayer1>ResultPlayer2:
    print("Cala gre wygral gracz 1")
else:
    print("Cala gre wygral gracz 2")

Ale jak nie chcesz zmuszać gracza do pisania to:

GameTill=3
ResultPlayer1=0
ResultPlayer2=0

Options=["kamien","papier","nozyczki"]

def PlayerChoise(who):
    while True:
        p=0
        for opt in Options:
            p+=1
            print(str(p)+". "+opt)
        choise=int(input(who+" podaj swoj wybor: "))
        if 1<=choise and choise<=3:
            return choise-1

while ResultPlayer1<GameTill and ResultPlayer2<GameTill:
    pc1=PlayerChoise("Gracz1")
    pc2=PlayerChoise("Gracz2")
    if pc1==(pc2+1)%3:
        print("gracz1 wygral")
        ResultPlayer1+=1
    elif pc2==(pc1+1)%3:
        print("gracz2 wygral")
        ResultPlayer1+=1
    else:
        print("remis")
if ResultPlayer1>ResultPlayer2:
    print("Cala gre wygral gracz 1")
else:
    print("Cala gre wygral gracz 2")

Ale nadal da się skrócić używając tablic:

GameTill=3
Results=[0,0,0]
Options=["kamień","papier","nożyczki"]
Players=["Gracz 1","Gracz 2"]

def PlayerChoise(who):
    while True:
        print("\n".join([str(p+1)+". "+Options[p] for p in range(0,len(Options))]).strip())
        choise=int(input(who+" podaj swoj wybor: "))
        if 1<=choise and choise<=3:
            return choise-1

while max(Results[:-1])<GameTill:
    choises=[PlayerChoise(player) for player in Players]
    result=int(choises[0]==(choises[1]+1)%3)+2*int(choises[1]==(choises[0]+1)%3)-1
    if result<0:
        print("remis")
    else:
        Results[result]+=1
        print("Wygrywa",Players[result],"Wynik:",Results[:-1])
print("Cala grę wygrał "+Players[int(Results[0]<Results[1])])

1 użytkowników online, w tym zalogowanych: 0, gości: 1