public void FactoryShouldCreateCorrectField()
        {
            var field = new GameFieldFactory().PrepareField();

            Assert.That(field.Height, Is.EqualTo(8));
            Assert.That(field.Width, Is.EqualTo(8));

            Assert.That(field.GetCell("D4").Piece.Color, Is.EqualTo(Color.White));
            Assert.That(field.GetCell("D5").Piece.Color, Is.EqualTo(Color.Black));
            Assert.That(field.GetCell("E4").Piece.Color, Is.EqualTo(Color.Black));
            Assert.That(field.GetCell("E5").Piece.Color, Is.EqualTo(Color.White));

            Assert.That(field.GetCell("E6").HasPiece, Is.False);
        }
示例#2
0
        private async Task <SingleTestResult> Play(Process process)
        {
            var gameFieldFactory = new GameFieldFactory();

            try
            {
                var random = new Random();
                var output = process.StandardOutput;
                var input  = process.StandardInput;

                var game = new ReversiGame(gameFieldFactory.PrepareField(await SetUpBlackHole()));

                var playersColor = random.NextDouble() > .5? Color.Black : Color.White;
                logger.Log(LogLevel.Info, $"Chosen color for player: {playersColor}");
                await input.WriteLineAsync(playersColor.ToString().ToLower());

                if (playersColor == Color.White)
                {
                    await PerformMove();
                }

                while (!game.IsOver)
                {
                    var possibleMoves = new PossibleMovesFinder().GetPossibleMoves(game.Field)
                                        .Where(move => move.Color == playersColor).ToList();
                    var command = FetchNextCommand(output);
                    if (!command.HasValue)
                    {
                        return(SingleTestResult.FromError(command.Error));
                    }

                    var line = command.Value;
                    if (line == null)
                    {
                        return(SingleTestResult.FromError("Error: can not fetch next move"));
                    }

                    logger.Log(LogLevel.Info, $"<- {line}");
                    if (possibleMoves.Any() && line == "pass")
                    {
                        return(SingleTestResult.FromError("Error: can not pass when possible moves are available"));
                    }

                    if (possibleMoves.All(move => move.Position.ToCode() != line) && line != "pass")
                    {
                        return(SingleTestResult.FromError($"Error: can not make move to {line}"));
                    }

                    game.MakeMove(line);

                    await PerformMove();
                }

                Console.WriteLine($"Black {game.GetScoreFor(Color.Black)} : {game.GetScoreFor(Color.White)} White");
                return(new SingleTestResult(game.GetScoreFor(playersColor) < game.GetScoreFor(playersColor.Opposite())
                    ? TestResultType.Win
                    : TestResultType.Loss));

                async Task <Position> SetUpBlackHole()
                {
                    var blackHoleVariants = gameFieldFactory.PrepareField().AllCells().Where(tuple => !tuple.cell.HasPiece).ToList();
                    var blackHole         = blackHoleVariants[random.Next(blackHoleVariants.Count)].position;

                    logger.Log(LogLevel.Info, $"Black hole is chosen to: {blackHole.ToCode()}");
                    await input.WriteLineAsync(blackHole.ToCode());

                    return(blackHole);
                }

                Task PerformMove()
                {
                    var moves = new PossibleMovesFinder().GetPossibleMoves(game.Field)
                                .Where(move => move.Color == playersColor.Opposite()).ToList();
                    var move = moves.Any()? moves[random.Next(moves.Count)].Position.ToCode() : "pass";

                    game.MakeMove(move);

                    logger.Log(LogLevel.Info, $"-> {move}");
                    return(input.WriteLineAsync(move));
                }
            }
            catch (Exception e)
            {
                logger.Log(LogLevel.Error, $"Internal error occured: {e.StackTrace}");
                return(new SingleTestResult(TestResultType.InternalError, e.Message));
            }
            finally
            {
                process.Exited -= OnProcessOnExited;
                logger.Log(LogLevel.Info, "Killing client process...");
                process.Kill();
                logger.Log(LogLevel.Info, $"Child process killed: {process.HasExited}");
            }
        }