Strings aus einer Liste Klasse zuordnen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
lol44__44lol
User
Beiträge: 9
Registriert: Freitag 10. Februar 2023, 00:29

Hier ist das Programm jetzt:

Code: Alles auswählen

import random
from clrprint import *
import json

class Player:
    def __init__(self, name, landmarks, industries):
        self.name = name
        self.money = 30
        self.industries = {}
        for industry in industries:
            self.industries[industry] = 0
        self.industries[bakery] += 1
        self.industries[wheat_field] += 1
        self.landmarks = {}
        for landmark in landmarks:
            self.landmarks[landmark] = 0

class Industry:
    def __init__(self, name, cost, profit_basic, profit_bonus, profit_bonus_dependencies, shop_rarity, dice_rolls, dice_info, text_colour, description):
        self.name = name
        self.cost = cost
        self.profit_basic = profit_basic
        self.profit_bonus = profit_bonus
        self.profit_bonus_dependencies = profit_bonus_dependencies
        self.dice_rolls = dice_rolls
        self.profit = 0
        self.true_dependencies = 0
        self.text_colour = text_colour
        self.shop_rarity = shop_rarity
        self.description = description
        self.profit_shopping_mall_bonus = 0
        self.dice_info = dice_info

    def get_true_dependencies():
        self.true_dependencies = 0
        if player.landmarks[shopping_mall] > 0:
            self.profit_shopping_mall_bonus += 10
        for industry in player.industries:
            for dependency in self.profit_bonus_dependencies:
                if dependency == industry:
                    self.true_dependencies += player.industries[industry]

    def get_profit(self, players, player, player_at_turn, roll, names):
        get_true_depencies()
        self.profit = (self.profit_basic + self.profit_bonus * self.true_dependencies) * player.industries[self]

class AllIndustry(Industry):
    def get_profit(self, players, player, player_at_turn, roll, names):
        self.profit_shopping_mall_bonus = 0
        self.profit = 0
        if roll in self.dice_rolls and player.industries[self] > 0:
            self.get_true_dependencies
            self.profit = (self.profit_basic + self.profit_bonus * self.true_dependencies) * player.industries[self]

class OwnIndustry(Industry):
    def get_profit(self, players, player, player_at_turn, roll, names):
        self.profit_shopping_mall_bonus = 0
        self.profit = 0
        if roll in self.dice_rolls and player.industries[self] > 0 and player == players[player_at_turn]:
            self.get_true_dependencies
            self.profit = (self.profit_basic + self.profit_bonus * self.true_dependencies) * player.industries[self]
            if self == convenience_store or self == bakery:
                self.profit += self.profit_shopping_mall_bonus

class StealIndustry(Industry):
    def get_profit(self, players, player, player_at_turn, roll, names):
        self.profit_shopping_mall_bonus = 0
        self.profit = 0
        if roll in self.dice_rolls and player.industries[self] > 0 and player != players[player_at_turn]:
            self.get_true_dependencies
            self.profit = (self.profit_basic + self.profit_bonus * self.true_dependencies) * player.industries[self] + self.profit_shopping_mall_bonus
            if 0 < players[player_at_turn].money:
                if self.profit <= players[player_at_turn].money:
                    players[player_at_turn].money -= self.profit
                else:
                    self.profit = players[player_at_turn].money
                    players[player_at_turn].money -= self.profit
            else:
                self.profit = 0


class StadiumIndustry(Industry):
    def get_profit(self, players, player, player_at_turn, roll, names):
        self.profit = 0
        if roll in self.dice_rolls and player.industries[self] > 0 and player == players[player_at_turn]:
            for player in players:
                profit_per_player = (self.profit_basic + self.profit_bonus) * player.industries[self]
                if player == players[player_at_turn]:
                    continue
                if 0 < player.money:
                    if profit_per_player <= player.money:
                        self.profit += profit_per_player
                        player.money -= profit_per_player
                    else:
                        profit_per_player = player.money
                        self.profit += profit_per_player
                        player.money -= profit_per_player

class TvStationIndustry(Industry):
    def get_profit(self, players, player, player_at_turn, roll, names):
        self.profit = 0
        if roll in self.dice_rolls and player.industries[self] > 0 and player == players[player_at_turn]:
            while True:
                answer = input(f"{player.name}, gebe den Namen des Spielers dem du {str(self.profit_bonus)} Münzen stehlen willst ein: ")
                if answer in names:
                    break
            for i in [i for i, x in enumerate(names) if x == answer]:
                    choosen_player = i
            self.profit = self.profit_bonus * player.industries[self]
            players[choosen_player].money -= self.profit

