Пример #1
0
        /// <summary>
        /// Safely read from a file and convert to our coordinate data and 
        /// First list is source, destanation coordinates and (if there are) capture list
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="board"></param>
        /// <param name="path"></param>
        /// <param name="playerColor">return the last played player</param>
        /// <returns>returns a coordinate list which repesnt the move and captures</returns>
        public IList<Coordinate> ReadFromFile(FileStream stream, Board board, string path, out Player playerColor)
        {
            IList<Coordinate> cor = new List<Coordinate>();
            string temp = string.Empty;
            if (File.Exists(@path))
            {
                byte[] byteData = new byte[stream.Length];
                stream.Read(byteData, 0, (int) stream.Length);
                string content = Encoding.ASCII.GetString(byteData);
                cor = ShmulToCoordinate(board, content, out temp);
            }

            //Who made the last move
            if (temp == "B")
            {
                playerColor = Player.Black;
            }
            else if (temp == "W")
            {
                playerColor = Player.White;
            }
            else
            {
                playerColor = Player.None;
            }
            return cor;
        }
Пример #2
0
 /// <summary>
 /// Print Board in Console
 /// </summary>
 /// <param name="board"></param>
 /// <param name="writer"></param>
 private void drawBoard(Board board, TextWriter writer)
 {
     var buf1 = new StringBuilder();
     var buf2 = new StringBuilder();
     writer.WriteLine("+--------------------------------+       +--------------------------------+");
     for (int k = 1; k <= 32; k++)
     {
         for (int i = 8; i > 0; i--)
         {
             int j = 1;
             if (i%2 == 0)
             {
                 j = 2;
                 buf1.AppendFormat("    ");
             }
             int shift;
             for (shift = 3; (j <= 8 && shift >= 0); j += 2, shift--)
             {
                 int cellNum = i*4 - shift;
                 var coord = board[i, j];
                 string soldierColor;
                 if (board.IsBlack(coord))
                 {
                     soldierColor = "b";
                     if (board.IsKing(coord)) soldierColor = "bk";
                 }
                 else if (board.IsWhite(coord))
                 {
                     soldierColor = "w";
                     if (board.IsKing(coord)) soldierColor = "wk";
                 }
                 else
                 {
                     soldierColor = ".";
                 }
                 k++;
                 buf1.AppendFormat(" | {0} |  ", soldierColor);
                 if (cellNum >= 1 && cellNum <= 9)
                 {
                     buf2.AppendFormat("  | {0} | ", cellNum);
                 }
                 else
                 {
                     buf2.AppendFormat("  | {0}| ", cellNum);
                 }
             }
             writer.WriteLine("{0}        {1}", buf1, buf2);
             writer.WriteLine("+--------------------------------+       +--------------------------------+");
             buf1.Length = 0;
             buf2.Length = 0;
         }
     }
     buf1.Append("|");
     buf2.Append("|");
 }
Пример #3
0
        /// <summary>
        ///     Calucalte new game boards which are optional moves
        /// </summary>
        /// <param name="board"></param>
        /// <param name="player"></param>
        /// <returns></returns>
        public IDictionary<Board, IList<Coordinate>> CalculateNewBoardsFromCoordinates(Board board, Player player)
        {
            IDictionary<Board, IList<Coordinate>> newBoardsPositions = new Dictionary<Board, IList<Coordinate>>();
            for (int i = 1; i <= board.Size; i++)
            {
                if (board.IsOwner(player, board[i]))
                {
                    IList<Coordinate> coordinateList = GetMovesInDirection(board, board[i], player);
                    foreach (Coordinate coordinate in coordinateList.Reverse())
                    {
                        //if a soldier of mine exists in this coord then this coord is not optional;
                        if (board.IsOwner(player, coordinate))
                        {
                            coordinateList.Remove(coordinate);
                        }
                            //if an oppenent soldier exsist in this coord try capturing him!
                        else if (board.IsOpponentPiece(player, coordinate))
                        {
                            IList<Coordinate> destList =
                                CoordsToCaptureAndDest(board, board[i], coordinate, player).Values.ToList();

                            if (destList.Count != 0)
                            {
                                // destList is all the coordinates presenting the board after the capture.
                                foreach (Coordinate coord in destList.Reverse())
                                {
                                    Board nBoard = board.Copy();
                                    nBoard.UpdateBoard(nBoard[nBoard.Search(board[i])], coord);
                                    IsBecameAKing(nBoard, coord);
                                    IList<Coordinate> temp = new List<Coordinate>();

                                    temp.Add(nBoard[nBoard.Search(board[i])]);
                                    temp.Add(nBoard[nBoard.Search(coord)]);
                                    newBoardsPositions.Add(nBoard, temp);
                                }
                            }
                        }
                        else if (!board.IsAloacted(coordinate))
                        {
                            //create new board that represnt board after the move
                            Board nBoard = board.Copy();
                            nBoard.UpdateBoard(nBoard[nBoard.Search(board[i])], coordinate);
                            IsBecameAKing(nBoard, coordinate);
                            IList<Coordinate> temp = new List<Coordinate>();
                            temp.Add(nBoard[nBoard.Search(board[i])]);
                            temp.Add(nBoard[nBoard.Search(coordinate)]);
                            newBoardsPositions.Add(nBoard, temp);
                        }
                    }
                }
            }

            return newBoardsPositions;
        }
