Wątek przeniesiony 2019-09-06 16:08 z przez cerrato.

kamień papier nożyce

Odpowiedz Nowy wątek
2019-09-06 15:42
0

Witam, jestem raczkującym programista, przerabiam sobie aktualnie temat funkcji i po zdobyciu już jakiejś wiedzy chciałem sobie poćwiczyć pisząc jakiś prosty program, do głowy wpadł pomysł z grą kamień papier nożyce, zamieszczę tutaj kod jaki udało mi się wyskrobać i byłbym wdzięczny jak ktoś o większej wiedzy podpowie co by można było zmienić żeby kod był bardziej czytelny (dla mnie osobiście jest, aczkolwiek myślę że dużo można by tutaj jeszcze zmienić), bądź jak go można zmienić/skrócić

import random
import sys

kpn = ['kamień','papier','nożyce']

def play_again():
    answer = None
    while answer != 'y' or answer != 'n':
        if answer == 'n':
            print("Dziękuje za gre, zamykam program!")
            sys.exit()
        elif answer == 'y':
            wynik()
        answer = input("Czy chcesz zagrać jeszcze raz? y/n: ")

def comp_choice():
    cc = random.choice(kpn)
    return cc

def player_choice():
    pc = input("wybierz kamień[k], papier[p] lub nożycze[n] : ")
    while True:
        if pc == 'k':
            pc = 'kamień'
            break
        elif pc == 'p':
            pc = 'papier'
            break
        elif pc == 'n':
            pc = 'nożyce'
            break
        pc = input("wybierz jeszcze raz: kamień[k], papier[p] lub nożycze[n] : ")
    return pc

def wynik():
    cc = comp_choice()
    pc = player_choice()
    print('gracz : ', pc)
    print("komputer : ",cc)
    if cc == pc:
        print("remis")
    elif cc == 'kamień' and pc == 'nożyce':
        print('Wygrywa komputer')
    elif cc == 'kamień' and pc == 'papier':
        print("Wygrywa gracz")
    elif cc == 'papier' and pc == 'kamień':
        print("Wygrywa komputer")
    elif cc == 'papier' and pc == 'nożyce':
        print("Wygrywa gracz")
    elif cc == 'nożyce' and pc == 'papier':
        print("Wygrywa komputer")
    else:
        print("wygrywa gracz")

wynik()
play_again()
edytowany 1x, ostatnio: cerrato, 2019-09-06 16:10

Pozostało 580 znaków

2019-09-06 16:02
2

Pierwsza rzecz, którą możesz zrobić to wytłumacz po co zamieniasz p na papier itd? Przecież w funkcji wynik możesz posługiwać się jednoliterowymi nazwami.


Wiedza to potęga
słuszna uwaga, tak się skupiłem na tych IFach, że nie zwróciłem na to uwagi ;) - cerrato 2019-09-06 16:08

Pozostało 580 znaków

2019-09-06 16:08
6

Pierwsza i wielokrotnie wałkowana sprawa - nazwy zmiennych. Wiem, że może się to wydawać mało istotne przy takim małym programiku, ale lepiej od początku wyrabiać dobre nawyki. Zmienne cc czy pc za wiele nie mówią. Ja zamiast tego bym je nazwał opisowo, coś w stylu computerChoice = getComputerChoice(). Poza tym jesteś niekonsekwentny - raz nazywasz funkcje po angielsku, a potem walisz wynik() :P

Po drugie - drabinki if'ów są czymś, czego lepiej unikać.

Ja bym wydzielił całe sprawdzanie odpowiedzi do osobnej funkcji, ale najpierw w ogóle bym sprawdził coś, o czym chyba zapomniałeś - czyli remis. Jeśli obaj gracze wybiorą taką samą odpowiedź, to trzeba poinformować o tym, że mamy remis i nie ma sensu prowadzić dalszych sprawdzeń. Jeśli natomiast odpowiedzi są różne, to wywołujemy funkcję sprawdzającą, w której zamiast wielu IF dałbym konstrukcję typu SWITCH/CASE. Poniżej pseudokod (sam sobie to zapiszesz w Pythonie)

winner=komputer
switch computerChoice
case kamien:
  if (playerChoice==papier): winner=player 
case nozyce:
  if (playerChoice==kamien): winner=player
case papier:
  if (playerchoice==nozyce): winner=player

EDIT
zauważyłem, że na samym początku sprawdzenia wyniku masz uwzględniony remis, przepraszam i zwracam honor ;)


