Beispiel #1
0
        public bool PlayAutomated(bool pauseOnTurn)
        {
            AutoTurns++;
            var random       = new Random();
            var randomChance = random.Next(10);

            GameLogEntry logEntry = NewLogEntry();

            int column = -1;

            var boardSearch = new BoardSearch(numberToWin);
            var legalMoves  = boardSearch.FindAllLegalMoves(board);

            if (legalMoves.Count == 0)
            {
                return(EndTurn(logEntry, -1, pauseOnTurn));
            }

            if (boardSearch.IsBoardEmpty(board))
            {
                //Console.WriteLine("Random move. ");
                column = random.Next(6);
            }
            else
            {
                var strategy = PlayerTurn == 1 ? strategy1 : strategy2;

                var depth = PlayerTurn == 1 ? Player1SearchDepth : GetSearchDepth(AutoTurns);


                column = strategy.Run(board, numberToWin, PlayerTurn, depth);
            }

            return(EndTurn(logEntry, column, pauseOnTurn, true));
        }
Beispiel #2
0
        public int Run(Board board, int numToWin, int playerNumber, int searchDepth = 8)
        {
            Random rand = new Random();

            var test = rand.Next(0, 2);

            if (test == 0)
            {
                var search     = new BoardSearch(numToWin);
                var legalMoves = search.FindAllLegalMoves(board);

                var allColumns = legalMoves.Select(p => p.Col).ToList();

                if (!allColumns.Any())
                {
                    return(-1);
                }


                var index = rand.Next(allColumns.Count() - 1);
                return(allColumns[index]);
            }
            else
            {
                var strat = new MinMaxStrategy();
                return(strat.Run(board, numToWin, playerNumber));
            }
        }
Beispiel #3
0
        public bool DoesPlayer1HaveZugzwang(Board board)
        {
            //find threats, label even or odd
            var boardSearch = new BoardSearch(4);

            var groups       = boardSearch.FindGroups(1, board, 1);
            var hasOddThreat = groups.Select(g => g.Coords.Any(t => t.Row % 2 != 0)).Any();

            return(hasOddThreat);
        }
Beispiel #4
0
        public int Run(Board board, int numToWin, int playerNumber, int searchDepth = 8)
        {
            BoardSearch boardSearch = new BoardSearch(numToWin);

            var boardToEvaluate = new Board(board.MAX_COL_INDEX, board.MAX_ROW_INDEX);

            int[,] matrix          = (int[, ])board.Matrix.Clone();
            boardToEvaluate.Matrix = matrix;

            Player[,] boardState = BoardToPlayerBoard(boardToEvaluate, playerNumber);
            var           columnToPlay = -1;
            Connect4State state        = new Connect4State(boardState, (Player)playerNumber);

            try
            {
                var searchResult = searchEngine.Search(state, searchDepth);
                var newBoard     = (Connect4State)searchResult.NextMove;


                for (var r = 0; r <= board.MAX_ROW_INDEX; r++)
                {
                    for (var c = 0; c <= board.MAX_COL_INDEX; c++)
                    {
                        var value    = boardState[r, c];
                        var newValue = newBoard.Board[r, c];

                        if (value != newValue)
                        {
                            columnToPlay = c;
                        }
                    }
                }
            }
            catch (NoNeighborsException e)
            {
                var    legalMoves = boardSearch.FindAllLegalMoves(boardToEvaluate);
                Random rand       = new Random();
                columnToPlay = legalMoves[rand.Next(legalMoves.Count - 1)].Col;
            }

            return(columnToPlay);
        }
Beispiel #5
0
        public int Run(Board board, int numToWin, int playerNumber = 2)
        {
            PLAYERNUM = playerNumber;
            var search = new BoardSearch(numToWin);

            var legalMoves = search.FindAllLegalMoves(board);

            var yourThreats = search.FindGroups(PLAYERNUM, board, 1);
            var oppThreats  = search.FindGroups(1, board, 1);

            int?columnToPlay = 0;

            //can you win?
            columnToPlay = MatchThreatsWithLegal(yourThreats, legalMoves);
            if (columnToPlay.HasValue)
            {
                return(columnToPlay.Value);
            }

            //should you block?
            columnToPlay = MatchThreatsWithLegal(oppThreats, legalMoves);
            if (columnToPlay.HasValue)
            {
                return(columnToPlay.Value);
            }

            //are there hidden forks for player 1?
            //look for threats with 2 blanks
            var forkThreats = search.FindGroups(1, board, 2);
            //do any threats share a blank?
            var forkPositions = new List <Position>();

            for (var i = 0; i < forkThreats.Count; i++)
            {
                var ft     = forkThreats[i];
                var blanks = ft.Coords.Where(c => c.Mark == 0);

                for (var j = 0; j < forkThreats.Count; j++)
                {
                    if (j == i)
                    {
                        continue;
                    }

                    var jft     = forkThreats[j];
                    var jBlanks = jft.Coords.Where(c => c.Mark == 0);

                    var shared = jBlanks.Intersect <Position>(blanks, new PositionEqualityComparer());
                    forkPositions.AddRange(shared);
                }
            }

            //are any blanks legal moves?
            columnToPlay = MatchPositionsThreatsWithLegal(forkPositions, legalMoves);
            if (columnToPlay.HasValue)
            {
                return(columnToPlay.Value);
            }

            //should we remove a legal move if it will harm us?
            //can player1 score after this move?
            //take all legal moves and transpose one row up - do any fulfill player 1 threats?
            var toRemove = new List <Position>();

            foreach (var legalMove in legalMoves)
            {
                var transposedMove = new Position(legalMove.Row + 1, legalMove.Col, 0);
                foreach (var threat in oppThreats)
                {
                    var blank = threat.Coords.Single(t => t.Mark == 0);
                    if (blank.Equals(transposedMove))
                    {
                        toRemove.Add(legalMove);
                    }
                }
            }

            toRemove.ForEach(r => legalMoves.Remove(r));

            //claimeven
            var claimevens = search.FindPossibleClaimEvens(board);

            foreach (var claimEven in claimevens)
            {
                foreach (var move in legalMoves)
                {
                    if (claimEven == move.Col)
                    {
                        return(claimEven);
                    }
                }
            }

            var moveIndex = random.Next(0, legalMoves.Count());

            return(legalMoves[moveIndex].Col);
        }