Roulette-Simulation in Python

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
luk1eeh9e
User
Beiträge: 2
Registriert: Dienstag 23. November 2021, 13:03

bei diesem Roulette gehen wir von 33 Feldern aus, wobei gerade Zahlen rot sind und ungerade Zahen schwarz. Die 0 ist eine besondere Zahl, da sie grun ist (also we- ¨ der rot noch schwarz), das klassische Roulette hat etwas andere REgeln.

Um einen Eindruck zu erwartenden Gewinne zu erhalten, sollen wir zuerst eine Simulation
durchfuhren:

ˆ wir sollen insgesamt n Nächte Roulette spielen.
ˆ Jede Nacht sollen Sie k Spiele durchfuhren. ¨
ˆ In jedem Spiel sollen Sie e Euro setzen.
ˆ wir sollen bei jedem Spiel zufällig auf Rot oder auf Schwarz setzen.
ˆ Anschließend erhalten wir Einsatz verdoppelt als Gewinn g, wenn im Spiel die Farbe auftrat,
auf welche Sie gesetzt haben.
ˆ Spielen wir nun fur ein Jahr Roulette mit 100 Spielen pro Nacht und lassen Sie sich Ihren Gewinn ¨
auszahlen (geben Sie g aus).
ˆ Implementieren die beschriebene Simulation. Die Variablen n, k und e werden durch den
Benutzer eingegeben.

Hallo , ich brauche Hilfe, könnte mir bitte jemand die Lösüng zeigen ? Grüß
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bitte einmal diesen Beitrag lesen: An alle Schüler und Studenten mit Informatikproblemen. Danke. 🙂
Benutzeravatar
__blackjack__
User
Beiträge: 13063
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Hm, jetzt hab ich gewartet ob noch ein Struktogramm folgt, aber das muss ich dann wohl selbst machen. 😉
Bild
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
luk1eeh9e
User
Beiträge: 2
Registriert: Dienstag 23. November 2021, 13:03

__blackjack__ hat geschrieben: Dienstag 23. November 2021, 15:16 Hm, jetzt hab ich gewartet ob noch ein Struktogramm folgt, aber das muss ich dann wohl selbst machen. 😉
Bild
hallo ,vielen dank aber, Struktogramm kann ich nicht übersetzen. Aber ich habe ein Programm geschrieben, ist hier:


import random

grün = [0]
rot = [2,4,6,8,9,10,14,16,18,20,22,24,26,28,30,32]
schwarz = [1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33]
drehen = random.randint (0,33)
#Program
bet = int(input("Geben Sie Ihre Wetten ein: "))
farbe = input("wählen Sie eine Farbe: ")
print ("das Rad dreht sich")

if drehen in grün:
gewinnende_farbe = "grün"
print("Der Ball landete auf", gewinnende_farbe)
if drehen in rot:
gewinnende_farbe = "rot"
print("Der Ball landete auf", gewinnende_farbe)
if drehen in schwarz:
gewinnende_farbe = "schwarz"
print("Der Ball landete auf", gewinnende_farbe)

if gewinnende_farbe == farbe:
print("Glückwunsch sie haben gewonnen!")
print("Sie haben gewonnen", bet*2, "!")

else:
print("Entschuldigung, Sie haben verloren.")


Aber ich weiß nicht, wie und wo ich Nächte, Spiele und Geld in diesen Code schreiben soll damit ich 100 Spiele pro Nacht im Jahr berechnen kann. können Sie mir bitte dabei helfen?
Benutzeravatar
__blackjack__
User
Beiträge: 13063
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@luk1eeh9e: Den Beitrag muss man nicht komplett zitieren, der steht doch bereits da.

Beim anschauen von dem Python-Quelltext ist mir ein Fehler im Struktogramm aufgefallen, und eine offensichtliche Optimierungsmöglichkeit:

Bild

Der Fehler war, dass man Zahlen zwischen 0 und 32 hat. Denn die 0 ist ja auch eine der 33 Zahlen. Damit ist die Zahl 33 selbst nicht mehr auf dem Roulette-Rad. Der Fehler ist auch in dem Python-Programm!

