示例#1
0
        public static List <Mill> getMills(int[,] a, int player)
        {
            List <Mill> mills = new List <Mill>();

            for (int ii = 1; ii < 25; ii++)
            {
                for (int jj = ii + 1; jj < 25; jj++)
                {
                    for (int k = jj + 1; k < 25; k++)
                    {
                        var numbers = new int[] { ii, jj, k };
                        Array.Sort(numbers);
                        Cell x = new Cell(numbers[0]);
                        Cell y = new Cell(numbers[1]);
                        Cell z = new Cell(numbers[2]);
                        // check if the stones are different, neighbours and on the same row or column
                        if ((k != ii) && (k != jj) && (Cell.neighbour(a, x, y)) && (Cell.neighbour(a, y, z)) &&
                            (a[x.i, x.j] == a[y.i, y.j]) &&
                            (a[x.i, x.j] == a[z.i, z.j]) && (a[x.i, x.j] == player) && Cell.consecutive(x, y, z))
                        {
                            Mill m = new Mill(numbers[0], numbers[1], numbers[2]);
                            if (!(mills.Contains(m)))
                            {
                                mills.Add(m);
                            }
                        }
                    }
                }
            }

            return(mills);
        }
示例#2
0
        public override bool Equals(Object obj)
        {
            if (obj == null || this.GetType() != obj.GetType())
            {
                return(false);
            }

            Mill m = (Mill)obj;

            return((this.start == m.start) && (this.middle == m.middle) && (this.stop == m.stop));
        }
