public void MakeTurn( long targetPosition, TicketType ticket, bool useDoubleTicket = false) { if (MatchState != MatchState.Running) { throw new DomainException("Invalid state"); } CurrentPlayer.MakeTurn( targetPosition, ticket, useDoubleTicket); if (CurrentPlayer.Role == PlayerRole.Detective) { Villian.Tickets.AddTicket(ticket); if (CurrentPlayer.Position() == Villian.Position()) { MatchState = MatchState.DetectivesWon; AddGameEvent(new MatchOverGameEvent(this)); } } else { // it should not be possible to move onto a detective Debug.Assert(!Detectives.Any(p => p.Position() == CurrentPlayer.Position())); ++Round; AddGameEvent(new MatchRoundGameEvent()); if (IsVillianRevealRound) { lastStationVillianReveal = Villian.Position().Position; AddGameEvent(new MatchVillianRevealedGameEvent()); } if (Round >= Settings.Rounds) { MatchState = MatchState.VillianWon; AddGameEvent(new MatchOverGameEvent(this)); } } if (!useDoubleTicket) { Player player = Players .OrderBy(p => p.Order) .FirstOrDefault(p => CurrentPlayer.Order < p.Order); if (player == null) { player = FirstPlayer; } CurrentPlayer = player; CurrentPlayerId = CurrentPlayer.Id; } // ensure next player has any valid moves if (CurrentPlayer.ValidRoutes().Count == 0) { MatchState = CurrentPlayer.Role == PlayerRole.Detective ? MatchState.VillianWon : MatchState.DetectivesWon; AddGameEvent(new MatchOverGameEvent(this)); } AddGameEvent(new MatchTurnGameEvent(this)); }