Skip to content

Instantly share code, notes, and snippets.

@mattmazzola
Created November 23, 2020 03:04
Show Gist options
  • Save mattmazzola/eb8aaa3e78d65ffc2e3bf2fd53397f3d to your computer and use it in GitHub Desktop.
Save mattmazzola/eb8aaa3e78d65ffc2e3bf2fd53397f3d to your computer and use it in GitHub Desktop.
Simulate Games
// For each player simulate the player answering series of questions and observe rating changes
export default function simulateGames(
ratingSystem: RatingSystem,
players: Player[],
questions: Question[],
numQuestionsPerPlayer: number,
ratingRange: number
): Result[] {
const results: Result[] = []
for (const player of players) {
for (let i = 0; i < numQuestionsPerPlayer; i++) {
// Get opponentn for player using current ratings
// Would simulate another matching system which pairs condidate players
const minRating = player.rating - ratingRange
const maxRating = player.rating + ratingRange
const isRatingWithinRange = (question: Question) => minRating <= question.rating && question.rating <= maxRating
const question = getRandomWhichMeetsConstraints(questions, isRatingWithinRange)
// Need to expose the probabilities in order to compute the outcome
// For the simulation we want the score biased based on the skill difference
// Intention is the better / more knowledgeable user is more likely to score / answer correct
const [playerProbability, questionProbability] = ratingSystem.getPlayerProbabilities(player.rating, question.rating)
const expectedOutcome = playerProbability > 0.5 ? 1 : 0
const playerOutcome = Math.random() < playerProbability ? 1 : 0
// const questionOutcome = 1 - playerOutcome
const nextRatingsInfo = ratingSystem.getNextRatings(player.rating, question.rating, playerOutcome)
const result: Result = {
iteration: i,
playerId: player.id,
questionId: question.id,
playerRating: player.rating,
questionRating: question.rating,
playerProbability: playerProbability,
questionProbability: questionProbability,
playerOutcome,
expectedOutcome,
updatedPlayerRating: nextRatingsInfo.nextPlayerARating,
updatedPlayerDiff: nextRatingsInfo.playerARatingDiff,
updatedQuestionRating: nextRatingsInfo.nextPlayerBRating,
updatedQuestionDiff: nextRatingsInfo.playerBRatingDiff
}
player.rating = Math.round(nextRatingsInfo.nextPlayerARating)
question.rating = Math.round(nextRatingsInfo.nextPlayerBRating)
// console.log(`add result: ${player.id} i:${i}`)
results.push(result)
}
}
return results
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment