Here s the code. Possibly quite buggy, was coding this while trying to construct a toy game. (You need R to run this:
www.r-project.org/ )
<font class="small">Code:</font><hr /><pre>
#our "equity transformation"
chipTrans<-function(chips=0){return(chips^0.5)}
#stack sizes
stacks = 5
#winning percentage of range1 vs range2
winPct<-function(r1=1,r2=1)
{
return((0.5*min(r1,r2)+0.66*max(r2-r1,0)+0.34*max(r1-r2,0))/max(r1,r2))
}
#EV of pusher, p..pushrange, c..callrange
EVPusher <- function(p=1,c=1)
{
return (
(1-p)*chipTrans(stacks-0.5)+
p*(
c*(
winPct(p,c)*chipTrans(2*stacks) +
(1-winPct(p,c))*chipTrans(0)
)+
(1-c)*chipTrans(stacks+1)
)
)
}
#EV of caller, p..pushrange, c..callrange
EVCaller <- function(p=1,c=1)
{
return (
(1-p)*chipTrans(stacks+0.5)+
p*(
c*(
winPct(c,p)*chipTrans(2*stacks) +
(1-winPct(c,p))*chipTrans(0)
)+
(1-c)*chipTrans(stacks-1)
)
)
}
#One iteration of fictitious play
nextIter<-function(s=c(1,1), weight=1)
{
bestcev=0
bestpev=0
bestp=-1
bestc=-1
pos = (1:1000)/1000
for(i in c(1:length(pos)))
{
thisc = EVCaller(s[1],pos[i])
thisp = EVPusher(pos[i],s[2])
if(thisc>bestcev){
bestcev=thisc
bestc=pos[i]
}
if(thisp>bestpev){
bestpev=thisp
bestp=pos[i]
}
}
sn = c(bestp,bestc)
return(weight*sn+(1-weight)*s)
}
#300 iters of fictitious play
runFictitiousPlay<-function()
{
# r[0]: push range, r[1]: call range
r=c(1,0)
for(w in 1/(1:300))
{
r=nextIter(r,w)
print(r)
}
return(r)
}
#cr = (1:1000)/1000
###plotting EQ vs variable callrange
#pev = apply(X=t(cr),FUN=EVPusher,p=r[1],MARGIN=2)
#cev = apply(X=t(cr),FUN=EVCaller,p=r[1],MARGIN=2)
#plot(cr,cev,ty='l', lty=2,ylim=c(2.2,3.5))
#lines(cr,pev)
###plotting EQ vs variable pushrange
#pev = apply(X=t(cr),FUN=EVPusher,c=r[2],MARGIN=2)
#cev = apply(X=t(cr),FUN=EVCaller,c=r[2],MARGIN=2)
#plot(cr,cev,ty='l', lty=2)
#lines(cr,pev)
</pre><hr />