class BuisnessCenterIndustry(Industry):
    def get_profit(self, players, player, player_at_turn, roll, names):
        self.profit = 0
        if roll in self.dice_rolls and player.industries[self] > 0 and player == players[player_at_turn]:
            while True:
                answer = input(f"{player.name}, gebe den Namen des Spielers mit dem du eine Karte tauschen willst ein: ")
                if answer in names:
                    break
            for i in [i for i, x in enumerate(names) if x == answer]:
                choosen_player = i
            x = True
            while x == True:
                answer = input(f"{player.name}, gebe den Namen der Industrie die du von {players[choosen_player].name} haben willst ein: ")
                for industry in players[choosen_player].industries:
                    if answer == industry.name and players[choosen_player].industries[industry] > 0:
                        get_industry = industry
                        x = False
            x = True
            while x == True:
                answer = input(f"{player.name}, gebe den Namen der Industrie die du {players[choosen_player].name} geben willst ein: ")
                for industry in player.industries:
                    if answer == industry.name and player.industries[industry] > 0:
                        give_industry = industry
                        x = False
            player.industries[give_industry] -= 1
            player.industries[get_industry] += 1
            players[choosen_player].industries[give_industry] += 1
            players[choosen_player].industries[get_industry] -= 1


class Landmark:
    def __init__(self, name, cost, modifier_type, description):
        self.name = name
        self.cost = cost
        self.modifier_type = modifier_type
        self.description = description

