diff --git a/README.md b/README.md index 90df23b5c..17ffb69a0 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,61 @@ # MATLAB Fall 2014 – Research Plan (Template) (text between brackets to be removed) -> * Group Name: (be creative!) -> * Group participants names: (alphabetically sorted by last name) -> * Project Title: (can be changed later) +> * Group Name: Royal Flush +> * Group participants names: Weber Tim, Lionel Gulich, Jan Speckien +> * Project Title: Active and passive strategies in Texas hold'em ## General Introduction +Texas hold’em is a variation of the card game of poker. The game is played with a 52-card deck that includes four suits: hearts, diamonds, clubs and spades with each 13 ranks. The ranking from the top down is: A, K, Q, J, 10, 9, 8, 7, 6, 5, 4, 3, and 2. All the players start with the same amount of money. When a player has no more money, he is eliminated. The goal is to be the last man standing with all the cash of the opponents. The game is played in rounds and every round is divided into four phases: +1) Every player gets handed two cards called the hold cards, these are used for one’s own benefit and kept secret for the others +2) Three cards are dealt on the table called “the flop”, from now on every player can make use of the cards on table +3) Then one more is dealt called “the turn” +4) A last card called “the river” is dealt + +The rules are straight forward, in every phase one either: +- “folds” that means you don’t want to play anymore in this round +- “raises” that is when a player puts in more money on the table to play for +- “calls” which means you put in as much money as there is on the table +- “checks” that is when a player doesn’t want to do any of the above which is only possible when nobody has raised the pot. +As soon as somebody has raised the amount of money to play for the others have to call to get into the next phase or they drop out. + +A player wins a round when all his opponents have folded their cards or at the end when comes to a “showdown” and every party has come to an agreement on how much money to play for, they show each other their cards and the player with the best combination of cards wins the round. + +Texas hold’em is a game of strategy, psychology and probability and gamble. It often doesn’t even come to the showdown because a player makes another believe that he has the strongest hand through his way of raising the pot. Of course it is also possible to lure opponents into a trap or to just gamble, luck is involved after all. + +Our goal is to research what style of play prevails in a heads-up in Texas hold’em. Even further, if time alouds it, how beneficiary learning the other’s pattern is to winning the game. +Our program is going to include a dealer whom is dealing a random numbers with a certain value, with that abstraction we avoid programming the complexity of all the combinations of cards. Players are going to make decisions based on the card’s value. Later on we want to include the height of a raise of the opponent into the decision making. A last step would be to give one of the players a learning effect with which he studies the pattern of the other player and plays accordingly. -(States your motivation clearly: why is it important / interesting to solve this problem?) -(Add real-world examples, if any) -(Put the problem into a historical context, from what does it originate? Are there already some proposed solutions?) ## The Model +There are a couple of variables that would be interesting to study, depending how far we come with our model. +- The first being the thresholds which decide how conservative/aggressive the players are and because of that what play style prevails +- The second one is the quality of the cards that are dealt and which impact that has on the outcome +- Further interesting are things like learning the opponents play style: can player A capitalise on a too aggressive player B after A has learnt B’s pattern to play. Or the other way around, that B starts to bluff A out of the game because A is too timid. -(Define dependent and independent variables you want to study. Say how you want to measure them.) (Why is your model a good abtraction of the problem you want to study?) (Are you capturing all the relevant aspects of the problem?) ## Fundamental Questions - -(At the end of the project you want to find the answer to these questions) -(Formulate a few, clear questions. Articulate them in sub-questions, from the more general to the more specific. ) + - Is an aggressive or a passive style of play the most successful in a heads-up in Texas hold'em? + - What influence does the quality of the cards have? + - What changes if a player can decide how much he wants to raise the pot? + - Will studying the opponent's pattern lead to a more successful outcome? ## Expected Results - -(What are the answers to the above questions that you expect to find before starting your research?) +From personal experience we think the more aggressive player will be more successful over a long period of time. +But it all depends on how the risk-thresholds are set. ## References -(Add the bibliographic references you intend to use) -(Explain possible extension to the above models) -(Code / Projects Reports of the previous year) - +- ## Research Methods -(Cellular Automata, Agent-Based Model, Continuous Modeling...) (If you are not sure here: 1. Consult your colleagues, 2. ask the teachers, 3. remember that you can change it afterwards) +We don't know yet what kind of model we are going to use but we guess cellular atomata might be interesting to show a learning effect. ## Other -(mention datasets you are going to use) + diff --git a/code/README.md b/code/README.md index cf73f2a80..25128b7c5 100644 --- a/code/README.md +++ b/code/README.md @@ -1,3 +1,5 @@ # Code Folder Your code goes here. You could also replace the content of this file with something more meaningful + +The main executable file currently is "runheadsup.m" \ No newline at end of file diff --git a/code/adjustRandValue.m b/code/adjustRandValue.m new file mode 100644 index 000000000..702a92dc4 --- /dev/null +++ b/code/adjustRandValue.m @@ -0,0 +1,9 @@ +function [ newRandValue ] = adjustRandValue( randValue, sigma ) + + newRandValue=-1; + + while newRandValue<0 || newRandValue>1 + newRandValue=sigma*randn+randValue; + end +end + diff --git a/code/headsup.m b/code/headsup.m new file mode 100644 index 000000000..808953cd9 --- /dev/null +++ b/code/headsup.m @@ -0,0 +1,182 @@ + + +function[EndCreditP1, EndCreditP2,x,Pot] = headsup(CP1,CP2,RiskP1,RiskP2) %Funktionsaufruf + + + +%% S T A R T V A R I A B L E +Player_1 = RiskP1; %Risikobereitschaft P1 +Player_2 = RiskP2; %Risikobereitschaft P2 + +BetValue = 1; %Einsatz +Blind = 1; %Blind-einsatz + +CreditP1 = CP1; +CreditP2 = CP2; + +PlayP1 = [0 0]; % [ Wert Karte P1 | Wert Bet P1 ] +PlayP2 = [0 0]; % [ Wert Karte P2 | Wert Bet P2 ] + +%% S P I E L V A R I A B L E N + + +PlayP1(1) = rand; %Einstigskarte P1 +PlayP2(1) = rand; %Einstigskarte P2 + +Pot = 0; % Geld im Pot +x = 0; % Anzahl Runden + + + +%% Blind + + PlayP1(2) = Blind; + PlayP2(2) = Blind; + + +%% P R E F L O P +% 1. W E T T R U N D E + +if PlayP1(1) >= Player_1 % Raise bzw. Call P1 + if CreditP1-PlayP1(2)>0 + PlayP1(2) = PlayP1(2)+BetValue; % Gewetteter Betrag P1 + end +end; +if PlayP2(1) >= Player_2 % Raise bzw. Call P2 + if CreditP2-PlayP2(2)>0 + PlayP2(2) = PlayP2(2)+BetValue; % Gewetteter Betrag P2 + end +end; + + +%% F L O P +% 2. W E T T R U N D E + + % 3 neue Karten +if PlayP1(2) > 0 && PlayP2(2) > 0 %Beide wollen Spielen + + PlayP1(1) = adjustRandValue(PlayP1(1),.4); %Handkarten aktualisiert nach altem Kartenwert + PlayP2(1) = adjustRandValue(PlayP2(1),.4); %Handkarten aktualisiert nach altem Kartenwert + + + x= x +1; % Anzahl Runden + + % E I N S A T Z A U F F L O P + + % Obwohl schon Geld investiert wurde Gilt die Gleiche Grenze! + + if PlayP1(1) >= Player_1 %Raise bzw. Call P1 + if CreditP1-PlayP1(2)>0 + PlayP1(2) = PlayP1(2)+1; %Achtung Bet ist immernoch 1 + end + end; + if PlayP2(1) >= Player_2 % Raise bzw. Call P2 + if CreditP2-PlayP2(2)>0 + PlayP2(2) = PlayP2(2)+1; + end + end; +end; +%% T U R N +% 3. W E T T R U N D E + % 1 neue Karte + %if PlayP1(2) == 2 && PlayP2(2) == 2 %%%%%!!!!!!!! + +if PlayP1(2) == PlayP2(2) %Beide wollen Spielen + + PlayP1(1) = adjustRandValue(PlayP1(1),0.2); %Handkarten aktualisiert nach altem Kartenwert + PlayP2(1) = adjustRandValue(PlayP2(1),0.2); %Handkarten aktualisiert nach altem Kartenwert + + + x= x +1; % Anzahl Runden + + % E I N S A T Z A U F T U R N + + + if PlayP1(1) >= Player_1 % Raise bzw. Call P1 + if CreditP1-PlayP1(2)>0 + PlayP1(2) = PlayP1(2)+1; + end + end; + if PlayP2(1) >= Player_2 % Raise bzw. Call P2 + if CreditP2-PlayP2(2)>0 + PlayP2(2) = PlayP2(2)+1; + end + end; + +end; +%% R I V E R +% 4. W E T T R U N D E ------------------% + % 1 neue Karte + +if PlayP1(2) == PlayP2(2) %Beide wollen Speilen + PlayP1(1) = adjustRandValue(PlayP1(1),0.1); %Handkarten aktualisiert nach altem Kartenwert + PlayP2(1) = adjustRandValue(PlayP2(1),0.1); %Handkarten aktualisiert nach altem Kartenwert + + + x= x +1; % Anzahl Runden + + % E I N S A T Z A U F R I V E R + + + if PlayP1(1) >= Player_1 %Raise bzw. Call P1 + if CreditP1-PlayP1(2)>0 + PlayP1(2) = PlayP1(2)+1; + end + end; + if PlayP2(1) >= Player_2 % Raise bzw. Call P2 + if CreditP2-PlayP2(2)>0 + PlayP2(2) = PlayP2(2)+1; + end + end; +end; +%% R A N D O M + +Pot = PlayP1(2) + PlayP2(2); %Pot +EndCreditP1 = CreditP1-PlayP1(2); %EndCreditP1 +EndCreditP2 = CreditP2-PlayP2(2); %EndCreditP2 +%% S H O W D O W N + +if PlayP1(2) == Blind && PlayP2(2) == Blind %Kein Spiel + %disp('Draw: '); + %disp(Pot - PlayP1(2)); +end; + +if PlayP1(2) > PlayP2(2) %P2 Bietet nicht mehr + %disp('Player 1 Wins: '); + %disp(Pot - PlayP1(2)); + EndCreditP1 = EndCreditP1+Pot; +end; + +if PlayP1(2) < PlayP2(2) %P1 Bietet nicht mehr + %disp('Player 2 Wins:'); + %disp(Pot - PlayP2(2)); + EndCreditP2 = EndCreditP2+Pot; +end; + +if PlayP1(2) == PlayP2(2) %beide Spielen ALLE Runden + %disp('SHOWDOWN') + if PlayP1(1) > PlayP2(1) + %disp('Player 1 Wins: '); + %disp(Pot - PlayP1(2)); + EndCreditP1 = EndCreditP1+Pot; + elseif PlayP1(1) == PlayP2(1) + %disp('Draw'); + EndCreditP1 = EndCreditP1+PlayP1(2); + EndCreditP2 = EndCreditP2+PlayP2(2); + elseif PlayP2(1) > PlayP1(1) + %disp('Player 2 Wins:'); + %disp(Pot - PlayP2(2)); + EndCreditP2 = EndCreditP2+Pot; + end; +end; + + + + + +%% B I L A N Z + +%% Bilanz = ['gespielte Runden ' num2str(x) ' EndCredit P1: ' num2str(EndCreditP1) '|' 'EndCredit P2: ' num2str(EndCreditP2)]; +%%disp(Bilanz); + +end %End of the Function \ No newline at end of file diff --git a/code/main.m b/code/main.m new file mode 100644 index 000000000..4fbc42acb --- /dev/null +++ b/code/main.m @@ -0,0 +1,46 @@ +%% Startvariablen + + +n = 1000 % Anzahl simulierter Spiele +RiskP1 = 0.3 +RiskP2 = 0.4 +Startkapital = 20 + + +%% Auswertungsvariablen + +WinsP1=0; % Anzahl Siege Player 1 +WinsP2=0; % Anzahl Siege Player 2 +Rounds=0; + + +%% Schleife f?r Pokerrunden + +for i=1:n + ResultOfGame=runPokerGame(RiskP1,RiskP2,Startkapital); + Rounds = Rounds + ResultOfGame(3); + if ResultOfGame(4)==1 + WinsP1=WinsP1+1; + elseif ResultOfGame(4)==2 + WinsP2=WinsP2+1; + else + disp(ResultOfGame(4)) + disp('Error with Result of Game') + end +end + + + + + + + +%% Statistik und Auswertung + +WinsP1=WinsP1/n*100; +WinsP2=WinsP2/n*100; +Rounds=Rounds/n; + +sprintf('Wins Player 1: %d %', WinsP1) +sprintf('Wins Player 2: %d %', WinsP2) +sprintf('Average Rounds played: %d', Rounds) \ No newline at end of file diff --git a/code/poker_v2.m b/code/poker_v2.m new file mode 100644 index 000000000..1e66226b9 --- /dev/null +++ b/code/poker_v2.m @@ -0,0 +1,157 @@ +clear all; %Alle Variablen L�schen + +%% S T A R T V A R I A B L E N +Player_1 = 0.3; %Risikobereitschaft P1 +Player_2 = 0.6; %Risikobereitschaft P2 + +BetValue = 1; %Einsatz + +StartKapital = 12; %Startkapital + +CreditP1 = StartKapital; +CreditP2 = StartKapital; + +PlayP1 = [0 0]; % [ Wert Karte P1 | Wert Bet P1 ] +PlayP2 = [0 0]; % [ Wert Karte P2 | Wert Bet P2 ] + +%% S P I E L V A R I A B L E N + + +PlayP1(1) = rand; %Einstigskarte P1 +PlayP2(1) = rand; %Einstigskarte P2 + +Pot = 0; % Geld im Pot +x = 0; % Anzahl Runden +%% P R E F L O P +% 1. W E T T R U N D E + +if PlayP1(1) >= Player_1; % Raise bzw. Call P1 + PlayP1(2) = BetValue; % Gewetteter Betrag P1 +end; +if PlayP2(1) >= Player_2; % Raise bzw. Call P2 + PlayP2(2) = BetValue; % Gewetteter Betrag P2 +end; + + +%% F L O P +% 2. W E T T R U N D E + + % 3 neue Karten +if PlayP1(2) == 1 && PlayP2(2) == 1; %Beide wollen Speilen + ChanceP1 = ((rand + rand + rand + PlayP1(1))/4); + %Neue Karten P1 Nach Flop Normiert + ChanceP2 = ((rand + rand + rand + PlayP2(1))/4); + %Neue Karten P1 Nach Flop Normiert + PlayP1(1) = ChanceP1; + PlayP2(1) = ChanceP2; + + x= x +1; % Anzahl Runden + + % E I N S A T Z A U F F L O P + + % Obwohl schon Geld investiert wurde Gilt die Gleiche Grenze! + + if PlayP1(1) >= Player_1; %Raise bzw. Call P1 + PlayP1(2) = PlayP1(2)+1; %Achtung Bet ist immernoch 1 + end; + if PlayP2(1) >= Player_2; % Raise bzw. Call P2 + PlayP2(2) = PlayP2(2)+1; + end; +end; +%% T U R N +% 3. W E T T R U N D E + % 1 neue Karte +if PlayP1(2) == 2 && PlayP2(2) == 2; %Beide wollen Speilen + NP1 = ((rand + PlayP1(1)*4)/5); %Neue Karten P1 nach Turn Normiert + NP2 = ((rand + PlayP2(1)*4)/5); %Neue Karten P2 nach Turn Normiert + + PlayP1(1) = NP1; + PlayP2(1) = NP2; + + x= x +1; % Anzahl Runden + + % E I N S A T Z A U F T U R N + + + if PlayP1(1) >= Player_1; %Raise bzw. Call P1 + PlayP1(2) = PlayP1(2)+1; + end; + if PlayP2(1) >= Player_2; % Raise bzw. Call P2 + PlayP2(2) = PlayP2(2)+1; + end; + +end; +%% R I V E R +% 4. W E T T R U N D E ------------------% + % 1 neue Karte + +if PlayP1(2) == 3 && PlayP2(2) == 3; %Beide wollen Speilen + NPP1 = ((rand + PlayP1(1)*5)/6); %Neue Karten P1 nach River Normiert + NPP2 = ((rand + PlayP2(1)*5)/6); %Neue Karten P2 nach River Normiert + + PlayP1(1) = NPP1; + PlayP2(1) = NPP2; + + x= x +1; % Anzahl Runden + + % E I N S A T Z A U F R I V E R + + + if PlayP1(1) >= Player_1; %Raise bzw. Call P1 + PlayP1(2) = PlayP1(2)+1; + end; + if PlayP2(1) >= Player_2; % Raise bzw. Call P2 + PlayP2(2) = PlayP2(2)+1; + end; +end; +%% R A N D O M + +Pot = PlayP1(2) + PlayP2(2) %Pot +EndCreditP1 = CreditP1-PlayP1(2); %EndCreditP1 +EndCreditP2 = CreditP2-PlayP2(2); %EndCreditP2 +%% S H O W D O W N + +if PlayP1(2) == 0 && PlayP2(2)==0; %Kein Spiel + disp('Draw: '); + disp(Pot - PlayP1(2)); + EndCreditP1 == EndCreditP1+PlayP1(2); + EndCreditP2 == EndCreditP2+PlayP2(2); +end; + +if PlayP1(2) > PlayP2(2); %P2 Bietet nicht mehr + disp('Player 1 Wins: '); + disp(Pot - PlayP1(2)); + EndCreditP1 = EndCreditP1+Pot; +end; + +if PlayP1(2) < PlayP2(2); %P1 Bietet nicht mehr + disp('Player 2 Wins:'); + disp(Pot - PlayP2(2)); + EndCreditP2 = EndCreditP2+Pot; +end; + +if PlayP1(2) == PlayP2(2) && PlayP1(2) > 3; %beide Spielen ALLE Runden + disp('SHOWDOWN') + if PlayP1(1) > PlayP2(1); + disp('Player 1 Wins: '); + disp(Pot - PlayP1(2)); + EndCreditP1 = EndCreditP1+Pot; + elseif PlayP1(1) == PlayP2(1); + disp('Draw'); + EndCreditP1 == EndCreditP1+PlayP1(2); + EndCreditP2 == EndCreditP2+PlayP2(2); + elseif PlayP2(1) > PlayP1(1); + disp('Player 2 Wins:'); + disp(Pot - PlayP2(2)); + EndCreditP2 = EndCreditP2+Pot; + end; +end; + + + + +%% B I L A N Z + +Bilanz = ['gespielte Runden ' num2str(x) ' EndCredit P1: ' num2str(EndCreditP1) '|' 'EndCredit P2: ' num2str(EndCreditP2)]; +disp(Bilanz); + diff --git a/code/runPokerGame.m b/code/runPokerGame.m new file mode 100644 index 000000000..9d2d6bd08 --- /dev/null +++ b/code/runPokerGame.m @@ -0,0 +1,51 @@ +function [ GeldverlaufP1, GeldverlaufP2, Counter, Winner ] = runPokerGame( RiskP1, RiskP2, Startkapital ) + +%% Outputvariablen + +GeldverlaufP1 = []; %Geld-Zeit-Verlauf des Spielers 1 +GeldverlaufP2 = []; %Geld-Zeit-Verlauf des Spielers 2 +Counter = 0; %z?hlt Anzahl Runden bis Ruin eines Spielers +Winner = 0; %speichert den Gewinner des Spiels + +%% Zwischenspeichervariablen +%Variablen zum zwischenspeichern der Kapitale von jedem Spieler nach einer +%gespielten Runde. Dienen als Laufvariable der while-Schleife + +LaufP1= 1; +LaufP2 = 1; + + + +CP1=Startkapital; +CP2=Startkapital; +%Jeder durchlauf der while-Schleife entspricht einer gespielten Runde +%Abbruchbedingung: Ein Spieler hat kein Kapital mehr <-> LaufP1 oder LaufP2 +%ist 0 + + +while LaufP1 > 0 && LaufP2 > 0; + Counter = Counter + 1; + [EndCreditP1,EndCreditP2,Tempx,TempPot] = headsup(CP1,CP2,RiskP2,RiskP2); %Simulation einer einzelnen Runde + CP1=EndCreditP1; + CP2=EndCreditP2; + + + LaufP1 = EndCreditP1; + LaufP2 = EndCreditP2; + + GeldverlaufP1(Counter) = EndCreditP1; + GeldverlaufP2(Counter) = EndCreditP2; + + + +end; + +if LaufP1 == 0 + Winner = 2; +end +if LaufP2 == 0 + Winner = 1; +end + +end + diff --git a/code/runheadsup.m b/code/runheadsup.m new file mode 100644 index 000000000..dc81e9770 --- /dev/null +++ b/code/runheadsup.m @@ -0,0 +1,76 @@ +clear all; +close all; + +%% This File should run the function until one player wins. + + +%% Konstante Startvariablen (=Input) + +%Risikobereitschaft der Spieler. Umso tiefer die Zahl, umso mehr Risiko +%nimmt ein Spieler +RiskP1 = 0.8; +RiskP2 = 0.2; +Startkapital=20000; %Konstante Startkapitalvariable + +%% Outputvariablen fuer die Statistik + +GeldverlaufP1 = []; %Geld-Zeit-Verlauf des Spielers 1 +GeldverlaufP2 = []; %Geld-Zeit-Verlauf des Spielers 2 +Counter = 0; %z?hlt Anzahl Runden bis Ruin eines Spielers +Winner = 0; %speichert den Gewinner des Spiels + +%% Zwischenspeichervariablen +%Variablen zum zwischenspeichern der Kapitale von jedem Spieler nach einer +%gespielten Runde. Dienen als Laufvariable der while-Schleife + +LaufP1= 1; +LaufP2 = 1; + + + +CP1=Startkapital; +CP2=Startkapital; +%Jeder durchlauf der while-Schleife entspricht einer gespielten Runde +%Abbruchbedingung: Ein Spieler hat kein Kapital mehr <-> LaufP1 oder LaufP2 +%ist 0 + + +while LaufP1 > 0 && LaufP2 > 0; + Counter = Counter + 1; + [EndCreditP1,EndCreditP2,Tempx,TempPot] = headsup(CP1,CP2,RiskP2,RiskP2); %Simulation einer einzelnen Runde + CP1=EndCreditP1; + CP2=EndCreditP2; + + + LaufP1 = EndCreditP1; + LaufP2 = EndCreditP2; + + GeldverlaufP1(Counter) = EndCreditP1; + GeldverlaufP2(Counter) = EndCreditP2; + + + +end; + +if LaufP1 == 0 + Winner = 2; +end +if LaufP2 == 0 + Winner = 1; +end + +%% Endstatistics + +% Ausgabe der wichtigsten gefundenen Werte + +sprintf('Player %d wins all in %d rounds', Winner, Counter) + +% Plotten des Geldverlaufes von Spieler 1 und 2 +Q=1:Counter; +subplot(2,1,1) +plot (Q, GeldverlaufP1) +title('Geldverlauf Spieler 1') +subplot(2,1,2) +hold on +plot(Q, GeldverlaufP2) +title('Geldverlauf Spieler 2')