That game of life is hard to play
I'm gonna lose it anyway
The losing card I'll someday lay
So this is all I have to say
edytowany 5x, ostatnio: cerrato, 2019-09-06 17:28
2019-09-06 16:13
1

@warjatt11: Tak na szybko

  • dlaczego mieszasz polskie nazwy z angielskimi (pisz kod po angielsku)
  • nazywaj zmienne w zrozumiały sposób a nie cc czy pc
  • zastanów sie jak inaczej sprawdzić kto wygrał, gdybyś miał rozbudowaną wersję (paper rock scissors lizard spock) to miałbyś już całkiem pokaźną drabinkę if'ów

Pozostało 580 znaków

2019-09-06 16:44
1

dzięki za uwagi, co to nazw zmiennych tutaj oczywiście widzę swój problem, aczkolwiek nie wiem czemu nad nimi nie popracowałem bardziej(dziękuje za uwagę) a co się tyczy if'ów to racja że średnio to wygląda lecz nie wpadłem na żaden pomysł jak inaczej zaimplementować wynik, próbowałem zrobić to z słownikiem ale nie wychodziło mi to w ogóle

Pozostało 580 znaków

2019-09-06 16:52
0

No to teraz masz temat do zabawy - wprowadź nasze sugestie w życie i pokaż, co stworzyłeś :)


That game of life is hard to play
I'm gonna lose it anyway
The losing card I'll someday lay
So this is all I have to say

Pozostało 580 znaków

2019-09-06 18:44
1

Wyskrobałem coś takiego, zamiast porównywać if'ami to zastąpiłem to słownikiem, nie będę oszukiwał że sam do tego doszedłem tylko znalazłem takie rozwiązanie w internecie, ale zrozumiałem jak ono działa(więc chyba dobre posunięcie?:)) więc nie jest to bezmyślne kopiuj/wklej


import random
import sys

rock_stone_scissors = ['kamień','papier','nożyce']

def play_again():
    answer = input("Czy chcesz zagrać jeszcze raz? y/n: ")
    while answer != 'y' or answer != 'n':
        if answer == 'n':
            print("Dziękuje za gre, zamykam program!")
            sys.exit()
        elif answer == 'y':
            victory()
        else:
            print("Nie ma takiej odpowiedzi")
        answer = input("Czy chcesz zagrać jeszcze raz? y/n: ")

def cpu_choice():
    getComputer_Choice = random.choice(rock_stone_scissors)
    return getComputer_Choice

def player_choice():
    getPlayer_Choice = input("wybierz kamień[k], papier[p] lub nożycze[n] : ")
    while True:
        if getPlayer_Choice == 'k':
            getPlayer_Choice = 'kamień'
            break
        elif getPlayer_Choice == 'p':
            getPlayer_Choice = 'papier'
            break
        elif getPlayer_Choice == 'n':
            getPlayer_Choice = 'nożyce'
            break
        getPlayer_Choice = input("wybierz jeszcze raz: kamień[k], papier[p] lub nożycze[n] : ")
    return getPlayer_Choice

def victory():
    computer_Choice = cpu_choice()
    player_Choice = player_choice()
    print('gracz : ', player_Choice)
    print("komputer : ",computer_Choice)
    if player_Choice == computer_Choice:
        print("remis")
    elif compare(player_Choice,computer_Choice):
        print("Wygrał gracz")
    else:
        print("Wygrał komputer")

def compare(playerChoice,cpuChoice):
    results = {('kamień','nożyce') : True,
               ('kamień','papier') : False,
               ('papier','kamień') : True,
               ('papier','nożyce') : False,
               ('nożyce','papier') : True,
               ('nożyce','kamień') : False}
    return playerChoice,cpuChoice

