Exemplo n.º 1
0
        public static Tuple <bool, char> ComputeGameResult(char[,] board, char emptyChar)
        {
            var boardLines = BoardUtils.GetAllBoardLinesCoordinates(board.GetLength(0));

            foreach (var line in boardLines)
            {
                char c = board[line.First().Item1, line.First().Item2];
                if (c == emptyChar)
                {
                    continue;
                }

                bool win = true;
                foreach (var coord in line)
                {
                    if (c != board[coord.Item1, coord.Item2])
                    {
                        win = false;
                        break;
                    }
                }

                if (win)
                {
                    return(new Tuple <bool, char>(true, c));
                }
            }

            if (BoardUtils.IsDraw(board, emptyChar))
            {
                return(new Tuple <bool, char>(true, emptyChar));
            }

            return(new Tuple <bool, char>(false, emptyChar));
        }
Exemplo n.º 2
0
        protected Tuple <int, int> findWinningMove(char[,] board, char symbol)
        {
            List <List <Tuple <int, int> > > boardLines = BoardUtils.GetAllBoardLinesCoordinates(boardSize);

            foreach (var line in boardLines)
            {
                int currentLineScore       = 0;
                int movesToWin             = 0;
                Tuple <int, int> winCoords = null;

                foreach (var coord in line)
                {
                    if (board[coord.Item1, coord.Item2] == symbol)
                    {
                        currentLineScore++;
                    }
                    else if (board[coord.Item1, coord.Item2] == Engine.EMPTY_CHAR)
                    {
                        movesToWin++;
                        winCoords = coord;
                    }
                }

                if (currentLineScore == boardSize - 1 && movesToWin == 1)
                {
                    return(winCoords);
                }
            }

            return(null);
        }
Exemplo n.º 3
0
        public bool IsGameOver()
        {
            var gameResult = BoardUtils.ComputeGameResult(board, EMPTY_CHAR);

            if (gameResult.Item1 && gameResult.Item2 != EMPTY_CHAR)
            {
                Winner = getWinnerFromSymbol(gameResult.Item2);
            }

            return(gameResult.Item1);
        }
Exemplo n.º 4
0
        private int minimaxScoreWithCache(char[,] board, char currentSymbol)
        {
            Tuple <bool, char> result = BoardUtils.ComputeGameResult(board, Engine.EMPTY_CHAR);

            if (result.Item1)
            {
                // win
                if (result.Item2 == Symbol)
                {
                    return(10);
                }
                // loose
                else if (result.Item2 != Engine.EMPTY_CHAR)
                {
                    return(-10);
                }
                // draw
                else
                {
                    return(0);
                }
            }

            List <int> scores = new List <int>();

            foreach (var move in BoardUtils.GetAllLegalMoves(board, Engine.EMPTY_CHAR))
            {
                char[,] workingBoard = (char[, ])board.Clone();
                workingBoard[move.Item1, move.Item2] = currentSymbol;
                string key = GetCustomHash(workingBoard);
                if (!cache.ContainsKey(key))
                {
                    IPlayer opponent = PlayerManager.GetInstance().GetOpponent(currentSymbol);
                    int     score    = minimaxScoreWithCache(workingBoard, opponent.Symbol);
                    cache.Add(key, score);
                }
                scores.Add(cache[key]);
            }

            // if current player is our IA, we try to maximize the score,
            // else minimize it
            if (currentSymbol == Symbol)
            {
                return(scores.Max());
            }
            else
            {
                return(scores.Min());
            }
        }
Exemplo n.º 5
0
        internal override Tuple <int, int> AskNextMove(char[,] board)
        {
            Tuple <int, int> bestMove = null;
            int bestScore             = int.MinValue;

            foreach (var move in BoardUtils.GetAllLegalMoves(board, Engine.EMPTY_CHAR))
            {
                char[,] workingBoard = (char[, ])board.Clone();
                workingBoard[move.Item1, move.Item2] = Symbol;
                IPlayer opponent     = PlayerManager.GetInstance().GetOpponent(Symbol);
                int     currentScore = minimaxScoreWithCache(workingBoard, opponent.Symbol);

                if (currentScore > bestScore)
                {
                    bestScore = currentScore;
                    bestMove  = new Tuple <int, int>(move.Item1, move.Item2);
                }
            }

            return(bestMove);
        }