예제 #1
0
        /// <summary>
        /// Is a coordinate neighbors with a specific index?
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static bool NeighborsWith(FastBoard board, int x, int y, ulong index, out int testX, out int testY)
        {
            ulong leftCardIndex  = x > 0 ? board.GetCardIndex(x - 1, y) : 0;
            ulong rightCardIndex = x < FastBoard.Width - 1 ? board.GetCardIndex(x + 1, y) : 0;
            ulong upCardIndex    = y > 0 ? board.GetCardIndex(x, y - 1) : 0;
            ulong downCardIndex  = y < FastBoard.Height - 1 ? board.GetCardIndex(x, y + 1) : 0;

            if (leftCardIndex == index)
            {
                testX = x - 1;
                testY = y;
                return(true);
            }

            if (rightCardIndex == index)
            {
                testX = x + 1;
                testY = y;
                return(true);
            }

            if (upCardIndex == index)
            {
                testX = x;
                testY = y - 1;
                return(true);
            }

            if (downCardIndex == index)
            {
                testX = x;
                testY = y + 1;
                return(true);
            }

            testX = -1;
            testY = -1;

            return(false);
        }
예제 #2
0
        /// <summary>
        /// Is a coordinate neighbors with a specific index?
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static bool NeighborsWith(FastBoard board, int x, int y, ulong index, out int testX, out int testY)
        {
            ulong leftCardIndex = x > 0 ? board.GetCardIndex(x - 1, y) : 0;
            ulong rightCardIndex = x < FastBoard.Width - 1 ? board.GetCardIndex(x + 1, y) : 0;
            ulong upCardIndex = y > 0 ? board.GetCardIndex(x, y - 1) : 0;
            ulong downCardIndex = y < FastBoard.Height - 1 ? board.GetCardIndex(x, y + 1) : 0;

            if(leftCardIndex == index)
            {
                testX = x - 1;
                testY = y;
                return true;
            }

            if(rightCardIndex == index)
            {
                testX = x + 1;
                testY = y;
                return true;
            }

            if(upCardIndex == index)
            {
                testX = x;
                testY = y - 1;
                return true;
            }

            if(downCardIndex == index)
            {
                testX = x;
                testY = y + 1;
                return true;
            }

            testX = -1;
            testY = -1;

            return false;
        }
예제 #3
0
 /// <summary>
 /// A BoardQualityEvaluator that uses the Board's total number of empty spaces as its quality.
 /// </summary>
 public static float EmptySpaces(FastBoard board)
 {
     int total = 0;
     for(int x = 0; x < FastBoard.Width; x++)
     {
         for(int y = 0; y < FastBoard.Height; y++)
         {
             if(board.GetCardIndex(x, y) == 0)
                 total++;
         }
     }
     return total;
 }
예제 #4
0
        /// <summary>
        /// A BoardQualityEvaluator that uses the Board's total number of empty spaces as its quality.
        /// </summary>
        public static float EmptySpaces(FastBoard board)
        {
            int total = 0;

            for (int x = 0; x < FastBoard.Width; x++)
            {
                for (int y = 0; y < FastBoard.Height; y++)
                {
                    if (board.GetCardIndex(x, y) == 0)
                    {
                        total++;
                    }
                }
            }
            return(total);
        }
