static void Main(string[] args)
        {
            var game        = new ReversiGame(new GameFieldFactory().PrepareField());
            var movesFinder = new PossibleMovesFinder();

            DrawField(game.Field, game.CurrentColor, movesFinder.GetPossibleMoves(game.Field).ToList());

            while (!game.IsOver)
            {
                var move = ReadMove();
                ValueOrError <bool> result;
                if (move == "rnd" || move == "r")
                {
                    result = game.MakeMove(movesFinder.GetPossibleMoves(game.Field)
                                           .First(possibleMove => possibleMove.Color == game.CurrentColor).Position.ToCode());
                }
                else
                {
                    result = game.MakeMove(move);
                }


                if (result.HasValue)
                {
                    DrawField(game.Field, game.CurrentColor, movesFinder.GetPossibleMoves(game.Field).ToList());
                }
                else
                {
                    Console.WriteLine($"Error occured during move: {result.Error}");
                }
            }
        }
        private static void MakeMove(ReversiGame reversiGame, Color myColor)
        {
            var moves = new PossibleMovesFinder().GetPossibleMoves(reversiGame.Field).Where(move => move.Color == myColor).ToList();

            // Console.WriteLine($"//{string.Join(",", moves)}, {reversiGame.Field.GetCell("B4").Piece?.Color}");
            if (!moves.Any())
            {
                Console.WriteLine("pass");
                reversiGame.MakeMove("pass");
                return;
            }

            var move = moves[random.Next(moves.Count)];
            var code = move.Position.ToCode();

            reversiGame.MakeMove(code);
            Console.WriteLine(code);
        }
Exemple #3
0
        public void FinderShouldFindMovesAtStartingPosition()
        {
            var moves  = new PossibleMovesFinder().GetPossibleMoves(new GameFieldFactory().PrepareField());
            var parser = new PositionParser();

            var expectedMoves = new List <PossibleMove>()
            {
                new PossibleMove()
                {
                    Color = Color.White, Position = parser.Parse("E3")
                },
                new PossibleMove()
                {
                    Color = Color.White, Position = parser.Parse("F4")
                },
                new PossibleMove()
                {
                    Color = Color.White, Position = parser.Parse("C5")
                },
                new PossibleMove()
                {
                    Color = Color.White, Position = parser.Parse("D6")
                },

                new PossibleMove()
                {
                    Color = Color.Black, Position = parser.Parse("C4")
                },
                new PossibleMove()
                {
                    Color = Color.Black, Position = parser.Parse("D3")
                },
                new PossibleMove()
                {
                    Color = Color.Black, Position = parser.Parse("F5")
                },
                new PossibleMove()
                {
                    Color = Color.Black, Position = parser.Parse("E6")
                },
            };

            CollectionAssert.AreEquivalent(moves, expectedMoves);
        }
Exemple #4
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}");
            }
        }