Die Zahlen zu den Farben in Listen von Hand alle hin zu schreiben macht unnötig Arbeit und ist fehleranfällig. Und in den Listen sind dann auch tatsächlich Fehler drin. Es gibt mindestens eine Zahl die Rot *und* Schwarz ist, und mindestens eine die vergessen wurde.

Man kann die Farbe wesentlich kürzer ermitteln. Mit einem Vergleich mit einem Wert für Grün und einer kleinen Rechnung für Rot und Schwarz. Der Hinweis steht bereits in der Aufgabe, welche mathematische Eigenschaft die Zahlen haben die Rot sind.

`drehen` ist kein guter Name für einen ”passiven” Wert. Das beschreibt ja eine Tätigkeit und wäre etwas für eine Funktion oder eine Methode.

Die drei Fälle der ersten drei ``if``-Anweisungen schliessen sich ja aus (oder würden sie zumindest wenn da keine Fehler in den Listen wären), also sind die zweiten ``if`` eigentlich ein Fall für ``elif``. Und dann macht es auch immer Sinn über ein ``else`` nachzudenken um sicherzustellen, dass einem da wirklich kein Fall durchrutschen kann, auch wenn das eigentlich nicht möglich wäre. Ist es hier ja aber wegen Fehlern in den Listen.

Man wiederholt/kopiert möglichst keinen Code (und auch keine Daten). Das macht unnötig Arbeit beim schreiben und beim ändern, und ist fehleranfällig, weil man immer aufpassen muss alles anzupassen, und auch alles gleichwertig anzupassen. Wenn der gleiche Code am Anfang oder am Ende von jedem ``if``/``elif``/``else``-Zweig steht, dann kann man den in der Regel *einmal* davor beziehungsweise danach schreiben.

Die `print()`-Ausgaben sollten da nicht sein. Niemand will und wird das lesen was da bei mehreren zehntausend Spielen ausgegeben wird, die laut Aufgabe simuliert werden sollen. Das verlangsamt das Programm auch nur unnötig.

Wenn man etwas wiederholen möchte, verwendet man Schleifen.

Auch wenn das alles eigentlich recht wenig Code ist, könnte es gerade für Anfänger auch Sinn machen sich mit Funktionen auseinanderzusetzen und das Problem in mehrere kleinere Teilprobleme aufzuteilen, die jeweils durch eine eigene Funktion gelöst werden. Die kann man dann einzeln entwickeln und testen. Das macht es einfacher und übersichtlicher/verständlicher. (Wenn man den Funktionen gute Namen gibt.)

Zwischenstand:

Code: Alles auswählen

#!/usr/bin/env python3
import random


def main():
    grün = [0]
    rot = [2, 4, 6, 8, 9, 10, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]
    schwarz = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31]
    #
    # FIXME Die Listen sind nicht korrekt.  Entweder korrigieren bis der Code an
    #   diesem ``assert`` vorbei kommt, oder sinnvoller lösen, ohne alle Zahlen
    #   hinschreiben zu müssen.
    #
    assert sorted(grün + rot + schwarz) == list(range(33))

    bet = int(input("Geben Sie Ihre Wette ein: "))
    #
    # FIXME Den Benutzer seine Farbe wählen zu lassen entspricht nicht der
    #   Aufgabenstellung.
    #
    farbe = input("Wählen Sie eine Farbe: ")
    #
    # TODO Die `print()`-Ausgaben entfernen.
    #
    print("Das Rad dreht sich...")
    zahl = random.randint(0, 32)

    if zahl in grün:
        gewinnende_farbe = "grün"
    elif zahl in rot:
        gewinnende_farbe = "rot"
    elif zahl in schwarz:
        gewinnende_farbe = "schwarz"
    else:
        assert False, f"unbekannte Farbe für {zahl!r}"

    print(f"Der Ball landete auf {gewinnende_farbe}.")

    if gewinnende_farbe == farbe:
        print("Glückwunsch sie haben gewonnen!")
        print("Sie haben gewonnen", bet * 2, "!")
    else:
        print("Entschuldigung, Sie haben verloren.")


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
ulipy
User
Beiträge: 83
Registriert: Mittwoch 17. November 2021, 21:42
Wohnort: Ba-Wü