예제 #5
0
        /// <summary>
        /// A BoardQualityEvaluator that calculates how "open" the board is.
        /// </summary>
        public static float Openness(FastBoard board)
        {
            int total = 0;

            for (int x = 0; x < FastBoard.Width; x++)
            {
                for (int y = 0; y < FastBoard.Height; y++)
                {
                    ulong cardIndex = board.GetCardIndex(x, y);
                    if (cardIndex == 0)
                    {
                        // 2 points for an empty cell.
                        total += 2;
                    }
                    else
                    {
                        ulong leftCardIndex  = x > 0 ? board.GetCardIndex(x - 1, y) : 0;
                        ulong rightCardIndex = x < FastBoard.Width - 1 ? board.GetCardIndex(x + 1, y) : 0;
                        ulong upCardIndex    = y > 0 ? board.GetCardIndex(x, y - 1) : 0;
                        ulong downCardIndex  = y < FastBoard.Height - 1 ? board.GetCardIndex(x, y + 1) : 0;

                        // 1 point for each adjacent card we can merge with.
                        if (leftCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, leftCardIndex))
                        {
                            total += 1;
                        }
                        if (rightCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, rightCardIndex))
                        {
                            total += 1;
                        }
                        if (upCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, upCardIndex))
                        {
                            total += 1;
                        }
                        if (downCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, downCardIndex))
                        {
                            total += 1;
                        }

                        // -1 point if we're trapped between higher-valued cards, either horizontally or vertically.
                        if ((x == 0 || (leftCardIndex >= 3 && cardIndex < leftCardIndex)) &&
                            (x == FastBoard.Width - 1 || (rightCardIndex >= 3 && cardIndex < rightCardIndex)))
                        {
                            total -= 1;
                        }
                        if ((y == 0 || (upCardIndex >= 3 && cardIndex < upCardIndex)) &&
                            (y == FastBoard.Height - 1 || (downCardIndex >= 3 && cardIndex < downCardIndex)))
                        {
                            total -= 1;
                        }

                        // 1 point if next to at least one card twice our value.
                        if (cardIndex >= 3)
                        {
                            if ((leftCardIndex != 0 && leftCardIndex == cardIndex + 1) ||
                                (rightCardIndex != 0 && rightCardIndex == cardIndex + 1) ||
                                (upCardIndex != 0 && upCardIndex == cardIndex + 1) ||
                                (downCardIndex != 0 && downCardIndex == cardIndex + 1))
                            {
                                total += 1;
                            }
                        }
                    }
                }
            }
            return(total);
        }
