Here is the code with notes included.
E IS BUY-IN AMOUNT
L IS LITTLE BLIND, RESET EVERY GAME
M IS CURRENT BETTER
N IS THE NUMBER OF PLAYERS
R IS BET RAISE
P IS THE CURRENT BETTERS VALUE
S IS NUMBER OF CARDS SHOWN
L₁ IS FLUSH LIST
L₂ IS PAIR, TRIP, QUAD LIST
L₃ IS BETS
L₄ WILL BE TEMP PKR
L₅ IS WIN MONEY
L₆ IS DEAL
Sets up graph screen
Full
1→Xmin
95→Xmax
1→Ymin
63→Ymax
AxesOff
Store card values as STR1. Stores LPRK as L4 during gameplay to reduce game size. L4 has a sforter name.
"A23456789TJQKASHCD→Str1
8→dim(⌊PKR
⌊PKR→L₄
Looks for existing game. If not found, sets up new game w/ 1000 credits.
ClrHome
Lbl NW
1→B
Disp "YOU HAVE
Pause L₄(6
If L₄(6
Menu("WELCOME","HOLDEM",HM,"SIT N GO",T,"VIEW MONEY",NW,"RESET GAME",N,"EXIT",E
If not(L₄(6
Menu("WELCOME","NEW GAME",N,"EXIT",E
Lbl E
L₄→⌊PKR
Stop
Lbl N
If L₄(6
Menu("ERASE","YES",YS,"NO",NW
Lbl YS
1000→L₄(6
Goto NW
Begin regular holdem or tournament. For tournament, if player doesn't have enough credits to join that value tournament it jumps back to the menu. For Holdem, it deducts 100 credits or the amount of credits you have remaining. The DelVar L resets little blind to player 0.
Lbl T
500→A
Menu("BUY-IN AMOUNT","500",1,"1500",2,"15000",3,"BACK",NW
Lbl 3
10A→A
Lbl 2
3A→A
Lbl 1
2→B
Lbl HM
If B=1
Then
100→A
If 100>L₄(6
L₄(6→A
End
B=2 and A>L₄(6→C
If C
Pause "NOT ENOUGH MONEY
If C
Goto T
augment(seq(100,C,1,5),{L₄(6)-A,B,A→L₄
If A<100
A→L₄(1
DelVar L
The game is about to deal cards to each player. Before that, it looks for players that ran out of money on the last round. In Holdem, it simply resets that player to 100 credits. For Tournament, it removes that player.
Here it removes and resets players. When it removes a player that ran out of money in Tournament mode, it shifts the remaining players to the left so that there are no empty spots in L4.
Lbl D
For(A,2,5)
If not(L₄(A
Then
If A<5 and 2=L₄(7
Then
For(B,A,4
L₄(B+1→L₄(B
0→L₄(B+1
End
End
If 1=L₄(7
100→L₄(A
End
End
Sets the number of players by looking for values above 0 in the first 5 places of L4. This applies to Tournaments.
Looks at L4(1) to see if you lose. In Holdem it takes me back to the home screen. In Tournament, it checks to see whether you came in 2nd or 3rd place and pays if you did.
If 2=L₄(7) and not(L₄(1
Then
L₄(8)(2-.5N)(N<3
Disp "YOU WIN"
Disp Ans
Ans+L₄(6→L₄(6
End
If not(L₄(1
Goto NW
Looks at L4(2-5) to see if you win. Pays out and sends you back to the home screen. This doesn't do anything in Holdem, just Tournament.
If not(sum(L₄,2,5
2.5L₄(8→L₄(6
If not(sum(L₄,2,5
Goto NW
Deals cards. This is the standard deal you can find on the site.
rand(52→L₁
seq(A/4,A,8,59→L₆
SortA(L₁,L₆
Adds +1 to little blind. If little blind exceeds the number of players, its sets to 1.
Draws the cards and sets up the text on the graph screen. I used variables because many of the points intersect and it saves a few bytes.
ClrDraw
45→A
49→B
63→C
95→D
Text(57,50,"YOU BET:
Text(0,22,"POT:
Line(B,7,D,7
Line(B,7,B,1
Line(1,B,1,C
Line(1,C,21,C
Line(11,C,11,B
Line(21,B,1,B
Line(21,B,21,C
Line(D,C,A,C
Line(D,C,D,B
Line(D,B,A,B
Line(A,B,A,C
For(A,55,D,10
Line(A,50,A,62
End
For(A,1,2
int(L₆(A:For(B,1,7,6
Text(B,10(A=2)+2,sub(Str1,Ans,1
15+4fPart(L₆(A
End
End
S is the number of cards shown. 3 is flop, 4 is turn, 5 is river.
It's about to analyze the cards and give a value for each player. It only analyzes the cards currently shown, so the AI doesn't get to cheat and see the Flop, Turn, and River until the human player does. The down side of this is that it has to analyze the cards more than once. It only analyzes from the Flop onward. The game uses a modified Chen formula for the Draw.
Here it displays the cards. First none, then 3, then 4, then 5.
While S<6
For(A,1,S
int(L₆(2N+A:For(B,1,7,6
Text(B,36+10A,sub(Str1,Ans,1
15+4fPart(L₆(2N+A
End
End
Now begins to analyze the hands when S is greater than 0. It displays the status on the graph screen.
If S
Then
S+2→H
For(θ,1+(S≠5),N
Text(51,0,"CALCULATING
Text(57,0,.92θ/(N)," PERCENT
Tells it to only calculate players that have not folded. When a player folds it sets that player's LWIN value to 0. Each player's LWIN status is set to 1 a little later during Flop betting.
Sets up the current player's cards as LH. It only sets up cards that are shown.
augment({L₆(2θ-1),L₆(2θ)},seq(L₆(2N-2+A),A,3,S+2→⌊H
SortD(⌊H
Sets up 2 matrices. One provides a fast way of detecting a flush, and the other gives a fast way of detecting pairs, trips, and fours. It doesn't know yet what cards have those values, just that they exist. It sets the Ace L2(14) to L2(1) so the program correctly finds Straights and Straight Flushes.
DelVar [A]
{14,4→dim([A]
For(A,1,H
⌊H(A
1→[A](int(Ans),1+4fPart(Ans
End
Matrlist((cumSum([A])),14,L₁
Matrlist((cumSum([A])),4,L₂
L₂(14→L₂(1
If L1 has a number 5 or greater, it means this player has a flush. The code then runs to determine which cards make up the sequence. It will also determine whether is has a royal flush or straight flush. The value stored to LV(1) shows what the player has. 6 means flush, 9 means straight flush, 10 means royal flush.
Looks for Royal and Straight Flush
For(A,1,H-4)
If ⌊H(A)>9 and 1=prod(List(⌊H),A,A+3
{10→⌊V
If ⌊V(1)<9 and 1=prod(List(⌊H),A,A+3
{9,⌊H(A),⌊H(A+1),⌊H(A+2),⌊H(A+3),⌊H(A+4)→⌊V
End
Looks for regular Flush
If ⌊V(1)=6
Then
For(A,1,4)
If L₁(A)>4
.25(A-1→B
End
For(A,1,H)
If B=fPart(⌊H(A
int(⌊H(A→⌊V(1+dim(⌊V
End
End
End
If a Royal or Straight flush is found, jump to the Lbl F because further analysis isn't needed.
If L2 has a max of 4, it means Four of a Kind exists. If then looks for the cards the player has 4 of and sets that to LV(2). It then looks for the kicker and stores to LV(3). If 2 players have the same Four of a Kind, the kicker decides the winner. It then goes to Lbl F because V is 8.
If 4=max(L₂
Then
For(A,2,14)
If 4=L₂(A
{8,A→⌊V
End
For(A,2,14)
If L₂(A) and A≠⌊V(2
A→⌊V(3
End
End
If 7<⌊V(1
Goto F
This looks for Three of a Kind and a Full House. I combined them because it makes no sense to do the same math twice. Works in the same way as Four of a Kind.
If 3=max(L₂
Then
For(A,14,2,1)
If L₂(A)=3
Then
{4,A→⌊V
2→A
End
End
For(A,14,2,1
If L₂(A)>1 and A≠⌊V(2
Then
{7,⌊V(2),A→⌊V
2→A
End
End
End
If 5<⌊V(1
Goto F
Looks for a Straight. If found, stores to LV and goes to Lbl F.
If H>4
Then
For(A,1,10
If prod(L₂,A,A+4
{5,A,A+1,A+2,A+3,A+4→⌊V
End
End
If 4<⌊V(1
Goto F
If Three of a Kind was found when looking for a Full House, it looks for the remaining 2 cards.
If 3<⌊V(1
Then
3→B
For(A,14,2,1)
If A≠⌊V(2) and L₂(A
Then
A→⌊V(B
B+1→B
If 5=dim(⌊V
2→A
End
End
End
If 3<⌊V(1
Goto F
Looks for Pairs and 2 Pairs
If 2=max(L₂
Then
For(A,14,2,1)
If L₂(A)=2
Then
{2,A→⌊V
For(B,A,2,1)
If L₂(B)=2 and B≠A
Then
{3,A,B→⌊V
2→B
End
End
2→A
End
End
If 2=⌊V(1
Then
For(A,14,2,1)
If L₂(A) and A≠⌊V(2
A→⌊V(1+dim(⌊V
If 5=dim(⌊V
2→A
End
End
If 3=⌊V(1
Then
For(A,14,2,1)
If L₂(A) and A≠⌊V(2) and A≠⌊V(3)
Then
A→⌊V(4
2→A
End
End
End
End
If 1<⌊V(1
Goto F
If nothing was found (LV(1) is still 1), it stores the player's 5 highest cards to Lv(2-6)
augment({1},int(⌊H→⌊V
Lbl F
6→dim(⌊V
Stores all players hand value to LWIN. Each player now has a value of at least 1.
sum(seq(⌊V(A)10^(4-2A),A,1,6→⌊WIN(θ
End
End
End
This is the end of the hand analysis. Now it moves on to betting.
Text(51,0,"BET-ROUND: ",1+(S>0)+(S>3)+(S>4
Text(57,0,"USE ARROWS
Resets R, which is the number of times the sequence has run without a bet being raised. This makes sure each player bets after a raise. Stores L to M. M is the current better, and should start with the little blind.
If S=0 (We are at the Draw) it puts in the little and big blinds. L3 is the list of bets. If the player doesn't have enough money to put in, it puts them all-in.
If not(S
Then
DelVar L₃
N→dim(L₃
seq(1,A,1,N→⌊WIN
DelVar P
1+L(L<N→M
2→L₃(L
If 2>L₄(L
L₄(L→L₃(L
Text(6L+15,54,Ans
4→L₃(M
If 4>L₄(M
L₄(M→L₃(M
Text(6M+15,54,Ans
1+M(M<N→M
End
Displays each player's number of credits.
For(A,1,N
If S and ⌊WIN(A) and L₄(A
Text(6A+15,54," "
Text(6A+15,0,"PL",A," HAS:",L₄(A),"
Text(6A+15,40,"BET:
End
Begins the betting, and keeps going until R=N
Stores the current better's number of credits to P to save space in the code. Displays text of who the current better is. Draws an arrow pointing toward the better.
While R<N
L₄(M→P
Text(15,0,"CURRENT BETTER:"
If M>1
Text(15,56,"PL",M
If M=1
Text(15,56,"YOU
For(A,14,16
Line(80,45-6M,85+(A=15)5,3A-6M
End
B is the highest bet. This will be the minimum that any player can bet. If little and big blinds are all-in and were not able to put in the whole 4 credits, it still makes sure that 4 is the minimum bet.
int(max(L₃→B
If B<4 and not(S
4→B
The is where and AIs bet. The first part is a modified Chen formula, and only runs on the Draw. The second part uses the values from the hand analysis and the player checks, calls, bets, and folds depending on the value of LWIN(M)
Here is the Chen formula.
If M>1 and ⌊WIN(M) and P and P≠int(L₃(M
Then
If not(S
Then
"B IS HIGH BET"
{L₆(2M),L₆(2M-1→⌊J
"CHENFORMULA"
"STEP 1"
int(max(⌊J→U
int(min(⌊J→V
10(U=14)+8(U=13)+7(U=12)+6(U=11)+.5U(U<11→W
"STEP 2"
If U=V
2W→W
"STEP 3"
If fPart(⌊J(1))=fPart(⌊J(2
W+2→W
"STEP 4"
If U=V+2 or U=14 and V=3
W-1→W
If U=V+3 or U=14 and V=4
W-2→W
If U=V+4 or U=14 and V=5
W-4→W
If U-V>4 and U<14 or U=14 and V=8 or U=14 and V=7 or U=14 and V=6
W-5→W
"STEP 5"
If V+1=U and U<13
W+1→W
If V+2=U and U<13
W+1→W
round(W,0→W
"FOLD"
If W<6 and B>5 or W<9 and B>10
0→⌊WIN(M
"RAISE"
If W≥12 and B≤10 or W≥9 and B≤5
2B→B
End
Here is the code for Flop onward. It values the size of the pot against the current minimum bet and the player's hand value. The square is the little E.
If S
Then
⌊WIN(M
If Ans>400
2Ans
3Ans5/S→K
(B/(sum(int(L₃))+2sum(fPart(L₃→C
If randInt(1,2)K<C
0→⌊WIN(M
If K-.25>C and not(B
randInt(0,5→B
End
End
Human betting. Up/down/left/right adjust the bet.
If M=1 and ⌊WIN(M) and P and P≠int(L₃(M
Then
B→A
getKey
Repeat X=105
If A≥0
Text(57,77,A," "
If A<0
Text(57,77,"FOLD
getKey→X
A+(X=25)-(X=34)+10(X=26)-10(X=24)→A
If A<B
Then
If X=24 or X=34
B→A
If X=25 or X=26
B→A
End
If A>P
P→A
End
If A≥B
Then
A→B
Else
If A≠P
0→⌊WIN(M
End
End
Adds +1 to R. If the bet was increased, it resets R to 1 to continue betting.
R+1→R
If B>int(max(L₃
1→R
If the player didn't fold and they have enough money, add the bet to the integer part of L3(M)
If the player didn't fold and they don't have enough money, the players entire value will be stored to L3(M)
If B≤P and ⌊WIN(M
B+fPart(L₃(M→L₃(M
If B>P and ⌊WIN(M
P+fPart(L₃(M→L₃(M
Display the amount the current better put in. If they folded, show folded. If they are all-in, show all-in.
If ⌊WIN(M
Text(6M+15,54,int(L₃(M
If not(⌊WIN(M
Text(6M+15,54,"FOLD
If not(P) or P=int(L₃(M
Text(6M+15,54,"ALL IN
Remove the arrow that was drawn next to the better.
For(A,14,16
Line(80,45-6M,85+(A=15)5,3A-6M,0
End
Add +1 to M so it moves on to the next better. If M is greater than the number of betters, it sets M to 1.
If all players folded and only one player remains, end betting immediately.
If sum(⌊WIN)=max(⌊WIN
Then
5→S
N→R
End
End
Betting is not complete for this round. This subtracts the player's bets from L4. These bets are the integer part of L3.
For(A,1,N
L₄(A)-int(L₃(A→L₄(A
End
Stores the integer part of L3 as the fpart of L3.
.01(100fPart(L₃)+int(L₃→L₃
Displays the pot.
Text(6,22,100sum(fPart(L₃))," "
S+1+2(S=0→S
Betting is complete. This displays the cards of all players that didn't fold and sets the fpart of L3 to a whole number again.
End
For(A,2,N)
If ⌊WIN(A
Then:For(B,1,2
Text(6A+15,65+11B,sub(Str1,int(L₆(2(A-1)+B)),1),sub(Str1,15+4fPart(L₆(2(A-1)+B)),1),",
End
End
End
2L₃→L₃
This code looks for winners and pays them accordingly. It handles possible combination of winners(multiple winners, multiple all-in players with different bets, etc). I'm quite proud of what I did here. It wasn't really complicated math, but it was hard figuring out the right way to execute it.
It looks for players with the highest LWIN value and pays out the lowest amount that the the player put in. For example, if 2 players has the highest valued cards, one put in 25 and the other put in 30, then it will subtract 25 from all players and divide the money between the 2 winners. It first looks for players that didn't have 25, and subtract the difference from the winnings. The L3 of the 25 player is now at 0 so he isn't included in the next sequence. It continues until all L3s are at 0.
While 0<sum(L₃
0→dim(L₅
For(A,1,N
If ⌊WIN(A)=max(⌊WIN
L₃(A→L₅(1+dim(L₅
End
min(L₅→X
L₃-X→L₃
XN→X
For(A,1,N)
If 0≥L₃(A
Then
X+L₃(A→X
0→L₃(A
End
End
max(⌊WIN→B
For(A,1,N)
If B=⌊WIN(A
Then
round(L₄(A)+X/dim(L₅),0→L₄(A
Text(6A+15,40,"WINS:",round(X/dim(L₅),0
If 0=L₃(A
0→⌊WIN(A
End
End
End
This part is graphical only and tells the player to push enter to continue playing or clear to go back to the home screen.
getKey
42→A
0→C
Line(39,47,39,20
Line(1,20,38,20
Repeat B=105 or B=45
getKey→B
Line(1,A,38,A,C
If A>20
A-1→A
If A=40
Text(15,0,"PUSH ENTER
If A=34
Text(21,0,"TO DEAL
If A=26
Text(30,0,"PUSH CLEAR
If A=20
Text(36,0,"TO LEAVE
If A=20
47→A
End
Exits back to the home screen. It does this by setting L4(1) to zero. If you are playing regular Holdem, it first moves your money back to L4(6). It still goes back to Lbl D because it will go back to the code that looks for you to be 2nd or 3rd place winner in Tournament. It will then pay you what you won and send you back to the home screen.
If B=45 and 1=L₄(7
Then
L₄(1
Disp "YOU GET
Disp Ans
Ans+L₄(6→L₄(6
End
If B=45
0→L₄(1
Goto D