@blackjack
Kann man hier eigentlich niemanden loben :o ?
Ich glaubs nicht, mit welcher Leichtigkeit du hier in Null Komma Nichts so umfassende Sachen hinlegst... (Prüfung hat natürlich keine stattgefunden :wink: )
Py::: 1. funktional zuverlässig, 2. Anfänger-lesbar, 3. Py-Konformität
Benutzeravatar
__blackjack__
User
Beiträge: 13063
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ulipy: Na so besonders kompliziert und umfangreich ist die Aufgabenstellung ja nicht. Und ich programmiere halt schon eine Weile. Seit dem ich in der Schule damals Struktogramme für Pascal-Programme zeichnen lernen musste. Damals noch von Hand.

Hier wäre das Pascal-Programm, welches ich damals geschrieben hätte:

Code: Alles auswählen

program Roulette;

type
  TColor = (Red, Black, Green);
  TSpin = 0..32;

var
  nightCount, gameCount, i: Word;
  bet: Byte;
  totalGameCount, profit: LongInt;
  playerColor, spinColor: TColor;
  spinResult: TSpin;

begin
  Randomize;
  Write('      Anzahl Nächte? ');
  ReadLn(nightCount);
  Write('Anzahl Spiele/Nacht? ');
  ReadLn(gameCount);
  Write('  Einsatz pro Spiel? ');
  ReadLn(bet);

  totalGameCount := nightCount * gameCount;
  profit := 0;
  for i := 1 to totalGameCount do
    begin
      playerColor := TColor(Random(2));
      spinResult := Random(High(TSpin) + 1);
      if spinResult = 0 then
        spinColor := Green
      else
        if Odd(spinResult) then spinColor := Black else spinColor := Red;

      if playerColor = spinColor then
        profit := profit + bet * 2
      else
        profit := profit - bet;

  WriteLn('Gewinn: ', profit);
end.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
Dennis89
User
Beiträge: 1152
Registriert: Freitag 11. Dezember 2020, 15:13

ulipy hat geschrieben: Dienstag 23. November 2021, 23:05 Kann man hier eigentlich niemanden loben :o ?
Gilt nicht die allgemeine Regel: Nicht gemeckert ist genügend gelobt?

Für dein 'FIXME' solltest du dich damit beschäftigen wie du einen Zahlenbereich bestimmen kannst, wie man mit Listen arbeitet und wie man Bedingungen prüft. Die rechnerische Herausforderung, ob eine Zahl rot oder schwarz ist sollte sich in Grenzen halten. Aber auch da bietet Python eine geschickte Möglichkeit.


Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
ulipy
User
Beiträge: 83
Registriert: Mittwoch 17. November 2021, 21:42
Wohnort: Ba-Wü

@Dennis (offtopic..)
Ja, bei den Schwaben ist das schon so... :)
Py::: 1. funktional zuverlässig, 2. Anfänger-lesbar, 3. Py-Konformität
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

In Berlin auch.
Benutzeravatar
__blackjack__
User
Beiträge: 13063
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

In Berlin ist ja sogar anmotzen lieb gemeint. Berliner Verkehrsbetriebe zu einer Beschwerde warum der Busfahrer so ausfallend war, wo doch der Werbeslogan „BVG. Weil wir Dich lieben.“ lautet: „Weil wir Dich lieben — wir können's halt nicht immer so zeigen.“ 🤣

Um dem Thema wieder ein bisschen näher zu kommen: Auch bei dem Roulette in Pascal hätte ich natürlich damals handgeschriebenes Assembler eingebaut:

Code: Alles auswählen

program Roulette;

type
  TColor = (Red, Black, Green);
  TSpin = 0..32;

var
  nightCount, gameCount, i: Word;
  bet: Byte;
  totalGameCount, profit: LongInt;
  playerColor: TColor;
  spinResult: TSpin;