예제 #6
0
        /// <summary>
        /// A BoardQualityEvaluator that calculates how "open" the board is.
        /// </summary>
        public static float OpennessMatthew(FastBoard board)
        {
            var maxIndex = board.GetMaxCardIndex();

            int total = 0;

            for (int x = 0; x < FastBoard.Width; x++)
            {
                for (int y = 0; y < FastBoard.Height; y++)
                {
                    ulong cardIndex = board.GetCardIndex(x, y);
                    if (cardIndex == 0)
                    {
                        // 2 points for an empty cell.
                        total += 3;
                    }
                    else
                    {
                        ulong leftCardIndex  = x > 0 ? board.GetCardIndex(x - 1, y) : 0;
                        ulong rightCardIndex = x < FastBoard.Width - 1 ? board.GetCardIndex(x + 1, y) : 0;
                        ulong upCardIndex    = y > 0 ? board.GetCardIndex(x, y - 1) : 0;
                        ulong downCardIndex  = y < FastBoard.Height - 1 ? board.GetCardIndex(x, y + 1) : 0;

                        // for each adjacent card we can merge with.
                        if (leftCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, leftCardIndex))
                        {
                            total += 2;
                        }
                        if (rightCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, rightCardIndex))
                        {
                            total += 2;
                        }
                        if (upCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, upCardIndex))
                        {
                            total += 2;
                        }
                        if (downCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, downCardIndex))
                        {
                            total += 2;
                        }

                        // negative if we're trapped between higher-valued cards, either horizontally or vertically.
                        if ((x == 0 || (leftCardIndex >= 3 && cardIndex < leftCardIndex)) &&
                            (x == FastBoard.Width - 1 || (rightCardIndex >= 3 && cardIndex < rightCardIndex)))
                        {
                            total -= 5;
                        }
                        if ((y == 0 || (upCardIndex >= 3 && cardIndex < upCardIndex)) &&
                            (y == FastBoard.Height - 1 || (downCardIndex >= 3 && cardIndex < downCardIndex)))
                        {
                            total -= 5;
                        }

                        // point if next to at least one card twice our value.
                        if (cardIndex >= 3)
                        {
                            if ((leftCardIndex != 0 && leftCardIndex == cardIndex + 1) ||
                                (rightCardIndex != 0 && rightCardIndex == cardIndex + 1) ||
                                (upCardIndex != 0 && upCardIndex == cardIndex + 1) ||
                                (downCardIndex != 0 && downCardIndex == cardIndex + 1))
                            {
                                total += 2;
                            }
                        }

                        if (maxIndex > 4)
                        {
                            // for each wall we're touching if we're the biggest card
                            if (cardIndex == maxIndex)
                            {
                                if (x == 0 || x == 3)
                                {
                                    total += 3;
                                }

                                if (y == 0 || y == 3)
                                {
                                    total += 3;
                                }
                            }

                            // for sticking next to the biggest piece
                            if (cardIndex == maxIndex - 1)
                            {
                                int testX, testY;
                                if (NeighborsWith(board, x, y, maxIndex, out testX, out testY))
                                {
                                    total += 1;

                                    // and a bonus if we're also along a wall
                                    if (x == 0 || x == 3)
                                    {
                                        total += 1;
                                    }

                                    if (y == 0 || y == 3)
                                    {
                                        total += 1;
                                    }
                                }
                            }

                            // if we're two below
                            if (cardIndex == maxIndex - 2)
                            {
                                // and we're neighbors with a 1-below
                                int testX, testY;
                                if (NeighborsWith(board, x, y, maxIndex - 1, out testX, out testY))
                                {
                                    // who is also neighbors with the max
                                    if (NeighborsWith(board, testX, testY, maxIndex, out testX, out testY))
                                    {
                                        total += 1;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(total);
        }
예제 #7
0
        /// <summary>
        /// A BoardQualityEvaluator that calculates how "open" the board is.
        /// </summary>
        public static float Openness(FastBoard board)
        {
            int total = 0;
            for(int x = 0; x < FastBoard.Width; x++)
            {
                for(int y = 0; y < FastBoard.Height; y++)
                {
                    ulong cardIndex = board.GetCardIndex(x, y);
                    if(cardIndex == 0)
                    {
                        // 2 points for an empty cell.
                        total += 2;
                    }
                    else
                    {
                        ulong leftCardIndex = x > 0 ? board.GetCardIndex(x - 1, y) : 0;
                        ulong rightCardIndex = x < FastBoard.Width - 1 ? board.GetCardIndex(x + 1, y) : 0;
                        ulong upCardIndex = y > 0 ? board.GetCardIndex(x, y - 1) : 0;
                        ulong downCardIndex = y < FastBoard.Height - 1 ? board.GetCardIndex(x, y + 1) : 0;

                        // 1 point for each adjacent card we can merge with.
                        if(leftCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, leftCardIndex))
                            total += 1;
                        if(rightCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, rightCardIndex))
                            total += 1;
                        if(upCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, upCardIndex))
                            total += 1;
                        if(downCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, downCardIndex))
                            total += 1;

                        // -1 point if we're trapped between higher-valued cards, either horizontally or vertically.
                        if((x == 0 || (leftCardIndex >= 3 && cardIndex < leftCardIndex)) &&
                           (x == FastBoard.Width - 1 || (rightCardIndex >= 3 && cardIndex < rightCardIndex)))
                        {
                            total -= 1;
                        }
                        if((y == 0 || (upCardIndex >= 3 && cardIndex < upCardIndex)) &&
                           (y == FastBoard.Height - 1 || (downCardIndex >= 3 && cardIndex < downCardIndex)))
                        {
                            total -= 1;
                        }

                        // 1 point if next to at least one card twice our value.
                        if(cardIndex >= 3)
                        {
                            if((leftCardIndex != 0 && leftCardIndex == cardIndex + 1) ||
                               (rightCardIndex != 0 && rightCardIndex == cardIndex + 1) ||
                               (upCardIndex != 0 && upCardIndex == cardIndex + 1) ||
                               (downCardIndex != 0 && downCardIndex == cardIndex + 1))
                            {
                                total += 1;
                            }
                        }
                    }
                }
            }
            return total;
        }
