Exemple #1
0
        /// <summary>
        /// Checks to see if a square is next to a corner
        /// </summary>
        /// <param name="square"></param>
        /// <param name="board"></param>
        /// <returns></returns>
        public bool IsNextToCorner(SimpleSquare square, SimpleBoard board)
        {
            int sizeX = board.OccupationArray.GetLength(0);
            int sizeY = board.OccupationArray.GetLength(1);
            int posX  = square.Column;
            int posY  = square.Row;

            if (posX == 0 && posY == 1)
            {
                return(true);
            }
            if (posX == 1 && posY == 0)
            {
                return(true);
            }
            if (posX == 0 && posY == sizeY - 2)
            {
                return(true);
            }
            if (posX == 1 && posY == sizeY - 1)
            {
                return(true);
            }
            if (posX == sizeX - 2 && posY == 0)
            {
                return(true);
            }
            if (posX == sizeX - 1 && posY == 1)
            {
                return(true);
            }
            if (posX == sizeX - 2 && posY == sizeY - 1)
            {
                return(true);
            }
            if (posX == sizeX - 1 && posY == sizeY - 2)
            {
                return(true);
            }

            return(false);
        }
Exemple #2
0
        public List <Move> Evaluate(List <List <Move> > inputMoveList, TurnState currentTurnState)
        {
            moveList = inputMoveList;

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

            if (currentTurnState == TurnState.Defender)
            {
                SimpleSquare evalSquare = new SimpleSquare();

                bool foundWin = false;
                //Evaluate the if the King's path to the thrones is clear.  If so one of the moves will have the King on the throne.
                moveList[0].ForEach((item) =>
                {
                    evalSquare = item.GetSquare(item.endRow, item.endColumn);
                    if (evalSquare.SquareType == Square.square_type.Corner)
                    {
                        item.scoreKingsCouncil = desireToWin;
                        suggestedMoves.Add(item);
                        foundWin = true;
                    }
                });
                if (foundWin)
                {
                    return(suggestedMoves);
                }

                int          numMovesForKing     = 0;
                List <Move>  tempMoveList        = new List <Move>();
                List <Move>  kingsMoveList       = new List <Move>();
                List <Move>  winningKingMoveList = new List <Move>();
                SimpleSquare kingSquare          = new SimpleSquare();
                int          numberDepth2Wins    = 0;

                int sizeX = moveList[0][0].board.OccupationArray.GetLength(0) - 1;
                int sizeY = moveList[0][0].board.OccupationArray.GetLength(1) - 1;

                //Look at all depth 2 moves (generated from move[0]'s) to see if any of these are wins. Don't just iterate over all depth[2] as this would
                //include depth [1] moves by attacker moving out of the way...
                //Also Award moves that have the King more free to move
                moveList[0].ForEach((item) =>
                {
                    try
                    {
                        //Find the King
                        kingSquare = item.FindTheKing(item.board, true);

                        tempMoveList = item.board.GetPossibleMoves(TurnState.Defender, null, 0);

                        //filter the list based on moves of the king
                        kingsMoveList   = tempMoveList.Where(move => move.startRow == kingSquare.Row && move.startColumn == kingSquare.Column).ToList();
                        numMovesForKing = kingsMoveList.Count;
                        //Give a bonus for the king being freed up
                        item.scoreKingsCouncil += (double)numMovesForKing * desireForFreeKing;

                        winningKingMoveList = kingsMoveList.Where(mov => (mov.endColumn == 0 && mov.endRow == 0) ||
                                                                  (mov.endColumn == 0 && mov.endRow == sizeY) ||
                                                                  (mov.endColumn == sizeX && mov.endRow == 0) ||
                                                                  (mov.endColumn == sizeX && mov.endRow == sizeY)).ToList();
                        if (winningKingMoveList.Count > 0)
                        {
                            numberDepth2Wins++;
                            item.scoreKingsCouncil += desrieToWinDepth2;
                        }
                    }
                    catch (Exception ex)
                    {
                        numberDepth2Wins += 0;
                    }
                });


                //if number of depth 2 wins is zero allow more full analyis
                if (numberDepth2Wins == 0)
                {
                    moveList[2].ForEach(item =>
                    {
                        kingSquare    = item.FindTheKing(item.board, true);
                        Piece king    = new Piece(kingSquare.Column, kingSquare.Row, Piece.PieceType.King);
                        kingsMoveList = item.board.GetMovesForPiece(king, item, 3);
                        kingsMoveList = kingsMoveList.Where(mov => (mov.endColumn == 0 && mov.endRow == 0) ||
                                                            (mov.endColumn == 0 && mov.endRow == sizeY) ||
                                                            (mov.endColumn == sizeX && mov.endRow == 0) ||
                                                            (mov.endColumn == sizeX && mov.endRow == sizeY)
                                                            ).ToList();
                        if (kingsMoveList.Count > 0)
                        {
                            item.parent.parent.scoreKingsCouncil += desireForKingToBeClearToCorner / (double)moveList[1].Count;
                        }
                    });
                }

                //return the best
                suggestedMoves.Add(moveList[0].MaxObject((item) => item.scoreKingsCouncil));
            }
            else
            {
                return(suggestedMoves); //will be empty.
            }

            return(suggestedMoves);
        }