begin
  Randomize;
  Write('      Anzahl Nächte? ');
  ReadLn(nightCount);
  Write('Anzahl Spiele/Nacht? ');
  ReadLn(gameCount);
  Write('  Einsatz pro Spiel? ');
  ReadLn(bet);

  totalGameCount := nightCount * gameCount;
  profit := 0;
  for i := 1 to totalGameCount do
    begin
      playerColor := TColor(Random(2));
      spinResult := Random(High(TSpin) + 1);
      asm
        mov al,spinResult
        or  al,al
        jnz @L0
        mov al,Green
        jmp @L1
      @L0:
        and al,1
      @L1:
        db 66h
        xor bx,bx
        mov bl,bet
        cmp al,playerColor
        jne @L2
        shl bx,1
        jmp @L3
      @L2:
        db 66h
        neg bx
      @L3:
        db 66h
        add word ptr profit,bx
      end;
    end;
  WriteLn('Gewinn: ', profit);
end.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
__blackjack__
User
Beiträge: 13063
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Also einerseits ist eine Laufzeit von 22 Minuten und 49 Sekunden ganz schön lang, andererseits ca. 22.852 mal schneller als tatsächlich ein ganzes Jahr lang in Echtzeit zu spielen. 😀

Code: Alles auswählen

   10 X=RND(-TI):P=0
   20 INPUT"# NAECHTE";NC:INPUT"# SPIELE/NACHT";GC:INPUT"EINSATZ/SPIEL";B
   30 TI$="000000":FOR I=1 TO NC:PRINT I:PRINT"{UP}";:FOR J=1 TO GC
   40 PC=INT(RND(1)*2):SR=INT(RND(1)*33)
   50 IF SR AND (SR AND 1)=PC THEN P=P+2*B:GOTO 70
   60 P=P-B
   70 NEXT:NEXT:PRINT"GEWINN:";P:PRINT TI$
Testlauf:

Code: Alles auswählen

RUN
# NAECHTE? 365
# SPIELE/NACHT? 100
EINSATZ/SPIEL? 1
GEWINN: 16237
002249

READY.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
__blackjack__
User
Beiträge: 13063
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Kleine Erweiterung um zwei Kommentarzeilen mit Anweisungen/Typdeklarationen für den Basic-Boss Compiler:

Code: Alles auswählen

    0 rem@ £protocol:£shortif:£fastfor:£lineoff
    1 rem@ £word nc,i=fast:£byte gc,b,j=fast,sr=fast
Und schon läuft es etwas mehr als doppelt so schnell in 10 Minuten und 27 Sekunden:

Code: Alles auswählen

RUN
# NAECHTE? 365
# SPIELE/NACHT? 100
EINSATZ/SPIEL? 1
GEWINN: 16318
001027

READY.
Und eine Lösung in Python:

Code: Alles auswählen

#!/usr/bin/env python3
from enum import Enum
from itertools import islice
from random import choice, randint

from more_itertools import repeatfunc


class Color(Enum):
    BLACK = 0
    RED = 1
    GREEN = 2

    @classmethod
    def from_number(cls, number):
        return cls.GREEN if number == 0 else cls(number % 2)


def ask_integer(prompt):
    while True:
        try:
            return int(input(prompt))
        except ValueError:
            print("Fehler! Bitte eine ganze Zahl eingeben!")


def main():
    night_count = ask_integer("Anzahl der Nächte: ")
    games_per_night = ask_integer("Anzahl Spiele pro Nacht: ")
    bet = ask_integer("Einsatz pro Spiel: ")

    player_choices = repeatfunc(choice, None, [Color.RED, Color.BLACK])
    roulette_numbers = repeatfunc(randint, None, 0, 32)
    roulette_colors = map(Color.from_number, roulette_numbers)
    profit = sum(
        2 * bet if player == bank else -bet
        for player, bank in islice(
            zip(player_choices, roulette_colors), night_count * games_per_night
        )
    )
    print(profit)


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten