Here’s a testing script where you can just add the function into the code:
function rock()return function()return 0 end end
function paper()return function()return 1 end end
function scissors()return function()return 2 end end
function cycle(t)return function()return #t%3 end end
function rand()return function()return math.random(3)-1 end end
function RRPPSS(t)return function()return math.floor(#t/2)%3 end end
function copy(t)return function()return #t==0 and math.random(3)-1 or t[#t]end end
function count(t)
local r,p,s=0,0,0
local function f(x)
if x==0 then r=r+1 elseif x==1 then p=p+1 else s=s+1 end
end
for i=1,#t do f(t[i])end
return function()
if #t~=0 then f(t[#t])else return math.random(3)-1 end
if r>p and r>s then return 1
elseif p>s and p>r then return 2
elseif s>p and s>r then return 0
elseif p>s and p==r then return math.random(2)-1
elseif s>r and s==p then return math.random(2)
elseif r>p and r==s then return(math.random(2)+1)%3
else return math.random(3)-1
end
end
end
function hist(t)
return function()
return #t==0 and math.random(3)-1 or(t[math.random(#t)]+1)%3
end
end
function beatlast(t)
return function()
return #t==0 and math.random(3)-1 or(t[#t]+1)%3
end
end
function rockpaper(t)
return function()return #t%2 end
end
function change()
local last=math.random(3)-1
return function()
last=(last+math.random(2))%3
return last
end
end
local f,set,n={},{},{"rock","paper","scissors","cycle","rand","RRPPSS","copy","count","hist","beatlast","rockpaper","change"}
for i=1,#n do
n[n[i]]=i
f[i]=getfenv()[n[i]]
set[n[i]]={0,0}
end
for i=1,#f do
set[i]={}
for j=i+1,#f do
local hA,hB={},{}
local a,b=f[i](hB,hA),f[j](hA,hB)
set[i][j]={a,b,hA=hA,hB=hB,an=n[i],bn=n[j],a=0,b=0,d=0}
end
end
math.randomseed(os.time())
local ct=os.clock()
for _=0,200 do
for i=1,#f-1 do
for j=i+1,#f do
local t=set[i][j]
local A,B=t[1](),t[2]()
table.insert(t.hA,A)
table.insert(t.hB,B)
if _>0 then
if A==B then
t.d=t.d+1
elseif A==(B+1)%3 then
t.a=t.a+1
set[t.an][1]=set[t.an][1]+1
set[t.bn][2]=set[t.bn][2]+1
else
t.b=t.b+1
set[t.bn][1]=set[t.bn][1]+1
set[t.an][2]=set[t.an][2]+1
end
end
end
end
if os.clock()-ct>1 then ct=os.clock()print(_)end
end
print("- clock: "..os.clock())
local N={}
local V={}
for i=1,#n do
local x,y=set[n[i]][1],set[n[i]][2]
if x==0 and y==0 then x,y=1,1 end
N[i],V[i]=n[i],x/(x+y)
end
repeat
local k=true
for i=1,#V-1 do
if V[i+1]>V[i]then
V[i],V[i+1]=V[i+1],V[i]
N[i],N[i+1]=N[i+1],N[i]
k=false
end
end
until k
local mlen=1
local ratio={}
for i=1,#n do mlen=math.max(mlen,#N[i]+1)ratio[i]={}end
for i=1,#n do
for j=1,#n do
if i~=j then
local x,r=set[n[n[i]]][n[n[j]]]
if x then r=x.a/(x.a+x.b)else x=set[n[n[j]]][n[n[i]]]r=x.b/(x.a+x.b)end
if x.a==0 and x.b==0 then r=.5 end
ratio[i][j]=r
ratio[j][i]=1-r
end
end
end
local score={}
for i=1,#n do score[n[i]]=1 end
function scoreiter()
local m=0
for i=1,#n do
local v=0
for j=1,#n do
if i~=j then
v=v+ratio[i][j]--*score[n[j]]
end
end
if v>m then m=v end
score[n[i]]=v
end
for i=1,#n do score[n[i]]=score[n[i]]/m end
end
for _=1,1 do scoreiter()end
local N,Ni={},{}for i=1,#n do N[i],Ni[i]=n[i],i end
repeat
local k=true
for i=1,#N-1 do
if score[N[i]]<score[N[i+1]]then
N[i],N[i+1]=N[i+1],N[i]
Ni[i],Ni[i+1]=Ni[i+1],Ni[i]
k=false
end
end
until k
for i=1,#n do
print(string.format("%-"..mlen.."s%.05f",N[i],score[N[i]]))
end
for i=1,#N do
local pr={}
local tot=0
local op,ov="",math.huge
for j=1,#N do
if i~=j then
local x,r=set[n[N[i]]][n[N[j]]]
if x then r=x.a/(x.a+x.b)else x=set[n[N[j]]][n[N[i]]]r=x.b/(x.a+x.b)end
if x.a==0 and x.b==0 then r=.5 end
if ov>r then op,ov=N[j],r end
r=r
pr[#pr+1]=string.format("- %-"..mlen.."s%.02f",N[j],r)tot=tot+r
end
end
print(string.format("%-"..mlen.."s%.02f, %-"..mlen.."s%.05f",N[i],V[i]*100,op,ov))
--for _,v in pairs(pr)do print(v)end
--print("= "..tot)
end
You can change the number of games played per pair on line 64. List the names of all of the bot functions you want to test at once in the “n” table on line 47.