Possibly fixed #375 trivia bug

This commit is contained in:
Kwoth
2022-08-06 17:28:31 +02:00
parent 8c51cf8537
commit 71d6eeb9dd

View File

@@ -57,123 +57,133 @@ public sealed class TriviaGame
// loop until game is stopped // loop until game is stopped
// each iteration is one round // each iteration is one round
var firstRun = true; var firstRun = true;
while (!_isStopped) try
{ {
if (errorCount >= 5) while (!_isStopped)
{ {
Log.Warning("Trivia errored 5 times and will quit"); if (errorCount >= 5)
break;
}
// wait for 3 seconds before posting the next question
if (firstRun)
{
firstRun = false;
}
else
{
await Task.Delay(3000);
}
var maybeQuestion = await _questionPool.GetQuestionAsync();
if(!(maybeQuestion is TriviaQuestion question))
{
// if question is null (ran out of question, or other bugg ) - stop
break;
}
CurrentQuestion = question;
try
{
// clear out all of the past guesses
while (_inputs.Reader.TryRead(out _)) ;
await OnQuestion(this, question);
}
catch (Exception ex)
{
Log.Warning(ex, "Error executing OnQuestion: {Message}", ex.Message);
errorCount++;
continue;
}
// just keep looping through user inputs until someone guesses the answer
// or the timer expires
var halfGuessTimerTask = TimeOutFactory();
var hintSent = false;
var guessed = false;
while (true)
{
var readTask = _inputs.Reader.ReadAsync().AsTask();
// wait for either someone to attempt to guess
// or for timeout
var task = await Task.WhenAny(readTask, halfGuessTimerTask);
// if the task which completed is the timeout task
if (task == halfGuessTimerTask)
{ {
// if hint is already sent, means time expired Log.Warning("Trivia errored 5 times and will quit");
// break (end the round) await OnEnded(this);
if (hintSent) break;
break; }
// else, means half time passed, send a hint // wait for 3 seconds before posting the next question
hintSent = true; if (firstRun)
// start a new countdown of the same length {
halfGuessTimerTask = TimeOutFactory(); firstRun = false;
// send a hint out }
await OnHint(this, question); else
{
await Task.Delay(3000);
}
var maybeQuestion = await _questionPool.GetQuestionAsync();
if (!(maybeQuestion is TriviaQuestion question))
{
// if question is null (ran out of question, or other bugg ) - stop
break;
}
CurrentQuestion = question;
try
{
// clear out all of the past guesses
while (_inputs.Reader.TryRead(out _))
;
await OnQuestion(this, question);
}
catch (Exception ex)
{
Log.Warning(ex, "Error executing OnQuestion: {Message}", ex.Message);
errorCount++;
continue; continue;
} }
// otherwise, read task is successful, and we're gonna
// get the user input data
var (user, input) = await readTask;
// check the guess // just keep looping through user inputs until someone guesses the answer
if (question.IsAnswerCorrect(input)) // or the timer expires
var halfGuessTimerTask = TimeOutFactory();
var hintSent = false;
var guessed = false;
while (true)
{ {
// add 1 point to the user var readTask = _inputs.Reader.ReadAsync().AsTask();
var val = _users.AddOrUpdate(user.Id, 1, (_, points) => ++points);
guessed = true;
// reset inactivity counter // wait for either someone to attempt to guess
inactivity = 0; // or for timeout
var task = await Task.WhenAny(readTask, halfGuessTimerTask);
var isWin = false; // if the task which completed is the timeout task
// if user won the game, tell the game to stop if (task == halfGuessTimerTask)
if (val >= _opts.WinRequirement)
{ {
_isStopped = true; // if hint is already sent, means time expired
isWin = true; // break (end the round)
if (hintSent)
break;
// else, means half time passed, send a hint
hintSent = true;
// start a new countdown of the same length
halfGuessTimerTask = TimeOutFactory();
// send a hint out
await OnHint(this, question);
continue;
} }
// call onguess // otherwise, read task is successful, and we're gonna
await OnGuess(this, user, question, isWin); // get the user input data
break; var (user, input) = await readTask;
// check the guess
if (question.IsAnswerCorrect(input))
{
// add 1 point to the user
var val = _users.AddOrUpdate(user.Id, 1, (_, points) => ++points);
guessed = true;
// reset inactivity counter
inactivity = 0;
var isWin = false;
// if user won the game, tell the game to stop
if (val >= _opts.WinRequirement)
{
_isStopped = true;
isWin = true;
}
// call onguess
await OnGuess(this, user, question, isWin);
break;
}
} }
}
if (!guessed) if (!guessed)
{
await OnTimeout(this, question);
if (_opts.Timeout != 0 && ++inactivity >= _opts.Timeout)
{ {
Log.Information("Trivia game is stopping due to inactivity"); await OnTimeout(this, question);
break;
if (_opts.Timeout != 0 && ++inactivity >= _opts.Timeout)
{
Log.Information("Trivia game is stopping due to inactivity");
break;
}
} }
} }
} }
catch
{
// make sure game is set as ended }
_isStopped = true; finally
{
await OnEnded(this); // make sure game is set as ended
_isStopped = true;
_ = OnEnded(this);
}
} }
public IReadOnlyList<(ulong User, int points)> GetLeaderboard() public IReadOnlyList<(ulong User, int points)> GetLeaderboard()