Esempio n. 1
0
        public static Move[] GetAllMovedByColor(Square[,] Board, CheckerColour color)
        {
            List <Move> result = new List <Move>();

            for (int x = 0; x < BoardPanel.sizeCheckers; x++)
            {
                for (int y = 0; y < BoardPanel.sizeCheckers; y++)
                {
                    if (Board[y, x].Colour == color)
                    {
                        foreach (Move move in GetOpenSquares(Board, new Point(x, y)))
                        {
                            result.Add(move);
                        }
                    }
                }
            }

            Move[] captured = GetAllMoveCapturedByColor(Board, color);
            if (captured.Any())
            {
                return(captured);
            }

            return(result.ToArray());
        }
Esempio n. 2
0
        private void CalculateChildMoves(int recursionLevel, Tree <Move> branch, Move move, Square[,] vBoard)
        {
            if (recursionLevel >= AI_MAXPLYLEVEL)
            {
                return;
            }

            CheckerColour moveColour = vBoard[move.Source.Y, move.Source.X].Colour;

            //Move the checker
            vBoard = ExecuteVirtualMove(move, vBoard);

            //Calculate the other player's moves
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    if (vBoard[i, j].Colour != moveColour)
                    {
                        foreach (Move otherPlayerMove in Utils.GetOpenSquares(vBoard, new Point(j, i)))
                        {
                            if (vBoard[i, j].Colour != CheckerColour.Empty)
                            {
                                CalculateChildMoves(
                                    ++recursionLevel,
                                    branch.AddChild(otherPlayerMove),
                                    otherPlayerMove,
                                    DeepCopy(vBoard));
                            }
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        private void AdvanceTurn()
        {
            _currentTurn = _currentTurn == CheckerColour.Red ? CheckerColour.Black : CheckerColour.Red;

            // check victory of one side
            int redCount   = 0;
            int blackCount = 0;

            for (int i = 0; i < sizeCheckers; i++)
            {
                for (int j = 0; j < sizeCheckers; j++)
                {
                    if (_board[i, j].Colour == CheckerColour.Red)
                    {
                        redCount++;
                    }
                    if (_board[i, j].Colour == CheckerColour.Black)
                    {
                        blackCount++;
                    }
                }
            }

            // If a winner is present
            if (blackCount == 0 || redCount == 0)
            {
                String side = blackCount == 0 ? "rouges" : "noirs";
                // display the message and ask the user want to replay
                if (MessageBox.Show(@"Les " + side + @" ont gagnés voulez-vous rejouer ?", @"Victoire des " + side,
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    init_game();
                }
                else
                {
                    Application.Exit();
                }
            }


            // Let the AI play
            if (_ai != null && _ai.Colour == _currentTurn)
            {
                Move aiMove = _ai.Process(_board);
                MoveChecker(aiMove);
            }

            if (_ai2 != null && _ai2.Colour == _currentTurn)
            {
                Move aiMove = _ai2.Process(_board);
                MoveChecker(aiMove);
            }
        }
Esempio n. 4
0
        private void AdvanceTurn()
        {
            if (currentTurn == CheckerColour.Red)
            {
                currentTurn = CheckerColour.Black;
            }
            else
            {
                currentTurn = CheckerColour.Red;
            }

            if (AI != null && AI.Colour == currentTurn)
            {
                Move aiMove = AI.Process(Board);
                MoveChecker(aiMove);
            }
        }
Esempio n. 5
0
        private static Move[] GetOpenSquares(Square[,] board, Point checker, Move lastMove, List <Point> priorPositions)
        {
            if (priorPositions == null)
            {
                priorPositions = new List <Point> {
                    checker
                };
            }

            List <Move> openSquares = new List <Move>();

            //Top Left
            if (board[priorPositions[0].Y, priorPositions[0].X].Colour != CheckerColour.Red || board[priorPositions[0].Y, priorPositions[0].X].King)        //Stop regular red pieces from moving backwards
            {
                if (IsValidPoint(checker.X - 1, checker.Y - 1))
                {
                    if (board[checker.Y - 1, checker.X - 1].Colour == CheckerColour.Empty && lastMove.Destination.X == -1)  //Allow immediate empty spaces if it's the first jump
                    {
                        openSquares.Add(new Move(priorPositions[0], checker.X - 1, checker.Y - 1));
                    }
                    //Check for a capturable piece
                    else if (IsValidPoint(checker.X - 2, checker.Y - 2) &&
                             ((checker.X - 2) != lastMove.Destination.X || (checker.Y - 2) != lastMove.Destination.Y) &&
                             ((checker.X - 2) != priorPositions[0].X || (checker.Y - 2) != priorPositions[0].Y) &&
                             board[checker.Y - 1, checker.X - 1].Colour != board[checker.Y, checker.X].Colour &&
                             board[checker.Y - 2, checker.X - 2].Colour == CheckerColour.Empty)
                    {
                        Point newDest = new Point(checker.X - 2, checker.Y - 2);
                        if (!priorPositions.Contains(newDest))
                        {
                            Move move = new Move(priorPositions[0], newDest);
                            move.Captures.Add(new Point(checker.X - 1, checker.Y - 1));
                            move.Captures.AddRange(lastMove.Captures);
                            openSquares.Add(move);

                            priorPositions.Add(newDest);

                            //Use recursion to find multiple captures
                            openSquares.AddRange(GetOpenSquares(board, new Point(checker.X - 2, checker.Y - 2), move, priorPositions));
                        }
                    }
                }
            }

            //Top Right
            if (board[priorPositions[0].Y, priorPositions[0].X].Colour != CheckerColour.Red || board[priorPositions[0].Y, priorPositions[0].X].King)
            {
                if (IsValidPoint(checker.X + 1, checker.Y - 1))
                {
                    if (board[checker.Y - 1, checker.X + 1].Colour == CheckerColour.Empty && lastMove.Destination.X == -1)
                    {
                        openSquares.Add(new Move(priorPositions[0], checker.X + 1, checker.Y - 1));
                    }
                    //Check for a capturable piece
                    else if (IsValidPoint(checker.X + 2, checker.Y - 2) &&
                             ((checker.X + 2) != lastMove.Destination.X || (checker.Y - 2) != lastMove.Destination.Y) &&
                             ((checker.X + 2) != priorPositions[0].X || (checker.Y - 2) != priorPositions[0].Y) &&
                             board[checker.Y - 1, checker.X + 1].Colour != board[checker.Y, checker.X].Colour &&
                             board[checker.Y - 2, checker.X + 2].Colour == CheckerColour.Empty)
                    {
                        Point newDest = new Point(checker.X + 2, checker.Y - 2);
                        if (!priorPositions.Contains(new Point(checker.X + 2, checker.Y - 2)))
                        {
                            Move move = new Move(priorPositions[0], newDest);
                            move.Captures.Add(new Point(checker.X + 1, checker.Y - 1));
                            move.Captures.AddRange(lastMove.Captures);
                            openSquares.Add(move);

                            priorPositions.Add(newDest);

                            //Use recursion to find multiple captures
                            openSquares.AddRange(GetOpenSquares(board, new Point(checker.X + 2, checker.Y - 2), move, priorPositions));
                        }
                    }
                }
            }

            //Bottom Left
            if (board[priorPositions[0].Y, priorPositions[0].X].Colour != CheckerColour.Black || board[priorPositions[0].Y, priorPositions[0].X].King)
            {
                if (IsValidPoint(checker.X - 1, checker.Y + 1))
                {
                    if (board[checker.Y + 1, checker.X - 1].Colour == CheckerColour.Empty && lastMove.Destination.X == -1)
                    {
                        openSquares.Add(new Move(priorPositions[0], checker.X - 1, checker.Y + 1));
                    }
                    //Check for a capturable piece
                    else if (IsValidPoint(checker.X - 2, checker.Y + 2) &&
                             ((checker.X - 2) != lastMove.Destination.X || (checker.Y + 2) != lastMove.Destination.Y) &&
                             ((checker.X - 2) != priorPositions[0].X || (checker.Y + 2) != priorPositions[0].Y) &&
                             board[checker.Y + 1, checker.X - 1].Colour != board[checker.Y, checker.X].Colour &&
                             board[checker.Y + 2, checker.X - 2].Colour == CheckerColour.Empty)
                    {
                        Point newDest = new Point(checker.X - 2, checker.Y + 2);
                        if (!priorPositions.Contains(newDest))
                        {
                            Move move = new Move(priorPositions[0], newDest);
                            move.Captures.Add(new Point(checker.X - 1, checker.Y + 1));
                            move.Captures.AddRange(lastMove.Captures);
                            openSquares.Add(move);

                            priorPositions.Add(newDest);

                            //Use recursion to find multiple captures
                            openSquares.AddRange(GetOpenSquares(board, new Point(checker.X - 2, checker.Y + 2), move, priorPositions));
                        }
                    }
                }
            }

            //Bottom Right
            if (board[priorPositions[0].Y, priorPositions[0].X].Colour != CheckerColour.Black || board[priorPositions[0].Y, priorPositions[0].X].King)
            {
                if (IsValidPoint(checker.X + 1, checker.Y + 1))
                {
                    if (board[checker.Y + 1, checker.X + 1].Colour == CheckerColour.Empty && lastMove.Destination.X == -1)
                    {
                        openSquares.Add(new Move(priorPositions[0], checker.X + 1, checker.Y + 1));
                    }
                    //Check for a capturable piece
                    else if (IsValidPoint(checker.X + 2, checker.Y + 2) &&
                             ((checker.X + 2) != lastMove.Destination.X || (checker.Y + 2) != lastMove.Destination.Y) &&
                             ((checker.X + 2) != priorPositions[0].X || (checker.Y + 2) != priorPositions[0].Y) &&
                             board[checker.Y + 1, checker.X + 1].Colour != board[checker.Y, checker.X].Colour &&
                             board[checker.Y + 2, checker.X + 2].Colour == CheckerColour.Empty)
                    {
                        Point newDest = new Point(checker.X + 2, checker.Y + 2);
                        if (!priorPositions.Contains(newDest))
                        {
                            Move move = new Move(priorPositions[0], newDest);
                            move.Captures.Add(new Point(checker.X + 1, checker.Y + 1));
                            move.Captures.AddRange(lastMove.Captures);
                            openSquares.Add(move);

                            priorPositions.Add(newDest);

                            //Use recursion to find multiple captures
                            openSquares.AddRange(GetOpenSquares(board, new Point(checker.X + 2, checker.Y + 2), move, priorPositions));
                        }
                    }
                }
            }

            List <Move> capturesMoves = new List <Move>();

            // The color of the player
            CheckerColour playerColor = board[checker.Y, checker.X].Colour;

            // The possibility for the king to move
            int[,] possibility = { { 1, 1 }, { 1, -1 }, { -1, 1 }, { -1, -1 } };
            ////King move
            if ((board[checker.Y, checker.X].King))
            {
                for (int i = 0; i < 4; i++)
                {
                    int testX = checker.X + possibility[i, 0];
                    int testY = checker.Y + possibility[i, 1];

                    List <Move> emptyMove    = new List <Move>();
                    List <Move> capturedMove = new List <Move>();

                    while (IsValidPoint(testY, testX))
                    {
                        if (board[testY, testX].Colour == CheckerColour.Empty)
                        {
                            Move move = new Move(new Point(checker.X, checker.Y), new Point(testX, testY));
                            emptyMove.Add(move);
                        }
                        else
                        {
                            // Position of the king
                            int furtherX = testX + possibility[i, 0];
                            int furtherY = testY + possibility[i, 1];

                            // Check if the point to catch is a ennemy
                            // And if it is
                            if (IsValidPoint(furtherX, furtherY) && board[testY, testX].Colour != playerColor && board[furtherY, furtherX].Colour == CheckerColour.Empty)
                            {
                                emptyMove.Clear();
                                Move move = new Move(new Point(checker.X, checker.Y), new Point(furtherX, furtherY));
                                move.Captures.Add(new Point(testX, testY));
                                move.Captures.AddRange(lastMove.Captures);

                                // Add the position
                                openSquares.Add(move);

                                Square[,] copy = board.Clone() as Square[, ];

                                Square tmp = new Square {
                                    Colour = CheckerColour.Empty
                                };
                                if (copy != null)
                                {
                                    copy[checker.Y, checker.X] = tmp;
                                    copy[testY, testX]         = tmp;

                                    copy[furtherY, furtherX] = board[checker.Y, checker.X];
                                }


                                //Use recursion to find multiple captures
                                capturesMoves.AddRange(GetOpenSquares(board, new Point(furtherX, furtherY), move, priorPositions));

                                break;
                            }
                        }

                        // Iterate through all the possibility
                        testX += possibility[i, 0];
                        testY += possibility[i, 1];
                    }


                    openSquares.AddRange(emptyMove.Any() ? emptyMove : capturedMove);
                }
            }


            // Check Captures
            foreach (Move move in openSquares)
            {
                if (move.Captures.Any())
                {
                    capturesMoves.Add(move);
                }
            }

            if (capturesMoves.Any())
            {
                return(capturesMoves.ToArray());
            }
            return(openSquares.ToArray());
        }
Esempio n. 6
0
        private int ScoreByChild(Square[,] board, Move move, CheckerColour colour_to_test)
        {
            int count          = 0;
            int count_opponent = 0;

            CheckerColour opponent_color = colour_to_test == CheckerColour.Black ? CheckerColour.Red : CheckerColour.Black;


            for (int i = 0; i < BoardPanel.sizeCheckers; i++)
            {
                for (int j = 0; j < BoardPanel.sizeCheckers; j++)
                {
                    if (board[j, i].Colour == colour)
                    {
                        count++;
                    }
                    else
                    if (board[j, i].Colour == opponent_color)
                    {
                        count_opponent++;
                    }
                }
            }
            if (count == 0)
            {
                return(-999);
            }
            if (count_opponent == 0)
            {
                return(999);
            }

            // Avoid to pass the object by reference
            Square[,] test_board = DeepCopy(board);

            // Make the move on the saved board
            ExecuteVirtualMove(move, test_board);

            // We get all the possibilities for this state
            Move[] possibilities = Utils.GetAllMovedByColor(board, colour_to_test);

            if (possibilities.Count() == 0)
            {
                return(0);
            }

            int score = ScoreMove(move, board, colour_to_test);

            // We limit our search at our known states
            if (memory.ContainsKey(board))
            {
                List <Move> played_moved = memory[board];
                // We have not enough information on the state we must try all the possibilites
                if (played_moved.Count < possibilities.Length)
                {
                    int indexToGet = played_moved.Any() ? played_moved.Count : 0;
                    played_moved.Add(possibilities[indexToGet]);
                    memory.Remove(board);
                    memory.Add(board, played_moved);

                    Square[,] test_board_bis = DeepCopy(test_board);
                    ExecuteVirtualMove(possibilities[indexToGet], test_board_bis);
                    score += ScoreByChild(test_board, possibilities[indexToGet], opponent_color);
                }
                else
                {
                    foreach (Move test_move in played_moved)
                    {
                        Square[,] test_board_bis = DeepCopy(test_board);
                        ExecuteVirtualMove(test_move, test_board_bis);
                        score += ScoreByChild(test_board, test_move, opponent_color);
                    }
                }

                return(score);
            }
            else
            {
                List <Move> to_play = new List <Move>();
                to_play.Add(possibilities[0]);
                memory.Add(board, to_play);

                Square[,] test_board_bis = DeepCopy(test_board);
                ExecuteVirtualMove(possibilities[0], test_board_bis);
                return(ScoreByChild(test_board, possibilities[0], opponent_color));
            }
        }
Esempio n. 7
0
        private int ScoreMove(Move move, Square[,] board, CheckerColour test_color)
        {
            int score = 0;

            int count_opponent = 0;
            int count_piece    = 0;

            CheckerColour opponent_color = test_color == CheckerColour.Black ? CheckerColour.Red : CheckerColour.Black;

            //Offensive traits
            score += move.Captures.Count * WEIGHT_CAPTUREPIECE;

            if (move.Captures.Count == 2)
            {
                score += WEIGHT_CAPTUREDOUBLE;
            }
            if (move.Captures.Count > 2)
            {
                score += WEIGHT_CAPTUREMULTI;
            }

            //Check King Captures
            foreach (Point point in move.Captures)
            {
                if (board[point.Y, point.X].King)
                {
                    score += WEIGHT_CAPTUREKING;
                }
            }

            //Check if piece is at risk
            for (int i = 0; i < BoardPanel.sizeCheckers; i++)
            {
                for (int j = 0; j < BoardPanel.sizeCheckers; j++)
                {
                    if (board[j, i].Colour == test_color)
                    {
                        count_piece++;
                        foreach (Move opponentMove in Utils.GetAllMovedByColor(board, opponent_color))
                        {
                            if (opponentMove.Captures.Contains(move.Source))
                            {
                                if (board[move.Source.Y, move.Source.X].King)
                                {
                                    score += WEIGHT_KINGATRISK;
                                }
                                else
                                {
                                    score += WEIGHT_ATRISK;
                                }
                            }
                        }
                    }

                    if (board[j, i].Colour == opponent_color)
                    {
                        count_opponent++;
                    }
                }
            }

            if (count_opponent == 0)
            {
                score += 999;
            }
            if (count_piece == 0)
            {
                score -= 999;
            }


            //Subtract score if we are evaluating an opponent's piece
            if (board[move.Source.Y, move.Source.X].Colour != test_color)
            {
                score *= -1;
            }

            Console.WriteLine("Score : " + count_piece + " opponent " + count_opponent);

            return(score);
        }