Esempio n. 1
0
        // looks for immediate win or loss, and moves to win or prevent loss
        private Board Easy_Bot(Board b)
        {
            // see if there is an immediate win available
            for (int c = 0; c < 7; c++)
            {
                Board copy1 = (Board)b.Copy();

                if (copy1.AddPiece(2, c) && copy1.Winner() == 2)
                {
                    b.AddPiece(2, c);
                    return(b);
                }
            }

            // see if there is an immediate threat needed to block
            for (int c = 0; c < 7; c++)
            {
                Board copy2 = (Board)b.Copy();

                if (copy2.AddPiece(1, c) && copy2.Winner() == 1)
                {
                    b.AddPiece(2, c);
                    return(b);
                }
            }

            // otherwise, just pick a random move
            return(Random_Bot(b));
        }
Esempio n. 2
0
        protected override int SelectNonWinningBlockingMove(Board b, int lastColumn, int color)
        {
            var m = WinInXMoves(b, color, 4);

            if (m >= 0)
            {
                return(m);
            }

            var nonLosers = new List <int>();

            foreach (var column in PossibleMoves(b))
            {
                var copy = b.Copy();
                copy.DoMove(new Move(column, color));

                var t = WinInXMoves(copy, -color, 3);
                if (t < 0)
                {
                    nonLosers.Add(column);
                }
            }

            if (nonLosers.Count > 0)
            {
                return(nonLosers[RNG.Next(nonLosers.Count)]);
            }

            return(base.SelectNonWinningBlockingMove(b, lastColumn, color));
        }
Esempio n. 3
0
        protected override int SelectNonWinningBlockingMove(Board b, int lastColumn, int color)
        {
            var nonLosers = new List <int>();

            foreach (var column in PossibleMoves(b))
            {
                var copy = b.Copy();
                copy.DoMove(new Move(column, color));
                var m = Win(copy, -color);
                if (m >= 0)
                {
                    continue;
                }
                nonLosers.Add(column);

                var winner = true;
                foreach (var column2 in PossibleMoves(copy))
                {
                    var copy2 = copy.Copy();
                    m = Win(copy2, color);
                    if (m < 0)
                    {
                        winner = false;
                        break;
                    }
                }

                if (winner)
                {
                    return(column);
                }
            }

            if (nonLosers.Count > 0)
            {
                return(nonLosers[RNG.Next(nonLosers.Count)]);
            }

            return(base.SelectNonWinningBlockingMove(b, lastColumn, color));
        }
Esempio n. 4
0
        int WinInXMoves(Board b, int color, int X)
        {
            var pm = PossibleMoves(b);

            foreach (var column in pm)
            {
                if (b.IsWinningMove(new Move(column, color)))
                {
                    return(column);
                }
            }

            var oppWins = 0;

            foreach (var column in PossibleMoves(b))
            {
                if (b.IsWinningMove(new Move(column, -color)))
                {
                    pm = new List <int>()
                    {
                        column
                    };
                    oppWins++;
                }
            }

            if (oppWins > 1)
            {
                return(-1);
            }

            foreach (var column in pm)
            {
                var copy = b.Copy();
                copy.DoMove(new Move(column, color));

                var winner = true;
                foreach (var column2 in PossibleMoves(copy))
                {
                    var copy2 = copy.Copy();
                    copy2.DoMove(new Move(column2, -color));

                    int m;

                    if (X <= 1)
                    {
                        m = Win(copy2, color);
                    }
                    else
                    {
                        m = WinInXMoves(copy2, color, X - 1);
                    }
                    if (m < 0)
                    {
                        winner = false;
                        break;
                    }
                }

                if (winner)
                {
                    return(column);
                }
            }

            return(-1);
        }
Esempio n. 5
0
        // helper for minimax alg, recursively determines move strength
        private int moveStrength(Board b, int move, int depth)
        {
            int   currentPlayer = b.Turn;
            Board copy          = (Board)b.Copy();

            if (copy.AddPiece(copy.Turn, move))
            {
                // if this move would spell an immediate win for either player
                int winner = copy.Winner();
                if (winner != 0)
                {
                    // return the id of the current player * 10, with depth added
                    return((currentPlayer * 100) + depth);
                    //return (currentPlayer * 10);
                }
            }
            // if the move is illegal, return -1
            else
            {
                return(-1);
            }

            // base case: if depth has hit 0 (and no immediate win after this move established by previous step)
            if (depth == 0)
            {
                return(0);
            }
            // otherwise, begin searching further through moves
            else
            {
                bool tieAvailable          = false;
                int  strongestMoveStrength = 0;
                int  bestBadMoveStrength   = 0;

                for (int c = 0; c < 7; c++)
                {
                    int nextMoveStrength = moveStrength(copy, c, depth - 1);
                    // if the next move will ultimately result in a loss for currentPlayer, mark it as such
                    if ((nextMoveStrength / 100) == copy.Turn && nextMoveStrength > strongestMoveStrength)
                    {
                        strongestMoveStrength = nextMoveStrength;
                    }
                    // if at least one of the next moves will continue towards a potential victory for currentPlayer
                    else if (nextMoveStrength == 0)
                    {
                        tieAvailable = true;
                    }
                    else if (nextMoveStrength > bestBadMoveStrength)
                    {
                        bestBadMoveStrength = nextMoveStrength;
                    }
                }
                if (strongestMoveStrength > 0)
                {
                    return(strongestMoveStrength);
                }
                else if (tieAvailable)
                {
                    return(0);
                }
                else
                {
                    return(bestBadMoveStrength);
                }
            }
        }