Würfeln in Matlab

Neue Frage »

liyaah Auf diesen Beitrag antworten »
Würfeln in Matlab
Meine Frage:
Hallo ihr lieben Helfer,
ich möchte gerne ein Würfelspiel in Matlab programmieren.
Regeln:
Spieler a spielt gegen Spieler b.
Ich entscheide wer anfängt.
Der Beginner würfelt so oft er will, wobei seine Augen addiert werden, aber:
1)er kann jederzeit stoppen womit seine augensumme gesichert wird und der Gegner am Zug ist
2)kommt eine 6 endet sein Zug mit 0 Punkten und der Gegner ist dran

So geht das dann hin und her, bis einer ein Ziel, sagen wir 100 Punkte erreicht.
Die Spieler müssen sich also überlegen, wie lange sie würfeln.
Mein Ziel ist es nun ein Programm zu schreiben, dass diese Situation simuliert.
z.B. soll Spieler a immer so lange würfeln bis er >= 15 Punkte hat und Spieler b bis er >= 17 Punkte hat.
Das würde ich dann gerne so 10000 mal durchspielen und sehen wie oft wer gewonnen hat.

Meine Ideen:
Ich habe mich mal an Matlab probiert, mit folgendem Ergebnis:
a=zeros(1,100000);
n=15
for i=1:100000
while a(i)<n
w=randi(6);
if w <6
a(i)=a(i)+w;
else
a(i)=0;
break
end
end
end

erfolg=0;
verlust=0;
for i=1:100000
if a(i)~=0
erfolg=erfolg+1;
else
verlust=verlust+1;
end
end

erfolg
verlust

Das ist jetzt erstmal völlig unabhängig vom Punkteziel des Spiels und auch nur für einen Spieler.
erfolg zeigt mir wie oft der Spieler es geschafft hat die Regel überhaupt einzuhalten (also ohne 6 bis mind. 15 zu würfeln).
Ich könnte das gleiche ja für Spieler b schreiben, z.B. mit n=17, aber ich weiß z.B. nicht wie ich matlab dann sagen soll, dass wenn a eine 6 gewürfelt oder gestoppt hat Spieler b an der Reihe ist usw..
Wisst ihr weiter?
liyaah Auf diesen Beitrag antworten »
RE: Würfeln in Matlab
Ich weiß leider nicht wie ich den Code schön posten kann, aber ich versuchs mal ein bischen besser:

a=zeros(1,100000);
n=15
for i=1:100000
while a(i)<n
w=randi(6);
if w <6
a(i)=a(i)+w;
else
a(i)=0;
break
end
end
end

erfolg=0;
verlust=0;
for i=1:100000
if a(i)~=0
erfolg=erfolg+1;
else
verlust=verlust+1;
end
end

erfolg
verlust
Airblader Auf diesen Beitrag antworten »

[ code ] ... Quelltext ... [ /code ]

Natürlich ohne die Leerzeichen.

Edit:

Mein Vorschlag würde in diese Richtung gehen (Matlab-/C-/JS-Pseudocode). Optimaler, flexibler und schöner würde man natürlich klassenorientiert arbeiten, aber du willst es ja mit Matlab umsetzen.

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
function score = throwDice(turnLimit) {
   score = 0;

   while (score < turnLimit) {
      val = randi(6);

      if (val < 6) { 
         score += val; 
      }
      else { 
         score = 0;
         break;
      }
   }
}

function [winner, playerScores] = startGame(turnLimit, gameLimit) {
   playerScores = [0 0];
   player = 0;

   while (max(playerScores) < gameLimit) {
      playerScores[player] += throwDice(turnLimit[player]);
      player = (player + 1) mod 2;   
   }

   winner = (player+1) mod 2;
}


Aufruf dann sozusagen mit

code:
1:
startGame([15 17], 100)


bzw., wenn du es oft ausführen willst,

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
wonGamesP1 = 0;
totalGames = 1000;

for (i=1; i <= totalGames; i++) {
   currentWinner = startGame([15 17], 100);
   
   if (!currentWinner) { wonGamesP1++; }
}

print 'Spieler 1 hat ' + wonGamesP1 + ' gewonnen.';
print 'Spieler 2 hat ' + (totalGames - wonGamesP1) + ' gewonnen.';


Ist nur aus dem Kopf runtergeschrieben, könnte also fehlerhaft sein. Aber die Idee sollte rüberkommen.

Edit #2:
Habe es aus Langeweile mal programmiert. Wenn man's eben auf Matlab anpasst, dann klappt es.

air
Mystic Auf diesen Beitrag antworten »

Hm, sehe ich das richtig, dass deine Spieler auch dann noch weiterwürfeln, wenn sie das gameLimit schon erreicht haben, das turnLimit aber noch nicht? verwirrt
Airblader Auf diesen Beitrag antworten »

Richtig. Alles wollte ich dann nicht vormachen. Augenzwinkern Es gibt noch 1-2 andere Dinge im obigen Code, über die man ein bisschen nachdenken muss, wenn man es auf Matlab umschreibt.

