public void StartRegularSesionAsync(IUserDto user1, IUserDto user2) { Task.Run(async() => { user1.EnterGame(); user2.EnterGame(); bool timeoutHasCome = false; var timer = new Timer(Callback => { timeoutHasCome = true; }, null, 300_000, Timeout.Infinite); var session = new Session(user1.Account.Login, user2.Account.Login); await Task.Delay(3000); while (!user1.CurrentGame().Token.IsCancellationRequested && !user2.CurrentGame().Token.IsCancellationRequested) { if (timeoutHasCome) { if (session.Rounds.Count == 0) { return; } session.EndingReason = "session was cancelled due to timeout"; user1.RegisterNewSession(session); user2.RegisterNewSession(session); return; } _logger.LogWarning($"User {user1.Account.Login} " + $"and {user2.Account.Login} started new round!"); _logger.LogWarning($"First player fig: {user1.GetCurrentFigure()}, " + $"Second player fig: {user2.GetCurrentFigure()}"); var round = await _gamePerformer.StartRoundWithPlayerAsync(user1, user2, user1.CurrentGame().Token, user2.CurrentGame().Token, new CancellationTokenSource(TimeSpan.FromSeconds(20)).Token); user1.ChangeCurrentFigure(Figure.None); user2.ChangeCurrentFigure(Figure.None); if (round != null) { _logger.LogWarning($"new round successfully added" + $" to users {user1.Account.Login} and {user2.Account.Login}"); session.Rounds.Add(round); timer.Change(300_000, Timeout.Infinite); } } timer.Dispose(); user1.ExitGame(); user2.ExitGame(); _logger.LogWarning($"User {user1.Account.Login} " + $"and {user2.Account.Login} ended session!"); user1.ResetCancellationToken(); user2.ResetCancellationToken(); if (session.Rounds.Count == 0) { return; } session.EndingReason = "user quited session"; _logger.LogWarning($"User {user1.Account.Login} " + $"and {user2.Account.Login} added new session to their sesion lists!"); user1.RegisterNewSession(session); user2.RegisterNewSession(session); return; }); }
public async Task <Round> StartRoundWithPlayerAsync(IUserDto user1, IUserDto user2, CancellationToken user1Ct, CancellationToken user2Ct, CancellationToken timeoutCt) { return(await Task.Run(async() => { user1.StartRound(); user2.StartRound(); _logger.LogWarning($"Waiting for users {user1.Account.Login}" + $" and {user2.Account.Login} turns"); while (user1.GetCurrentFigure() == Figure.None || user2.GetCurrentFigure() == Figure.None) { if (user1Ct.IsCancellationRequested || user2Ct.IsCancellationRequested) { user1.EndRound(); user2.EndRound(); return default; } if (timeoutCt.IsCancellationRequested) { return default; } } _logger.LogWarning($"Users {user1.Account.Login} " + $"and {user2.Account.Login} have chosen figures {user1.GetCurrentFigure()}" + $"and {user2.GetCurrentFigure()}!"); var result = CheckForWinner(user1.GetCurrentFigure(), user2.GetCurrentFigure()); user1.EndRound(); user2.EndRound(); await Task.Delay(1000); switch (result) { case 1: { _logger.LogWarning($"Player {user1.Account.Login} won!"); user1.LastRoundResult = "victory"; user2.LastRoundResult = "defeat"; return new Round { Winner = (user1.Account.Login), Looser = user2.Account.Login, WinnerFigure = user1.GetCurrentFigure(), LooserFigure = user2.GetCurrentFigure() }; } case 2: { _logger.LogWarning($"Player {user2.Account.Login} won!"); user1.LastRoundResult = "defeat"; user2.LastRoundResult = "victory"; return new Round { Winner = (user2.Account.Login), Looser = user1.Account.Login, WinnerFigure = user2.GetCurrentFigure(), LooserFigure = user1.GetCurrentFigure() }; } case 0: { user1.LastRoundResult = "draw"; user2.LastRoundResult = "draw"; return new Round { Winner = ("draw"), Looser = ("draw"), WinnerFigure = Figure.None, LooserFigure = Figure.None }; } } return default; }, timeoutCt)); }
public void StartAISesionAsync(IUserDto user) { //I used Task.Run instead of TaskFactory.StartNew to reuse threads in thread pool Task.Run(async() => { user.EnterGame(); bool timeoutHasCome = false; var timer = new Timer(Callback => { timeoutHasCome = true; }, null, 300_000, Timeout.Infinite); var session = new Session(user.Account.Login, "computer"); await Task.Delay(3000); while (!user.CurrentGame().Token.IsCancellationRequested) { if (timeoutHasCome) { if (session.Rounds.Count == 0) { return; } session.EndingReason = "session was cancelled due to timeout"; user.RegisterNewSession(session); return; } _logger.LogWarning($"User {user.Account.Login} " + $"started new round with AI!"); _logger.LogWarning($"First player fig: {user.GetCurrentFigure()}"); var round = await _gamePerformer.StartRoundWithAIAsync(user, user.CurrentGame().Token, new CancellationTokenSource(TimeSpan.FromSeconds(20)).Token); user.ChangeCurrentFigure(Figure.None); if (round != null) { _logger.LogWarning($"new round with AI successfully added" + $" to user {user.Account.Login}"); session.Rounds.Add(round); timer.Change(300_000, Timeout.Infinite); } } timer.Dispose(); user.ExitGame(); _logger.LogWarning($"User {user.Account.Login} " + $"ended session!"); user.ResetCancellationToken(); if (session.Rounds.Count == 0) { return; } session.EndingReason = "user quited session"; _logger.LogWarning($"User {user.Account.Login} " + $"added new session with AI to his sesion lists!"); user.RegisterNewSession(session); return; }); }
public async Task <Round> StartRoundWithAIAsync(IUserDto user, CancellationToken ct, CancellationToken timeoutCt) { return(await Task.Run(async() => { user.StartRound(); _logger.LogWarning($"Waiting for user {user.Account.Login}" + $"turn"); while (user.GetCurrentFigure() == Figure.None) { if (ct.IsCancellationRequested) { user.EndRound(); return default; } if (timeoutCt.IsCancellationRequested) { return default; } } var aiFigure = new AIPlayer().GetRandomFigure(); _logger.LogWarning($"User {user.Account.Login} " + $"and AI have chosen figures {user.GetCurrentFigure()}" + $"and {aiFigure}!"); var result = CheckForWinner(user.GetCurrentFigure(), aiFigure); user.EndRound(); await Task.Delay(1000); switch (result) { case 1: { _logger.LogWarning($"Player {user.Account.Login} won!"); user.LastRoundResult = "victory"; return new Round { Winner = (user.Account.Login), Looser = "computer", WinnerFigure = user.GetCurrentFigure(), LooserFigure = aiFigure }; } case 2: { _logger.LogWarning($"Computer won!"); user.LastRoundResult = "defeat"; return new Round { Winner = "computer", Looser = user.Account.Login, WinnerFigure = aiFigure, LooserFigure = user.GetCurrentFigure() }; } case 0: { user.LastRoundResult = "draw"; return new Round { Winner = ("draw"), Looser = ("draw"), WinnerFigure = Figure.None, LooserFigure = Figure.None }; } } return default; }, timeoutCt)); }