Пример #4
0
 /// <summary>
 /// Checks if draw and return number of moves (draw - if there are 15 king's moves with no captures of both opponent and player)
 /// </summary>
 /// <param name="board"></param>
 /// <param name="coordinate"></param>
 /// <param name="canCapture"></param>
 /// <param name="count"></param>
 public GameState CheckDraw(Board board, Coordinate coordinate, bool canCapture, ref int count)
 {
     if (board.IsKing(coordinate) && !canCapture)
     {
         count++;
         if (count == 15)
         {
             return GameState.Draw;
         }
     }
     else
     {
         count = 0;
     }
     return GameState.Undetermined;
 }
Пример #5
0
 /// <summary>
 /// Checks if draw and return number of moves (draw - if there are 15 king's moves with no captures of both opponent and player)
 /// </summary>
 /// <param name="board"></param>
 /// <param name="coordinate"></param>
 /// <param name="captured"></param>
 public GameState CheckDraw(Board board, Coordinate coordinate, bool captured)
 {
     if (board.IsKing(coordinate) && !captured)
     {
         countMove++;
         if (countMove == 15)
         {
             return GameState.Draw;
         }
     }
     else
     {
         countMove = 0;
     }
         return GameState.Undetermined;
 }
Пример #6
0
 /// <summary>
 /// Parse input to coordinates
 /// </summary>
 /// <param name="input"></param>
 /// <param name="board"></param>
 /// <returns></returns>
 public IList<Coordinate> ParseStrToCoords(string input, Board board)
 {
     IList<Coordinate> moves = new List<Coordinate>();
     const char delimiterChar = ' ';
     string[] word = input.Split(delimiterChar);
     try
     {
         Coordinate srcCoord = new Coordinate(board[Int32.Parse(word[0])]);
         moves.Add(srcCoord);
         Coordinate destCoord = new Coordinate(board[Int32.Parse(word[1])]);
         moves.Add(destCoord);
     }
     catch (Exception)
     {
         return null;
     }
     return moves;
 }
Пример #7
0
        /// <summary>
        /// Check GameState
        /// </summary>
        /// <param name="player"></param>
        /// <param name="board"></param>
        /// <returns></returns>
        public GameState GetGameState(Player player, Board board)
        {
            var rule = new Rules();

            var numberplayerPieces = rule.NumberOfPlayerPieces(board, player);
            var isplayerBlocked = rule.IsPlayerBlocked(board, player);
            if (numberplayerPieces == 0 || isplayerBlocked)
            {
                return GameState.Lost;
            }
            var numberopponentPieces = rule.NumberOfPlayerPieces(board, board.GetOpponent(player));
            var isopponentBlocked = rule.IsPlayerBlocked(board, board.GetOpponent(player));
            if (numberopponentPieces == 0 || isopponentBlocked)
            {
                return GameState.Won;
            }
            else
            {
                return GameState.Undetermined;
            }
        }
Пример #8
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;
        }
Пример #9
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;
        }
Пример #10
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;
            }
        }
Пример #11
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;
                }
            }
        }
Пример #12
0
        /// <summary>
        /// Finds destination by captured coordinate
        /// </summary>
        /// <param name="board"></param>
        /// <param name="srcCoordinate"></param>
        /// <param name="oponentCoordinate"></param>
        /// <returns></returns>
        public Coordinate FindDestByCap(Board board, Coordinate srcCoordinate, Coordinate oponentCoordinate)
        {
            int srcX = srcCoordinate.X;
            int srcY = srcCoordinate.Y;
            int oponentX = oponentCoordinate.X;
            int oponentY = oponentCoordinate.Y;
            var dest = new Coordinate();
            int destX, destY;

            //find the direction of the optional capture and set destination accordingly
            if (srcX < oponentX) destX = oponentX + 1;
            else destX = oponentX - 1;

            if (srcY < oponentY) destY = oponentY + 1;
            else destY = oponentY - 1;
            if (InBounds(board, destX, destY))
            {
                dest = new Coordinate(board[destX, destY]);
            }
            return dest;
        }