(Das ist übrigens ein "Fehler", der behoben werden sollte, da er den Spielausgang tatsächlich verändern kann)

Edit: Na gut, nachdem's schon angesprochen wurde: Ich würde dafür übrigens nicht über den Weg gehen, der erstmal naheliegt, und throwDice auch noch das gameLimit übergeben. Stattdessen würde ich mich darum kümmern, in startGame einfach ein kleineres turnLimit an throwDice zu übergeben, falls nötig.

air
Airblader Auf diesen Beitrag antworten »

Scheinbar mal wieder in gleich zwei Threads völlig umsonst die Mühe gemacht, zu helfen. Bei der Rate, die bei programmier-bezogenen Threads zumindest gefühlsmäßig besteht, ist es echt kein Wunder, dass einem die Lust daran vergeht. unglücklich
 
 
liyaah Auf diesen Beitrag antworten »

Hallo Airblader,
danke für deine Hilfe.
Es tut mir leid, dass ich mich bisher nicht gemeldet habe, aber es kam etwas sehr wichtiges dazwischen...
Jedenfalls habe ich mich jetzt mal mit deinem Programm beschäftigt.
throwDice ist ja relativ äquivalent zu meinem.
Die Spielerunterscheidung nach gerade und ungerade ist natürlich clever smile , aber matlab kann ja mit dem nullten Eintrag nichts anfangen. Deshalb habe ich alles ein bischen umgeschrieben:


code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function score = throwDice(turnLimit) 
   score = 0;

   while (score < turnLimit) 
      val = randi(6);

      if (val < 6) 
         score =score+ val; 
      
      else  
         score = 0;
         break;
      end
   end


code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function [winner, playerScores] = startgames(turnLimit,gameLimit) 
   playerScores = [0 0];
   player = 0;

   
   while max(playerScores) < gameLimit
      playerScores(player+1) = playerScores(player+1)+throwDice(turnLimit(player+1));
       player = mod(player + 1,2);  
   
      end
   winner = mod(player + 1,2)+1 ;
     


code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
wonGamesP1 = 0;
wonGamesP2 = 0
totalGames = 1000000;

for i=1:totalGames 
   currentWinner = startgames([17 17], 50);
   
   if currentWinner == 1 
       wonGamesP1 = wonGamesP1 +1;
   elseif currentWinner == 2
        wonGamesP2 = wonGamesP2 +1;
   end
end

wonGamesP1
wonGamesP2


So weit funktioniert alles auch super, aber eine Sache wird noch nicht beachtet: Hat der Beginner die (bei mir) 50-Marke erreicht, dann darf der Nicht-Beginner noch einen Zug durchführen.(Damit beide gleich viele Züge hatten.)
Hast du vielleicht eine Idee wie ich das noch reinschreiben könnte?

Viele Grüße
liyaah
Airblader Auf diesen Beitrag antworten »

Modifiziere

code:
1:
 while max(playerScores) < gameLimit


indem du eine Bool-Variable á la "lastTurn" einführst (nur eine von mehreren Möglichkeiten). Wo du den Wert wie zu setzen hast überlasse ich dir mal zum Nachdenken – so schwierig ist es nicht, zumal ich dir ja doch einen großen Teil der Arbeit abgenommen habe.

Das mit der Nullindizierung war übrigens Absicht – wie gesagt, ein paar Implementierungsdinge muss man dir ja auch noch überlassen.

air
liyaah Auf diesen Beitrag antworten »

Hab mich gerad nochmal kurz an das Problem, dass weitergewürfelt wird wenn das gamelimit erreicht wurde, aber das turnlimit nicht.
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function [winner, playerScores] = startgames(turnLimit,gameLimit) 
   playerScores = [0 0];
   player = 0;

   
   while max(playerScores) < gameLimit
      playerScores(player+1) = playerScores(player+1)+throwDice(min(turnLimit(player+1),(gameLimit-playerScores(player+1))))
       player = mod(player + 1,2);  
   
      end
   winner = mod(player + 1,2)+1 ;



Ich glaub das ist so richtig.
Was meinst du?
liyaah Auf diesen Beitrag antworten »

Zu dem Problem, dass der Nicht-Beginner nochmal würfeln darf, habe ich folgendes geschrieben:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
function [winner, playerScores] = startgames(turnLimit,gameLimit) 
   playerScores = [0 0];
   player = 0;

   
   while max(playerScores) < gameLimit
      playerScores(player+1) = playerScores(player+1)+throwDice(min(turnLimit(player+1),(gameLimit-playerScores(player+1))));
       player = mod(player + 1,2);  
   
   end
   if playerScores(2)<50
      playerScores(2) = playerScores(2) + throwDice(50-playerScores(2));
   end
   if playerScores(1)==max(playerScores(1),playerScores(2))
       winner=1;
   else
       winner=2;
   end
     
 winner


Es wäre schön, wenn du mir zu den letzten eiden Posts ein Feedback geben würdest.

Liyaah
Airblader Auf diesen Beitrag antworten »

Sieht gut aus Augenzwinkern

air
Neue Frage »
Antworten »



Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »