Gra testowa - przekazywanie zmienionych zmiennych z funkcji do funkcji.

0

Wcześniej robiłem prostą grę tekstową typu wybierz to lub to, a tak potoczy się twoja przygoda, dodawałem jakieś losowe rzeczy typu losuj i jak wylosowana zostania t, a ta liczba to wtedy masz szczęście lub pecha. Teraz chciałbym dodać pewne zmienne takie jak zdrowie, moralność, pieniądzę. Chcę po prostu zrobić to w ten sposób, że mam jedną funkcję i w tej gracz dokonuje wyboru i np. tam jest walka i jego zdrowie zostaje zmniejszone i potem kolejna funkcja -> kolejna część przygody tyle, że muszę tą wartość już zmienioną zdrowie przenieść do kolejnej funkcji i z tym mam problem. Na razie zrobiłem przykładowo takie coś króciutkie:


import random
import time

zdrowie = 10
moralnosc = 10
pieniadze = 10

print('''Witaj wojowniku w Królestwie Aniołów i Demonów. Znajdujesz się w Pandemonium. Jest ono odwiecznym miejscem walki 
pomiędzy aniołami i demonami. Od ciebie będzie zależeć jak potoczą się losy tej krainy. ''')
time.sleep(3)
def zraniony_wojak(zdrowie,moralnosc,pieniadze):
    print('''Widzisz na swojej drodze rannego żołnierza Armii Niebios. Zwraca się do ciebie \"-Proszę pomóż mi, opatrz
          moje rany i daj mi coś do jedzenia\". ''')
    decyzja_wojaka = int(input("Co postanawiasz uczynić? Wybierz 0 - pomóż mu lub 1 - zabij go i zabierz łupy."))
    if decyzja_wojaka == 0:
        print("Dziękuję ci za okazaną pomoc. Otrzymujesz moje błogosławieństwo. ")
        zdrowie = zdrowie + 2
        moralnosc = moralnosc - 2
        return (zdrowie, moralnosc, pieniadze)

    elif decyzja_wojaka == 1:
        print("Zabijasz go i zabierasz mu łupy")
        pieniadze = pieniadze + 2
        moralnosc = moralnosc - 2
        return (zdrowie, moralnosc, pieniadze)

    else:
        print("Wpisałeś złą wartość")

def walka(nowe_wartości):
    print("Napotykasz wielkiego demona. Potwór z łatwością posługuje się swoim dwumetrowym toporem. Czeka cię ciężka walka.")
    zdrowie = nowe_wartości(0)  #Wybrałem 1, bo to wcześniej było zdrowie, muszę na nowo zmienić zdrowie, bo jak to nie zrobię to bierze zmienną globalną, czyli 10, zamiast np. 12 (jeśli w poprzednim punkcie wpisaliśmy 0).
    if zdrowie < 11:
        print("Umarłeś")
    else:
        print("Zabiłeś bestię")