Пример #13
0
 /// <summary>
 ///     Write the board state to the console
 /// </summary>
 /// <param name="board">The board</param>
 public void DrawBoard(Board board)
 {
     drawBoard(board, Console.Out);
 }
Пример #14
0
        /// <summary>
        /// alpha beta algorithm
        /// boardcoordlist- each item in this map contains a new board (representing a new state) and a list of 2 coords representing the move that brought to this new state
        /// mapBoardSrcDestCap- each item in this map contains the new board and source- dest coords (like above) and a list of captured coordinate (in case the new board is a result of a capture)
        /// </summary>
        /// <param name="board"></param>
        /// <param name="depth"></param>
        /// <param name="alpha"></param>
        /// <param name="beta"></param>
        /// <param name="player"></param>
        /// <param name="maxplayer"></param>
        /// <param name="srcCoord"></param>
        /// <param name="destCoord"></param>
        /// <param name="updateBoard"></param>
        /// <param name="captures"></param>
        /// <returns></returns>
        public int AlphaBeta(Board board, int depth, int alpha, int beta, Player player, bool maxplayer,
            ref Coordinate srcCoord, ref Coordinate destCoord, ref Board updateBoard,
            ref IList<Coordinate> captures)
        {
            var robj = new Rules();
            if (depth == 0 || rule.IsBoardLeaf(player, board)) // is node a terminal node
            {
                var obj = new HeuristicFunction();
                return obj.Evaluate(board, player); //return Heurisitic value of node
            }

            //Finds if there are any captures
            IDictionary<IList<Coordinate>, IList<Coordinate>> capturesAvailable = robj.FindCaptures(board, player);
            IDictionary<Board, IList<Coordinate>> boardCoordsList;

            //Calculating board according to current state (with or without captures)
            if (capturesAvailable.Count > 0)
            {
                boardCoordsList = robj.CreateNewBoards(board, capturesAvailable);
            }
            else
            {
                boardCoordsList = robj.CalculateNewBoardsFromCoordinates(board, player);
            }

            //values which save capture list , source, detination on the chosen move
            var minsrcCoord = new Coordinate();
            var mindestCoord = new Coordinate();
            var maxsrcCoord = new Coordinate();
            var maxdestCoord = new Coordinate();
            var maxCapturesList = new List<Coordinate>();
            var minCapturesList = new List<Coordinate>();
            var minBoard = new Board();
            var maxBoard = new Board();

            //player
            if (maxplayer)
            {
                foreach (var newState in boardCoordsList)
                {
                    Coordinate newSrcCoord = newState.Value[0];
                    Coordinate newDestCoord = newState.Value[1];
                    IList<Coordinate> capturesList = robj.MapContainsCoords(capturesAvailable, newSrcCoord, newDestCoord);
                    IList<Coordinate> tempCapList = new List<Coordinate>();
                    int res = AlphaBeta(newState.Key, depth - 1, alpha, beta, board.GetOpponent(player), !maxplayer,
                                        ref newSrcCoord, ref newDestCoord, ref updateBoard, ref tempCapList);
                    if (res > alpha)
                    {
                        alpha = res;
                        maxsrcCoord = newState.Value[0];
                        maxdestCoord = newState.Value[1];
                        maxBoard = newState.Key.Copy();
                        maxCapturesList = new List<Coordinate>(capturesList);
                    }
                    if (beta <= alpha)
                    {
                        break;
                    }
                    if (capturesList.Count > 0)
                    {
                        capturesAvailable.Remove(capturesList);
                    }
                }
                srcCoord = maxsrcCoord;
                destCoord = maxdestCoord;
                updateBoard = maxBoard.Copy();
                captures = maxCapturesList;
                return alpha;
            }

                //opponent
            else
            {
                foreach (var newState in boardCoordsList)
                {
                    Coordinate newSrcCoord = newState.Value[0];
                    Coordinate newDestCoord = newState.Value[1];
                    IList<Coordinate> capturesList = robj.MapContainsCoords(capturesAvailable, newSrcCoord, newDestCoord);
                    IList<Coordinate> tempCapList = new List<Coordinate>();
                    int res = AlphaBeta(newState.Key, depth - 1, alpha, beta, board.GetOpponent(player), !maxplayer,
                                        ref newSrcCoord, ref newDestCoord, ref updateBoard, ref tempCapList);
                    if (res < beta)

                    {
                        beta = res;
                        minsrcCoord = newState.Value[0];
                        mindestCoord = newState.Value[1];
                        minBoard = newState.Key.Copy();
                        minCapturesList = new List<Coordinate>(capturesList);
                    }
                    if (beta <= alpha)
                    {
                        break;
                    }
                    if (capturesList.Count > 0)
                    {
                        capturesAvailable.Remove(capturesList);
                    }
                }
                srcCoord = minsrcCoord;
                destCoord = mindestCoord;
                updateBoard = minBoard.Copy();
                captures = minCapturesList;
                return beta;
            }
        }
