Advertisement
Deduction42

Simulation.jl

Apr 2nd, 2018
698
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Julia 5.16 KB | None | 0 0
  1. using PyPlot
  2.  
  3. #Number of games to run simulation
  4. N_Games = 1000;
  5.  
  6. #MMR window for matching
  7. Match_Range = 100;
  8.  
  9. #Team balance options
  10. TeamBalance = 1;
  11. #Option 1 does a swapping algorithm to balance teams
  12. #Option 2 does a fully random assignment
  13. #Option 3 does a quasi-random assignment based on player number
  14.  
  15. nNewPlayers = 1; #Number of new accounts being made
  16. nPeaks = 5;       #Numberof "real MMR" clusters
  17. PeakWidth = 0.5;  #less than 0.2 means weak cluster overlap
  18. WinBonus = Match_Range/5;    #Amount of mmr change from a win/loss
  19. PoolGrowth = 50;  #Growth of the pool on every iteration
  20.  
  21. NewSim = true;
  22. N = 2000;
  23.  
  24.  
  25. #Indices to mark attributes of "Data"
  26. iPlayers = 1;
  27. iMMR = 2;
  28. iRealMMR = 3;
  29. iTime = 4;
  30.  
  31. #MMR History
  32. MMR_History = zeros(Int64,N,N_Games)
  33.  
  34. Pool = Int64.([]);
  35. Leftovers = Int64.([]);
  36.  
  37. #Create an initial starting point
  38. if NewSim
  39.   Peaks = ceil.(nPeaks*rand(N,1))./nPeaks
  40.   RealMMR = round.( Int64 , 3000*( Peaks + (PeakWidth/nPeaks)*randn(N,1) ) );
  41.  
  42.   MMR = round.( Int64 , 1500 + 500*randn(N,1) );  #Noisy MMR reset state
  43.   #MMR = round.( Int64 , RealMMR + 300*randn(N,1) );  #Noisy but mostly corret state
  44.   Data = [collect(1:N)  MMR  RealMMR  collect(1:N)];
  45. end
  46.  
  47. figure()
  48. PyPlot.plt[:hist](RealMMR,60)
  49. title("Real MMR Distribution")
  50.  
  51. #Assign horribly missmatched MMRs for player 1 and 2
  52. BaseCase = Data[1,:];
  53.  
  54. #Obtain rank error statistics
  55. RankErr = zeros(N_Games,1);
  56. MatchErrStats = zeros(Float64,N_Games,2);
  57.  
  58. Rank1 = zeros(N,1);
  59. Rank2 = zeros(N,1);
  60.  
  61. include( "TeamAssignment.jl")
  62.  
  63.  
  64. for game = 1:N_Games
  65.  
  66.   #Subtract time to pool entry
  67.   Data[:,iTime] = Data[:,iTime] - PoolGrowth;
  68.  
  69.   #Initialize the pool with a new set of players
  70.   NewPlayers = find( Data[:,iTime] .< PoolGrowth );
  71.   Pool = union( Pool , NewPlayers);
  72.  
  73.   #Re-initialize match quality statistics
  74.   MeasuredMatchErr = Int64.([])
  75.   RealMatchErr = Int64.([])
  76.  
  77.   for ii = 1:(floor( Int64 , N/PoolGrowth)-1)
  78.  
  79.     #Sort the players by MMR
  80.     PoolMMR = Data[ Pool , iMMR ];
  81.     Ind = sortperm( PoolMMR );
  82.     Pool[1:end,:] = Pool[Ind,:];
  83.  
  84.     #Use a moving window to match players if the MMR range is acceptable
  85.     while size(Pool,1) > 10
  86.  
  87.       #If the group is cloase enough to gether, place them in a game
  88.       if abs.( Data[Pool[1],iMMR] - Data[Pool[10],iMMR] ) < Match_Range
  89.         #Select the 10 players and remove them from the pool
  90.         SelectedPlayers = Pool[1:10];
  91.         Pool = Pool[11:end];
  92.  
  93.         #For selected players reset their re-entry timer
  94.         Data[SelectedPlayers,iTime] = N;
  95.  
  96.         #fprintf( "\n Players Pooled \n" )
  97.         #disp( [SelectedPlayers , Data(SelectedPlayers,iMMR)] )
  98.  
  99.         #Assign teams based on MMR (see options at beginning)
  100.         Team1,Team2 = TeamAssignment( SelectedPlayers , Data[SelectedPlayers,iMMR] , TeamBalance );
  101.  
  102.         #Record error in matchmaking (imbalance of teams)
  103.         DiffR = abs( sum(Data[Team1,iRealMMR] .- Data[Team2,iRealMMR]) );
  104.         DiffM = abs( sum(Data[Team1,iMMR] .- Data[Team2,iMMR]) );
  105.         push!(RealMatchErr,DiffR)
  106.         push!(MeasuredMatchErr,DiffM)
  107.  
  108.         #Adjust MMR based on the win (which is based on Real MMR)
  109.         if  sum(Data[Team1,iRealMMR])  > ( sum(Data[Team2,iRealMMR]) + 200*randn(1)[1] )
  110.           Data[ Team1 , iMMR ] = Data[ Team1 , iMMR ] + WinBonus;
  111.           Data[ Team2 , iMMR ] = Data[ Team2 , iMMR ] - WinBonus;
  112.         else
  113.           Data[ Team1 , iMMR ] = Data[ Team1 , iMMR ] - WinBonus;
  114.           Data[ Team2 , iMMR ] = Data[ Team2 , iMMR ] + WinBonus;
  115.         end
  116.  
  117.       #If the group is too far apart to be matched, discard the first player in pool
  118.       else
  119.         #Place the first player on the list in "leftovers" and remove from pool
  120.         Leftovers = [ Leftovers ; Pool[1] ];
  121.         Pool = Pool[2:end];
  122.       end
  123.     end
  124.  
  125.     #Combine the pool and the leftovers
  126.     Pool = [Pool;Leftovers];
  127.     Leftovers = [];
  128.  
  129.     #Select a set of new players
  130.     Data[:,iTime] = Data[:,iTime] - PoolGrowth;
  131.     NewPlayers = find( Data[:,iTime] .< PoolGrowth );
  132.  
  133.  
  134.     #Add new players to the pool (omitting redundancy)
  135.     Pool = union( Pool , NewPlayers );
  136.   end
  137.  
  138.  
  139.   #Calcualte rank error statistics
  140.   I = sortperm( Data[:,iMMR] );
  141.   Rank1[I] = 1:N;
  142.   I = sortperm( Data[:,iRealMMR] );
  143.   Rank2[I] = 1:N;
  144.  
  145.   rankerr = sum(abs.(Rank1-Rank2))/N;
  146.   RankErr[game] = rankerr;
  147.  
  148.   #Save MMR History
  149.   MMR_History[:,game] = Data[:,iMMR]
  150.  
  151.   #Save match quality statistics
  152.   MatchErrStats[game,:] = [ mean(MeasuredMatchErr),mean(RealMatchErr) ]
  153.  
  154.   #Simulate new players, some being smurfs
  155.   Selected = ceil.( Int64, N*rand(nNewPlayers) )
  156.   Data[Selected,iMMR] = Data[Selected,iMMR] + round.(Int64 , 300 .+ 300 .*randn(nNewPlayers) )
  157.  
  158. end
  159.  
  160.  
  161. figure()
  162. plot(1:N_Games,MatchErrStats)
  163. title("Average team mismatch")
  164. xlabel("Games per player")
  165. ylabel("Team Mismatch")
  166. ylim([0,maximum(MatchErrStats)*1.1])
  167. legend(["Measured","Real"])
  168.  
  169. figure()
  170. plot(1:length(RankErr),RankErr)
  171. title("Average error in Rank")
  172. xlabel("Games per player")
  173. ylabel("Rank error")
  174. ylim([0,maximum(RankErr)*1.1])
  175.  
  176. figure()
  177. plot( Data[:,iRealMMR] , Data[:,iMMR] , ".k")
  178. title("Real vs System MMR")
  179. xlabel("Real MMR")
  180. ylabel("Estimated MMR")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement