Exemplo n.º 1
0
        /// <summary>
        /// Evalution function which counts number of pieces per player and calculates if player can be captured
        /// </summary>
        /// <param name="board"></param>
        /// <param name="player"></param>
        /// <returns></returns>
        public int Evaluate(Board board, Player player)
        {
            const int kingConstant = 120;
            const int soldierConstant = 100;
            int score = 0;
            int blackCaptures = 0;
            int whiteCaptures = 0;

            int numWhiteKings = board.NumberOfWhiteKings;
            int numBlackKings = board.NumberOfBlackKings;
            int numOfWhiteSold = board.NumberOfWhitePieces;
            int numOfBlackSold = board.NumberOfBlackPieces;

            int numOfSoldOnBoard = numWhiteKings + numBlackKings + numOfWhiteSold + numOfBlackSold;
            if (numOfSoldOnBoard <= 7)
                return Evaluate2(board, player);

            int blackScore = (numOfBlackSold*soldierConstant) + (numBlackKings*kingConstant);
            int whiteScore = (numOfWhiteSold*soldierConstant) + (numWhiteKings*kingConstant);
            score += ((blackScore - whiteScore)*200)/(blackScore + whiteScore);
            score += blackScore - whiteScore;

            for (int i = 1; i <= 32; i++)
            {
                if (board.GetPlayer(board[i]) == Player.Black)
                {
                    blackCaptures += (CanCapture(board, board[i], Player.Black)/(numOfBlackSold + numBlackKings))*30;
                }
                else if (board.GetPlayer(board[i]) == Player.White)
                {
                    whiteCaptures += (CanCapture(board, board[i], Player.White)/(numOfWhiteSold + numWhiteKings))*30;
                }
            }
            score += (blackCaptures - whiteCaptures);
            return (player == Player.Black) ? score : -score;
        }
Exemplo n.º 2
0
        /// <summary>
        /// returns the number of ways in which soldier on coord can be captured;
        /// </summary>
        /// <param name="board"></param>
        /// <param name="coord"></param>
        /// <param name="player"></param>
        /// <returns></returns>
        public int CanBeCaptured(Board board, Coordinate coord, Player player)
        {
            int num = 0;
            Rules rule = new Rules();
            IList<Coordinate> optionalCoords = rule.OptionalMoves(board, coord, player);
            IList<Coordinate> coordsInDir = rule.GetMovesInDirection(board, coord, player);

            //collect all coords behind coord
            IList<Coordinate> coordsfrombehind = optionalCoords.Where(opCor => !coordsInDir.Contains(opCor)).ToList();
            foreach (var cid in coordsInDir)
            {
                if (board.GetPlayer(board[cid.X, cid.Y]) == board.GetOpponent(player) &&
                    rule.CoordsToCaptureAndDest(board, cid, coord, board.GetOpponent(player)).Count > 0)
                    num++;
            }

            foreach (var cfb in coordsfrombehind)
            {
                if (board.GetPlayer(board[cfb.X, cfb.Y]) == board.GetOpponent(player) && board.IsKing(coord) &&
                    rule.CoordsToCaptureAndDest(board, cfb, coord, board.GetOpponent(player)).Count > 0)
                    num++;
            }
            return num;
        }
