예제 #1
0
func TwoOnTwoUnbalancedDrawTest(t *testing.T, calc skills.Calc) {
	gameInfo := skills.DefaultGameInfo

	team1 := skills.NewTeam()
	team1.AddPlayer(1, skills.NewRating(15, 8))
	team1.AddPlayer(2, skills.NewRating(20, 6))

	team2 := skills.NewTeam()
	team2.AddPlayer(3, skills.NewRating(25, 4))
	team2.AddPlayer(4, skills.NewRating(30, 3))

	teams := []skills.Team{team1, team2}

	newRatings := calc.CalcNewRatings(gameInfo, teams, 1, 1)

	// Winners
	AssertRating(t, 21.570, 6.556, newRatings[1])
	AssertRating(t, 23.696, 5.418, newRatings[2])

	// Losers
	AssertRating(t, 23.357, 3.833, newRatings[3])
	AssertRating(t, 29.075, 2.931, newRatings[4])

	AssertMatchQuality(t, 0.214, calc.CalcMatchQual(gameInfo, teams))
}
예제 #2
0
func TwoOnTwoUpsetTest(t *testing.T, calc skills.Calc) {
	gameInfo := skills.DefaultGameInfo

	team1 := skills.NewTeam()
	team1.AddPlayer(1, skills.NewRating(20, 8))
	team1.AddPlayer(2, skills.NewRating(25, 6))

	team2 := skills.NewTeam()
	team2.AddPlayer(3, skills.NewRating(35, 7))
	team2.AddPlayer(4, skills.NewRating(40, 5))

	teams := []skills.Team{team1, team2}

	newRatings := calc.CalcNewRatings(gameInfo, teams, 1, 2)

	// Winners
	AssertRating(t, 29.698, 7.008, newRatings[1])
	AssertRating(t, 30.455, 5.594, newRatings[2])

	// Losers
	AssertRating(t, 27.575, 6.346, newRatings[3])
	AssertRating(t, 36.211, 4.768, newRatings[4])

	AssertMatchQuality(t, 0.084, calc.CalcMatchQual(gameInfo, teams))
}
예제 #3
0
func TwoPlayerChessTestNotDrawn(t *testing.T, calc skills.Calc) {
	// Inspired by a real bug :-)
	gameInfo := &skills.GameInfo{
		InitialMean:     1200,
		InitialStddev:   1200 / 3,
		Beta:            200,
		DynamicsFactor:  1200 / 300,
		DrawProbability: 0.03,
	}

	team1 := skills.NewTeam()
	team1.AddPlayer(1, skills.NewRating(1301.0007, 42.9232))

	team2 := skills.NewTeam()
	team2.AddPlayer(2, skills.NewRating(1188.7560, 42.5570))

	teams := []skills.Team{team1, team2}

	newRatings := calc.CalcNewRatings(gameInfo, teams, 1, 2)

	player1NewRating := newRatings[1]
	AssertRating(t, 1304.7820836053318, 42.843513887848658, player1NewRating)

	player2NewRating := newRatings[2]
	AssertRating(t, 1185.0383099003536, 42.485604606897752, player2NewRating)
}
예제 #4
0
파일: ladder.go 프로젝트: Aaah/erosd
func calculateNewRating(winnerId, loserId int64, winnerRating, winnerStdDev, loserRating, loserStdDev float64) (winnerNewRating, winnerNewStdDev, loserNewRating, loserNewStdDev, quality float64) {
	team1 := skills.NewTeam()
	team2 := skills.NewTeam()

	team1.AddPlayer(winnerId, skills.NewRating(winnerRating, winnerStdDev))
	team2.AddPlayer(loserId, skills.NewRating(loserRating, loserStdDev))

	teams := []skills.Team{team1, team2}

	var calc trueskill.TwoPlayerCalc
	ratings := calc.CalcNewRatings(skills.DefaultGameInfo, teams, 1, 2)
	quality = calc.CalcMatchQual(skills.DefaultGameInfo, teams)

	return ratings[winnerId].Mean(), ratings[winnerId].Stddev(), ratings[loserId].Mean(), ratings[loserId].Stddev(), quality
}
예제 #5
0
func ThreeOnTwoTests(t *testing.T, calc skills.Calc) {
	gameInfo := skills.DefaultGameInfo

	team1 := skills.NewTeam()
	team1.AddPlayer(1, skills.NewRating(28, 7))
	team1.AddPlayer(2, skills.NewRating(27, 6))
	team1.AddPlayer(3, skills.NewRating(26, 5))

	team2 := skills.NewTeam()
	team2.AddPlayer(4, skills.NewRating(30, 4))
	team2.AddPlayer(5, skills.NewRating(31, 3))

	teams := []skills.Team{team1, team2}

	newRatings := calc.CalcNewRatings(gameInfo, teams, 1, 2)

	// Winners
	AssertRating(t, 28.658, 6.770, newRatings[1])
	AssertRating(t, 27.484, 5.856, newRatings[2])
	AssertRating(t, 26.336, 4.917, newRatings[3])

	// Losers
	AssertRating(t, 29.785, 3.958, newRatings[4])
	AssertRating(t, 30.879, 2.983, newRatings[5])

	newRatings = calc.CalcNewRatings(gameInfo, teams, 2, 1)

	// Losers
	AssertRating(t, 21.840, 6.314, newRatings[1])
	AssertRating(t, 22.474, 5.575, newRatings[2])
	AssertRating(t, 22.857, 4.757, newRatings[3])

	// Winners
	AssertRating(t, 32.012, 3.877, newRatings[4])
	AssertRating(t, 32.132, 2.949, newRatings[5])

	AssertMatchQuality(t, 0.254, calc.CalcMatchQual(gameInfo, teams))
}
예제 #6
0
func OneOnTwoSomewhatBalanced(t *testing.T, calc skills.Calc) {
	gameInfo := skills.DefaultGameInfo

	team1 := skills.NewTeam()
	team1.AddPlayer(1, skills.NewRating(40, 6))

	team2 := skills.NewTeam()
	team2.AddPlayer(2, skills.NewRating(20, 7))
	team2.AddPlayer(3, skills.NewRating(25, 8))

	teams := []skills.Team{team1, team2}

	newRatings := calc.CalcNewRatings(gameInfo, teams, 1, 2)

	// Winners
	AssertRating(t, 42.744, 5.602, newRatings[1])

	// Losers
	AssertRating(t, 16.266, 6.359, newRatings[2])
	AssertRating(t, 20.123, 7.028, newRatings[3])

	AssertMatchQuality(t, 0.478, calc.CalcMatchQual(gameInfo, teams))
}
예제 #7
0
func twoTeamUpdateRatings(gi *skills.GameInfo, newSkills skills.PlayerRatings, selfTeam, otherTeam skills.Team, comparison int) {
	drawMargin := drawMarginFromDrawProbability(gi.DrawProbability, gi.Beta)
	betaSqr := numerics.Sqr(gi.Beta)
	tauSqr := numerics.Sqr(gi.DynamicsFactor)

	totalPlayers := selfTeam.PlayerCount() + otherTeam.PlayerCount()

	selfMeanSum := selfTeam.Accum(skills.MeanSum)
	otherMeanSum := otherTeam.Accum(skills.MeanSum)

	c := math.Sqrt(selfTeam.Accum(skills.VarianceSum) + otherTeam.Accum(skills.VarianceSum) + float64(totalPlayers)*betaSqr)

	winningMean := selfMeanSum
	losingMean := otherMeanSum

	if comparison == skills.Lose {
		winningMean, losingMean = losingMean, winningMean
	}

	meanDelta := winningMean - losingMean

	var v, w, rankMultiplier float64

	if comparison != skills.Draw {
		v = vExceedsMarginC(meanDelta, drawMargin, c)
		w = wExceedsMarginC(meanDelta, drawMargin, c)
		rankMultiplier = float64(comparison)
	} else {
		v = vWithinMarginC(meanDelta, drawMargin, c)
		w = wWithinMarginC(meanDelta, drawMargin, c)
		rankMultiplier = 1
	}

	for p, r := range selfTeam.PlayerRatings {
		prevPlayerRating := r

		meanMultiplier := (prevPlayerRating.Variance() + tauSqr) / c
		stdDevMultiplier := (prevPlayerRating.Variance() + tauSqr) / numerics.Sqr(c)

		playerMeanDelta := rankMultiplier * meanMultiplier * v
		newMean := prevPlayerRating.Mean() + playerMeanDelta

		newStdDev := math.Sqrt((prevPlayerRating.Variance() + tauSqr) * (1 - w*stdDevMultiplier))

		newSkills[p] = skills.NewRating(newMean, newStdDev)
	}
}
예제 #8
0
func OneOnOneMassiveUpsetDrawTest(t *testing.T, calc skills.Calc) {
	gameInfo := skills.DefaultGameInfo

	team1 := skills.NewTeam()
	team1.AddPlayer(1, gameInfo.DefaultRating())

	team2 := skills.NewTeam()
	team2.AddPlayer(2, skills.NewRating(50, 12.5))

	teams := []skills.Team{team1, team2}

	newRatings := calc.CalcNewRatings(gameInfo, teams, 1, 1)

	player1NewRating := newRatings[1]
	AssertRating(t, 31.662, 7.137, player1NewRating)

	player2NewRating := newRatings[2]
	AssertRating(t, 35.010, 7.910, player2NewRating)
	AssertMatchQuality(t, 0.110, calc.CalcMatchQual(gameInfo, teams))
}
예제 #9
0
파일: matchmaking.go 프로젝트: Aaah/erosd
func NewMatchmakerParticipant(connection *ClientConnection) *MatchmakerParticipant {

	// TrueSkill stuff
	team := skills.NewTeam()
	team.AddPlayer(connection.client.Id, skills.NewRating(connection.client.RatingMean, connection.client.RatingStdDev))

	return &MatchmakerParticipant{
		connection: connection,
		client:     connection.client,
		enrollTime: time.Now(),
		team:       team,
		points:     connection.client.LadderPoints,
		rating:     connection.client.RatingMean,
		radius:     connection.client.LadderSearchRadius,
		regions:    connection.client.LadderSearchRegions,
		matching:   false,
		abort:      make(chan bool),
		match:      make(chan *MatchmakerMatch),
	}
}
예제 #10
0
func twoPlayerCalcNewRating(gi *skills.GameInfo, selfRating, oppRating skills.Rating, comparison int) skills.Rating {
	drawMargin := drawMarginFromDrawProbability(gi.DrawProbability, gi.Beta)

	c := math.Sqrt(numerics.Sqr(selfRating.Stddev()) + numerics.Sqr(oppRating.Stddev()) + 2*numerics.Sqr(gi.Beta))

	winningMean := selfRating.Mean()
	losingMean := oppRating.Mean()

	if comparison == skills.Lose {
		winningMean = oppRating.Mean()
		losingMean = selfRating.Mean()
	}

	meanDelta := winningMean - losingMean

	var v, w, rankMultiplier float64

	if comparison != skills.Draw {
		v = vExceedsMarginC(meanDelta, drawMargin, c)
		w = wExceedsMarginC(meanDelta, drawMargin, c)
		rankMultiplier = float64(comparison)
	} else {
		v = vWithinMarginC(meanDelta, drawMargin, c)
		w = wWithinMarginC(meanDelta, drawMargin, c)
		rankMultiplier = 1
	}

	meanMultiplier := (numerics.Sqr(selfRating.Stddev()) + numerics.Sqr(gi.DynamicsFactor)) / c

	varianceWithDynamics := numerics.Sqr(selfRating.Stddev()) + numerics.Sqr(gi.DynamicsFactor)
	stdDevMultiplier := varianceWithDynamics / numerics.Sqr(c)

	newMean := selfRating.Mean() + (rankMultiplier * meanMultiplier * v)
	newStdDev := math.Sqrt(varianceWithDynamics * (1 - w*stdDevMultiplier))

	return skills.NewRating(newMean, newStdDev)
}
예제 #11
0
func rating2srating(r Rating) skills.Rating {
	return skills.NewRating(r.Mean, r.Stddev)
}