Exemple #3
0
        public List <Move> Evaluate(List <List <Move> > inputMoveList, TurnState currentTurnState)
        {
            List <Move> suggestedMoves = new List <Move>();

            //Look to have the outer pieces on the maximum number of rows
            DateTime     start         = DateTime.Now;
            DateTime     start2        = DateTime.Now;
            TimeSpan     duration      = new TimeSpan();
            double       runTime       = 0.0d;
            double       runTime2      = 0.0d;
            SimpleSquare kingSquare    = new SimpleSquare();
            List <Move>  kingsMoveList = new List <Move>();

            int sizeX = inputMoveList[0][0].board.OccupationArray.GetLength(0);
            int sizeY = inputMoveList[0][0].board.OccupationArray.GetLength(1);

            int  numberMovesDepth0   = 0;
            int  numberOfLosesDepth1 = 0;
            bool foundwin            = false;

            inputMoveList[0].ForEach(item =>
            {
                if (item.CheckForAttackerVictory())
                {
                    item.scoreAssassin = desireForWinDepth0;
                    numberMovesDepth0++;
                    foundwin = true;
                }
            });

            //check to see if a move blocks a depth 1 loss
            if (!foundwin)
            {
                inputMoveList[1].ForEach(item =>
                {
                    //If a loss is possible all moves in which the loss can happen should be penalised.
                    SimpleSquare kingSquareWin = item.FindTheKing(item.board, true);
                    if (kingSquareWin.SquareType == Square.square_type.Corner)
                    {
                        numberOfLosesDepth1++;
                        item.parent.scoreAssassin -= desireNotToLoseDepth1;
                    }
                    //if the king can get to a square next to a corner it is also a definte loss effectively at depth 3
                    //so penalise at depth 1
                    if (IsNextToCorner(kingSquareWin, item.board))
                    {
                        numberOfLosesDepth1++;
                        item.parent.scoreAssassin -= desireNotToLoseDepth1;
                    }
                });

                runTime = (DateTime.Now - start).TotalSeconds;

                start2 = DateTime.Now;

                //Check to see if can win, but not if can lose on next defender move
                bool worthLookingDeep = false;

                if (numberOfLosesDepth1 < 1)
                {
                    //Check if king is at least surrounded by 2 attackers  -  if so look for a 2 move combo that might win
                    inputMoveList[0].ForEach(item =>
                    {
                        if (item.NumberOfAttackersAroundKing() >= 2)
                        {
                            worthLookingDeep = true;
                        }
                    });

                    if (worthLookingDeep)
                    {
                        Parallel.ForEach(inputMoveList[2], item =>
                        {
                            if (item.CheckForAttackerVictory())
                            {
                                item.parent.parent.scoreAssassin += desireForWinDepth2 / (double)inputMoveList[1].Count;
                            }
                        });
                    }
                }
                runTime2 = (DateTime.Now - start2).TotalSeconds;
                runTime  = (DateTime.Now - start).TotalSeconds;

                //look for moves of the king at depth 3
                //Look for routes for the king at depth 3 to get to corner
                sizeX = inputMoveList[0][0].board.OccupationArray.GetLength(0) - 1;
                sizeY = inputMoveList[0][0].board.OccupationArray.GetLength(1) - 1;


                Object _lock = new Object();
                if (numberOfLosesDepth1 < 1)
                {
                    inputMoveList[1].ForEach(item =>   //This could be moveList[2] but would be slow.   This only evolves from the defenders last move (i.e. skips the attackers move)
                    {
                        kingSquare    = item.FindTheKing(item.board, true);
                        Piece king    = new Piece(kingSquare.Column, kingSquare.Row, Piece.PieceType.King);
                        kingsMoveList = item.board.GetMovesForPiece(king, item, 3); // This is very expensive
                        kingsMoveList = kingsMoveList.Where(mov => (mov.endColumn == 0 && mov.endRow == 0) ||
                                                            (mov.endColumn == 0 && mov.endRow == sizeY) ||
                                                            (mov.endColumn == sizeX && mov.endRow == 0) ||
                                                            (mov.endColumn == sizeX && mov.endRow == sizeY)
                                                            ).ToList();
                        if (kingsMoveList.Count > 0)
                        {
                            item.parent.scoreAssassin -= desireNotToLoseDepth3 / (double)inputMoveList[1].Count;
                        }
                    });
                }
            }
            runTime = (DateTime.Now - start).TotalSeconds;

            suggestedMoves.Add(inputMoveList[0].MaxObject(item => item.scoreAssassin));

            return(suggestedMoves);
        }