Пример #1
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;
        }
Пример #2
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;
            }
        }
Пример #3
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;
                }
            }
        }
Пример #4
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;
            }
        }
Пример #5
0
 /// <summary>
 /// Create new boards if there are captures
 /// </summary>
 /// <param name="srcBoard"></param>
 /// <param name="capturesAvailable">first list are captures and second list is src-dest coords</param>
 /// <returns></returns>
 public IDictionary<Board, IList<Coordinate>> CreateNewBoards(Board srcBoard,
     IDictionary<IList<Coordinate>, IList<Coordinate>>
     capturesAvailable)
 {
     IDictionary<Board, IList<Coordinate>> res = new Dictionary<Board, IList<Coordinate>>();
     foreach (var item in capturesAvailable)
     {
         Board nBoard = srcBoard.Copy();
         nBoard.UpdateBoard(nBoard[nBoard.Search(item.Value.First())], item.Value.Last());
         IsBecameAKing(nBoard, item.Value.Last());
         Player player = nBoard.GetPlayer(item.Value.First());
         Player oPlayer = nBoard.GetOpponent(player);
         foreach (var capCoord in item.Key)
         {
             nBoard[nBoard.Search(capCoord)].Status = Piece.None;
             nBoard.UpdateCapturedSoldiers(capCoord, oPlayer);
         }
         IList<Coordinate> temp = new List<Coordinate>();
         temp.Add(nBoard[nBoard.Search(item.Value.First())]);
         temp.Add(nBoard[nBoard.Search(item.Value.Last())]);
         res.Add(nBoard, temp);
     }
     return res;
 }
Пример #6
0
 /// <summary>
 /// Constructor which perform alphabeta algorithm and set soruce ,destinationn coordinate and return captures list if exists
 /// </summary>
 /// <param name="board"></param>
 /// <param name="player"></param>
 /// <param name="depth"></param>
 public Move(IBoardState board, Player player, int depth)
 {
     Rules rule = new Rules();
     board.Board = board.ConvertBoardStateToBoard(board);
     var alphaBeta = new Alphabeta();
     Board temp = new Board();
     var srcCoord = new Coordinate();
     var destCoord = new Coordinate();
     IList<Coordinate> tempCaptures = new List<Coordinate>();
     if (depth%2 != 0)
         depth++;
     alphaBeta.AlphaBeta(board.Board, depth, Int32.MinValue, Int32.MaxValue, player, true, ref srcCoord, ref destCoord, ref temp, ref tempCaptures);
     if ((rule.InBounds(board.Board, srcCoord.X, srcCoord.Y)) && (rule.InBounds(board.Board, destCoord.X, destCoord.Y)))
     {
         board.Board = temp.Copy();
         board.BoardCells = board.ConvertBoardToBoardState(board.Board);
         Board = board;
     }
     bool pcCaptured = tempCaptures.Count > 0;
     board.DrawGame = board.CheckDraw(board.Board, board.Board[destCoord.X, destCoord.Y], pcCaptured);
 }