Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[RPS bot testing program
- - Add your bot(s) inside of the bots function
- - The main function is passed two tables, which contain
- the history of moves made by the opponent
- the history of moves made by the bot
- - The main function returns another function
- which returns its move as a number, 0 or 1 or 2
- 1 beats 0; 2 beats 1; 0 beats 2
- A list of bots, their win percentages and scores will be printed to the output.
- Win percentages are calculated by wins/(wins+losses) and do not include draws.
- Un-comment the "details" line for a breakdown of percentages between bots.
- Submitting bots to RPS botwar
- https://www.roblox.com/games/437771957/RPS-Botwar
- Submit the function to hastebin and copy the link ID into the submission form in the game.
- The name of the bot is read from the name of the function.
- ]]
- local bots=(function()local ENV=getfenv(setfenv(1,{}))
- function Rock() -- returns rock every round
- return function()
- return 0
- end
- end
- function Random() -- returns a random move every round
- return function()
- return math.random(3)-1
- end
- end
- function Copy(t) -- returns the opponent's previous move
- return function()
- return t[#t]or math.random(3)-1
- end
- end
- function BeatLast(t) -- beats the opponent's previous move
- return function()
- return((t[#t]or math.random(3))+1)%3
- end
- end
- function WinStay(t) -- returns the same move if it won last round, otherwise changes
- local last=math.random(3)-1
- return function()
- if #t~=0 and last~=(t[#t]+1)%3 then
- last=(last+math.random(2))%3
- end
- return last
- end
- end
- function History(t) -- plays against a random move the opponent has made in the past
- return function()
- return #t==0 and math.random(3)-1 or(t[math.random(#t)]+1)%3
- end
- end
- function Count(t) -- plays against the opponent's most common move
- local r,p,s=0,0,0
- return function()
- local m=t[#t]
- if m==0 then r=r+1 elseif m==1 then p=p+1 elseif m==2 then s=s+1 end
- if r>p and r>s then
- return 1
- elseif p>s then
- return 2
- else
- return 0
- end
- end
- end
- function Repetition(t,t2) -- predicts the opponent's next move from repeated strings of responses
- return function()
- local r,len=math.random(3)-1,0
- for i=#t-1,1,-1 do
- for j=0,i do
- if t[i-j]==t[#t-j]and t2[i-j]==t2[#t2-j]then
- if j>=len then
- r,len=(t[i+1]+1)%3,j+1
- end
- else
- break
- end
- end
- end
- return r
- end
- end
- return ENV end)()
- local names={}
- for name,v in pairs(bots)do
- if type(v)=='function'then
- local bot=setfenv(v,{tostring=tostring,tonumber=tonumber,type=type,unpack=unpack,pcall=pcall,pairs=pairs,ipairs=ipairs,next=next,select=select,string=string,table=table,math=math})
- names[#names+1]=name
- end
- end
- local games,scores={},{}
- for i=1,#names-1 do
- scores[i]={}
- for j=i+1,#names do
- local score={0,0,0}
- scores[i][j]=score
- local x,y=names[i],names[j]
- local xmoves=setmetatable({},{__newindex=function()end})
- local ymoves=setmetatable({},{__newindex=function()end})
- local a,b=bots[x](ymoves,xmoves),bots[y](xmoves,ymoves)
- local game=0
- local function f()
- local A,B=a(),b()
- if A~=0 and A~=1 and A~=2 then error(x.." did not return 0 or 1 or 2")end
- if B~=0 and B~=1 and B~=2 then error(y.." did not return 0 or 1 or 2")end
- if A==(B+1)%3 then
- score[1]=score[1]+1
- elseif A==B then
- score[2]=score[2]+1
- else
- score[3]=score[3]+1
- end
- game=game+1
- rawset(xmoves,game,A)
- rawset(ymoves,game,B)
- end
- games[#games+1]=f
- end
- end
- for round=1,100 do
- for _,f in pairs(games)do
- f()
- end
- end
- local points={}
- for i=1,#names do points[i]=0 end
- for i=1,#names-1 do
- for j=i+1,#names do
- local s=scores[i][j]
- local rate=s[1]/(s[1]+s[3])
- if not(s[1]==0 and s[3]==0)then
- points[i]=points[i]+rate
- points[j]=points[j]+1-rate
- end
- end
- end
- local points2={}
- for i=1,#names do points2[i]=0 end
- for i=1,#names-1 do
- for j=i+1,#names do
- local s=scores[i][j]
- local rate=s[1]/(s[1]+s[3])
- if not(s[1]==0 and s[3]==0)then
- points2[i]=points2[i]+rate*points[j]
- points2[j]=points2[j]+(1-rate)*points[i]
- end
- end
- end
- local indices={}
- for i=1,#names do indices[i]=i end
- for i=1,#names-1 do
- for j=i+1,#names do
- local I,J=indices[i],indices[j]
- if points2[J]>points2[I]then
- indices[i],indices[j]=J,I
- end
- end
- end
- local namelen=1
- for i=1,#names do namelen=math.max(namelen,#names[i]+1)end
- local totalpoints=0
- for i=1,#points do totalpoints=totalpoints+points[i]end
- for i=1,#names do
- i=indices[i]
- print(string.format("%-"..namelen.."sWin:%6.02f%% Score:%6.02f",names[i],points[i]/(#names-1)*100,points2[i]*100/(totalpoints-points[i])))
- for j=1,#names do
- j=indices[j]
- if j~=i then
- local r=i<j and scores[i][j]or scores[j][i]
- if i>j then r={r[3],r[2],r[1]}end
- --details
- --print(string.format(" - %-"..namelen.."s%.02f%%",names[j],(r[1]==0 and r[3]==0)and 0 or 100*r[1]/(r[1]+r[3])))
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement