Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using PyPlot
- #Number of games to run simulation
- N_Games = 1000;
- #MMR window for matching
- Match_Range = 100;
- #Team balance options
- TeamBalance = 1;
- #Option 1 does a swapping algorithm to balance teams
- #Option 2 does a fully random assignment
- #Option 3 does a quasi-random assignment based on player number
- nNewPlayers = 1; #Number of new accounts being made
- nPeaks = 5; #Numberof "real MMR" clusters
- PeakWidth = 0.5; #less than 0.2 means weak cluster overlap
- WinBonus = Match_Range/5; #Amount of mmr change from a win/loss
- PoolGrowth = 50; #Growth of the pool on every iteration
- NewSim = true;
- N = 2000;
- #Indices to mark attributes of "Data"
- iPlayers = 1;
- iMMR = 2;
- iRealMMR = 3;
- iTime = 4;
- #MMR History
- MMR_History = zeros(Int64,N,N_Games)
- Pool = Int64.([]);
- Leftovers = Int64.([]);
- #Create an initial starting point
- if NewSim
- Peaks = ceil.(nPeaks*rand(N,1))./nPeaks
- RealMMR = round.( Int64 , 3000*( Peaks + (PeakWidth/nPeaks)*randn(N,1) ) );
- MMR = round.( Int64 , 1500 + 500*randn(N,1) ); #Noisy MMR reset state
- #MMR = round.( Int64 , RealMMR + 300*randn(N,1) ); #Noisy but mostly corret state
- Data = [collect(1:N) MMR RealMMR collect(1:N)];
- end
- figure()
- PyPlot.plt[:hist](RealMMR,60)
- title("Real MMR Distribution")
- #Assign horribly missmatched MMRs for player 1 and 2
- BaseCase = Data[1,:];
- #Obtain rank error statistics
- RankErr = zeros(N_Games,1);
- MatchErrStats = zeros(Float64,N_Games,2);
- Rank1 = zeros(N,1);
- Rank2 = zeros(N,1);
- include( "TeamAssignment.jl")
- for game = 1:N_Games
- #Subtract time to pool entry
- Data[:,iTime] = Data[:,iTime] - PoolGrowth;
- #Initialize the pool with a new set of players
- NewPlayers = find( Data[:,iTime] .< PoolGrowth );
- Pool = union( Pool , NewPlayers);
- #Re-initialize match quality statistics
- MeasuredMatchErr = Int64.([])
- RealMatchErr = Int64.([])
- for ii = 1:(floor( Int64 , N/PoolGrowth)-1)
- #Sort the players by MMR
- PoolMMR = Data[ Pool , iMMR ];
- Ind = sortperm( PoolMMR );
- Pool[1:end,:] = Pool[Ind,:];
- #Use a moving window to match players if the MMR range is acceptable
- while size(Pool,1) > 10
- #If the group is cloase enough to gether, place them in a game
- if abs.( Data[Pool[1],iMMR] - Data[Pool[10],iMMR] ) < Match_Range
- #Select the 10 players and remove them from the pool
- SelectedPlayers = Pool[1:10];
- Pool = Pool[11:end];
- #For selected players reset their re-entry timer
- Data[SelectedPlayers,iTime] = N;
- #fprintf( "\n Players Pooled \n" )
- #disp( [SelectedPlayers , Data(SelectedPlayers,iMMR)] )
- #Assign teams based on MMR (see options at beginning)
- Team1,Team2 = TeamAssignment( SelectedPlayers , Data[SelectedPlayers,iMMR] , TeamBalance );
- #Record error in matchmaking (imbalance of teams)
- DiffR = abs( sum(Data[Team1,iRealMMR] .- Data[Team2,iRealMMR]) );
- DiffM = abs( sum(Data[Team1,iMMR] .- Data[Team2,iMMR]) );
- push!(RealMatchErr,DiffR)
- push!(MeasuredMatchErr,DiffM)
- #Adjust MMR based on the win (which is based on Real MMR)
- if sum(Data[Team1,iRealMMR]) > ( sum(Data[Team2,iRealMMR]) + 200*randn(1)[1] )
- Data[ Team1 , iMMR ] = Data[ Team1 , iMMR ] + WinBonus;
- Data[ Team2 , iMMR ] = Data[ Team2 , iMMR ] - WinBonus;
- else
- Data[ Team1 , iMMR ] = Data[ Team1 , iMMR ] - WinBonus;
- Data[ Team2 , iMMR ] = Data[ Team2 , iMMR ] + WinBonus;
- end
- #If the group is too far apart to be matched, discard the first player in pool
- else
- #Place the first player on the list in "leftovers" and remove from pool
- Leftovers = [ Leftovers ; Pool[1] ];
- Pool = Pool[2:end];
- end
- end
- #Combine the pool and the leftovers
- Pool = [Pool;Leftovers];
- Leftovers = [];
- #Select a set of new players
- Data[:,iTime] = Data[:,iTime] - PoolGrowth;
- NewPlayers = find( Data[:,iTime] .< PoolGrowth );
- #Add new players to the pool (omitting redundancy)
- Pool = union( Pool , NewPlayers );
- end
- #Calcualte rank error statistics
- I = sortperm( Data[:,iMMR] );
- Rank1[I] = 1:N;
- I = sortperm( Data[:,iRealMMR] );
- Rank2[I] = 1:N;
- rankerr = sum(abs.(Rank1-Rank2))/N;
- RankErr[game] = rankerr;
- #Save MMR History
- MMR_History[:,game] = Data[:,iMMR]
- #Save match quality statistics
- MatchErrStats[game,:] = [ mean(MeasuredMatchErr),mean(RealMatchErr) ]
- #Simulate new players, some being smurfs
- Selected = ceil.( Int64, N*rand(nNewPlayers) )
- Data[Selected,iMMR] = Data[Selected,iMMR] + round.(Int64 , 300 .+ 300 .*randn(nNewPlayers) )
- end
- figure()
- plot(1:N_Games,MatchErrStats)
- title("Average team mismatch")
- xlabel("Games per player")
- ylabel("Team Mismatch")
- ylim([0,maximum(MatchErrStats)*1.1])
- legend(["Measured","Real"])
- figure()
- plot(1:length(RankErr),RankErr)
- title("Average error in Rank")
- xlabel("Games per player")
- ylabel("Rank error")
- ylim([0,maximum(RankErr)*1.1])
- figure()
- plot( Data[:,iRealMMR] , Data[:,iMMR] , ".k")
- title("Real vs System MMR")
- xlabel("Real MMR")
- ylabel("Estimated MMR")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement