<commit_before>﻿namespace Santase.Logic.GameMechanics
{
    using Santase.Logic.Logger;
    using Santase.Logic.Players;
    using Santase.Logic.WinnerLogic;

    public class SantaseGame : ISantaseGame
    {
        private readonly IGameRules gameRules;

        private readonly IPlayer firstPlayer;

        private readonly IPlayer secondPlayer;

        private readonly ILogger logger;

        private PlayerPosition firstToPlay = PlayerPosition.NoOne;

        public SantaseGame(IPlayer firstPlayer, IPlayer secondPlayer)
            : this(firstPlayer, secondPlayer, GameRulesProvider.Santase, new NoLogger())
        {
        }

        public SantaseGame(IPlayer firstPlayer, IPlayer secondPlayer, IGameRules gameRules, ILogger logger)
        {
            this.RestartGame();
            this.firstPlayer = firstPlayer;
            this.secondPlayer = secondPlayer;
            this.gameRules = gameRules;
            this.logger = logger;
        }

        public int FirstPlayerTotalPoints { get; private set; }

        public int SecondPlayerTotalPoints { get; private set; }

        public int RoundsPlayed { get; private set; }

        public PlayerPosition Start(PlayerPosition firstToPlay = PlayerPosition.FirstPlayer)
        {
            this.firstToPlay = firstToPlay;
            this.RestartGame();

            // Inform players
            this.firstPlayer.StartGame(this.secondPlayer.Name);
            this.secondPlayer.StartGame(this.firstPlayer.Name);

            while (this.GameWinner() == PlayerPosition.NoOne)
            {
                this.PlayRound();
                this.RoundsPlayed++;
            }

            var gameWinner = this.GameWinner();

            this.firstPlayer.EndGame(gameWinner == PlayerPosition.FirstPlayer);
            this.secondPlayer.EndGame(gameWinner == PlayerPosition.SecondPlayer);

            return gameWinner;
        }

        private void RestartGame()
        {
            this.FirstPlayerTotalPoints = 0;
            this.SecondPlayerTotalPoints = 0;
            this.RoundsPlayed = 0;
        }

        private void PlayRound()
        {
            var round = this.firstToPlay == PlayerPosition.FirstPlayer
                            ? new Round(this.firstPlayer, this.secondPlayer, this.gameRules)
                            : new Round(this.secondPlayer, this.firstPlayer, this.gameRules);

            var roundResult = round.Play();

            this.logger.LogLine(
                this.firstToPlay == PlayerPosition.FirstPlayer
                    ? $"{roundResult.FirstPlayer.RoundPoints} - {roundResult.SecondPlayer.RoundPoints}"
                    : $"{roundResult.SecondPlayer.RoundPoints} - {roundResult.FirstPlayer.RoundPoints}");

            this.UpdatePoints(roundResult);
        }

        private void UpdatePoints(RoundResult roundResult)
        {
            IRoundWinnerPointsLogic roundWinnerPointsPointsLogic = new RoundWinnerPointsPointsLogic();
            var roundWinnerPoints = roundWinnerPointsPointsLogic.GetWinnerPoints(
                roundResult.FirstPlayer.RoundPoints,
                roundResult.SecondPlayer.RoundPoints,
                roundResult.GameClosedBy,
                roundResult.NoTricksPlayer,
                this.gameRules);

            if (roundWinnerPoints.Winner == PlayerPosition.NoOne)
            {
                return;
            }

            // TODO: Test this complex logic somehow or refactor? Pass first to play to round?
            if (this.firstToPlay == PlayerPosition.FirstPlayer)
            {
                if (roundWinnerPoints.Winner == PlayerPosition.FirstPlayer)
                {
                    this.FirstPlayerTotalPoints += roundWinnerPoints.Points;
                    this.firstToPlay = PlayerPosition.SecondPlayer;
                }
                else
                {
                    this.SecondPlayerTotalPoints += roundWinnerPoints.Points;
                    this.firstToPlay = PlayerPosition.FirstPlayer;
                }
            }
            else
            {
                if (roundWinnerPoints.Winner == PlayerPosition.FirstPlayer)
                {
                    // It is actually our second player
                    this.SecondPlayerTotalPoints += roundWinnerPoints.Points;
                    this.firstToPlay = PlayerPosition.FirstPlayer;
                }
                else
                {
                    this.FirstPlayerTotalPoints += roundWinnerPoints.Points;
                    this.firstToPlay = PlayerPosition.SecondPlayer;
                }
            }
        }
<commit_msg>Game class complex logic in deciding winner is replaced with passing information who to play first in the Round class<commit_after>﻿namespace Santase.Logic.GameMechanics
{
    using Santase.Logic.Logger;
    using Santase.Logic.Players;
    using Santase.Logic.WinnerLogic;

    public class SantaseGame : ISantaseGame
    {
        private readonly IGameRules gameRules;

        private readonly IPlayer firstPlayer;

        private readonly IPlayer secondPlayer;

        private readonly ILogger logger;

        private PlayerPosition firstToPlay = PlayerPosition.NoOne;

        public SantaseGame(IPlayer firstPlayer, IPlayer secondPlayer)
            : this(firstPlayer, secondPlayer, GameRulesProvider.Santase, new NoLogger())
        {
        }

        public SantaseGame(IPlayer firstPlayer, IPlayer secondPlayer, IGameRules gameRules, ILogger logger)
        {
            this.RestartGame();
            this.firstPlayer = firstPlayer;
            this.secondPlayer = secondPlayer;
            this.gameRules = gameRules;
            this.logger = logger;
        }

        public int FirstPlayerTotalPoints { get; private set; }

        public int SecondPlayerTotalPoints { get; private set; }

        public int RoundsPlayed { get; private set; }

        public PlayerPosition Start(PlayerPosition firstToPlay = PlayerPosition.FirstPlayer)
        {
            this.firstToPlay = firstToPlay;
            this.RestartGame();

            // Inform players
            this.firstPlayer.StartGame(this.secondPlayer.Name);
            this.secondPlayer.StartGame(this.firstPlayer.Name);

            // Play rounds until game winner is determined
            while (this.GameWinner() == PlayerPosition.NoOne)
            {
                this.PlayRound();
                this.RoundsPlayed++;
            }

            var gameWinner = this.GameWinner();

            // Inform players
            this.firstPlayer.EndGame(gameWinner == PlayerPosition.FirstPlayer);
            this.secondPlayer.EndGame(gameWinner == PlayerPosition.SecondPlayer);

            return gameWinner;
        }

        private void RestartGame()
        {
            this.FirstPlayerTotalPoints = 0;
            this.SecondPlayerTotalPoints = 0;
            this.RoundsPlayed = 0;
        }

        private void PlayRound()
        {
            var round = new Round(this.firstPlayer, this.secondPlayer, this.gameRules, this.firstToPlay);
            var roundResult = round.Play();
            this.UpdatePoints(roundResult);

            this.logger.LogLine($"{roundResult.FirstPlayer.RoundPoints} - {roundResult.SecondPlayer.RoundPoints}");
        }

        private void UpdatePoints(RoundResult roundResult)
        {
            IRoundWinnerPointsLogic roundWinnerPointsPointsLogic = new RoundWinnerPointsPointsLogic();
            var roundWinnerPoints = roundWinnerPointsPointsLogic.GetWinnerPoints(
                roundResult.FirstPlayer.RoundPoints,
                roundResult.SecondPlayer.RoundPoints,
                roundResult.GameClosedBy,
                roundResult.NoTricksPlayer,
                this.gameRules);

            switch (roundWinnerPoints.Winner)
            {
                case PlayerPosition.FirstPlayer:
                    this.FirstPlayerTotalPoints += roundWinnerPoints.Points;
                    this.firstToPlay = PlayerPosition.SecondPlayer;
                    break;
                case PlayerPosition.SecondPlayer:
                    this.SecondPlayerTotalPoints += roundWinnerPoints.Points;
                    this.firstToPlay = PlayerPosition.FirstPlayer;
                    break;
            }
        }

{'fraction_non_alphanumeric': 0.07064496684749849, 'fraction_numerical': 0.0007233273056057866, 'mean_word_length': 1.8479231033299004, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '668973', 'n_tokens_mistral': 2057, 'n_tokens_neox': 1958, 'n_words': 396}