Exemplo n.º 3
0
        /// <summary>
        /// Pc VS Pc
        /// </summary>
        /// <returns> </returns>
        public void StartGameWithPc(Board board)
        {
            int countmovesforDraw = 0;
            var rule = new Rules();
            var print = new PrintBoardState();
            int depth;
            Coordinate srcCoord = new Coordinate();
            Coordinate destCoord = new Coordinate();

            //Create the file engine who Read\write to file all moves
            FileEngine file = new FileEngine();

            //define that file will be created in the root folder under the name sync.txt
            string path = "sync.txt";

            //define colors.
            Console.WriteLine("Opponent color is white? [Yes/No]");
            Opponet:
            string opponentColor = Console.ReadLine();
            if (!(opponentColor == "Yes" || opponentColor == "yes" || opponentColor == "No" || opponentColor == "no"))
            {
                Console.WriteLine("Invalid input,please try again");
                goto Opponet;
            }
            Player oppColor = (opponentColor == "Yes" || opponentColor == "yes") ? Player.White : Player.Black;
            Player pcColor = oppColor == Player.White ? Player.Black : Player.White;

            //define who starts.
            Console.WriteLine("Opponent Starts? [Yes/No]");
            Start:
            string opponentStarts = Console.ReadLine();
            if (
                !(opponentStarts == "Yes" || opponentStarts == "yes" || opponentStarts == "No" || opponentStarts == "no"))
            {
                Console.WriteLine("Invalid input,please try again");
                goto Start;
            }
            if (opponentStarts == "Yes" || opponentStarts == "yes")
                goto OppTurn;
            goto MyTurn;

            //oppoenent tuen
            OppTurn:
            try
            {
                //open file in path with read permision and no sharing
                using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None))
                {
                    ShowPlayerChange(oppColor);
                    Player color = Player.None;
                    bool capMove = false;
                    IList<Coordinate> oppMove = new List<Coordinate>();
                    //read moves and captures (if exists)
                    while (oppMove.Count == 0)
                    {
                        oppMove = file.ReadFromFile(stream, board, path, out color);
                    }
                    //Source
                    srcCoord = oppMove.First();
                    oppMove.RemoveAt(0);
                    //Destination
                    destCoord = oppMove[0];
                    oppMove.RemoveAt(0);
                    //Captures list
                    var capturesOppdid = oppMove;
                    //if move is not oppoent move or source piece is not opponenet color return to read file
                    if ((color != oppColor) || (board.GetPlayer(srcCoord) != oppColor))
                    {
                        goto OppTurn;
                    }

                    //Find captures
                    IDictionary<IList<Coordinate>, IList<Coordinate>> capturesAvailable = rule.FindCaptures(board,
                                                                                                            oppColor);
                    if (capturesAvailable.Count > 0)
                    {
                        var boolean = rule.MapContainsCoordsOfCaptures(capturesAvailable, srcCoord, destCoord,
                                                                       capturesOppdid);
                        if (!boolean)
                        {
                            Console.WriteLine("You must capture maximum opponent soldiers on board");
                            goto OppTurn;
                        }
                        else
                        {
                            foreach (var coordinate in capturesOppdid)
                            {
                                board[coordinate.X, coordinate.Y].Status = Piece.None;
                                board.UpdateCapturedSoldiers(coordinate, pcColor);
                                capMove = true;
                            }
                        }
                    }
                    if (capMove || rule.IsValidMove(board, srcCoord, destCoord, oppColor))
                    {
                        board.UpdateBoard(srcCoord, destCoord);
                        rule.IsBecameAKing(board, board[destCoord.X, destCoord.Y]);
                        print.DrawBoard(board);
                    }
                    else
                    {
                        Console.WriteLine("This is not a valid move, please enter again");
                        goto OppTurn;
                    }

                    //check if game has been determined
                    GameState game = GetGameState(oppColor, board);
                    if (GameState.Draw ==
                        CheckDraw(board, board[destCoord.X, destCoord.Y], capMove, ref countmovesforDraw))
                    {
                        Console.WriteLine("Draw");
                        return;
                    }
                    if (game == GameState.Lost)
                    {
                        Console.WriteLine("{0} Lost the game and {1} won", oppColor.ToString(), pcColor.ToString());
                        return;
                    }
                    if (game == GameState.Won)
                    {
                        Console.WriteLine("{0} Won", oppColor.ToString());
                        return;
                    }
                }
            }
            catch (Exception)
            {
                goto OppTurn;
            }

            //local turn
            MyTurn:
            try
            {
                using (var stream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
                {
                    ShowPlayerChange(pcColor);
                    var alphaBeta = new Alphabeta();
                    Board temp = new Board();
                    IList<Coordinate> tempCaptures = new List<Coordinate>();
                    depth = rule.DefineDepth(board);
                    alphaBeta.AlphaBeta(board, depth, Int32.MinValue, Int32.MaxValue, pcColor, true, ref srcCoord,
                                        ref destCoord,
                                        ref temp, ref tempCaptures);
                    if ((rule.InBounds(board, srcCoord.X, srcCoord.Y)) &&
                        (rule.InBounds(board, destCoord.X, destCoord.Y)))
                    {
                        board = temp.Copy();
                        print.DrawBoard(board);
                    }

                    //write move to file
                    file.WriteToFile(stream, srcCoord, destCoord, tempCaptures, path, pcColor);

                    //check if game has been determined
                    bool pcCaptured = tempCaptures.Count > 0;
                    GameState game = GetGameState(oppColor, board);
                    if (GameState.Draw ==
                        CheckDraw(board, board[destCoord.X, destCoord.Y], pcCaptured, ref countmovesforDraw))
                    {
                        Console.WriteLine("Draw");
                        return;
                    }
                    if (game == GameState.Lost)
                    {
                        Console.WriteLine("{0} Lost the game and {1} won", oppColor.ToString(), pcColor.ToString());
                        return;
                    }
                    if (game == GameState.Won)
                    {
                        Console.WriteLine("{0} Won", oppColor.ToString());
                        return;
                    }
                }
                Thread.Sleep(5000);
                goto OppTurn;
            }
            catch (Exception)
            {
                goto MyTurn;
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Human VS PC
        /// </summary>
        /// <param name="board"></param>
        public void StartGameWithHuman(Board board)
        {
            int countmovesforDraw = 0;
            var humanColor = Player.None;
            var pcColor = Player.None;
            bool firstTurn = true;
            var rule = new Rules();
            var print = new PrintBoardState();
            while (true)
            {
                //first turn is always the human's
                Console.WriteLine("Your turn, please enter a move in format 'from cell number' 'to cell number'");
                HumanTurn:
                bool capMove = false;
                var input = Console.ReadLine();
                IList<Coordinate> coords = ParseStrToCoords(input, board);
                //If there is no input
                if (coords == null)
                {
                    Console.WriteLine("Wrong Input, please try again");
                    goto HumanTurn;
                }

                var srcCoord = coords.First();
                var destCoord = coords.Last();
                if (firstTurn)
                {
                    humanColor = board.GetPlayer(srcCoord);
                    pcColor = board.GetOpponent(humanColor);
                    firstTurn = false;
                }
                    //if select coordinate is not your coordinate then show error message
                else if (humanColor != board.GetPlayer(srcCoord))
                {
                    Console.WriteLine(
                        "This is not your piece , please enter cell number which allocated with your piece color");
                    goto HumanTurn;
                }

                //Fins captures
                IDictionary<IList<Coordinate>, IList<Coordinate>> capturesAvailable = rule.FindCaptures(board,
                                                                                                        humanColor);
                //if there are any captures
                if (capturesAvailable.Count > 0)
                {
                    //check if they are contained in captured dictionary by looking on source and destination
                    IList<Coordinate> captures = rule.MapContainsCoords(capturesAvailable, srcCoord, destCoord);
                    //id they are not contained show error message
                    if (captures.Count == 0)
                    {
                        Console.WriteLine("You must capture maximum opponent soldiers on board");
                        goto HumanTurn;
                    }
                    else
                    {
                        //if there are captures and source and destination are corrrect, update board with move and captures
                        foreach (var coordinate in captures)
                        {
                            board[coordinate.X, coordinate.Y].Status = Piece.None;
                            board.UpdateCapturedSoldiers(coordinate, pcColor);
                            capMove = true;
                        }
                    }
                }
                //update board
                if (capMove || rule.IsValidMove(board, srcCoord, destCoord, humanColor))
                {
                    board.UpdateBoard(srcCoord, destCoord);
                    rule.IsBecameAKing(board, board[destCoord.X, destCoord.Y]);
                    print.DrawBoard(board);
                }
                else
                {
                    Console.WriteLine("This is not a valid move, please enter again");
                    goto HumanTurn;
                }

                //check if game is finish by checking if players draw,lost or won
                GameState game = GetGameState(humanColor, board);
                if (GameState.Draw == CheckDraw(board, board[destCoord.X, destCoord.Y], capMove, ref countmovesforDraw))
                {
                    Console.WriteLine("Draw");
                    break;
                }
                if (game == GameState.Lost)
                {
                    Console.WriteLine("{0} Lost the game and {1} won", humanColor.ToString(), pcColor.ToString());
                    break;
                }
                if (game == GameState.Won)
                {
                    Console.WriteLine("{0} Won", humanColor.ToString());
                    break;
                }

                //switch to opponent (PC)
                ShowPlayerChange(pcColor);
                var alphaBeta = new Alphabeta();
                Board temp = new Board();
                IList<Coordinate> tempCaptures = new List<Coordinate>();
                //Define depth
                int depth = rule.DefineDepth(board);
                //Calling alpha-beta algorithm which return the best move in addition, return source,destination coordinates and a list of captures
                alphaBeta.AlphaBeta(board, depth, Int32.MinValue, Int32.MaxValue, pcColor, true, ref srcCoord,
                                    ref destCoord, ref temp, ref tempCaptures);

                //Verify the move is in bounds, if yes update the board with it
                if ((rule.InBounds(board, srcCoord.X, srcCoord.Y)) && (rule.InBounds(board, destCoord.X, destCoord.Y)))
                {
                    board = temp.Copy();
                    print.DrawBoard(board);
                }
                // check if there were any captures. if yes check for draw
                bool pcCaptured = tempCaptures.Count > 0;
                //check if game was determined
                game = GetGameState(humanColor, board);
                if (GameState.Draw ==
                    CheckDraw(board, board[destCoord.X, destCoord.Y], pcCaptured, ref countmovesforDraw))
                {
                    Console.WriteLine("Draw");
                    break;
                }
                if (game == GameState.Lost)
                {
                    Console.WriteLine("{0} Lost the game and {1} won", humanColor.ToString(), pcColor.ToString());
                    break;
                }
                if (game == GameState.Won)
                {
                    Console.WriteLine("{0} Won", humanColor.ToString());
                    break;
                }
            }
        }
Exemplo n.º 5
0
 /// <summary>
 ///     Is opponet won the game by blocking player
 /// </summary>
 /// <param name="board"></param>
 /// <param name="player"></param>
 /// <returns></returns>
 public bool IsPlayerBlocked(Board board, Player player)
 {
     for (int i = 1; i <= 32; i++)
     {
         if (board.GetPlayer(board[i]) == player)
         {
             if (!IsCoordinateBlocked(board, board[i], player))
             {
                 return false;
             }
         }
     }
     return true;
 }
Exemplo n.º 6
0
 /// <summary>
 /// Checks if a coordinate can't move (capture or just move)
 /// </summary>
 /// <param name="srcBoard"></param>
 /// <param name="coordinate"></param>
 /// <param name="player"></param>
 /// <returns></returns>
 public bool IsCoordinateBlocked(Board srcBoard, Coordinate coordinate, Player player)
 {
     int count = 0;
     IList<Coordinate> moves = GetMovesInDirection(srcBoard, coordinate, player);
     if (moves.Count == 0)
     {
         return true;
     }
     foreach (var move in moves)
     {
         if (move.Status == Piece.None)
         {
             return false;
         }
         if (srcBoard.GetPlayer(move) == player)
         {
             count++;
             if (moves.Count == count)
             {
                 return true;
             }
         }
         else if (srcBoard.GetPlayer(move) != player)
         {
             IDictionary<IList<Coordinate>, Coordinate> captures = CoordsToCaptureAndDest(srcBoard, coordinate,
                                                                                          move, player);
             if (captures.Count > 0)
             {
                 return false;
             }
         }
     }
     return true;
 }
Exemplo n.º 7
0
 /// <summary>
 /// check if piece is in player color and valid
 /// </summary>
 /// <param name="board"></param>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="player"></param>
 /// <returns></returns>
 private bool CheckValidPieceColor(Board board, int x, int y, Player player)
 {
     var srcCoord = board[x, y];
     if (srcCoord != null && board.GetPlayer(srcCoord) == player)
         return true;
     return false;
 }
Exemplo n.º 8
0
        /// <summary>
        /// Check the safeness of a coordinate (can be captured). if the sold is on boundary than safe (4) else return the 
        /// delta between number of player soldiers and number of Opp soldiers around the coord. 
        /// </summary>
        /// <param name="board"></param>
        /// <param name="coord"></param>
        /// <param name="player"></param>
        /// <returns></returns>
        private int Safeness(Board board, Coordinate coord, Player player)
        {
            int playerCoords = 0;
            int opponentCoords = 0;
            Rules rule = new Rules();
            if (coord.X == 1 || coord.X == 8 || coord.Y == 1 || coord.Y == 8)
            {
                return 4;
            }
            IList<Coordinate> coordinates = rule.OptionalMoves(board, coord, player);
            foreach (var coordinate in coordinates)
            {
                if (player == board.GetPlayer(coordinate))
                {
                    playerCoords++;
                }
                else if (board.GetOpponent(player) == board.GetPlayer(coordinate))
                {
                    opponentCoords++;
                }
            }

            return playerCoords - opponentCoords;
        }
Exemplo n.º 9
0
        /// <summary>
        /// An old revion of evalution function - our evaluation got better and better when playing thus we upgraded to the new one
        /// </summary>
        /// <param name="board"></param>
        /// <param name="player"></param>
        /// <returns></returns>
        public int EvaluateOld(Board board, Player player)
        {
            int score = 0;
            int blackscloseToKing = 0;
            int whitescloseToKing = 0;
            int whiteCanBeCaptured = 0;
            int blackCanBeCaptured = 0;
            int blackCaptures = 0;
            int whiteCaptures = 0;

            const int kingConstant = 130;
            const int soldierConstant = 100;
            int numWhiteKings = board.NumberOfWhiteKings;
            int numBlackKings = board.NumberOfBlackKings;
            int numOfWhiteSold = board.NumberOfWhitePieces;
            int numOfBlackSold = board.NumberOfBlackPieces;

            int blackScore = (numOfBlackSold*soldierConstant) + (numBlackKings*kingConstant);
            int whiteScore = (numOfWhiteSold*soldierConstant) + (numWhiteKings*kingConstant);
            score += ((blackScore - whiteScore)*200)/(blackScore + whiteScore);
            score += blackScore - whiteScore;

            for (int i = 1; i <= 32; i++)
            {
                if (board.GetPlayer(board[i]) == Player.Black)
                {
                    blackscloseToKing += CloseToBecomeAKing(board[i])*5;
                    blackCanBeCaptured += CanBeCaptured(board, board[i], Player.Black)*60;
                    blackCaptures += CanCapture(board, board[i], Player.Black)*30;
                }
                else if (board.GetPlayer(board[i]) == Player.White)
                {
                    whitescloseToKing += CloseToBecomeAKing(board[i])*5;
                    whiteCanBeCaptured += CanBeCaptured(board, board[i], Player.White)*60;
                    whiteCaptures += CanCapture(board, board[i], Player.White)*30;
                }
            }
            int closeToking = blackscloseToKing - whitescloseToKing;
            int canBeCapture = blackCanBeCaptured - whiteCanBeCaptured;
            int captures = blackCaptures - whiteCaptures;
            score += closeToking;
            score += canBeCapture;
            score += captures;

            const int randomizerMin = -10;
            const int randomizerMax = 10;
            return (player == Player.Black) ? score : -score + random.Next(randomizerMin, randomizerMax);
        }