protected override void OnGameEnded(GameEndInformation endInformation) { base.OnGameEnded(endInformation); GameSettings.Statistics.GameHasBeenCompleted(Game, endInformation); QuestsManager.GameCompleted(Game, endInformation); }
protected override async void OnGameEnded(GameEndInformation endInformation) { _gameEndInformation = endInformation; await DialogService.ShowAsync(GameEndTranslator.TranslateDetails(endInformation, Localizer), GameEndTranslator.TranslateCaption(endInformation, Localizer)); }
/// <summary> /// In local game we are in control of time, clock out the player /// </summary> /// <param name="player">Player the clocked out</param> protected override bool HandleLocalClockOut(GamePlayer player) { var endGameInformation = GameEndInformation.CreateTimeout(player, Controller.Players); Controller.EndGame(endGameInformation); return(true); }
public override async Task <bool> CanCloseViewModelAsync() { if (this.GetType() == typeof(LocalGameViewModel) && this.Game.Controller.Phase.Type != GamePhaseType.Finished) { if (await DialogService.ShowConfirmationDialogAsync(Localizer.ExitLocal_Text, Localizer.ExitLocal_Caption, Localizer.ExitLocal_Confirm, Localizer.Exit_ReturnToGame)) { UiConnector.AiLog -= Assistant_uiConnector_AiLog; await base.CanCloseViewModelAsync(); Game.Controller.EndGame(GameEndInformation.CreateCancellation(Game.Controller.Players)); return(true); } else { return(false); } } else { UiConnector.AiLog -= Assistant_uiConnector_AiLog; await base.CanCloseViewModelAsync(); return(true); } }
public static string TranslateCaption(GameEndInformation end, Localizer localizer) { switch (end.Reason) { case GameEndReason.Cancellation: return(localizer.TieByCancellation); case GameEndReason.Disconnection: return(localizer.TieByDisconnection); case GameEndReason.Resignation: return(String.Format(localizer.WinByResign, end.Winner.Info.Name)); case GameEndReason.ScoringComplete: if (end.HasWinnerAndLoser) { return(String.Format(localizer.WinsByPoints, end.Winner.Info.Name, end.Scores.AbsoluteScoreDifference)); } else { return(localizer.TheGameIsADraw); } case GameEndReason.Timeout: return(string.Format(localizer.WinByTimeout, end.Winner.Info.Name)); } return("?"); }
/// <summary> /// Starts the initialization phase /// </summary> public override void StartPhase() { Controller.OnDebuggingMessage("Game begins!"); bool thisIsAGoodFuegoGame = false; foreach (var player in Controller.Players) { if (player.Agent is AiAgent && (player.Agent as AiAgent).AI is Fuego) { if (FuegoSingleton.Instance.CurrentGame != null && !thisIsAGoodFuegoGame) { // Fuego can't be in two games at once. Controller.EndGame(GameEndInformation.CreateCancellation(Controller.Players)); return; } if (!thisIsAGoodFuegoGame) { FuegoSingleton.Instance.CurrentGame = Controller; thisIsAGoodFuegoGame = true; } } player.Agent.GameInitialized(); } GoToPhase(GamePhaseType.HandicapPlacement); }
private void ScoreGame(IgsGame gameInfo, float blackScore, float whiteScore) { Scores scores = new Scores(blackScore, whiteScore); GamePlayer winner = null; if (scores.BlackScore > scores.WhiteScore) { winner = gameInfo.Controller.Players.Black; } else if (scores.BlackScore < scores.WhiteScore) { winner = gameInfo.Controller.Players.White; } else { winner = null; } if (winner != null) { GetConnector(gameInfo.Info).EndTheGame( GameEndInformation.CreateScoredGame(winner, gameInfo.Controller.Players.GetOpponentOf(winner), scores)); } else { GetConnector(gameInfo.Info).EndTheGame( GameEndInformation.CreateDraw(gameInfo.Controller.Players, scores)); } }
public override async Task <bool> CanCloseViewModelAsync() { await(Game.Controller as RemoteGameController).Server.Commands.UnobserveAsync(Game.Info as RemoteGameInfo); await base.CanCloseViewModelAsync(); Game.Controller.EndGame(GameEndInformation.CreateCancellation(Game.Controller.Players)); return(true); }
public static string TranslateDetails(GameEndInformation end, Localizer localizer) { string victoryGoesTo = ""; if (end.HasWinnerAndLoser) { if (end.Winner.IsHuman ^ end.Loser.IsHuman) { // ^ means "xor". // If we play one of the players but not the other one, i.e. it is a solo game. if (end.Winner.IsHuman) { victoryGoesTo = localizer.YouHaveWon; } else if (end.Loser.IsHuman) { victoryGoesTo = localizer.YouHaveLost; } } else { if (end.Winner.Info.Color == Core.Game.StoneColor.Black) { victoryGoesTo = localizer.BlackWon; } else { victoryGoesTo = localizer.WhiteWon; } } } else { victoryGoesTo = localizer.TheGameIsADraw; } switch (end.Reason) { case GameEndReason.Cancellation: return(localizer.CancellationExplanation); case GameEndReason.Disconnection: return(localizer.DisconnectionExplanation); case GameEndReason.Resignation: return(victoryGoesTo); case GameEndReason.ScoringComplete: return(victoryGoesTo); case GameEndReason.Timeout: return(victoryGoesTo); } return("?"); }
private void ResignObservedGame(int gameInWhichSomebodyResigned, StoneColor whoResigned) { var game = GamesYouHaveOpened.FirstOrDefault(gm => gm.Info.IgsIndex == gameInWhichSomebodyResigned); if (game != null) { game.Controller.EndGame(GameEndInformation.CreateResignation(game.Controller.Players[whoResigned], game.Controller.Players)); DestroyGame(game.Info); } }
/// <summary> /// Handles completion of a game /// </summary> /// <param name="game">Game that completed</param> /// <param name="end">Information about the game's end</param> public void GameCompleted(IGame game, GameEndInformation end) { bool isOnlineGame = game is IRemoteGame; bool isHotseatGame = game.Controller.Players.All(pl => pl.Agent.Type == AgentType.Human); GamePlayer human = game.Controller.Players.FirstOrDefault(pl => pl.Agent.Type == AgentType.Human); bool isPlayedByUs = human != null; bool isVictory = (end.HasWinnerAndLoser && end.Winner == human); var gcqi = new GameCompletedQuestInformation(isOnlineGame, isHotseatGame, isPlayedByUs, isVictory, human, game, end); // Add points per game if (isPlayedByUs) { int points = 0; if (isVictory) { if (isOnlineGame) { points = RewardPoints.OnlineWin; } else if (!isHotseatGame) { points = RewardPoints.LocalWin; } } else { if (isOnlineGame) { points = RewardPoints.OnlineLoss; } else if (!isHotseatGame) { points = RewardPoints.LocalLoss; } } AddPoints(points); } foreach (var quest in _gameSettings.Quests.ActiveQuests.ToList()) { if (quest.Quest.GameCompleted(gcqi)) { ProgressQuest(quest, 1); } } }
/// <summary> /// Cancels all ongoing games and informs the UI that we're disconnected. Sets the <see cref="LoggedIn"/> flag. /// This does not send any information to the server and should only be called in response to a connection issue /// or when the server logs us out. /// </summary> /// <param name="reason">The reason.</param> internal void LogoutAndDisconnect(string reason) { bool disconnectionIsNotRedundant = this.LoggedIn || this.LoggingIn; this.LoggedIn = false; if (disconnectionIsNotRedundant) { this.Events.RaiseDisconnection(reason); } foreach (var game in this.Data.Games.ToList()) { GamePlayer whoDisconnected = game.Controller.Players.FirstOrDefault(pl => pl.Info.Name == this.Username); game.Controller.EndGame(GameEndInformation.CreateDisconnection(whoDisconnected, game.Controller.Players)); } this.Data.UnjoinEverything(); }
/// <summary> /// Ends the game /// </summary> /// <param name="endInformation">Game end info</param> public void EndGame(GameEndInformation endInformation) { foreach (var pl in Players) { pl.Clock.StopClock(); } UnsubscribePlayerEvents(); if (Phase != null && Phase.Type == GamePhaseType.Finished) { // Game has already ended. return; } OnDebuggingMessage("Game ended: " + endInformation); OnGameEnded(endInformation); SetPhase(GamePhaseType.Finished); }
/// <summary> /// Scores the game and moves us to the Finished phase. /// </summary> /// <param name="e">If this parameter is set, then it overriddes scores that would be determined from life/death determination and ruleset.</param> internal void ScoreIt(Scores e = null) { Scores scores = e; if (scores == null) { scores = Controller.Ruleset.CountScore(Controller.GameTree.LastNode, DeadPositions, Controller.Info.Komi); } bool isDraw = Math.Abs(scores.BlackScore - scores.WhiteScore) < 0.2f; GamePlayer winner; GamePlayer loser; if (isDraw) { winner = Controller.Players.Black; loser = Controller.Players.White; Controller.OnDebuggingMessage("It's a draw."); } else if (scores.BlackScore > scores.WhiteScore) { winner = Controller.Players.Black; loser = Controller.Players.White; } else if (scores.BlackScore < scores.WhiteScore) { winner = Controller.Players.White; loser = Controller.Players.Black; } else { throw new Exception("This cannot happen."); } if (!isDraw) { Controller.OnDebuggingMessage(winner + " wins."); } Controller.OnDebuggingMessage("Scoring complete! " + scores.AbsoluteScoreDifference); GameEndInformation gameEndInfo = null; gameEndInfo = isDraw ? GameEndInformation.CreateDraw(Controller.Players, scores) : GameEndInformation.CreateScoredGame(winner, loser, scores); Controller.EndGame(gameEndInfo); }
private void _controller_GameEnded(object sender, GameEndInformation e) { this.panelEnd.Visible = true; this.lblEndCaption.Text = e.ToString(); this.lblGameEndReason.Text = (e.Winner) + " wins against " + e.Loser; if (e.Reason == GameEndReason.ScoringComplete) { var scores = e.Scores; MessageBox.Show($"Black score: {scores.BlackScore}\nWhite score: {scores.WhiteScore}\n\n" + (scores.BlackScore > scores.WhiteScore ? "Black wins!" : (Math.Abs(scores.BlackScore - scores.WhiteScore) < 0.1f ? "It's a draw!" : "White wins!")), "Game completed!", MessageBoxButtons.OK, MessageBoxIcon.Information); } }
/// <summary> /// Applies the completed game statistics /// </summary> /// <param name="game">Game</param> /// <param name="gameEndInformation">Information about end of game</param> public void GameHasBeenCompleted(IGame game, GameEndInformation gameEndInformation) { bool isOnlineGame = game is IRemoteGame; bool isHotseatGame = game.Controller.Players.All(pl => pl.Agent.Type == AgentType.Human); GamePlayer human = game.Controller.Players.FirstOrDefault(pl => pl.Agent.Type == AgentType.Human); bool isPlayedByUs = human != null; if (!isPlayedByUs) { return; // We keep no statistics of games between AI's or that are merely observed. } if (isHotseatGame) { HotseatGamesPlayed++; return; // Hotseat games don't count for any other statistics } // Played if (isOnlineGame) { OnlineGamesPlayed++; } else { LocalGamesPlayed++; } // Won if (gameEndInformation.HasWinnerAndLoser && gameEndInformation.Winner == human) { if (isOnlineGame) { OnlineGamesWon++; } else { LocalGamesWon++; } } }
//////////////// // State Changes //////////////// protected virtual void OnGameEnded(GameEndInformation endInformation) { }
public void EndTheGame(GameEndInformation gameEndInfo) { GameEndedByServer?.Invoke(this, gameEndInfo); }
/// <summary> /// Fires the game ended event /// </summary> /// <param name="endInformation"></param> private void OnGameEnded(GameEndInformation endInformation) { GameEnded?.Invoke(this, endInformation); }
private void KgsConnector_GameEndedByServer(object sender, GameEndInformation e) { EndGame(e); }
public override void Process(KgsConnection connection) { var game = connection.Data.GetGame(ChannelId); var controller = game.Controller; var players = game.Controller.Players; var black = game.Controller.Players.Black; var white = game.Controller.Players.White; GameEndInformation gameEndInfo = null; if (Score.IsFloat) { if (Score.Float == 0) { gameEndInfo = GameEndInformation.CreateDraw(controller.Players, new Rules.Scores(0, 0)); } else { if (Score.Float > 0) { gameEndInfo = GameEndInformation.CreateScoredGame(controller.Players.Black, controller.Players.White, new Rules.Scores(Score.Float, 0)); } else { gameEndInfo = GameEndInformation.CreateScoredGame(controller.Players.White, controller.Players.Black, new Rules.Scores(0, -Score.Float)); } } } else { switch (Score.String) { case "B+RESIGN": case "B+FORFEIT": gameEndInfo = GameEndInformation.CreateResignation(white, players); break; case "W+RESIGN": case "W+FORFEIT": gameEndInfo = GameEndInformation.CreateResignation(black, players); break; case "B+TIME": gameEndInfo = GameEndInformation.CreateTimeout(white, players); break; case "W+TIME": gameEndInfo = GameEndInformation.CreateTimeout(black, players); break; case "NO_RESULT": gameEndInfo = GameEndInformation.CreateDraw(players, new Rules.Scores(0, 0)); break; case "UNKNOWN": case "UNFINISHED": default: gameEndInfo = GameEndInformation.CreateCancellation(players); break; } } controller.KgsConnector.EndTheGame(gameEndInfo); }
public void EndTheGame(GameEndInformation gameEndInfo) { GameEndedByServer?.Invoke(this, gameEndInfo); _connnection.DestroyGame(_gameController.Info); }
private async Task HandleIncomingData(StreamReader sr) { bool thisIsNotAMove = false; bool weAreHandlingAnInterrupt = false; bool interruptIsImpossible = false; List <IgsLine> currentLineBatch = new List <IgsLine>(); while (true) { string line; try { line = await sr.ReadLineAsync(); } catch (Exception) { line = null; } if (line == null) { ConnectionLost(); return; } line = line.Trim(); IgsCode code = ExtractCodeFromLine(line); IgsLine igsLine = new IgsLine(code, line); Events.OnIncomingLine((weAreHandlingAnInterrupt ? "(INTERRUPT) " : "") + (interruptIsImpossible ? "(INTERRUPT IMPOSSIBLE) " : "") + line); // IGS occasionally sends blank lines, I don't know why. They serve no reason. if (line == "") { continue; } switch (this.Composure) { case IgsComposure.Confused: case IgsComposure.Ok: case IgsComposure.Disconnected: // No special mode. break; case IgsComposure.InitialHandshake: if (igsLine.EntireLine.Trim() == "1 5") { this.Composure = IgsComposure.Ok; continue; } else { // Ignore. continue; } case IgsComposure.LoggingIn: if (igsLine.EntireLine.Contains("Invalid password.")) { this.Composure = IgsComposure.Confused; this._loginError = "The password is incorrect."; continue; } if (igsLine.EntireLine.Contains("Sorry, names can be")) { this.Composure = IgsComposure.Confused; this._loginError = "Your name is too long."; continue; } if (igsLine.EntireLine.Contains("This is a guest account.")) { this.Composure = IgsComposure.Confused; this._loginError = "The username does not exist."; continue; } if (igsLine.EntireLine.Contains("1 5")) { this.Composure = IgsComposure.Ok; continue; } break; } if (igsLine.Code == IgsCode.Error) { Events.OnErrorMessageReceived(igsLine.PureLine); } currentLineBatch.Add(igsLine); if (weAreHandlingAnInterrupt && code == IgsCode.Prompt) { // Interrupt message is over, let's wait for a new message weAreHandlingAnInterrupt = false; HandleFullInterrupt(currentLineBatch); thisIsNotAMove = false; interruptIsImpossible = false; currentLineBatch = new List <IgsLine>(); continue; } if (code == IgsCode.Prompt) { thisIsNotAMove = false; currentLineBatch = new List <IgsLine>(); interruptIsImpossible = false; if (this._ignoreNextPrompt) { this._ignoreNextPrompt = false; continue; } } if (code == IgsCode.Kibitz) { weAreHandlingAnInterrupt = true; continue; } if (code == IgsCode.Beep) { Events.OnBeep(); continue; } if (!interruptIsImpossible) { if (code == IgsCode.Tell) { if (igsLine.PureLine.StartsWith("*SYSTEM*")) { weAreHandlingAnInterrupt = true; continue; } HandleIncomingChatMessage(line); weAreHandlingAnInterrupt = true; continue; } if (code == IgsCode.SayInformation) { weAreHandlingAnInterrupt = true; continue; } if (code == IgsCode.Status) { weAreHandlingAnInterrupt = true; continue; } if (code == IgsCode.Shout) { HandleIncomingShoutMessage(line); weAreHandlingAnInterrupt = true; continue; } if (code == IgsCode.StoneRemoval) { Tuple <int, Position> removedStone = IgsRegex.ParseStoneRemoval(igsLine); OnIncomingStoneRemoval(removedStone.Item1, removedStone.Item2); continue; } if (code == IgsCode.Move) { var heading = IgsRegex.ParseGameHeading(igsLine); if (heading != null) { this.Data.LastReceivedGameHeading = heading; } if (!thisIsNotAMove) { HandleIncomingMove(igsLine); weAreHandlingAnInterrupt = true; } continue; } if (code == IgsCode.Undo) { thisIsNotAMove = true; weAreHandlingAnInterrupt = true; continue; } } if (code == IgsCode.Info) { // 9 Adding game to observation list. if (igsLine.EntireLine.Contains("9 Adding game to observation list.")) { interruptIsImpossible = true; } if (!interruptIsImpossible) { if (igsLine.PureLine == "yes") { // This is "ayt" response, ignore it. weAreHandlingAnInterrupt = true; continue; } if (igsLine.EntireLine == "9 You can check your score with the score command, type 'done' when finished.") { weAreHandlingAnInterrupt = true; continue; } if (igsLine.PureLine.Contains("accepted.")) { weAreHandlingAnInterrupt = true; continue; } if (igsLine.PureLine.Contains("Removing @")) { weAreHandlingAnInterrupt = true; continue; } if (igsLine.PureLine.Contains("has run out of time")) { weAreHandlingAnInterrupt = true; string whoRanOutOfTime = IgsRegex.WhoRanOutOfTime(igsLine); foreach (var game in GetGamesIncluding(whoRanOutOfTime).ToList()) { game.Controller.IgsConnector.EndTheGame( GameEndInformation.CreateTimeout( game.Controller.Players.First(pl => pl.Info.Name == whoRanOutOfTime), game.Controller.Players) ); } continue; } if (igsLine.PureLine.Contains("White resigns.}")) { int gameInWhichSomebodyResigned = IgsRegex.WhatObservedGameWasResigned(igsLine); ResignObservedGame(gameInWhichSomebodyResigned, StoneColor.White); weAreHandlingAnInterrupt = true; continue; } if (igsLine.PureLine.Contains("Black resigns.}")) { int gameInWhichSomebodyResigned = IgsRegex.WhatObservedGameWasResigned(igsLine); ResignObservedGame(gameInWhichSomebodyResigned, StoneColor.Black); weAreHandlingAnInterrupt = true; continue; } if (igsLine.PureLine.Contains("has resigned the game")) { string whoResigned = IgsRegex.WhoResignedTheGame(igsLine); if (whoResigned != this._username) { // .ToList() is used because the collection may be modified foreach (var game in GetGamesIncluding(whoResigned).ToList()) { HandleIncomingResignation(game.Info, whoResigned); } } weAreHandlingAnInterrupt = true; continue; } if (igsLine.PureLine.Contains("has typed done.")) { string username = IgsRegex.GetFirstWord(igsLine); weAreHandlingAnInterrupt = true; foreach (var game in GetGamesIncluding(username)) { var player = game.Controller.Players.First(pl => pl.Info.Name == username); game.Controller.IgsConnector.RaiseServerSaidDone(player); } continue; } if (igsLine.PureLine.Contains("Board is restored to what it was when you started scoring")) { foreach ( var game in this.GamesYouHaveOpened.Where( gi => gi.Controller.Phase.Type == GamePhaseType.LifeDeathDetermination)) { GetConnector(game.Info).ForceLifeDeathUndoDeathMarks(); } weAreHandlingAnInterrupt = true; continue; } if (igsLine.PureLine.Contains("Removed game file")) { weAreHandlingAnInterrupt = true; continue; } if (igsLine.PureLine.Contains("game completed.")) { weAreHandlingAnInterrupt = true; continue; } if (igsLine.PureLine.StartsWith("!!*Pandanet*!!:")) { // Advertisement weAreHandlingAnInterrupt = true; continue; } if (IgsRegex.IsIrrelevantInterruptLine(igsLine)) { weAreHandlingAnInterrupt = true; continue; } if (igsLine.PureLine.StartsWith("Increase ")) { weAreHandlingAnInterrupt = true; string person = IgsRegex.ParseIncreaseXTimeByYMinute(igsLine); foreach (var game in this.GamesYouHaveOpened) { if (game.Info.Black.Name == person || game.Info.White.Name == person) { MakeUnattendedRequest("refresh " + game.Info.IgsIndex); } } } if (igsLine.PureLine.EndsWith("declines undo.")) { string username = IgsRegex.WhoDeclinesUndo(igsLine); foreach (var game in GetGamesIncluding(username)) { Events.OnUndoDeclined(game.Info); } weAreHandlingAnInterrupt = true; continue; } if (igsLine.PureLine.EndsWith("declines your request for a match.")) { Events.OnMatchRequestDeclined(igsLine.PureLine.Substring(0, igsLine.PureLine.IndexOf(' '))); weAreHandlingAnInterrupt = true; continue; } IgsMatchRequest matchRequest = IgsRegex.ParseMatchRequest(igsLine); if (matchRequest != null) { this._incomingMatchRequests.Add(matchRequest); Events.OnIncomingMatchRequest(matchRequest); weAreHandlingAnInterrupt = true; continue; } } } if (!weAreHandlingAnInterrupt) { // We cannot handle this generally - let's hand it off to whoever made the request for this information. lock (this._mutex) { if (this._requestInProgress != null) { this._requestInProgress.IncomingLines.Post(igsLine); } else { if (this.Composure == IgsComposure.Ok) { Events.OnUnhandledLine(igsLine.EntireLine); } } } } } }
private void IgsConnector_Disconnected(object sender, System.EventArgs e) { var us = Players.FirstOrDefault(pl => pl.IsLocal); this.EndGame(GameEndInformation.CreateDisconnection(us, Players)); }
/// <summary> /// Handles player resignation /// </summary> /// <param name="agent">Agent that resigned</param> private void Agent_Resigned(IAgent agent) { //end game with resignation EndGame(GameEndInformation.CreateResignation(this.Players[agent.Color], this.Players)); LocalResignationHappened(this.Players[agent.Color]); }
public GameCompletedQuestInformation(bool isOnline, bool isHotseat, bool isPlayedByUs, bool isVictory, GamePlayer human, IGame game, GameEndInformation end) { this.IsOnline = isOnline; this.IsHotseat = isHotseat; this.IsPlayedByUs = isPlayedByUs; this.IsVictory = isVictory; this.Human = human; this.Game = game; this.End = end; }