Пример #15
0
 /// <summary>
 ///     Checks if Piece on coordinate became a King
 /// </summary>
 /// <param name="board"></param>
 /// <param name="coordinate"></param>
 public bool IsBecameAKing(Board board, Coordinate coordinate)
 {
     int index;
     if ((board[index = board.Search(coordinate)].Status == Piece.BlackPiece) && (coordinate.X == 1))
     {
         board[index].Status = Piece.BlackKing;
         board.NumberOfBlackKings++;
         board.NumberOfBlackPieces--;
     }
     else if ((board[index = board.Search(coordinate)].Status == Piece.WhitePiece) && (coordinate.X == board.Rows))
     {
         board[index].Status = Piece.WhiteKing;
         board.NumberOfWhiteKings++;
         board.NumberOfWhitePieces--;
     }
     else
     {
         return false;
     }
     return true;
 }
Пример #16
0
 /// <summary>
 ///     checks if player lost the game- is he blocked or have no soldiers;
 /// </summary>
 /// <param name="player"></param>
 /// <param name="srcBoard"></param>
 /// <returns></returns>
 public bool DidPlayerLost(Player player, Board srcBoard)
 {
     var numberplayerPieces = NumberOfPlayerPieces(srcBoard, player);
     var isplayerBlocked = IsPlayerBlocked(srcBoard, player);
     if (numberplayerPieces == 0 || isplayerBlocked)
     {
         return true;
     }
     return false;
 }
Пример #17
0
        /// <summary>
        /// For debug
        /// </summary>
        /// <param name="board"></param>
        /// <param name="coordinates"></param>
        /// <param name="playerColor"></param>
        /// <returns></returns>
        private IList<Coordinate> Debugging(Board board, string coordinates, out string playerColor)
        {
            IList<Coordinate> coords = new List<Coordinate>();
            const char delimiterChar = ' ';
            string[] word = coordinates.Split(delimiterChar);
            for (int i = 0; i < word.Length - 1; i++)
            {
                int x = Int32.Parse(word[i].Substring(1, 1));
                int y = Int32.Parse(word[i].Substring(3, 1));
                coords.Add(new Coordinate {X = x, Y = y});
            }
            foreach (var item in coords)
            {
                item.Status = board[board.Search(item)].Status;
            }
            playerColor = word[word.Length - 1];

            return coords;
        }
Пример #18
0
 /// <summary>
 /// in case this move isn't a capture- check if valid
 /// </summary>
 /// <param name="board"></param>
 /// <param name="srcCoord"></param>
 /// <param name="destCoord"></param>
 /// <param name="player"></param>
 /// <returns></returns>
 public bool IsValidMove(Board board, Coordinate srcCoord, Coordinate destCoord, Player player)
 {
     //Check if the move is in bounds
     if (!(InBounds(board, srcCoord.X, srcCoord.Y)) || !(InBounds(board, destCoord.X, destCoord.Y)))
         return false;
     //Check if is in direction and not more than 1 step
     if ((Math.Abs(srcCoord.X - destCoord.X) > 1) || (Math.Abs(srcCoord.Y - destCoord.Y) > 1))
         return false;
     //Find all availables move for the piece
     IList<Coordinate> coordsInDir = GetMovesInDirection(board, srcCoord, player);
     //crossing data with available moves and free location
     return coordsInDir.Contains(destCoord) && !board.IsAloacted(destCoord);
 }
