Risiko-Brettspiel-Kampf-Simulator

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.
Antworten
Casio
User
Beiträge: 5
Registriert: Dienstag 23. Oktober 2018, 17:32

Hallo Zusammen,
wir spielen in der WG zur Zeit gerne das Brettspiel "Risiko". Jedoch sind zum Ende des Spieles die Armeen sehr groß und das ewige Würfeln wird lästig. Mit einem Programm das, dass Auswürfeln einzelner Kämpfe übernimmt bin ich für meine Verhältnisse schon sehr weit gekommen. Jedoch versagt diese zentrale while-Schleife manchmal und erzeugt negative Punktestände, obwohl sie das nach meinem Verständnis von dem Quellcode gar nicht darf! Hat jemand einen Tipp wo mein Fehler liegt?

Code: Alles auswählen

from random import randint

Punkte_A = eval(input("Punkte des Angreifers zu Beginn:"))
Punkte_B = eval(input("Punkte des Verteidigers zu Beginn:"))


while Punkte_B or Punkte_A >= 0:
    # Würfel für den Angreifer
    a = randint(1, 6)
    b = randint(1, 6)
    c = randint(1, 6)

    # Würfel für den Verteidiger
    d = randint(1, 6)
    e = randint(1, 6)

    Würfel_A = [a, b, c]
    Würfel_V = [d, e]

    Sort_A = sorted(Würfel_A)
    Sort_B = sorted(Würfel_V)
    if Sort_A[2] > Sort_B[1]:
        Punkte_B -= 1
    elif Sort_A[2] == Sort_B[1]:
        Punkte_A -= 1
    else:
        Punkte_A -= 1

    if Sort_A[1] > Sort_B[0]:
        Punkte_B -= 1
    elif Sort_A[1] == Sort_B[0]:
        Punkte_A -= 1
    else:
        Punkte_A -= 1
    print("der Angriefer würfelt: ", Sort_A)
    print("der Verteidiger würfelt: ", Sort_B)
    print("Punktestand Angreifer: ", Punkte_A)
    print("Punktestand Verteidiger: ", Punkte_B)
    print("--------------------")

if Punkte_A > Punkte_B:
    print("der Angreifer gewinnt")
else:
    print("der Verteidiger gewinnt")
   
nezzcarth
User
Beiträge: 1755
Registriert: Samstag 16. April 2011, 12:47

Mal ein paar ausgewählte Punkte:
Wenn ich das richtig verstehe, ist unter anderem deine Schleifenbedigung fehlerhaft, da du es vmtl. so geschrieben hast, wie man es in der natürlichen Sprache sagen würde ("Solange a oder B größer/gleich null sind"). Es müsste aber so in Python übersetzt werden: "while punkte_b >=0 and punkte_a >=0". Statt 'eval' wäre 'int' die korrekte Wahl. Normale Variablennamen sollten per Konvention keine Großbuchstaben enthalten. Die ganzen Würfelwürfe könntest du in eine Funktion "roll()" oder so auslagern.
Zuletzt geändert von nezzcarth am Mittwoch 24. Oktober 2018, 18:35, insgesamt 1-mal geändert.
Sirius3
User
Beiträge: 18267
Registriert: Sonntag 21. Oktober 2012, 17:20

@Casio: Du hast doch Punkte_X -=1 in Deiner while-Schleife, also ist es doch prinzipiell möglich, dass negative Punkte rauskommen. Die while-Schleife wird erst beendet, wenn Punkte_B == 0 und Punkte_A < 0. Also muß Punkte_A negativ sein. Wird Punkte_b negativ, hast Du eine Endlosschleife. Wie soll denn die Bedingung eigentlich heißen?

Zum Code allgemein: `eval` hat in einem vernünftigen Programm nichts verloren. Hier willst Du doch nur `int` verwenden. Am Anfang der while-Schleife wird viel Code wiederholt. Am besten wäre es, eine Funktion zu schreiben, die n sortierte Würfelwürfe zurückgibt.

Wenn der elif-Block und der else-Block identisch sind, braucht es nur den else-Block.
Benutzeravatar
ThomasL
User
Beiträge: 1378
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Code: Alles auswählen

while Punkte_B or Punkte_A >= 0:
solange Punkte_B ungleich Null und damit True ist wird die Kondition Punkte_A >= 0 nicht geprüft
das passiert erst wenn Punkte_B gleich Null und damit False ist.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
__blackjack__
User
Beiträge: 14033
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mal ein Versuch von mir die Regeln in Code zu giessen:

Code: Alles auswählen

#!/usr/bin/env python3
from functools import partial
from random import randint


roll_die = partial(randint, 1, 6)


def roll_dice(dice_count):
    return sorted((roll_die() for _ in range(dice_count)), reverse=True)


def do_round(attacker_count, defender_count):
    attacker_rolls = roll_dice(min(attacker_count, 3))
    print(f'Der Angreifer würfelt {attacker_rolls}.')
    defender_rolls = roll_dice(min(defender_count, 2))
    print(f'Der Verteidiger würfelt {defender_rolls}.')
    
    for attacker_roll, defender_roll in zip(attacker_rolls, defender_rolls):
        if attacker_roll > defender_roll:
            attacker_count -= 1
        else:
            defender_count -= 1
    
    return attacker_count, defender_count


def battle(attacker_count, defender_count):
    if attacker_count < 0 or defender_count < 0:
        raise ValueError('counts must not be negative')
    
    while attacker_count and defender_count:
        attacker_count, defender_count = do_round(
            attacker_count, defender_count
        )
        print(f'# Angreifer: {attacker_count}')
        print(f'# Verteidiger: {defender_count}')
        print('-' * 20)
    
    return attacker_count, defender_count


def main():
    attacker_count = int(input('Anzahl Angreifer: '))
    defender_count = int(input('Anzahl Verteidiger: '))
    
    attacker_count, defender_count = battle(attacker_count, defender_count)
    
    winner = 'Angreifer' if attacker_count > defender_count else 'Verteidiger'
    print(f'Der {winner} gewinnt.')


if __name__ == '__main__':
    main()
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Casio
User
Beiträge: 5
Registriert: Dienstag 23. Oktober 2018, 17:32

@__blackjack__ :
habe gerade deine Variante nachvollzogen. War für mich viel neues dabei --> zip() und partial() sind auf jeden Fall ziemlich praktisch. Manchmal knarzt das Programm ein bischen.
Beispiel: Hier in Runde 3 würfelt der Verteidiger besser, bekommt aber trotzdem Punkte abgezogen.

Code: Alles auswählen

Anzahl Angreifer: 5
Anzahl Verteidiger: 5
Der Angreifer würfelt [6, 5, 3].
Der Verteidiger würfelt [4, 1].
# Angreifer: 3
# Verteidiger: 5
--------------------
Der Angreifer würfelt [5, 1, 1].
Der Verteidiger würfelt [4, 2].
# Angreifer: 2
# Verteidiger: 4
--------------------
Der Angreifer würfelt [4, 3].
Der Verteidiger würfelt [6, 6].
# Angreifer: 2
# Verteidiger: 2
--------------------
Der Angreifer würfelt [6, 1].
Der Verteidiger würfelt [4, 1].
# Angreifer: 1
# Verteidiger: 1
--------------------
Der Angreifer würfelt [2].
Der Verteidiger würfelt [1].
# Angreifer: 0
# Verteidiger: 1
--------------------
Der Verteidiger gewinnt.
Sirius3
User
Beiträge: 18267
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Bedingung müßt doch ›attacker_roll <= defender_roll‹ heißen?
Antworten