diff --git a/ColourMeOKGame/Assets/Scripts/AccountUI.cs b/ColourMeOKGame/Assets/Scripts/AccountUI.cs
index 1c68236..a46cabc 100644
--- a/ColourMeOKGame/Assets/Scripts/AccountUI.cs
+++ b/ColourMeOKGame/Assets/Scripts/AccountUI.cs
@@ -661,7 +661,7 @@ private void OnLocalPlayerDataChangeCallback(LocalPlayerData data)
$"updating AccountView ui with lkUsername={data.LastKnownUsername} and lkEmail={data.LastKnownEmail}");
_usernameField.value = data.LastKnownUsername;
_emailField.value = data.LastKnownEmail;
- _header.text = $"Signed in as {data.LastKnownUsername}";
+ if (state == State.SignedIn) _header.text = $"Signed in as {data.LastKnownUsername}";
}
///
diff --git a/ColourMeOKGame/Assets/Scripts/Backend.cs b/ColourMeOKGame/Assets/Scripts/Backend.cs
index a1443a4..55fd00a 100644
--- a/ColourMeOKGame/Assets/Scripts/Backend.cs
+++ b/ColourMeOKGame/Assets/Scripts/Backend.cs
@@ -571,7 +571,7 @@ public void GetRecentScores(Action
{
@@ -618,7 +618,7 @@ private void GetBestScores(Action
{
@@ -702,21 +702,23 @@ private void GetBestScores(Action LocalPlayerData.MaxRecentLocalScores) recentScoreQueue.Dequeue();
+ while (recentScoreQueue.Count > LocalPlayerData.MaxRecentScores) recentScoreQueue.Dequeue();
GetBestScores((bestRes, bestScores) =>
{
if (bestRes != DatabaseTransactionResult.Ok)
{
Debug.Log("failed to get recent scores");
+ GameManager.Instance.FireLocalPlayerDataChangeCallbacks(GameManager.Instance.Data);
callback(recentRes, 0f);
return;
}
var bestScoreQueue = GameManager.Instance.Data.BestOnlineScores;
foreach (var score in bestScores) bestScoreQueue.Enqueue(score);
- while (bestScoreQueue.Count > LocalPlayerData.MaxBestOnlineScores) bestScoreQueue.Dequeue();
+ while (bestScoreQueue.Count > LocalPlayerData.MaxBestScores) bestScoreQueue.Dequeue();
+ GameManager.Instance.FireLocalPlayerDataChangeCallbacks(GameManager.Instance.Data);
callback(DatabaseTransactionResult.Ok, GameManager.Instance.Data.CalculateUserRating());
});
});
@@ -737,14 +739,17 @@ private void GetBestScores(Action
{
if (task.IsCompletedSuccessfully)
{
+ Debug.Log($"updated online user rating to {userRating}");
callback(DatabaseTransactionResult.Ok);
}
else
diff --git a/ColourMeOKGame/Assets/Scripts/GameManager.cs b/ColourMeOKGame/Assets/Scripts/GameManager.cs
index 8ce1299..7937eef 100644
--- a/ColourMeOKGame/Assets/Scripts/GameManager.cs
+++ b/ColourMeOKGame/Assets/Scripts/GameManager.cs
@@ -175,42 +175,47 @@ public void SignalGameEnd(List playedRounds)
var historicalLightnessAcc = 0f;
var historicalChromaAcc = 0f;
var historicalHueAcc = 0f;
- var historicalRounds = 0;
+ var historicalPerceivedAcc = 0f;
+ var historicalGames = 0;
- foreach (var localScore in _data.RecentLocalScores)
+ foreach (var localScore in _data.RecentLocalScores.Take(LocalPlayerData.MaxRecentScores))
{
historicalLightnessAcc += localScore.AvgLightnessAccuracy;
historicalChromaAcc += localScore.AvgChromaAccuracy;
historicalHueAcc += localScore.AvgHueAccuracy;
- historicalRounds += localScore.NoOfRounds;
+ historicalPerceivedAcc += localScore.AvgPerceivedAccuracy;
+ historicalGames++;
}
- foreach (var onlineScore in _data.RecentOnlineScores)
+ foreach (var onlineScore in _data.RecentOnlineScores.Take(LocalPlayerData.MaxRecentScores))
{
historicalLightnessAcc += onlineScore.AvgLightnessAccuracy;
historicalChromaAcc += onlineScore.AvgChromaAccuracy;
historicalHueAcc += onlineScore.AvgHueAccuracy;
- historicalRounds += onlineScore.NoOfRounds;
+ historicalPerceivedAcc += onlineScore.AvgPerceivedAccuracy;
+ historicalGames++;
}
- foreach (var onlineScore in _data.BestOnlineScores)
+ foreach (var onlineScore in _data.BestOnlineScores.Take(LocalPlayerData.MaxBestScores))
{
historicalLightnessAcc += onlineScore.AvgLightnessAccuracy;
historicalChromaAcc += onlineScore.AvgChromaAccuracy;
historicalHueAcc += onlineScore.AvgHueAccuracy;
- historicalRounds += onlineScore.NoOfRounds;
+ historicalPerceivedAcc += onlineScore.AvgPerceivedAccuracy;
+ historicalGames++;
}
- historicalLightnessAcc /= historicalRounds;
- historicalChromaAcc /= historicalRounds;
- historicalHueAcc /= historicalRounds;
+ historicalGames = Math.Max(1, historicalGames);
+ historicalLightnessAcc /= historicalGames;
+ historicalChromaAcc /= historicalGames;
+ historicalHueAcc /= historicalGames;
+ historicalPerceivedAcc /= historicalGames;
// calculate round averages
var gameLightnessAcc = 0d;
var gameChromaAcc = 0d;
var gameHueAcc = 0d;
var gamePerceivedAcc = 0d;
-
var templateColour = Color.clear;
var responseColour = Color.clear;
var roundNumber = 1;
@@ -226,7 +231,7 @@ public void SignalGameEnd(List playedRounds)
var roundLightnessAcc = Math.Clamp(dLCh.L * 100d, 0d, 100d);
var roundChromaAcc = Math.Clamp(dLCh.C * 100d, 0d, 100d);
var roundHueAcc = Math.Clamp(dLCh.h * 100d, 0d, 100d);
- var roundPerceivedAcc = Math.Clamp((100d - distance.dE) * 100d, 0d, 100d);
+ var roundPerceivedAcc = Math.Clamp((1d - distance.dE) * 100d, 0d, 100d);
gameLightnessAcc += roundLightnessAcc;
gameChromaAcc += roundChromaAcc;
@@ -242,7 +247,7 @@ public void SignalGameEnd(List playedRounds)
showcaseTemplate.style.backgroundColor = templateColour;
showcaseResponse.style.backgroundColor = responseColour;
showcaseInfo.text =
- $"{roundLightnessAcc:N0}% {roundChromaAcc:N0}% {roundHueAcc:N0}% ({roundPerceivedAcc:N0}%)";
+ $"{roundLightnessAcc * (roundPerceivedAcc / 100d):N0}% {roundChromaAcc * (roundPerceivedAcc / 100d):N0}% {roundHueAcc * (roundPerceivedAcc / 100d):N0}% ({roundPerceivedAcc:N0}%)";
}
else
{
@@ -256,26 +261,31 @@ public void SignalGameEnd(List playedRounds)
gameChromaAcc /= Gameplay.RoundsPerGame;
gameHueAcc /= Gameplay.RoundsPerGame;
gamePerceivedAcc /= Gameplay.RoundsPerGame;
-
- // NOTE: this is NOT equiv to user rating, this is just a per-game accuracy score
- // all that math is done in LocalPlayerData.CalculateUserRating
- var gameAccuracy = (gameLightnessAcc + gameChromaAcc + gameHueAcc + gamePerceivedAcc) / 4;
+
+ var adjustedHistoricalLightnessAcc = historicalLightnessAcc * (historicalPerceivedAcc / 100d);
+ var adjustedHistoricalChromaAcc = historicalChromaAcc * (historicalPerceivedAcc / 100d);
+ var adjustedHistoricalHueAcc = historicalHueAcc * (historicalPerceivedAcc / 100d);
+ var adjustedGameLightnessAcc = gameLightnessAcc * (gamePerceivedAcc / 100d);
+ var adjustedGameChromaAcc = gameChromaAcc * (gamePerceivedAcc / 100d);
+ var adjustedGameHueAcc = gameHueAcc * (gamePerceivedAcc / 100d);
+ var gameAccuracy = (gameLightnessAcc + gameChromaAcc + gameHueAcc + gamePerceivedAcc) / 4d;
// make comparison texts
- var lAccDeltaText = (gameLightnessAcc > historicalLightnessAcc ? "+" : "-") +
- Math.Abs(gameLightnessAcc - historicalLightnessAcc).ToString("F2");
- var cAccDeltaText = (gameChromaAcc > historicalChromaAcc ? "+" : "-") +
- Math.Abs(gameChromaAcc - historicalChromaAcc).ToString("F2");
- var hAccDeltaText = (gameHueAcc > historicalHueAcc ? "+" : "-") +
- Math.Abs(gameHueAcc - historicalHueAcc).ToString("F2");
+ var lAccDeltaText = (adjustedGameLightnessAcc > adjustedHistoricalLightnessAcc ? "+" : "-") +
+ $"{Math.Abs(adjustedGameLightnessAcc - adjustedHistoricalLightnessAcc):F1}%";
+ var cAccDeltaText = (adjustedGameChromaAcc > adjustedHistoricalChromaAcc ? "+" : "-") +
+ $"{Math.Abs(adjustedGameChromaAcc - adjustedHistoricalChromaAcc):F1}%";
+ var hAccDeltaText = (adjustedGameHueAcc > adjustedHistoricalHueAcc ? "+" : "-") +
+ $"{Math.Abs(adjustedGameHueAcc - adjustedHistoricalHueAcc):F1}%";
var score = new LocalPlayerData.Score(DateTime.Now,
playedRounds.Count,
- (float)gameLightnessAcc,
- (float)gameChromaAcc,
- (float)gameHueAcc,
+ (float)adjustedGameLightnessAcc,
+ (float)adjustedGameChromaAcc,
+ (float)adjustedGameHueAcc,
(float)gamePerceivedAcc);
+ // breakpoint here: why is gamePerceivedAcc always "100"?
var oldRating = _data.CalculateUserRating();
_data.RegisterLocalScore(score);
FireLocalPlayerDataChangeCallbacks(Instance.Data);
@@ -298,7 +308,6 @@ public void SignalGameEnd(List playedRounds)
{
Debug.Log("couldn't calculate user rating");
TransitionToResultsView(_data.CalculateUserRating());
- FireLocalPlayerDataChangeCallbacks(Instance.Data);
return;
}
@@ -322,17 +331,17 @@ void TransitionToResultsView(float rating)
{
Debug.Log("signal GameManager-UIManager transition to results view");
- var ratingDifferenceDescriptor = oldRating > rating ? "decreased" : "increased";
+ var ratingDifferenceDescriptor = rating > oldRating ? "increased" : "decreased";
var ratingText = rating >= 0
? $"\nYour rating has {ratingDifferenceDescriptor} by {Math.Abs(rating - oldRating):F2}."
: "\nYour rating could not be calculated.";
// build the result text and show the results view
- ui.UI.Q
// ReSharper disable once MemberCanBePrivate.Global
- public const double SecondsPerRound = 15d;
+ public const double SecondsPerRound = 12d;
///
/// countdown text label for showing the countdown
@@ -118,7 +118,7 @@ private void StoreRoundInfo()
TemplateColour = _templateColour.style.backgroundColor.value,
ResponseColour = _responseColour.style.backgroundColor.value
});
- Debug.Log("stored round info");
+ Debug.Log($"stored round info (Template is {_templateColour.style.backgroundColor.value}, Response is {_responseColour.style.backgroundColor.value})");
}
///
@@ -127,13 +127,13 @@ private void StoreRoundInfo()
///
private void GenerateNewTemplateColour()
{
- // - lightness: 40-80
- // - chroma: 0.05-0.20
+ // - lightness: 30-90
+ // - chroma: 0.03-0.20
// - hue: all (0-360)
var r = new Random();
- var l = Math.Clamp(r.NextDouble() * 40d + 40d, 40d, 100d);
- var c = Math.Clamp(r.NextDouble() * 0.15d + 0.05d, 0.05d, 0.20d);
+ var l = Math.Clamp(r.NextDouble() * 60d + 30d, 30d, 90d);
+ var c = Math.Clamp(r.NextDouble() * 0.17d + 0.03d, 0.03d, 0.20d);
var h = Math.Clamp(r.NextDouble() * 360d, 0d, 360d);
var colour = Colorimetry.RawLchToColor(l, c, h);
Debug.Log($"generated new template colour LCh({l:F}, {c:F}, {h:F}) -> {colour}");
@@ -147,7 +147,7 @@ private void Render()
{
var remaining = (_countdownDatetime - DateTime.Now).TotalSeconds;
_roundText.text = $"{Round}/{RoundsPerGame}";
- _countdownText.text = $"{remaining:F}";
+ _countdownText.text = $"{remaining:F2}";
}
///
diff --git a/ColourMeOKGame/Assets/Scripts/LocalPlayerData.cs b/ColourMeOKGame/Assets/Scripts/LocalPlayerData.cs
index 783bd60..ace8d33 100644
--- a/ColourMeOKGame/Assets/Scripts/LocalPlayerData.cs
+++ b/ColourMeOKGame/Assets/Scripts/LocalPlayerData.cs
@@ -9,17 +9,17 @@ public class LocalPlayerData
///
/// maximum number of the best online scores to keep track of
///
- public const int MaxBestOnlineScores = 10;
+ public const int MaxBestScores = 10;
///
/// maximum number of recent local scores to keep track of
///
- public const int MaxRecentLocalScores = 10;
+ public const int MaxRecentScores = 10;
///
/// the gamma value used in the exponential user rating calculation
///
- private const float ExponentialUserRatingGamma = 1.75f;
+ private const float ExponentialUserRatingGamma = 2f;
///
/// last known email used
@@ -149,10 +149,23 @@ public void SaveToTheWorld()
/// the score to register
public void RegisterLocalScore(Score score)
{
- while (RecentLocalScores.Count >= MaxRecentLocalScores) RecentLocalScores.Dequeue();
+ while (RecentLocalScores.Count >= MaxRecentScores) RecentLocalScores.Dequeue();
RecentLocalScores.Enqueue(score);
}
+ ///
+ /// registers a score to the player's online data
+ ///
+ ///
+ /// the
+ ///
+ public static double UserRatingScalingF(double rating)
+ {
+ var rawUserRating = Math.Clamp(rating, 0d, 100d);
+ var exponentialRating = 100d * Math.Pow(rawUserRating / 100d, ExponentialUserRatingGamma);
+ return Math.Clamp(exponentialRating, 0d, 100d);
+ }
+
///
/// calculates the user rating based on whatever local data is available
///
@@ -164,9 +177,9 @@ public float CalculateUserRating()
// in this case 20 best scores, and 10 recent scores are used
// ensure the scores don't exceed their arbitrary limits
- while (RecentOnlineScores.Count > MaxRecentLocalScores) RecentOnlineScores.Dequeue();
- while (RecentLocalScores.Count > MaxRecentLocalScores) RecentLocalScores.Dequeue();
- while (BestOnlineScores.Count > MaxBestOnlineScores) BestOnlineScores.Dequeue();
+ while (RecentOnlineScores.Count > MaxRecentScores) RecentOnlineScores.Dequeue();
+ while (RecentLocalScores.Count > MaxRecentScores) RecentLocalScores.Dequeue();
+ while (BestOnlineScores.Count > MaxBestScores) BestOnlineScores.Dequeue();
// if online scores are available, use them
var recentScores = RecentOnlineScores.Count > 0 ? RecentOnlineScores : RecentLocalScores;
@@ -177,37 +190,20 @@ public float CalculateUserRating()
foreach (var score in recentScores.Take(10))
{
+ totalRating += (score.AvgLightnessAccuracy + score.AvgChromaAccuracy + score.AvgHueAccuracy + score.AvgPerceivedAccuracy) / 4d;
scores++;
- var dL = score.AvgLightnessAccuracy;
- var dC = score.AvgChromaAccuracy;
- var dH = score.AvgHueAccuracy;
- var dE = Math.Sqrt(score.AvgLightnessAccuracy * score.AvgLightnessAccuracy
- + score.AvgChromaAccuracy * score.AvgChromaAccuracy
- + score.AvgHueAccuracy * score.AvgHueAccuracy);
- totalRating += (dL + dC + dH + dE + dE) / 5d;
}
foreach (var score in bestScores.Take(20))
{
+ totalRating += (score.AvgLightnessAccuracy + score.AvgChromaAccuracy + score.AvgHueAccuracy + score.AvgPerceivedAccuracy) / 4d;
scores++;
- var dL = score.AvgLightnessAccuracy;
- var dC = score.AvgChromaAccuracy;
- var dH = score.AvgHueAccuracy;
- var dE = Math.Sqrt(score.AvgLightnessAccuracy * score.AvgLightnessAccuracy
- + score.AvgChromaAccuracy * score.AvgChromaAccuracy
- + score.AvgHueAccuracy * score.AvgHueAccuracy);
- totalRating += (dL + dC + dH + dE + dE) / 5d;
}
- scores = Math.Max(1, scores);
- totalRating /= scores;
+ var rating = UserRatingScalingF(totalRating /= Math.Max(1, scores));
+ Debug.Log($"locally calculated user rating: lin: {totalRating} -> exp: {rating}");
- var rawUserRating = Math.Clamp(totalRating, 0d, 100d);
- var exponentialRating = 100d * Math.Pow(rawUserRating / 100d, ExponentialUserRatingGamma);
-
- Debug.Log($"locally calculated user rating: lin: {rawUserRating} -> exp: {exponentialRating}");
-
- return (float)exponentialRating;
+ return (float)rating;
}
public struct Score
diff --git a/ColourMeOKGame/Assets/Scripts/SideViewUI.cs b/ColourMeOKGame/Assets/Scripts/SideViewUI.cs
index 5375a03..55611bb 100644
--- a/ColourMeOKGame/Assets/Scripts/SideViewUI.cs
+++ b/ColourMeOKGame/Assets/Scripts/SideViewUI.cs
@@ -111,7 +111,7 @@ private void RenderFromPlayerData(LocalPlayerData data)
var totalLightnessAcc = 0f;
var totalChromaAcc = 0f;
var totalHueAcc = 0f;
- var totalRounds = 0;
+ var totalGames = 0;
// average out all the scores we have to get a stable-ish average
@@ -120,7 +120,7 @@ private void RenderFromPlayerData(LocalPlayerData data)
totalLightnessAcc += localScore.AvgLightnessAccuracy;
totalChromaAcc += localScore.AvgChromaAccuracy;
totalHueAcc += localScore.AvgHueAccuracy;
- totalRounds += localScore.NoOfRounds;
+ totalGames++;
}
foreach (var onlineScore in data.RecentOnlineScores)
@@ -128,7 +128,7 @@ private void RenderFromPlayerData(LocalPlayerData data)
totalLightnessAcc += onlineScore.AvgLightnessAccuracy;
totalChromaAcc += onlineScore.AvgChromaAccuracy;
totalHueAcc += onlineScore.AvgHueAccuracy;
- totalRounds += onlineScore.NoOfRounds;
+ totalGames++;
}
foreach (var onlineScore in data.BestOnlineScores)
@@ -136,14 +136,14 @@ private void RenderFromPlayerData(LocalPlayerData data)
totalLightnessAcc += onlineScore.AvgLightnessAccuracy;
totalChromaAcc += onlineScore.AvgChromaAccuracy;
totalHueAcc += onlineScore.AvgHueAccuracy;
- totalRounds += onlineScore.NoOfRounds;
+ totalGames++;
}
- Debug.Log($"tL={totalLightnessAcc} tC={totalChromaAcc} tH={totalHueAcc} tR={totalRounds}");
- if (totalRounds == 0) totalRounds = 1;
- var lightnessAcc = totalLightnessAcc / totalRounds;
- var chromaAcc = totalChromaAcc / totalRounds;
- var hueAcc = totalHueAcc / totalRounds;
+ Debug.Log($"tL={totalLightnessAcc} tC={totalChromaAcc} tH={totalHueAcc} tG={totalGames}");
+ if (totalGames == 0) totalGames = 1;
+ var lightnessAcc = totalLightnessAcc / totalGames;
+ var chromaAcc = totalChromaAcc / totalGames;
+ var hueAcc = totalHueAcc / totalGames;
var playerText = GameManager.Instance.Backend.IsSignedIn
? data.LastKnownUsername
: $"{data.LastKnownUsername} (Not Signed In)";
@@ -151,9 +151,9 @@ private void RenderFromPlayerData(LocalPlayerData data)
// finally, set the labels
_playerText.text = playerText;
- _ratingText.text = $"{rating:F}";
- _lightnessAccuracyText.text = $"{lightnessAcc:F}";
- _chromaAccuracyText.text = $"{chromaAcc:F}";
- _hueAccuracyText.text = $"{hueAcc:F}";
+ _ratingText.text = $"{rating:F3}";
+ _lightnessAccuracyText.text = $"{lightnessAcc:F2}%";
+ _chromaAccuracyText.text = $"{chromaAcc:F2}%";
+ _hueAccuracyText.text = $"{hueAcc:F2}%";
}
}
\ No newline at end of file