Пример #19
0
        /// <summary>
        /// Copy Boards
        /// </summary>
        /// <returns></returns>
        public Board Copy()
        {
            var nboard = new Board();
            //Array.Copy(board,0,nboard.board,0,Size);

            for (int i = 1; i <= 32; i++)
            {
                nboard[i].Status = this[i].Status;
                nboard[i].X = this[i].X;
                nboard[i].Y = this[i].Y;
            }
            nboard.NumberOfWhitePieces = this.NumberOfWhitePieces;
            nboard.NumberOfBlackPieces = this.NumberOfBlackPieces;
            nboard.NumberOfBlackKings = this.NumberOfBlackKings;
            nboard.NumberOfWhiteKings = this.NumberOfWhiteKings;
            nboard.Size = this.Size;
            nboard.Rows = this.Rows;
            nboard.Columns = this.Columns;

            return nboard;
        }
Пример #20
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;
 }
Пример #21
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;
 }
Пример #22
0
 /// <summary>
 ///     checks if the game is already determined (one of the oppenents)
 /// </summary>
 /// <param name="player"></param>
 /// <param name="srcBoard"></param>
 /// <returns></returns>
 public bool IsBoardLeaf(Player player, Board srcBoard)
 {
     if (DidPlayerLost(player, srcBoard) || (DidPlayerLost(srcBoard.GetOpponent(player), srcBoard)))
         return true;
     return false;
 }
Пример #23
0
 /// <summary>
 /// Find dictionary of all captures on board per player
 /// </summary>
 /// <param name="board"></param>
 /// <param name="player"></param>
 /// <returns>dictionary of 2 lists : first  list of coordinates (captured coordinates) , second coordinates (src-destination cords)-</returns>
 public IDictionary<IList<Coordinate>, IList<Coordinate>> FindCaptures(Board board, Player player)
 {
     IDictionary<IList<Coordinate>, IList<Coordinate>> res =
         new Dictionary<IList<Coordinate>, IList<Coordinate>>();
     for (int i = 1; i <= 32; i++)
     {
         if (board.IsOwner(player, board[i]))
         {
             var coordsInDir = GetMovesInDirection(board, board[i], player);
             if (coordsInDir.Count == 0) break;
             foreach (Coordinate coordindir in coordsInDir)
             {
                 if (board.IsOpponentPiece(player, coordindir))
                 {
                     var coordsToJumpTo = CoordsToCaptureAndDest(board, board[i], coordindir, player);
                     if (coordsToJumpTo.Count != 0)
                     {
                         foreach (var item in coordsToJumpTo)
                         {
                             res.Add(item.Key, new List<Coordinate> {board[i], item.Value});
                         }
                     }
                 }
             }
         }
     }
     return res;
 }
Пример #24
0
        /// <summary>
        /// Convert Shmul and Limor moves to our coordinate
        /// </summary>
        /// <param name="board"></param>
        /// <param name="coordinates"></param>
        /// <param name="playerColor"></param>
        /// <returns>A list of coordinates</returns>
        private IList<Coordinate> ShmulToCoordinate(Board board, string coordinates, out string playerColor)
        {
            IList<Coordinate> coords = new List<Coordinate>();
            const char delimiterChar = ' ';
            string[] word = coordinates.Split(delimiterChar);

            for (int i = 0; i < word.Length - 1; i++)
            {
                int x = Int32.Parse(word[i].Substring(1, 1));
                int y = Int32.Parse(word[i].Substring(3, 1));
                coords.Add(new Coordinate {X = x, Y = y});
            }

            //If list is not empty
            if (coords.Count > 0)
            {
                //Convert to our ccordinates and update their status
                foreach (var item in coords)
                {
                    item.X = 8 - item.X;
                    item.Y++;
                    item.Status = board[board.Search(item)].Status;
                }
            }
            playerColor = word[word.Length - 1];
            return coords;
        }
Пример #25
0
 /// <summary>
 /// Console application entry 
 /// </summary>
 private static void Main()
 {
     bool input = true;
     var print = new PrintBoardState();
     //Create new board
     var board = new Board(8);
     Console.WriteLine("Game started");
     //print start board
     print.DrawBoard(board);
     Program p = new Program();
     Console.WriteLine("for PC vs Human Press 1, for PC vs PC press 2");
     while (input)
     {
         string type = Console.ReadLine();
         if (type == "1")
         {
             input = false;
             p.StartGameWithHuman(board);
         }
         else if (type == "2")
         {
             input = false;
             p.StartGameWithPc(board);
         }
         else
         {
             Console.WriteLine("Incorrect Input, please try again");
         }
     }
 }