class Game:
    def __init__(self):
        self.industries = []
        self.landmarks = []
        self.roll1 = 0
        self.roll2 = 0
        self.roll = 0
        self.player_at_turn = 0
        self.names = []
        self.players = []
        self.turn = 0
        self.purchases_this_turn = 0
        self.shop_deck = []
        self.shop = {}

    def get_players(self):
        self.players = []
        self.names = input("Gebe die Namen der Mitspieler an: ")
        self.names = self.names.split()
        self.players = [Player(name, self.landmarks, self.industries) for name in self.names]

    def next_turn(self):
        self.purchases_this_turn = 0
        answer = ""
        rerolls = 1
        self.turn += 1
        self.player_at_turn = (self.player_at_turn + 1) % len(self.players)
        clrprint("[" + str(self.turn) + "]", "Am Zug ist:", self.players[self.player_at_turn].name, clr = "b,d,r")
        while True:
            if self.players[self.player_at_turn].landmarks[station] == 1:
                while True:
                    if answer == "nein":
                        break
                    answer = input(f"{self.players[self.player_at_turn].name}, willst du 2 Würfel werfen? (ja/nein) ")
                    if answer == "ja":
                        self.roll1 = random.randint(1, 6)
                        self.roll2 = random.randint(1, 6)
                        self.roll = self.roll1 + self.roll2
                        print(f"Gewürfelt wurde eine: {str(self.roll1)} und eine: {str(self.roll2)} das macht eine: {str(self.roll)}")
                        break
                    elif answer == "nein":
                        self.roll = random.randint(1, 6)
                        print(f"Gewürfelt wurde eine: {str(self.roll)}")
                        break
            else:
                self.roll = random.randint(1, 6)
                print(f"Gewürfelt wurde eine: {str(self.roll)}")
            if self.players[self.player_at_turn].landmarks[radio_tower] == 1 and rerolls > 0:
                while True:
                    answer = input(f"\n{self.players[self.player_at_turn].name}, willst du neu werfen? (ja/nein)")
                    if answer == "nein" or answer == "ja":
                        rerolls -= 1
                        break
            else:
                break

        stats_profite = ""
        for player in self.players:
            stats_profite += f"\n{player.name}'s Profite:"
            for industry in self.industries:
                if industry in player.industries:
                    industry.get_profit(self.players, player, self.player_at_turn, self.roll, self.names)
                    player.money += industry.profit
                    num_profits = 0
                    if industry.profit > 0:
                        num_profits += 1
                    if num_profits > 0:
                        stats_profite += f"\n{industry.name}: {str(industry.profit)}"
        clrprint(stats_profite, clr = "d")
        self.get_stats()

    def end_turn(self):
        if self.players[self.player_at_turn].landmarks[amusement_park] == 1 and roll1 == roll2:
            self.player_at_turn -= 1

    def get_stats(self):
        for player in self.players:
            clrprint("\n-" + player.name + "-", "\nGeld: ", str(player.money) + "\nIndustrien: ", clr = "d,y,d")
            for industry in player.industries:
                if player.industries[industry] == 0:
                    continue
                clrprint(industry.name, ": " + str(player.industries[industry]), clr = industry.text_colour + ",d")

    def setup_shop_deck(self):
        regular_card_num = round(len(self.players) * 0.5) + 4
        special_card_num = len(self.players)
        self.shop_deck = []
        for industry in self.industries:
            if industry.shop_rarity == REGULAR:
                for x in range(0, regular_card_num):
                    self.shop_deck.append(industry)
            elif industry.shop_rarity == SPECIAL:
                for x in range(0, special_card_num):
                    self.shop_deck.append(industry)
        random.shuffle(self.shop_deck)

    def update_shop(self):
        while len(self.shop) != 10:
            if len(self.shop_deck) == 0:
                break
            elif self.shop_deck[0] in self.shop:
                self.shop[self.shop_deck[0]] += 1
                del self.shop_deck[0]
            elif self.shop_deck[0] not in self.shop:
                self.shop[self.shop_deck[0]] = 1
                del self.shop_deck[0]

    def view_shop(self):
        self.update_shop()
        for industry in self.shop:
            roll_numbers = ""
            for roll_number in industry.dice_rolls:
                roll_numbers += " " + str(roll_number)
            roll_numbers += "  " + industry.dice_info
            clrprint("[" + str(self.shop[industry]) + "]", industry.name, "\nKosten:", str(industry.cost) + "\n" + industry.description + "\nWurfzahlen: " + roll_numbers + "\n", clr = "d," + industry.text_colour + ",y,d")
        clrprint("\n" + "Du hast: ", str(self.players[self.player_at_turn].money) + " Münzen", clr = "d,y")
        if self.purchases_this_turn < 1:
            x = True
            while x == True:
                answer = input("\nWas willst du machen?(zurück/kaufen NAME)")
                if answer == "zurück":
                    break
                elif "kaufen" in answer.split():
                    for industry in self.industries:
                        if industry.name in answer.split() and industry.cost <= self.players[self.player_at_turn].money:
                            if self.shop[industry] == 1:
                                del self.shop[industry]
                                self.purchases_this_turn += 1
                                self.players[self.player_at_turn].industries[industry] += 1
                                self.players[self.player_at_turn].money -= industry.cost
                                x = False
                                break
                            elif self.shop[industry] > 1:
                                self.purchases_this_turn += 1
                                self.shop[industry] -= 1
                                self.players[self.player_at_turn].industries[industry] += 1
                                self.players[self.player_at_turn].money -= industry.cost
                                x = False
                                break

        self.ask_what_to_do()

    def view_landmarks(self):
        clrprint(self.players[self.player_at_turn].name + "'s", "Projekte", clr = "d,y")
        for landmark in self.landmarks:
            if self.players[self.player_at_turn].landmarks[landmark] == 1:
                building_status = "[abgeschlossen]"
            else:
                building_status = "[ noch im bau ]"
            clrprint("\n" + building_status, landmark.name + "\nKosten:", str(landmark.cost) + "\n" + landmark.description, clr = "d,y,d")
        clrprint("\n" + "Du hast: ", str(self.players[self.player_at_turn].money) + " Münzen", clr = "d,y")
        if self.purchases_this_turn < 1:
            x = True
            while x == True:
                answer = input("\nWas willst du machen?(zurück/bauen NAME)")
                if answer == "zurück":
                    break
                elif "bauen" in answer.split():
                    for landmark in self.landmarks:
                        if landmark.name in answer.split() and landmark.cost <= self.players[self.player_at_turn].money and self.players[self.player_at_turn].landmarks[landmark] < 1:
                            self.purchases_this_turn += 1
                            self.players[self.player_at_turn].landmarks[landmark] += 1
                            self.players[self.player_at_turn].money -= landmark.cost
                            x = False
                            break
        self.ask_what_to_do()

    def ask_what_to_do(self):
        while True:
            answer = input(f"\n{self.players[self.player_at_turn].name}, Was willst du machen?(projekt/shop/zug beenden)")
            if answer == "projekt":
                self.view_landmarks()
                break
            elif answer == "shop":
                self.view_shop()
                break
            elif answer == "zug beenden":
                break

    def main_game_loop(self):
        self.def_industries()
        self.def_landmarks()
        while True:
            self.turn = 0
            self.shop = {}
            self.player_at_turn = -1
            self.get_players()
            self.setup_shop_deck()
            self.update_shop()
            player_that_won = None
            while player_that_won == None:
                self.next_turn()
                self.ask_what_to_do()
                for player in self.players:
                    build_landmarks = 0
                    for landmark in player.landmarks:
                        if player.landmarks[landmark] > 0:
                            build_landmarks += 1
                    if build_landmarks == len(self.landmarks):
                        player_that_won = players[player_at_turn]
                self.end_turn()
            clrprint("\n\n==", "Gratulation", player_that_won.name, "du hast gewonnen!", "==\n\n", clr = "d,b,r,b,d")
            input("Drücke enter/return um nochmal zu spielen")

    def def_industries(self):
        self.industries = [wheat_field, ranch, forest, mine, apple_orchard, bakery, convenience_store, cheese_factory, fruit_and_vegetable_market, cafe, family_restaurant, stadium, tv_station, buisness_center]

    def def_landmarks(self):
        self.landmarks = [station, shopping_mall, amusement_park, radio_tower]