nowe_wartości = zraniony_wojak(zdrowie,moralnosc,pieniadze)
walka(nowe_wartości)
```py
Tak jak można było tego się spodziewać wyszedł mi ten błąd
TypeError: 'tuple' object is not callable

Więc jak to zrobić, żeby do jednej funkcji brać te zmienne trochę je poprzekształcać i żeby ta druga funkcja potem je wzięła itd.
0

zdrowie = nowe_wartości(0)

Tuple indeksujemy nawiasami kwadratowymi, nie zwykłymi.

1

Możesz to rozwiązać tak naprawdę na dwa sposoby.
Pierwszym z nich jest wykorzystanie tego, jak python przekazuje argumenty. W przypadku obiektów, które są immutable(tuple, stringi, liczby dla przykładu), przekazana zostaje ich wartość. W przypadku mutowalnych obiektów, przekazana zostaje referencja. Co to znaczy? A no to, że jak przekażesz w argumencie listę, dicta, seta do funkcji jakiejś, to jeśli poczynisz w niej jakieś zmiany względem tych argumentów, to po wyjściu z funkcji te zmienne, które przekazałeś jako argument, też zostaną zmienione poza nią.

Jak by to mogło wyglądać u ciebie?


import random
import time

wartosci_poza_funkcja = {'zdrowie': 10, 'moralnosc': 10, 'pieniadze': 10}
print('''Witaj wojowniku w Królestwie Aniołów i Demonów. Znajdujesz się w Pandemonium. Jest ono odwiecznym miejscem walki 
pomiędzy aniołami i demonami. Od ciebie będzie zależeć jak potoczą się losy tej krainy. ''')
time.sleep(3)
def zraniony_wojak(wartosci):
    print('''Widzisz na swojej drodze rannego żołnierza Armii Niebios. Zwraca się do ciebie \"-Proszę pomóż mi, opatrz
          moje rany i daj mi coś do jedzenia\". ''')
    decyzja_wojaka = int(input("Co postanawiasz uczynić? Wybierz 0 - pomóż mu lub 1 - zabij go i zabierz łupy."))
    if decyzja_wojaka == 0:
        print("Dziękuję ci za okazaną pomoc. Otrzymujesz moje błogosławieństwo. ")
        wartosci['zdrowie'] = wartosci['zdrowie'] + 2
        wartosci['moralnosc'] = wartosci['moralnosc'] + 2

    elif decyzja_wojaka == 1:
        print("Zabijasz go i zabierasz mu łupy")
        wartosci['pieniadze'] = wartosci['pieniadze'] + 2
        wartosci['moralnosc'] = wartosci['moralnosc'] - 2

    else:
        print("Wpisałeś złą wartość")

def walka(wartosci):
    print("Napotykasz wielkiego demona. Potwór z łatwością posługuje się swoim dwumetrowym toporem. Czeka cię ciężka walka.")
    zdrowie = wartosci['zdrowie']  #Wybrałem 1, bo to wcześniej było zdrowie, muszę na nowo zmienić zdrowie, bo jak to nie zrobię to bierze zmienną globalną, czyli 10, zamiast np. 12 (jeśli w poprzednim punkcie wpisaliśmy 0).
    if zdrowie < 11:
        print("Umarłeś")
    else:
        print("Zabiłeś bestię")
zraniony_wojak(wartosci_poza_funkcja)
walka(wartosci_poza_funkcja)

Czy to dobre rozwiązanie? Chyba nie do końca - twoje funkcje mają side efecty, nie jest to raczej dobra praktyka w tym wypadku. Można by to zatem troszkę inaczej zapisać, jak?

Twój kod jest prawie dobry, niepoprawnie użyłeś tam tylko nawiasów. Poza tym, zamiast korzystać z indexów w tupli, łatwiej ci będzie użyć takiego sprytnego mechanizmu pythona z tupli, która sprawi, że kod będzie bardziej czytelny. Co to takiego i jak to zrobić?

import random
import time

zdrowie = 10
moralnosc = 10
pieniadze = 10

print('''Witaj wojowniku w Królestwie Aniołów i Demonów. Znajdujesz się w Pandemonium. Jest ono odwiecznym miejscem walki 
pomiędzy aniołami i demonami. Od ciebie będzie zależeć jak potoczą się losy tej krainy. ''')
time.sleep(3)
def zraniony_wojak(zdrowie,moralnosc,pieniadze):
    print('''Widzisz na swojej drodze rannego żołnierza Armii Niebios. Zwraca się do ciebie \"-Proszę pomóż mi, opatrz
          moje rany i daj mi coś do jedzenia\". ''')
    decyzja_wojaka = int(input("Co postanawiasz uczynić? Wybierz 0 - pomóż mu lub 1 - zabij go i zabierz łupy."))
    if decyzja_wojaka == 0:
        print("Dziękuję ci za okazaną pomoc. Otrzymujesz moje błogosławieństwo. ")
        zdrowie = zdrowie + 2
        moralnosc = moralnosc - 2
        return (zdrowie, moralnosc, pieniadze)

    elif decyzja_wojaka == 1:
        print("Zabijasz go i zabierasz mu łupy")
        pieniadze = pieniadze + 2
        moralnosc = moralnosc - 2
        return (zdrowie, moralnosc, pieniadze)

    else:
        print("Wpisałeś złą wartość")

def walka(zdrowie, moralnosc, pieniadze):
    print("Napotykasz wielkiego demona. Potwór z łatwością posługuje się swoim dwumetrowym toporem. Czeka cię ciężka walka.")
    if zdrowie < 11:
        print("Umarłeś")
    else:
        print("Zabiłeś bestię")
nowe_zdrowie, nowa_moralnosc, nowe_pieniadze = zraniony_wojak(zdrowie,moralnosc,pieniadze)
walka(nowe_zdrowie, nowa_moralnosc, nowe_pieniadze)

Co tutaj zrobiłem?

nowe_zdrowie, nowa_moralnosc, nowe_pieniadze = zraniony_wojak(zdrowie,moralnosc,pieniadze)

tutaj kryje się cała magia - w skrócie python ma takie coś, że jak weźmiesz i do tupli np. 3 elementowej, będziesz chciał przypisać 3 zmienne, to python zrozumie to tak: "Weź przeleć po tej tupli co zwróci ci funkcja zraniony_wojak, czyli (zdrowie, moralnosc, pieniadze) i każdy kolejny jej element, przypisz do kolejnej zmiennej z lewej strony równania."
Oczywiście zamiast tam dawać nowe nazwy zmiennych, jak ja to zrobiłem, czyli

nowe_zdrowie, nowa_moralnosc, nowe_pieniadze

Możesz też po prostu uaktualnić stare zdrowie, moralnosc, pieniadze.

1

Wykorzystaj OOP i stwórz klasę. Np.:

class Fighter():
    def __init__(self):
        self.health = 10
        self.morality = 10
        self.cash = 10

    def loot_cash(self, cash):
         self.cash += cash

    def spend_cash(self, cash):
         self.cash -= cash

janWojak = Fighter()
janWojak.loot_cash(10)
janWojak.spend_cash(5)
print(jakWojak.cash)

Zrobiłem po prostu klasę podstawową ale możesz np. dziedzić po innej klasie bazowej jak np. Soldier, który ma generalne statystyki i funkcje i specjalizować je w podklasach (archer, wizard..)

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