public Game(Player playerA, Player playerB, String pathToInitialMaze)
 {
     _playerPool = new PlayerPool(playerA, playerB);
     _maze = new Maze(pathToInitialMaze);
     _gameMarshaller = new GameMarshaller();
     _iteration = 1;
     _secondMazePlayer = 'A';
 }
        static void Main(string[] args)
        {
            var playerAPath = args[0];
            var playerABot = args[1];
            var playerBPath = args[2];
            var playerBBot = args[3];

            var playerA = new Player("botB", playerBPath, playerBBot, 'B');
            var playerB = new Player("botA", playerAPath, playerABot, 'A');
            var game = new Game(playerA, playerB, Properties.Settings.Default.SettingInitialMazeFilePath);
            game.Run("Match-" + DateTime.UtcNow.ToString("yyyy-MM-dd hh-mm-ss"));
        }
        public void Run(String folderPath)
        {
            var gamePlayDirectoryPath = Properties.Settings.Default.SettingPrimaryDriveName + "\\" + folderPath;
            Directory.CreateDirectory(gamePlayDirectoryPath);
            var outputFilePath = gamePlayDirectoryPath + "\\" + Properties.Settings.Default.SettingGamePlayFile;
            _maze.WriteMaze(outputFilePath);
            Player winner = null;
            var gameOutcome = Enums.GameOutcome.ProceedToNextRound;
            Directory.CreateDirectory(folderPath);
            Directory.CreateDirectory(folderPath + "\\" + Properties.Settings.Default.SettingReplayFolder);
            var logFile = new StreamWriter(folderPath + "\\" + Properties.Settings.Default.SettingMatchLogFileName);
            logFile.WriteLine("[GAME] : Match started");
            while (gameOutcome.Equals(Enums.GameOutcome.ProceedToNextRound))
            {
                _currentPlayer = _playerPool.GetNextPlayer();
                var mazeFromPlayer = _currentPlayer.GetMove(_maze, gamePlayDirectoryPath + "\\" + Properties.Settings.Default.SettingGamePlayFile, logFile);
                if (mazeFromPlayer != null)
                {
                    var mazeValidationOutcome = GetMazeValidationOutcome(logFile, mazeFromPlayer);
                    if (mazeValidationOutcome.Equals(Enums.MazeValidationOutcome.ValidMaze))
                    {
                        var opponentPosition = _maze.FindCoordinateOf(Properties.Settings.Default.SymbolPlayerB);
                        var previousPosition = _maze.FindCoordinateOf(Properties.Settings.Default.SymbolPlayerA);
                        var currentPosition = mazeFromPlayer.FindCoordinateOf(Properties.Settings.Default.SymbolPlayerA);
                        var turnOutcome = GetTurnOutcome(mazeFromPlayer, currentPosition, previousPosition, opponentPosition, logFile);
                        if (!turnOutcome.Equals(Enums.TurnOutcome.MoveMadeAndDroppedPoisonPillIllegally))
                        {
                            gameOutcome = GetGameOutcome(logFile, gameOutcome, turnOutcome);
                            winner = DeterminIfWinnerWinner(gameOutcome, mazeFromPlayer, winner);
                        }
                        else gameOutcome = ProcessIllegalMove(logFile, gameOutcome, ref winner);
                    }
                    else gameOutcome = ProcessIllegalMove(logFile, gameOutcome, ref winner);

                    _maze.WriteMaze(gamePlayDirectoryPath + "\\" + Properties.Settings.Default.SettingGamePlayFile);
                    CreateIterationStateFile(folderPath);
                    _iteration++;
                    _maze.Print();
                }
                else gameOutcome = ProcessIllegalMove(logFile, gameOutcome, ref winner);
            }

            CreateMatchInfo(gameOutcome, winner, logFile);
            logFile.Close();
            var replayMatchOutcome = new StreamWriter(folderPath + "\\replay\\matchinfo.out");
            CreateMatchInfo(gameOutcome, winner, replayMatchOutcome);
            replayMatchOutcome.Close();
        }
        public static Enums.TurnOutcome ProcessMove(Maze currentMaze, Maze previousMaze, Point currentPosition, Point previousPosition, Point opponentPosition, Player currentPlayer)
        {
            currentPlayer.SetCurrentPosition(currentPosition);

            if (IsMoveMadeAndScoredPoint(previousMaze, currentPosition))
            {
                currentPlayer.AddToScore(Properties.Settings.Default.SettingPointsPerPill);
                return Enums.TurnOutcome.MoveMadeAndPointScored;
            }

            if (IsMoveMadeAndScoredBonusPoint(previousMaze, currentPosition))
            {
                currentPlayer.AddToScore(Properties.Settings.Default.SettingPointsPerBonusPill);
                return Enums.TurnOutcome.MoveMadeAndBonusPointScored;
            }

            if (IsMoveMadeAndDiedFromPoisonPill(previousMaze, currentPosition))
            {
                currentMaze.SetSymbol(currentPosition.X, currentPosition.Y, Symbols.SYMBOL_EMPTY);
                currentMaze.SetSymbol(Properties.Settings.Default.MazeCenterX, Properties.Settings.Default.MazeCenterY, Symbols.SYMBOL_PLAYER_A);
                return Enums.TurnOutcome.MoveMadeAndDiedFromPoisonPill;
            }

            if (IsMoveMadeAndKilledOpponent(currentPosition, opponentPosition))
            {
                currentMaze.SetSymbol(Properties.Settings.Default.MazeCenterX, Properties.Settings.Default.MazeCenterY, Symbols.SYMBOL_PLAYER_B);
                return Enums.TurnOutcome.MoveMadeAndKilledOpponent;
            }

            if (IsMoveMadeAndDroppedPoisonPill(currentMaze, previousPosition))
            {
                if (!currentPlayer.IsAllowedPoisonPillDrop())
                    return Enums.TurnOutcome.MoveMadeAndDroppedPoisonPillIllegally;

                currentPlayer.UsePoisonPill();
                return Enums.TurnOutcome.MoveMadeAndDroppedPoisonPill;
            }

            return (int)Enums.TurnOutcome.MoveMade;
        }
        static int Main(string[] args)
        {
            args = args ?? new string[] { };

            if (args.Any(x => helpOptions.Contains(x)) || args.Length != 4)
            {
                PrintUsage();
                return 1;
            }

            ShowArguments(args);

            var playerAPath = args[0];
            var playerABot = args[1];
            var playerBPath = args[2];
            var playerBBot = args[3];

            if (!Directory.Exists(playerAPath))
            {
                Console.WriteLine("error: <adir> '{0}' does not exist or is not a directory", playerAPath);
                return 1;
            }

            if (!File.Exists(Path.Combine(playerAPath, playerABot)))
            {
                Console.WriteLine("error: <abot> '{0}' does not exist inside <adir> or is not a file", playerABot);
                return 1;
            }

            if (!Directory.Exists(playerBPath))
            {
                Console.WriteLine("error: <bdir> '{0}' does not exist or is not a directory", playerBPath);
                return 1;
            }

            if (!File.Exists(Path.Combine(playerBPath, playerBBot)))
            {
                Console.WriteLine("error: <bbot> '{0}' does not exist inside <bdir> or is not a file", playerBBot);
                return 1;
            }

            var games = new List<GameResult>();

            Player playerA;
            Player playerB;

            var random = new Random();
            var randomPlayer = random.Next(1, 3);
            if (randomPlayer == 1)
            {
                playerA = new Player("botA", playerBPath, playerBBot, 'A');
                playerB = new Player("botB", playerAPath, playerABot, 'B');
            }
            else
            {
                playerA = new Player("botA", playerAPath, playerABot, 'A');
                playerB = new Player("botB", playerBPath, playerBBot, 'B');
            }

            var game = new Game(playerA, playerB, Properties.Settings.Default.SettingInitialMazeFilePath);
            var result = game.Run("Match_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
            games.Add(result);

            GameSummary(games);
            return 0;
        }
        public GameResult Run(String folderPath)
        {
            var gamePlayDirectoryPath = Properties.Settings.Default.SettingPrimaryDriveName + "\\" + folderPath;
            Directory.CreateDirectory(gamePlayDirectoryPath);
            var outputFilePath = gamePlayDirectoryPath + "\\" + Properties.Settings.Default.SettingGamePlayFile;
            _maze.WriteMaze(outputFilePath);
            Player winner = null;
            var gameOutcome = Enums.GameOutcome.ProceedToNextRound;
            Directory.CreateDirectory(folderPath);
            Directory.CreateDirectory(folderPath + "\\" + Properties.Settings.Default.SettingReplayFolder);
            var logFile = new StreamWriter(folderPath + "\\" + Properties.Settings.Default.SettingMatchLogFileName);
            logFile.WriteLine("[GAME] : Match started");
            while (gameOutcome == Enums.GameOutcome.ProceedToNextRound)
            {
                _currentPlayer = _playerPool.GetNextPlayer();
                var mazeFromPlayer = _currentPlayer.GetMove(_maze, gamePlayDirectoryPath + "\\" + Properties.Settings.Default.SettingGamePlayFile, logFile);
                if (mazeFromPlayer != null)
                {
                    var mazeValidationOutcome = GetMazeValidationOutcome(logFile, mazeFromPlayer);
                    if (mazeValidationOutcome == Enums.MazeValidationOutcome.ValidMaze)
                    {
                        var opponentPosition = _maze.FindCoordinateOf(Symbols.SYMBOL_PLAYER_B);
                        var previousPosition = _maze.FindCoordinateOf(Symbols.SYMBOL_PLAYER_A);
                        var currentPosition = mazeFromPlayer.FindCoordinateOf(Symbols.SYMBOL_PLAYER_A);
                        var turnOutcome = GetTurnOutcome(mazeFromPlayer, currentPosition, previousPosition, opponentPosition, logFile);
                        if (turnOutcome != Enums.TurnOutcome.MoveMadeAndDroppedPoisonPillIllegally)
                        {
                            RegenerateOpponentIfDead(opponentPosition, mazeFromPlayer);
                            gameOutcome = GetGameOutcome(mazeFromPlayer, logFile, gameOutcome, turnOutcome);
                            winner = DeterminIfWinner(gameOutcome, mazeFromPlayer, winner);
                        }
                        else gameOutcome = ProcessIllegalMove(logFile, gameOutcome, ref winner);
                    }
                    else gameOutcome = ProcessIllegalMove(logFile, gameOutcome, ref winner);

                    _maze.WriteMaze(gamePlayDirectoryPath + "\\" + Properties.Settings.Default.SettingGamePlayFile);
                    CreateIterationStateFile(folderPath);
                    _iteration++;
                    foreach (var player in _playerPool.GetPlayers())
                    {
                        Console.Write(player.GetSymbol() + "," + player.GetPlayerName() + ": " + player.GetScore() + "  ");
                    }
                    Console.WriteLine();
                    _maze.Print();
                }
                else gameOutcome = ProcessIllegalMove(logFile, gameOutcome, ref winner);
            }

            CreateMatchInfo(gameOutcome, winner, logFile);
            logFile.Close();
            var replayMatchOutcome = new StreamWriter(folderPath + "\\replay\\matchinfo.out");
            CreateMatchInfo(gameOutcome, winner, replayMatchOutcome);
            replayMatchOutcome.Close();

            return new GameResult()
            {
                Players = _playerPool.GetPlayers(),
                Outcome = gameOutcome,
                Iterations = _iteration - 1,
                Folder = folderPath
            };
        }
 private Enums.GameOutcome ProcessIllegalMove(StreamWriter logFile, Enums.GameOutcome gameOutcome, ref Player winner)
 {
     logFile.WriteLine("[GAME] : Illegal move made by " + _currentPlayer.GetPlayerName());
     gameOutcome = Enums.GameOutcome.IllegalMazeState;
     winner = _playerPool.GetNextPlayer();
     return gameOutcome;
 }
 private Player DeterminIfWinner(Enums.GameOutcome gameOutcome, Maze mazeFromPlayer, Player winner)
 {
     mazeFromPlayer.SwapPlayerSymbols();
     _maze = mazeFromPlayer;
     if (gameOutcome != Enums.GameOutcome.ProceedToNextRound)
     {
         if (gameOutcome == Enums.GameOutcome.NoScoringMaxed)
         {
             winner = _playerPool.GetNextPlayer();
         }
         else
         {
             winner = GameJudge.DetermineWinner(_playerPool);
         }
     }
     return winner;
 }
 private void CreateMatchInfo(Enums.GameOutcome gameOutcome, Player winner, StreamWriter file)
 {
     foreach (var player in _playerPool.GetPlayers())
     {
         file.WriteLine("PLAYER:" + player.GetSymbol() + "," + player.GetPlayerName() + "," + player.GetScore());
     }
     if (winner == null)
         file.WriteLine("GAME: DRAW," + gameOutcome + "," + _iteration);
     else
         file.WriteLine("GAME: " + winner.GetSymbol() + "," + gameOutcome + "," + _iteration);
 }
 public PlayerPool(Player playerA, Player playerB)
 {
     _players = new List<Player> {playerA, playerB};
     _currentPlayerIndex = 1;
 }
 private Player DeterminIfWinner(Enums.GameOutcome gameOutcome, Maze mazeFromPlayer, Player winner)
 {
     mazeFromPlayer.SwapPlayerSymbols();
     _maze = mazeFromPlayer;
     if (_maze.FindCoordinateOf(_secondMazePlayer).IsEmpty)
     {
         _maze.SetSymbol(Properties.Settings.Default.MazeCenterX, Properties.Settings.Default.MazeCenterY, _secondMazePlayer);
     }
     if (gameOutcome != Enums.GameOutcome.ProceedToNextRound)
         winner = GameJudge.DetermineWinner(_playerPool, gameOutcome);
     return winner;
 }