REGULAR = 100
SPECIAL = 101

wheat_field = AllIndustry("Feld", 10, 10, 0, [], REGULAR, [1], "(Bei allen Würfen)", "b", "Erhalte 10 Münzen aus der Bank")
ranch = AllIndustry("Bauernhof", 10, 10, 0, [], REGULAR, [2], "(Bei allen Würfen)", "b", "Erhalte 10 Münzen aus der Bank")
forest = AllIndustry("Wald", 30, 10, 50, [], REGULAR, [5], "(Bei allen Würfen)", "b", "Erhalte 10 Münzen aus der Bank")
mine = AllIndustry("Bergwerk", 60, 50, 0, [], REGULAR, [9], "(Bei allen Würfen)", "b", "Erhalte 50 Münzen aus der Bank")
apple_orchard = AllIndustry("Apfelplantage", 30, 30, 0, [], REGULAR, [10], "(Bei allen Würfen)", "b", "Erhalte 30 Münzen aus der Bank")
bakery = OwnIndustry("Bäckerei", 10, 10, 0, [], REGULAR, [2, 3], "(Bei deinen Würfen)", "g", "Erhalte 10 Münzen aus der Bank")
convenience_store = OwnIndustry("Mini-Markt", 20, 30, 0, [], REGULAR, [4], "(Bei deinen Würfen)", "g", "Erhalte 30 Münzen aus der Bank")
cheese_factory = OwnIndustry("Molkerei", 50, 0, 30, [ranch], REGULAR, [7], "(Bei deinen Würfen)", "g", "Erhalte 30 Münzen aus der Bank für jeden Bauernhof")
furniture_factory = OwnIndustry("Möbelfabrik", 30, 0, 30, [forest, mine], REGULAR, [8], "(Bei deinen Würfen)", "g", "Erhalte 30 Münzen aus der Bank für jeden Wald und jedes Bergwerk")
fruit_and_vegetable_market = OwnIndustry("Markthalle", 20, 0, 20, [wheat_field, apple_orchard], REGULAR, [11, 12], "(Bei deinen Würfen)", "g", "Erhalte 20 Münzen aus der Bank für jedes Feld und jede Apfelplantage")
cafe = StealIndustry("Cafe", 20, 0, 10, [], REGULAR, [3], "(Nicht deine Würfe)", "r", "Erhalte 10 Münzen von dem Mitspieler der eine 3 gewürfelt hat")
family_restaurant = StealIndustry("Familienrestaurant", 30, 20, 0, [], REGULAR, [9, 10], "(Nicht deine Würfe)", "r", "Erhalte 20 Münzen von dem Mitspieler der eine 9 oder 10 gewürfelt hat")
stadium = StadiumIndustry("Stadion", 60, 0, 20, [], SPECIAL, [6], "(Bei deinen Würfen)", "p", "Erhalte von jedem Mitspieler 20 Münzen")
tv_station = TvStationIndustry("Fernsehsender", 70, 0, 50, [], SPECIAL, [6], "(Bei deinen Würfen)", "p", "Erhalte von einem Mitspieler deiner Wahl 50 Münzen")
buisness_center = BuisnessCenterIndustry("Bürohaus", 80, 0, 0, [], SPECIAL, [6], "(Bei deinen Würfen)", "p", "Tausche 1 Karte mit einem Mitspieler deiner Wahl")