示例#3
0
        public static bool StonesOnlyInMills(int[,] a, int player)
        {
            // check if all the player stones from the board are inside mills
            List <Mill>   Mills         = Mill.getMills(a, player);
            HashSet <int> StonesInMills = new HashSet <int>();

            foreach (Mill m in Mills)
            {
                StonesInMills.Add(m.start);
                StonesInMills.Add(m.middle);
                StonesInMills.Add(m.stop);
            }
            // if the number of stones from player inside mills is equal to the total number
            // of stones from player from the board then all the stones from the player are inside mills
            if (Cell.count(a, player) == StonesInMills.Count)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#4
0
        private void moveBlue()
        {
            // the blue oponent moves too fast, so a delay is added in order for the human to spot clearly what move has been made
            var timer = new DispatcherTimer {
                Interval = TimeSpan.FromSeconds(1)
            };

            timer.Start();
            timer.Tick += (sender, args) =>
            {
                timer.Stop();
                warning.Text       = "";
                warning.Visibility = System.Windows.Visibility.Hidden;
                int move = 0;
                // blue opponent's first move is random
                int i = 1, j = 2, index = 1;
                if (firstMoveBlue)
                {
                    while (a[i, j] != 0)
                    {
                        index = rand.Next(1, 25);
                        Cell c = new Cell(index);
                        i = c.i;
                        j = c.j;
                    }
                    a[i, j]       = 2;
                    firstMoveBlue = false;
                    drawEllipse(ellipseV[index], 2, blueColor, 35, false);
                    move         = index;
                    ballPlayer2 -= 1;
                }
                else
                if (thirdPhaseBlue)
                {
                    // check if red will soon create a mill
                    List <Cell> incompleteRedMill = Mill.checkDangerMill(a, 1);
                    // check if blue will create soon a mill
                    List <Cell> incompleteBlueMill = Mill.checkDangerMill(a, 2);
                    List <Mill> blueMills          = Mill.getMills(a, 2);
                    Cell        moved = Mill.getBlueStoneThirdPhase(a);
                    if (incompleteBlueMill.Count != 0)
                    {
                        a[moved.i, moved.j] = 0;
                        drawEllipse(ellipseV[Helper.toIJ(moved.i, moved.j)], 2, yellowColor, 15, false);
                        int ii = incompleteBlueMill[0].i;
                        int jj = incompleteBlueMill[0].j;
                        drawEllipse(ellipseV[Helper.toIJ(ii, jj)], 2, blueColor, 35, false);
                        a[ii, jj] = 2;
                    }
                    else
                    if (incompleteRedMill.Count != 0)
                    {
                        a[moved.i, moved.j] = 0;
                        drawEllipse(ellipseV[Helper.toIJ(moved.i, moved.j)], 2, yellowColor, 15, false);
                        int ii = incompleteRedMill[0].i;
                        int jj = incompleteRedMill[0].j;
                        drawEllipse(ellipseV[Helper.toIJ(ii, jj)], 2, blueColor, 35, false);
                        a[ii, jj] = 2;
                    }
                    else
                    if (blueMills.Count != 0)
                    {
                        Cell x = new Cell(blueMills[0].start);
                        for (int k = 1; k < 25; k++)
                        {
                            Cell n = new Cell(k);
                            if (a[n.i, n.j] == 0)
                            {
                                a[n.i, n.j] = 2;
                                a[x.i, x.j] = 0;
                                drawEllipse(ellipseV[Helper.toIJ(x.i, x.j)], 2, yellowColor, 15, false);
                                drawEllipse(ellipseV[Helper.toIJ(n.i, n.j)], 2, blueColor, 35, false);
                            }
                        }
                    }
                    else
                    {
                        int  ct     = 0;
                        Cell first  = new Cell(0);
                        Cell second = new Cell(0);
                        for (int k = 1; k < 25; k++)
                        {
                            Cell x = new Cell(k);
                            if ((a[x.i, x.j] == 2) && (ct == 0))
                            {
                                ct++;
                                first = x;
                            }
                            else
                            if ((a[x.i, x.j] == 2) && (ct == 1))
                            {
                                second = x;
                                a[first.i, first.j] = 0;
                                drawEllipse(ellipseV[Helper.toIJ(first.i, first.j)], 2, yellowColor, 15, false);
                                for (int n = 1; n < 25; n++)
                                {
                                    Cell n_c = new Cell(n);
                                    if (Cell.neighbour(a, n_c, second) && (a[n_c.i, n_c.j] == 0))
                                    {
                                        a[n_c.i, n_c.j] = 2;
                                        drawEllipse(ellipseV[Helper.toIJ(n_c.i, n_c.j)], 2, blueColor, 35, false);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                else
                // if the game is in phase 1 check whether red will soon form a mill (two neighbour red stones)
                // and whether blue will form soon a mill;
                // completing blue mill has preference over blocking formation of red mill because after
                // completing a blue mill, it will remove a red stone that is inside a dangerous/ incomplete red mill)
                if (ballPlayer2 > 0)
                {
                    // check if red will soon create a mill
                    List <Cell> incompleteRedMill = Mill.checkDangerMill(a, 1);
                    // check if blue will create soon a mill
                    List <Cell> incompleteBlueMill = Mill.checkDangerMill(a, 2);
                    // try to build blue mill
                    Cell aimBlueMill = Mill.goMill(a);
                    // if no danger of red mill was detected and blue will not create soon a mill
                    if (incompleteRedMill.Count == 0 && incompleteBlueMill.Count == 0)
                    {
                        if (aimBlueMill != null)
                        {
                            a[aimBlueMill.i, aimBlueMill.j] = 2;
                            drawEllipse(ellipseV[Helper.toIJ(aimBlueMill.i, aimBlueMill.j)], 2, blueColor, 35, false);
                            move = Helper.toIJ(aimBlueMill.i, aimBlueMill.j);
                        }
                        else
                        {
                            i = 1; j = 2; index = 1;
                            while (a[i, j] != 0)
                            {
                                index = rand.Next(1, 25);
                                Cell c = new Cell(index);
                                i = c.i;
                                j = c.j;
                            }
                            a[i, j] = 2;
                            drawEllipse(ellipseV[index], 2, blueColor, 35, false);
                            move = index;
                        }
                    }
                    else
                    if ((incompleteRedMill.Count != 0) && (incompleteBlueMill.Count == 0))
                    {
                        // danger for red to create mill and blue will not create soon a mill
                        // => move blue stone to block red mill
                        a[incompleteRedMill[0].i, incompleteRedMill[0].j] = 2;
                        drawEllipse(ellipseV[Helper.toIJ(incompleteRedMill[0].i, incompleteRedMill[0].j)], 2, blueColor, 35, false);
                        move = Helper.toIJ(incompleteRedMill[0].i, incompleteRedMill[0].j);
                        checkMill(2, ellipseV[Helper.toIJ(incompleteRedMill[0].i, incompleteRedMill[0].j)]);
                    }
                    else
                    if ((incompleteRedMill.Count != 0) && (incompleteBlueMill.Count != 0))
                    {
                        // danger for red to create mill and blue will create soon a mill
                        // => complete blue mill
                        a[incompleteBlueMill[0].i, incompleteBlueMill[0].j] = 2;
                        drawEllipse(ellipseV[Helper.toIJ(incompleteBlueMill[0].i, incompleteBlueMill[0].j)], 2, blueColor, 35, false);
                        move = Helper.toIJ(incompleteBlueMill[0].i, incompleteBlueMill[0].j);
                    }
                    else
                    {
                        // no danger for red to create mill and blue will create soon a mill
                        a[incompleteBlueMill[0].i, incompleteBlueMill[0].j] = 2;
                        drawEllipse(ellipseV[Helper.toIJ(incompleteBlueMill[0].i, incompleteBlueMill[0].j)], 2, blueColor, 35, false);
                        move = Helper.toIJ(incompleteBlueMill[0].i, incompleteBlueMill[0].j);
                    }
                    ballPlayer2 -= 1;
                }
                else
                if (secondPhase)
                {
                    List <Cell> blueDangerousMills = Mill.checkDangerMill(a, 2);
                    List <Cell> redDangerousMills  = Mill.checkDangerMill(a, 1);
                    List <Mill> blueMills          = Mill.getMills(a, 2);
                    bool        blueMoved          = false;
                    // search through all the blue mills to get a free neighbour position where to move
                    // one of the blue stones from inside the mill (strategy for removing red stones => next move will close back the mill)
                    if (!blueMoved && (!breakMill))
                    {
                        HashSet <int> blueStones = new HashSet <int>();
                        foreach (Mill m in blueMills)
                        {
                            blueStones.Add(m.start);
                            blueStones.Add(m.middle);
                            blueStones.Add(m.stop);
                        }
                        if (blueStones.Count != 0)
                        {
                            foreach (int stone in blueStones)
                            {
                                if (!blueMoved)
                                {
                                    for (int k = 1; k < 25; k++)
                                    {
                                        Cell n_k = new Cell(k);
                                        Cell n_s = new Cell(stone);
                                        if (Cell.neighbour(a, n_k, n_s) && (a[n_k.i, n_k.j] == 0))
                                        {
                                            drawEllipse(ellipseV[Helper.toIJ(n_k.i, n_k.j)], 2, blueColor, 35, false);
                                            move = Helper.toIJ(n_k.i, n_k.j);
                                            drawEllipse(ellipseV[Helper.toIJ(n_s.i, n_s.j)], 2, yellowColor, 15, false);
                                            a[n_k.i, n_k.j] = 2;
                                            a[n_s.i, n_s.j] = 0;
                                            blueMoved       = true;
                                            breakMill       = true;
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                    // try to find an incomplete blue mill and if a blue stone is in the neighbourhood, move it to complete the mill
                    if (!blueMoved && breakMill)
                    {
                        HashSet <int> StonesInMills = new HashSet <int>();
                        foreach (Mill m in blueMills)
                        {
                            StonesInMills.Add(m.start);
                            StonesInMills.Add(m.middle);
                            StonesInMills.Add(m.stop);
                        }

                        foreach (Cell blue in blueDangerousMills)
                        {
                            for (int k = 1; k < 25; k++)
                            {
                                if (!blueMoved)
                                {
                                    Cell n = new Cell(k);
                                    if (Cell.neighbour(a, n, blue) && (a[n.i, n.j] == 2) && (!StonesInMills.Contains(k)))
                                    {
                                        drawEllipse(ellipseV[Helper.toIJ(blue.i, blue.j)], 2, blueColor, 35, false);
                                        move = Helper.toIJ(blue.i, blue.j);
                                        drawEllipse(ellipseV[Helper.toIJ(n.i, n.j)], 2, yellowColor, 15, false);
                                        a[n.i, n.j]       = 0;
                                        a[blue.i, blue.j] = 2;
                                        blueMoved         = true;
                                        breakMill         = false;
                                        break;                                                         // found a good position to move the blue stone, so stop searching
                                    }
                                }
                                else
                                {
                                    break;                                                     // break from the outer loop after finding a good postion to move
                                }
                            }
                        }
                    }
                    // if the precedent case didn't result in a position where to move the blue stone
                    // then search through all incomplete red mills for a position that has in
                    // the neighbourhood a blue stone and if one is found, move blue stone to block forming a red mill
                    if (!blueMoved)
                    {
                        foreach (Cell red in redDangerousMills)
                        {
                            for (int k = 1; k < 25; k++)
                            {
                                if (!blueMoved)
                                {
                                    Cell n = new Cell(k);
                                    if (Cell.neighbour(a, n, red) && (a[n.i, n.j] == 2))
                                    {
                                        drawEllipse(ellipseV[Helper.toIJ(red.i, red.j)], 2, blueColor, 35, false);
                                        move = Helper.toIJ(red.i, red.j);
                                        drawEllipse(ellipseV[Helper.toIJ(n.i, n.j)], 2, yellowColor, 15, false);
                                        a[n.i, n.j]     = 0;
                                        a[red.i, red.j] = 2;
                                        blueMoved       = true;
                                        break;
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }

                    while (!blueMoved)
                    {
                        index = rand.Next(1, 25);

                        for (int k = 1; k < 25; k++)
                        {
                            Cell n_k = new Cell(k);
                            Cell c   = new Cell(index);
                            if ((a[c.i, c.j] == 2) && (Cell.neighbour(a, n_k, c)) && (a[n_k.i, n_k.j] == 0))
                            {
                                a[n_k.i, n_k.j] = 2;
                                a[c.i, c.j]     = 0;
                                drawEllipse(ellipseV[k], 2, blueColor, 35, false);
                                drawEllipse(ellipseV[index], 2, yellowColor, 15, false);
                                move      = index;
                                blueMoved = true;
                            }
                        }
                    }
                }

                Helper.printBoard(a);
                blueMill = false;
                checkMill(2, ellipseV[move]);
                oldBlueMills = bMills.Count;
                bMills       = Mill.getMills(a, 2);
                newBlueMills = bMills.Count;
                if (oldBlueMills - newBlueMills == 1)
                {
                    removedRedStone--;                      // blue moved so that one mill is broken
                }
                if (newBlueMills != removedRedStone)
                {
                    Cell red = Mill.removeRedStone(a);
                    warning.SetResourceReference(TextBox.TextProperty, "redStoneRemoved");
                    warning.Visibility = System.Windows.Visibility.Visible;
                    a[red.i, red.j]    = 0;
                    Helper.printBoard(a);
                    drawEllipse(ellipseV[Helper.toIJ(red.i, red.j)], 1, yellowColor, 15, false);
                    removedRedStone++;
                }
            };
        }
示例#5
0
        private void ellipse_MouseDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled           = true;
            selectedNodeEllipse = (Ellipse)sender;
            Cell currentCell = new Cell((int)selectedNodeEllipse.Tag);

            checkMill(2, selectedNodeEllipse);
            // if blue reached phase 3 having only 3 blue stones left, move to form mills or block red mills
            if ((Cell.count(a, 2) == 3) && (secondPhase))
            {
                thirdPhaseBlue = true;
            }
            if ((Cell.count(a, 1) == 3) && (secondPhase))
            {
                thirdPhaseRed = true;
            }
            // blue player lost
            if (secondPhase && ((Cell.count(a, 2) < 3) || (!Mill.playerCanMove(a, 2))))
            {
                gameOver("redWon");
            }
            else
            // red player lost
            if (secondPhase && ((Cell.count(a, 1) < 3) || (!Mill.playerCanMove(a, 1))))
            {
                gameOver("blueWon");
            }
            else
            // if the game reached 70 moves (sum of both players moves) and no player won, it is a draw
            if (countMoves == 70)
            {
                gameOver("draw");
            }
            else
            // if red formed mill and user clicked on blue stone then remove the blue stone
            if (redMill && (a[currentCell.i, currentCell.j] == 2))
            {
                // remove blue stone that is not inside a mill or if all the blue stones are inside mills, allow to remove from mill
                if ((!blueMill) || (blueMill && Mill.StonesOnlyInMills(a, 2)))
                {
                    drawEllipse(selectedNodeEllipse, 2, yellowColor, 15, false);
                    redMill          = false;
                    removedBlueStone = true;
                    moveBlue();
                    a[currentCell.i, currentCell.j] = 0;
                    warning.SetResourceReference(TextBox.TextProperty, "blueStoneRemoved");
                    warning.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    warning.SetResourceReference(TextBox.TextProperty, "stoneNotInMill");
                    warning.Visibility = System.Windows.Visibility.Visible;
                }
            }
            else


            if (!redMill)
            {
                removedBlueStone = false;
                if (secondPhase && (secondClick == false))
                {
                    if (a[currentCell.i, currentCell.j] == 1)
                    {
                        secondClick                         = true;
                        previousEllipse                     = selectedNodeEllipse;
                        selectedNodeEllipse.Stroke          = Brushes.Yellow;
                        selectedNodeEllipse.StrokeThickness = 2;
                    }
                }
                else
                if (secondPhase && secondClick)
                {
                    Cell previousCell = new Cell((int)previousEllipse.Tag);
                    if (currentCell.Equals(previousCell))
                    {
                        selectedNodeEllipse.Stroke = Brushes.Transparent;
                        warning.Text       = "";
                        warning.Visibility = System.Windows.Visibility.Hidden;
                        secondClick        = false;
                    }
                    else
                    if ((a[currentCell.i, currentCell.j] == 0 && Cell.neighbour(a, previousCell, currentCell) && (!thirdPhaseRed)) ||
                        (a[currentCell.i, currentCell.j] == 0 && thirdPhaseRed))
                    {
                        a[previousCell.i, previousCell.j] = 0;
                        warning.Text       = "";
                        warning.Visibility = System.Windows.Visibility.Hidden;
                        drawEllipse(previousEllipse, 1, yellowColor, 15, false);
                        moveRed(selectedNodeEllipse);
                        secondClick = false;
                    }
                    else
                    if (a[currentCell.i, currentCell.j] != 0 || (!Cell.neighbour(a, previousCell, currentCell)) &&
                        (!currentCell.Equals(previousCell)) && (!thirdPhaseRed))
                    {
                        warning.SetResourceReference(TextBox.TextProperty, "invalidMove");
                        warning.Visibility = System.Windows.Visibility.Visible;
                        // previousEllipse = selectedNodeEllipse;
                    }
                }
                if (!secondPhase)
                {
                    moveRed(selectedNodeEllipse);
                }
            }
        }
示例#6
0
        public static Cell removeRedStone(int[,] a)
        {
            // returns what red stone should be removed in case blue formed a mill
            // check if red could create soon a mill (two red stones in vecinity)
            // else remove random red stone
            List <Cell>   redDangerousMills = Mill.checkDangerMill(a, 1);
            List <Mill>   redMills          = Mill.getMills(a, 1);
            HashSet <int> redStonesInMills  = new HashSet <int>();
            int           stone             = 0;

            foreach (Mill m in redMills)
            {
                redStonesInMills.Add(m.start);
                redStonesInMills.Add(m.middle);
                redStonesInMills.Add(m.stop);
                stone = m.start;
            }
            foreach (int s in redStonesInMills)
            {
                Console.Out.WriteLine(s + " ");
            }
            if (redDangerousMills.Count != 0)
            {
                // remove red stone that is inside an incomplete mill
                foreach (Cell incomplete in redDangerousMills)
                {
                    // find its neighbours that could form a mill
                    for (int i = 1; i < 25; i++)
                    {
                        for (int j = i + 1; j < 25; j++)
                        {
                            int k       = Helper.toIJ(incomplete.i, incomplete.j);
                            var numbers = new int[] { i, j, k };
                            Array.Sort(numbers);
                            Cell x = new Cell(numbers[0]);
                            Cell y = new Cell(numbers[1]);
                            Cell z = new Cell(numbers[2]);
                            // check if the stones are different, neighbours and on the same row or column
                            if ((k != i) && (k != j) && (Cell.neighbour(a, x, y)) && (Cell.neighbour(a, y, z)) &&
                                Cell.consecutive(x, y, z))
                            {
                                if (a[x.i, x.j] == 1 && (!redStonesInMills.Contains(numbers[0])))
                                {
                                    return(x);
                                }
                                else
                                if (a[y.i, y.j] == 1 && (!redStonesInMills.Contains(numbers[1])))
                                {
                                    return(y);
                                }
                                else
                                if (a[z.i, z.j] == 1 && (!redStonesInMills.Contains(numbers[2])))
                                {
                                    return(z);
                                }
                            }
                        }
                    }
                }
                // remove red stone that is in the vecinity of an incomplete mill, regardless of row or column
                foreach (Cell incomplete in redDangerousMills)
                {
                    for (int k = 1; k < 25; k++)
                    {
                        Cell c = new Cell(k);
                        if (Cell.neighbour(a, incomplete, c) && (a[c.i, c.j] == 1) &&
                            (!redStonesInMills.Contains(k)))
                        {
                            return(c);
                        }
                    }
                }
            }
            for (int index = 1; index < 25; index++)
            {
                Cell w = new Cell(index);
                if ((a[w.i, w.j] == 1) && (!redStonesInMills.Contains(index)))
                {
                    return(w);
                }
            }
            return(new Cell(stone));
        }