victory()
play_again()
Tylko nadal nie rozumiem, czemu zmieniasz "k" na "kamień" itp, czyli to, o czym pisał @Haskell 2 posty wyżej. Przecież w aplikacji możesz operować tymi jednoliterowymi wartościami podczas porównań i jedynie zamieniać je na słowa podczas wpisywania ich na ekranie. - cerrato 2019-09-06 19:59
właśnie nie rozumiem zbytnio o co chodzi, chyba się zagmatwałem, mógłbyś wskazać dokładnie o co kaman? Nie potrafię wyłapać jak to inaczej zapisać - warjatt11 2019-09-06 20:12
użytkownik wprowadza literę K i mógłbyś nią operować, ale Ty zamieniasz wciśnięty klawisz na opis, czyli zamiast "k" mamy "kamień". I potem, chociażby podczas porównywania, używasz już słów a nie liter (linie 51-56 z powyższego listingu). I teraz powiedzmy, że zachodzi potrzeba zmienienia "nożyce" na sekator - musisz w takim przypadku zmienić jednocześnie wartości podane w liniach 5, 32-33 oraz 51-56. Przy tak prostym programie nie będzie to jakąś tragedią, ale w przypadku rzeczy bardziej skomplikowanych już mogą się pojawić schody - cerrato 2019-09-06 21:20
Dlatego lepiej jest to zrobić na zasadzie "użytkownik wybrał opcję numer 2". Algorytmu porównującego udzielone odpowiedzi nie obchodzi, czy 2 to nożyce, czy walizka ;) Algorytm jedynie musi posiadać informacje o tym, jak "ocenić" dwójkę, z czym wygrywa, a z czym przegrywa. Jeśli chcesz zmienić jej nazwę, to zmieniasz w jednym miejscu. Jeśli chcesz zmienić zasady oceniania, to możesz zrobić, niezależnie od tego, co to 2 oznacza. - cerrato 2019-09-06 21:22

Pozostało 580 znaków

2019-09-06 19:55
0

znalazłem takie rozwiązanie w internecie, ale zrozumiałem jak ono działa(więc chyba dobre posunięcie?

Bardzo dobre. Obecnie jest tyle technologii, języków, frameworkow, że nieraz bardzo duża część pracy polega na szukaniu w necie i kopiowaniu. Jest nawet na to określenie SODD czyli Stack Overflow Driven Development ;) Nie chodzi o to, żeby wszystko wykuć na pałę, zresztą jest to nierealne, tylko żeby być zaradnym i umieć skutecznie znaleźć potrzebne informacje.

Twoim plusem jest to, że nie zrobiłeś bezmyślnego kopiuj-wklej, tylko załapałeś zasadę, czyli mamy tutaj podwójny sukces - uzyskałeś działająca apkę oraz się czegoś przy okazji nauczyłeś :)


That game of life is hard to play
I'm gonna lose it anyway
The losing card I'll someday lay
So this is all I have to say
edytowany 2x, ostatnio: cerrato, 2019-09-06 20:02

Pozostało 580 znaków

2019-09-06 20:10
1
def compare(playerChoice,cpuChoice):
    results = {('kamień','nożyce') : True,
               ('kamień','papier') : False,
               ('papier','kamień') : True,
               ('papier','nożyce') : False,
               ('nożyce','papier') : True,
               ('nożyce','kamień') : False}
    return playerChoice,cpuChoice

Yyyhhh, a nie tak?

def compare(playerChoice,cpuChoice):
    results = {('kamień','nożyce') : True,
               ('kamień','papier') : False,
               ('papier','kamień') : True,
               ('papier','nożyce') : False,
               ('nożyce','papier') : True,
               ('nożyce','kamień') : False}
    return results[(playerChoice,cpuChoice)]

01010100 01110101 01110100 01100001 01101010 00100000 01101110 01101001 01100101 00100000 01101101 01100001 00100000 01101110 01101001 01100011 00100000 01100011 01101001 01100101 01101011 01100001 01110111 01100101 01100111 01101111 00101110 00100000 01001001 01100011 00100000 01110011 01110100 01101111 01101110 01110100 00101110

Pozostało 580 znaków

2019-09-06 20:26
0

a no prawda, przeanalizowałem kod i zgadza się, tak powinno być, dzięki za uwage

edytowany 1x, ostatnio: cerrato, 2019-09-06 21:13

Pozostało 580 znaków

2019-09-06 20:29
1

No to chyba nie do konca zrozumiales za pierwszym razem :D


01010100 01110101 01110100 01100001 01101010 00100000 01101110 01101001 01100101 00100000 01101101 01100001 00100000 01101110 01101001 01100011 00100000 01100011 01101001 01100101 01101011 01100001 01110111 01100101 01100111 01101111 00101110 00100000 01001001 01100011 00100000 01110011 01110100 01101111 01101110 01110100 00101110
edytowany 1x, ostatnio: stivens, 2019-09-06 20:29
Nie przyglądałem się wynikowi, sama idee zrozumiałem, teraz jak mi na to zwróciłeś uwage to zacząłem grzebać i rzeczywiście wynik losowo wychodził, jak dodałem nawiasy to wszystko jest jak powinno, tak sobie teraz myślę to rzeczywiście nie miało prawa to działać :D no cóż dobrze że przynajmniej ktoś zwrócił uwage na to pozdro - warjatt11 2019-09-06 20:34
No dzialalo losowo bo zawsze dostawales wynik o wartosci logicznej true - stivens 2019-09-06 20:57

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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