station = Landmark("Bahnhof", 40, "station", "Würfle mit 2 Würfeln")
shopping_mall = Landmark("Einkaufszentrum", 100, "shopping_mall", "Erhalte +10 Münzen für jedes Cafe, Familienrestaurant, jede Bäckerei und jeden Mini-Markt")
amusement_park = Landmark("Freizeitpark", 160, "amusement_park", "Mache einen weiteren Zug wenn du einen Pasch wirfst")
radio_tower = Landmark("Funkturm", 220, "radio_tower", "Einmal im Zug kannst du deine Würfel neu werfen")

game = Game()
game.main_game_loop()
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast immer noch Unmengen an globalen Variablen, weil Dein Hauptprogramm nicht sauber in einer Funktion gekapselt ist (bakery, wheat_field...). Methoden wie `def_industries` oder `def_landmarks` machen so keinen Sinn.
`Industry.get_true_dependencies` benutzt ein undefiniertes `player`.
Methoden muß man aufrufen: self.get_true_dependencies(). Nur den Namen hinzuschreiben hat keinen Effekt. Deshalb ist der Bug mit `player` wahrscheinlich noch nicht aufgefallen.
Bei `Industry.get_profit` gibt es ein undefiniertes `get_true_depencies`.
Ein input so tief verschachtelt in TvStationIndustry.get_profit oder BuisnessCenterIndustry.get_profit sollte es nicht geben. Nutzerinteraktion sollte von Spiellogik möglichst getrennt sein.

Die Klasse `Game` ist ungünstig designed. Sie besteht zum Großteil nur aus isolierten Funktionen, die globale Variablen in Instanzvariablen verschleiern.

Insgesamt ist es in komisches Design, dass die Industrie-Instanzen eigentlich nur Blaupausen für die eigentlichen Industrien sind, deren Werte aber in den Player-Instanzen gespeichert werden.
Deshalb mußt Du player überall herumreichen. Da Du die Interaktion nicht sauber abgetrennt hast, mußt Du noch zusätzlich players, player_at_turn, roll, names bei get_profit dazugeben.

Als nächste Schritte würde ich vorschlagen, die Bugs zu beheben, eine main-Funktion einzuführen um alle globalen Variablen zu eliminieren.
Danach die Interaktion aus den get_profit-Methoden herausnehmen. Dann die Game-Klasse zerlegen und isolierte Funktionen als solche auch zu schreiben.
Benutzeravatar
grubenfox
User
Beiträge: 612
Registriert: Freitag 2. Dezember 2022, 15:49

Code: Alles auswählen

    def end_turn(self):
        if self.players[self.player_at_turn].landmarks[amusement_park] == 1 and roll1 == roll2:
            self.player_at_turn -= 1
hier fehlen auch noch zwei "self." [ohne die anführungszeichen]
lol44__44lol
User
Beiträge: 9
Registriert: Freitag 10. Februar 2023, 00:29

Sirius3 hat geschrieben: Dienstag 14. Februar 2023, 09:00 Dann die Game-Klasse zerlegen und isolierte Funktionen als solche auch zu schreiben.
wie soll ich dann auf variablen/listen zugreifen?
Ich habe nur zwei Ansätze:

1. Alle variablen/listen immer in jede Funktion mit geben

Oder

2. Alle Funktionen auflösen

(Beide Varianten scheinen für mich nicht optimal)
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Variante 2 ist natuerlich keine gangbarer Weg. Variante 1 hingegen ist der richtige Weg. Was daran ist nicht optimal? Man will wissen, welchen Zustand eine Funktion braucht, und welchen sie zurueckliefert. Das kann man bei globalen Variablen nicht. Eine weitere Stufe stellt dann bei langlebigem Zustand die Objektorientierung dar. Aber auch da hat man keinen globalen Zustand, sondern welchen, der sich auf ein konkretes "Ding" (zB Raumschiff und seine Position und Geschwindigkeit) bezieht.
lol44__44lol
User
Beiträge: 9
Registriert: Freitag 10. Februar 2023, 00:29

Ich kann zwar eine Variable in eine Funktion geben aber wie kann ich machen das die Funktion die veränderte Variable wieder zurück gibt?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Code: Alles auswählen

def berechne_was(eingabe):
    return eingabe * 1000
wert = 10
wert = berechne_was(wert)
Und das geht auch mit mehreren Werten, return kann ja ein Tupel zurueckgeben:

Code: Alles auswählen

def f():
    return 1, 2, 3
a, b, c = f()
Antworten