public Error TryStartGame() { var setup = _phase.Setup; if (setup == null) { return(Error.Codes.E03NotInSetupPhase); } var err = setup.TryFinalLock(); if (err) { return(err); } var trans = new TransitionPhase(GamePhase.starting, setup); //since only once thread can successfully call TryFinalLock, we don't need a CompareExchange here: Volatile.Write(ref _phase, trans); // (likely overkill, but it occurs seldom so just in case...) // ------------ TODO: do we want a countdown before the game starts? // currently we just start "instantly"... // ------ Setup game, bots, and listeners, then call Start! ------ var ingame = new IngamePhase(trans.Slots); ingame.WinnerDeclared += Ingame_WinnerDeclared; // TODO: bots Volatile.Write(ref _phase, trans); // (likely overkill, but it occurs seldom so just in case...) ingame.Start(); return(Error.Codes.E00NoError); }
private void Ingame_WinnerDeclared(IngamePhase sender) { // assuming we have handled the logic session correctly... // ...this should only called from one thread once (race free). sender.WinnerDeclared -= Ingame_WinnerDeclared; // <- important! Finish(sender); }
private void Finish(IngamePhase ingame) { // (kind of redundant but, whatever... keeps things consistent) var trans = new TransitionPhase(GamePhase.ending, ingame); Volatile.Write(ref _phase, trans); // -- announce that the game is / has ended (in a separate thread?) var finished = new FinishedPhase(ingame.Winner, ingame.Slots); Volatile.Write(ref _phase, finished); }
public static Error GetIngame(this ILudoService service, string gameId, out IngamePhase ingame) { ingame = null; var g = service.Games.TryGet(Id.Partial(gameId)); if (g == null) { return(Error.Codes.E01GameNotFound); } ingame = g.Phase.Ingame; return(ingame == null ? Error.Codes.E07NotInGamePhase : Error.Codes.E00NoError); }