예제 #8
0
        /// <summary>
        /// A BoardQualityEvaluator that calculates how "open" the board is.
        /// </summary>
        public static float OpennessMatthew(FastBoard board)
        {
            var maxIndex = board.GetMaxCardIndex();

            int total = 0;
            for(int x = 0; x < FastBoard.Width; x++)
            {
                for(int y = 0; y < FastBoard.Height; y++)
                {
                    ulong cardIndex = board.GetCardIndex(x, y);
                    if(cardIndex == 0)
                    {
                        // 2 points for an empty cell.
                        total += 3;
                    }
                    else
                    {
                        ulong leftCardIndex = x > 0 ? board.GetCardIndex(x - 1, y) : 0;
                        ulong rightCardIndex = x < FastBoard.Width - 1 ? board.GetCardIndex(x + 1, y) : 0;
                        ulong upCardIndex = y > 0 ? board.GetCardIndex(x, y - 1) : 0;
                        ulong downCardIndex = y < FastBoard.Height - 1 ? board.GetCardIndex(x, y + 1) : 0;

                        // for each adjacent card we can merge with.
                        if(leftCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, leftCardIndex))
                            total += 2;
                        if(rightCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, rightCardIndex))
                            total += 2;
                        if(upCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, upCardIndex))
                            total += 2;
                        if(downCardIndex != 0 && FastBoard.CanCardsMerge(cardIndex, downCardIndex))
                            total += 2;

                        // negative if we're trapped between higher-valued cards, either horizontally or vertically.
                        if((x == 0 || (leftCardIndex >= 3 && cardIndex < leftCardIndex)) &&
                           (x == FastBoard.Width - 1 || (rightCardIndex >= 3 && cardIndex < rightCardIndex)))
                        {
                            total -= 5;
                        }
                        if((y == 0 || (upCardIndex >= 3 && cardIndex < upCardIndex)) &&
                           (y == FastBoard.Height - 1 || (downCardIndex >= 3 && cardIndex < downCardIndex)))
                        {
                            total -= 5;
                        }

                        // point if next to at least one card twice our value.
                        if(cardIndex >= 3)
                        {
                            if((leftCardIndex != 0 && leftCardIndex == cardIndex + 1) ||
                               (rightCardIndex != 0 && rightCardIndex == cardIndex + 1) ||
                               (upCardIndex != 0 && upCardIndex == cardIndex + 1) ||
                               (downCardIndex != 0 && downCardIndex == cardIndex + 1))
                            {
                                total += 2;
                            }
                        }

                        if(maxIndex > 4)
                        {

                            // for each wall we're touching if we're the biggest card
                            if(cardIndex == maxIndex)
                            {
                                if(x == 0 || x == 3)
                                {
                                    total += 3;
                                }

                                if(y == 0 || y == 3)
                                {
                                    total += 3;
                                }
                            }

                            // for sticking next to the biggest piece
                            if(cardIndex == maxIndex - 1)
                            {
                                int testX, testY;
                                if(NeighborsWith(board, x, y, maxIndex, out testX, out testY))
                                {
                                    total += 1;

                                    // and a bonus if we're also along a wall
                                    if(x == 0 || x == 3)
                                    {
                                        total += 1;
                                    }

                                    if(y == 0 || y == 3)
                                    {
                                        total += 1;
                                    }
                                }
                            }

                            // if we're two below
                            if(cardIndex == maxIndex - 2)
                            {
                                // and we're neighbors with a 1-below
                                int testX, testY;
                                if(NeighborsWith(board, x, y, maxIndex - 1, out testX, out testY))
                                {
                                    // who is also neighbors with the max
                                    if(NeighborsWith(board, testX, testY, maxIndex, out testX, out testY))
                                    {
                                        total += 1;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return total;
        }