Пример #26
0
 /// <summary>
 ///     Get Moves In Direction
 /// </summary>
 /// <param name="board"></param>
 /// <param name="coordinate"></param>
 /// <param name="player"></param>
 /// <returns></returns>
 public IList<Coordinate> GetMovesInDirection(Board board, Coordinate coordinate, Player player)
 {
     //Finds all optional move for player
     IList<Coordinate> coordinateList = OptionalMoves(board, coordinate, player);
     if (coordinateList.Count != 0)
     {
         //checks if player is the owner of the piece
         if (board.IsOwner(player, coordinate))
         {
             foreach (Coordinate item in coordinateList.Reverse())
             {
                 //Removing coordinates which are not in the piece direction white - forward and black backword (according to board orientation)
                 if (board.IsBlack(coordinate) && (board.IsSoldier(coordinate)))
                 {
                     if (item.X > coordinate.X)
                     {
                         coordinateList.Remove(item);
                     }
                 }
                 if (board.IsWhite(coordinate) && (board.IsSoldier(coordinate)))
                 {
                     if (item.X < coordinate.X)
                     {
                         coordinateList.Remove(item);
                     }
                 }
             }
         }
     }
     return coordinateList;
 }
Пример #27
0
        /// <summary>
        ///     Count the number of player pieces on board
        /// </summary>
        /// <param name="board"></param>
        /// <param name="player"></param>
        /// <returns></returns>
        public int NumberOfPlayerPieces(Board board, Player player)
        {
            switch (player)
            {
                case Player.White:
                    {
                        return board.NumberOfWhiteKings + board.NumberOfWhitePieces;
                    }
                case Player.Black:
                    {
                        return board.NumberOfBlackKings + board.NumberOfBlackPieces;
                    }
            }

            return 0;
        }
Пример #28
0
 /// <summary>
 ///     Check if in bound
 /// </summary>
 /// <param name="board"></param>
 /// <param name="row"></param>
 /// <param name="column"></param>
 /// <returns></returns>
 public bool InBounds(Board board, int row, int column)
 {
     return ((row > 0) && (row <= board.Rows) && (column > 0) && (column <= board.Columns));
 }
Пример #29
0
 /// <summary>
 /// Finds 2 boards difference
 /// </summary>
 /// <param name="before"></param>
 /// <param name="after"></param>
 /// <returns></returns>
 public IList<Coordinate> FindBoardsDifference(Board before, Board after)
 {
     IList<Coordinate> diff = new List<Coordinate>();
     for(int i=1;i<=32;i++)
     {
         if (before[i] != after[i])
         {
             if (before[i].Status == Piece.None)
             {
                 diff.Add(before[i]);
             }
             if (before[i].Status == before.PieceColor(before[i]))
             {
                 diff.Add(before[i]);
             }
         }
     }
     return diff;
 }
Пример #30
0
        /// <summary>
        ///     Get all valid moves for a coordinate
        /// </summary>
        /// <param name="board"></param>
        /// <param name="coordinate"></param>
        /// <param name="player"></param>
        /// <returns></returns>
        public IList<Coordinate> OptionalMoves(Board board, Coordinate coordinate, Player player)
        {
            IList<Coordinate> coordinateList = new List<Coordinate>();
            //Check that player own the piece on that coordinate
            if (board.IsOwner(player, coordinate))
            {
                //Check in bounds
                if (InBounds(board, coordinate.X + 1, coordinate.Y + 1))
                {
                    var temp1 = new Coordinate(board[coordinate.X + 1, coordinate.Y + 1]);
                    coordinateList.Add(temp1);
                }

                //Check in bounds
                if (InBounds(board, coordinate.X + 1, coordinate.Y - 1))
                {
                    var temp2 = new Coordinate(board[coordinate.X + 1, coordinate.Y - 1]);
                    coordinateList.Add(temp2);
                }

                //Check in bounds
                if (InBounds(board, coordinate.X - 1, coordinate.Y + 1))
                {
                    var temp3 = new Coordinate(board[coordinate.X - 1, coordinate.Y + 1]);
                    coordinateList.Add(temp3);
                }

                //Check in bounds
                if (InBounds(board, coordinate.X - 1, coordinate.Y - 1))
                {
                    var temp4 = new Coordinate(board[coordinate.X - 1, coordinate.Y - 1]);
                    coordinateList.Add(temp4);
                }
            }
            return coordinateList;
        }