Пример #1
0
        /// <summary>
        /// check whether the position is forbidden
        /// </summary>
        /// <returns>if it is forbidden ,true;otherwise ,false
        /// </returns>
        private bool IsFobidden(ref IChessBoard chessBoard,Position point,PieceTypeEnum pieceType)
        {
            Referee platformCheck = new Referee();
            PlayStepResultEnum stepResult=platformCheck.Check(chessBoard, new ChessBoardPoint(point.Row, point.Col), PieceTypeEnum.Black);
            //it seems the platform does not check four-three-three

                if (stepResult == PlayStepResultEnum.Four_Four ||
                   stepResult == PlayStepResultEnum.Three_Three ||
                   stepResult == PlayStepResultEnum.Overline)
                {
                    if (pieceType == PieceTypeEnum.Black)
                    {
                        return true;
                    }
                    else
                    {
                        stepResult = platformCheck.Check(chessBoard, new ChessBoardPoint(point.Row, point.Col), PieceTypeEnum.White);
                        if (stepResult == PlayStepResultEnum.Four_Four ||
                            stepResult == PlayStepResultEnum.Three_Three||
                            stepResult==PlayStepResultEnum.Win)
                        {
                            return false;
                        }
                    }
                }

            return false;
        }
Пример #2
0
        /// <summary>
        /// check whether the position is forbidden
        /// </summary>
        /// <returns>if it is forbidden ,true;otherwise ,false
        /// </returns>
        private bool IsFobidden(ref IChessBoard chessBoard, Position point, PieceTypeEnum pieceType)
        {
            Referee            platformCheck = new Referee();
            PlayStepResultEnum stepResult    = platformCheck.Check(chessBoard, new ChessBoardPoint(point.Row, point.Col), PieceTypeEnum.Black);

            //it seems the platform does not check four-three-three

            if (stepResult == PlayStepResultEnum.Four_Four ||
                stepResult == PlayStepResultEnum.Three_Three ||
                stepResult == PlayStepResultEnum.Overline)
            {
                if (pieceType == PieceTypeEnum.Black)
                {
                    return(true);
                }
                else
                {
                    stepResult = platformCheck.Check(chessBoard, new ChessBoardPoint(point.Row, point.Col), PieceTypeEnum.White);
                    if (stepResult == PlayStepResultEnum.Four_Four ||
                        stepResult == PlayStepResultEnum.Three_Three ||
                        stepResult == PlayStepResultEnum.Win)
                    {
                        return(false);
                    }
                }
            }


            return(false);
        }
Пример #3
0
        /// <summary>
        /// 获得当前五子棋策略的下一步落棋位置。
        /// </summary>
        /// <param name="chessBoard">五子棋棋盘对象。</param>
        /// <param name="pieceType">棋子的类型。</param>
        /// <param name="stepIndex">下一步落子操作的序号。</param>
        /// <param name="prevStep">包含对方上一步落子操作信息的走步对象。</param>
        /// <returns>下一步落棋的位置。</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/3/23 9:40    创建
        /// </history>
        public ChessBoardPoint GetNextStep(IChessBoard chessBoard, PieceTypeEnum pieceType, int stepIndex, PlayStep?prevStep)
        {
            //判断是否为黑方的第一手棋
            if (pieceType == PieceTypeEnum.Black && stepIndex == 0)
            {
                //如果是黑方的第一手棋,则总是返回天元
                return(ChessBoardPoint.TENGEN);
            }
            //用于保存落子位置的行序号
            int rowIndex = 0;
            //用于保存落子位置的列序号
            int columnIndex = 0;

            //创建随机数生成器
            Random random = new Random();

            //循环直到获得可以落子的位置
            while (true)
            {
                //生成随机行坐标序号(有效的行序号为0~14)
                rowIndex = random.Next() % 15;

                //生成随机列坐标序号(有效的列序号为0~14)
                columnIndex = random.Next() % 15;

                //判断随机落子点是否已经存在棋子
                if (chessBoard.GetPointState(rowIndex, columnIndex) == PointStateEnum.Blank)
                {
                    //如果随机落子点为空白点,则返回随机落子点
                    return(new ChessBoardPoint(rowIndex, columnIndex));
                }
            }
        }
Пример #4
0
        /// <summary>
        /// 获得当前五子棋策略的下一步落棋位置。
        /// </summary>
        /// <param name="chessBoard">五子棋棋盘对象。</param>
        /// <param name="pieceType">棋子的类型。</param>
        /// <param name="stepIndex">下一步落子操作的序号。</param>
        /// <param name="prevStep">包含对方上一步落子操作信息的走步对象。</param>
        /// <returns>下一步落棋的位置。</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/3/23 9:40    创建
        /// </history>
        public ChessBoardPoint GetNextStep( IChessBoard chessBoard, PieceTypeEnum pieceType, int stepIndex, PlayStep? prevStep )
        {
            //判断是否为黑方的第一手棋
            if (pieceType == PieceTypeEnum.Black && stepIndex == 0)
            {
                //如果是黑方的第一手棋,则总是返回天元
                return ChessBoardPoint.TENGEN;
            }
            //用于保存落子位置的行序号
            int rowIndex = 0;
            //用于保存落子位置的列序号
            int columnIndex = 0;

            //创建随机数生成器
            Random random = new Random();

            //循环直到获得可以落子的位置
            while (true)
            {
                //生成随机行坐标序号(有效的行序号为0~14)
                rowIndex = random.Next() % 15;

                //生成随机列坐标序号(有效的列序号为0~14)
                columnIndex = random.Next() % 15;

                //判断随机落子点是否已经存在棋子
                if (chessBoard.GetPointState( rowIndex, columnIndex ) == PointStateEnum.Blank)
                {
                    //如果随机落子点为空白点,则返回随机落子点
                    return new ChessBoardPoint( rowIndex, columnIndex );
                }
            }
        }
Пример #5
0
        //is forbidden
        private bool IsFobidden(ref IChessBoard chessBoard, Position point, PieceTypeEnum pieceType)
        {
            Referee            platformCheck = new Referee();
            PlayStepResultEnum stepResult    = platformCheck.Check(chessBoard, new ChessBoardPoint(14 - point.Row, point.Col), PieceTypeEnum.Black);

            //it seems the platform does not check four-three-three

            if (stepResult == PlayStepResultEnum.Four_Four ||
                stepResult == PlayStepResultEnum.Three_Three ||
                stepResult == PlayStepResultEnum.Overline)
            {
                if (pieceType == PieceTypeEnum.Black)
                {
                    return(true);
                }
                else
                {
                    //white priority vs. black forbidden
                    //if this position is black-forbidden,generally white should not be put here
                    //but if is advantaged enough for white,it should
                    if (PlayStepResultEnum.Win == platformCheck.Check(chessBoard, new ChessBoardPoint(14 - point.Row, point.Col), PieceTypeEnum.White))
                    {
                        return(false);
                    }
                    else
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Пример #6
0
    private static Piece createPiece(PlayerIdentityEnum owner, PieceTypeEnum type, int x, int y)
    {
        var piece = new Piece();

        piece.Owner           = owner;
        piece.Type            = type;
        piece.PositionOnBoard = new Position(x, y);
        return(piece);
    }
Пример #7
0
        private Position FindBestPos(ref IChessBoard chessBoard, PieceTypeEnum pieceType)
        {
            //generally con not happen,all the position is not Okay
            if (invalidBestPos.Capacity >= 15 * 15)
            {
                return(invalidBestPos[(new Random()).Next(invalidBestPos.Count)]);
            }

            List <Position> bestPosList = new List <Position>();

            bestPosList.Add(new Position(0, 0));
            //find the point whose score is highest
            for (int row = 0; row < 15; row++)
            {
                for (int col = 0; col < 15; col++)
                {
                    if (!invalidBestPos.Contains(new Position(row, col)))
                    {
                        if (scoreTable[col, row] > scoreTable[bestPosList[0].Col, bestPosList[0].Row])
                        {
                            bestPosList.Clear();
                            bestPosList.Add(new Position(row, col));
                        }
                        else if (scoreTable[col, row] == scoreTable[bestPosList[0].Col, bestPosList[0].Row])
                        {
                            bestPosList.Add(new Position(row, col));
                        }
                    }
                }
            }

            //generally connot happen,there is no bestPos
            if (bestPosList.Count == 0)
            {
                return(new Position(-1, -1));
            }

            Random rnd   = new Random();
            int    index = rnd.Next(bestPosList.Count);

            while (IsFobidden(ref chessBoard, bestPosList[index], pieceType))
            {
                invalidBestPos.Add(bestPosList[index]);
                bestPosList.RemoveAt(index);
                index = rnd.Next(bestPosList.Count);
                if (index == 0)
                {
                    FindBestPos(ref chessBoard, pieceType);
                }
            }


            invalidBestPos.Clear();
            return(bestPosList[index]);
        }
Пример #8
0
        public void UpdateScoreTableTest()
        {
            PlayStrategy_Accessor target             = new PlayStrategy_Accessor(); // TODO: 初始化为适当的值
            IChessBoard           chessBoard         = null;                        // TODO: 初始化为适当的值
            IChessBoard           chessBoardExpected = null;                        // TODO: 初始化为适当的值
            Position      pos       = null;                                         // TODO: 初始化为适当的值
            PieceTypeEnum pieceType = new PieceTypeEnum();                          // TODO: 初始化为适当的值

            target.UpdateScoreTable(ref chessBoard, pos, pieceType);
            Assert.AreEqual(chessBoardExpected, chessBoard);
            Assert.Inconclusive("无法验证不返回值的方法。");
        }
Пример #9
0
        private Position FindBestPos(ref IChessBoard chessBoard,PieceTypeEnum pieceType)
        {
            //generally con not happen,all the position is not Okay
            if (invalidBestPos.Capacity>=15*15)
            {
                return invalidBestPos[(new Random()).Next(invalidBestPos.Count)];
            }

            List<Position> bestPosList = new List<Position>();
            bestPosList.Add(new Position(0, 0));
            //find the point whose score is highest
            for (int row = 0; row < 15; row++)
            {
                for (int col = 0; col < 15; col++)
                {
                    if (!invalidBestPos.Contains(new Position(row, col)))
                    {
                        if (scoreTable[col,row] > scoreTable[bestPosList[0].Col,bestPosList[0].Row])
                        {
                            bestPosList.Clear();
                            bestPosList.Add(new Position(row,col));
                        }
                        else if (scoreTable[col,row] == scoreTable[bestPosList[0].Col,bestPosList[0].Row])
                        {
                            bestPosList.Add(new Position(row, col));
                        }
                    }
                }
            }

            //generally connot happen,there is no bestPos
            if (bestPosList.Count==0)
            {
                return new Position(-1,-1);
            }

            Random rnd=new Random();
            int index=rnd.Next(bestPosList.Count);
            while (IsFobidden(ref chessBoard, bestPosList[index],pieceType))
            {
                invalidBestPos.Add(bestPosList[index]);
                bestPosList.RemoveAt(index);
                index = rnd.Next(bestPosList.Count);
                if (index == 0)
                {
                    FindBestPos(ref chessBoard, pieceType);
                }
            }

            invalidBestPos.Clear();
            return bestPosList[index];
        }
 public virtual IRelativePathProvider GetProviderByPieceType(PieceTypeEnum pieceType)
 {
     switch (pieceType)
     {
         case PieceTypeEnum.Pawn: return new PawnRelativePathProvider();
         case PieceTypeEnum.Rook: return new RookRelativePathProvider();
         case PieceTypeEnum.Knight: return new KnightRelativePathProvider();
         case PieceTypeEnum.Bishop: return new BishopRelativePathProvider();
         case PieceTypeEnum.Queen: return new QueenRelativePathProvider();
         case PieceTypeEnum.King: return new KingRelativePathProvider();
         default: throw new NotImplementedException(pieceType.ToString());
     }
 }
Пример #11
0
        /// <summary>
        /// 获得当前五子棋策略的下一步落棋位置。
        /// </summary>
        /// <param name="chessBoard">五子棋棋盘对象。</param>
        /// <param name="pieceType">棋子的类型。</param>
        /// <param name="stepIndex">下一步落子操作的序号。</param>
        /// <param name="prevStep">包含对方上一步落子操作信息的走步对象。</param>
        /// <returns>下一步落棋的位置。</returns>
        public ChessBoardPoint GetNextStep(IChessBoard chessBoard, PieceTypeEnum pieceType, int stepIndex, PlayStep?prevStep)
        {
            //change the frame of axes to our(   |_  to |-  )
            //判断是否为黑方的第一手棋
            if (stepIndex == 0 && pieceType == PieceTypeEnum.Black)
            {
                // update score table
                UpdateScoreTable(ref chessBoard, new Position(7, 7), PieceTypeEnum.Black);

                //如果是黑方的第一手棋,则总是返回天元
                return(ChessBoardPoint.TENGEN);
            }
            else if (stepIndex == 1 && pieceType == PieceTypeEnum.White)
            {
                //change scoreTable to defensive order
                for (int i = 1; i < 5; i++)
                {
                    int tmp = tupleScoreTable[i];
                    tupleScoreTable[i]     = tupleScoreTable[i + 4];
                    tupleScoreTable[i + 4] = tmp;
                }
            }

            Position preStepPos = new Position(14 - prevStep.Value.Location.RowIndex, prevStep.Value.Location.ColumnIndex);

            //update score table for changes caused by previous step
            UpdateScoreTable(ref chessBoard, preStepPos, prevStep.Value.PieceType);

            // position to play chess
            Position bestPos = FindBestPos(ref chessBoard, prevStep.Value.PieceType);

            //update score table for changes caused by this step
            UpdateScoreTable(ref chessBoard, bestPos, prevStep.Value.PieceType == PieceTypeEnum.Black?PieceTypeEnum.White:PieceTypeEnum.Black);

            return(new ChessBoardPoint(14 - bestPos.Row, bestPos.Col));
        }
Пример #12
0
        /// <summary>
        /// update score table
        /// </summary>
        /// <param name="scoreTable"></param>
        /// <param name="col">columnIndex of new joined chess</param>
        /// <param name="row">rowIndex of new joined chess</param>
        private void UpdateScoreTable(ref IChessBoard chessBoard, Position pos,PieceTypeEnum pieceType)
        {
            //could not happen
            /*            if (chessBoard.GetPointState(pos.Col,pos.Row)!=PointStateEnum.Blank)
            {
                return;
            }
            */
            #region ---partial board

            //get all the 32 piece states surrounding this position
            ExtendedPointStateEnum[,] pointState=new ExtendedPointStateEnum[4,9];

            int row,col;
            //horizontal
            for (col = pos.Col - 4; col < pos.Col + 5;col++)
            {
                if (col<0||col>14)
                {
                    pointState[0,col-pos.Col+4]=ExtendedPointStateEnum.Virtual;
                }
                else
                {
                    pointState[0, col - pos.Col + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(pos.Row,col);
                }
            }
            //vertical
            for (row = pos.Row - 4; row < pos.Row + 5;row++ )
            {
                if (row<0||row>14)
                {
                    pointState[1, row - pos.Row + 4] = ExtendedPointStateEnum.Virtual;
                }
                else
                {
                    pointState[1, row - pos.Row + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(row,pos.Col);
                }
            }
            //backslash
            for (row = pos.Row - 4, col = pos.Col - 4; row < pos.Row + 5;row++,col++ )
            {
                if (row < 0 || row > 14 || col < 0 || col > 14)
                {
                    pointState[2, row - pos.Row + 4] = ExtendedPointStateEnum.Virtual;
                }
                else
                {
                    pointState[2, row - pos.Row + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(row, col);
                }
            }
            //slash
            for (row = pos.Row + 4, col = pos.Col - 4; row > pos.Row - 5; row--, col++)
            {
                if (row < 0 || row > 14 || col < 0 || col > 14)
                {
                    pointState[3, col - pos.Col + 4] = ExtendedPointStateEnum.Virtual;
                }
                else
                {
                    pointState[3, col - pos.Col + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(col, col);
                }
            }
            //assume the center of partial board is empty
            for (int m = 0; m < 4;m++ )
            {
                pointState[m, 4] = ExtendedPointStateEnum.Blank;
            }

            #endregion

            #region ---recognize formerTuples
            //recognize types of all the 20 Tuples .
            TupleType[,] formerTuples = new TupleType[4, 5];
            TupleType[,] changedTuples = new TupleType[4, 5];

            int white, black, blank;
            for (int i = 0; i < 4;i++ )
            {
                int start=0;
                int finish = 0;
                //deal with virtual tuples from front
                for (int j = 0; j < 4;j++ )
                {
                    if (pointState[i,j]==ExtendedPointStateEnum.Virtual)
                    {
                        changedTuples[i,j] = formerTuples[i, j] = TupleType.Virtual;
                    }
                    else
                    {
                        start = j;
                        break;//jump inner layer loop
                    }

                }
                //deal with virtual tuples from back
                for (int j = 8; j >= 5;j-- )
                {
                    if (pointState[i, j] == ExtendedPointStateEnum.Virtual)
                    {
                        changedTuples[i, j-4] = formerTuples[i, j - 4] = TupleType.Virtual;
                    }
                    else
                    {
                        finish = j;
                        break;//jump inner layer loop
                    }
                }

                white = black = blank = 0;
                //start recognize general tuples,deal with first four points
                for (int j = start; j <start+4;j++ )
                {
                    if (pointState[i, j] == ExtendedPointStateEnum.Blank)
                    {
                        blank++;
                    }
                    else if (pointState[i, j] == ExtendedPointStateEnum.Black)
                    {
                        black++;
                    }
                    else if (pointState[i, j] == ExtendedPointStateEnum.White)
                    {
                        white++;
                    }
                }
                //tuples recognition sliding
                for (int j = start + 4; j <= finish;j++ )
                {
                    if (pointState[i, j] == ExtendedPointStateEnum.Blank)
                    {
                        blank++;
                    }
                    else if (pointState[i, j] == ExtendedPointStateEnum.Black)
                    {
                        black++;
                    }
                    else if (pointState[i, j] == ExtendedPointStateEnum.White)
                    {
                        white++;
                    }
                    //deal with formerTuples
                    if (black > 0 && white > 0)
                    {
                        formerTuples[i, j - 4] = TupleType.Polluted;
                    }
                    else if (black == 0 && white == 0)
                    {
                        formerTuples[i, j - 4] = TupleType.Blank;
                    }
                    else if (black == 0)
                    {
                        formerTuples[i, j - 4] = (TupleType)(white + 4);
                    }
                    else
                    {
                        formerTuples[i, j - 4] = (TupleType)black;
                    }
                    //deal with changedTuples,increase for change
                    if (pieceType==PieceTypeEnum.Black)
                    {
                        black++;
                    }
                    else
                    {
                        white++;
                    }
                    //recognize
                    if (black > 0 && white > 0)
                    {
                        changedTuples[i, j - 4] = TupleType.Polluted;
                    }
                    else if (black == 0 && white == 0)
                    {
                        changedTuples[i, j - 4] = TupleType.Blank;
                    }
                    else if (black == 0)
                    {
                        changedTuples[i, j - 4] = (TupleType)(white + 4);
                    }
                    else
                    {
                        changedTuples[i, j - 4] = (TupleType)black;
                    }
                    //deal with changedTuples,decrease
                    if (pieceType == PieceTypeEnum.Black)
                    {
                        black--;
                    }
                    else
                    {
                        white--;
                    }

                    //slide to next tuple ,so the first of current tuple should be dropped
                    if (pointState[i, j-4] == ExtendedPointStateEnum.Blank)
                    {
                        blank--;
                    }
                    else if (pointState[i, j-4] == ExtendedPointStateEnum.Black)
                    {
                        black--;
                    }
                    else if (pointState[i, j-4] == ExtendedPointStateEnum.White)
                    {
                        white--;
                    }
                }
            }
            #endregion

            #region ---update scores of correlative points

            //score changed caused by this chess
            int[,] changedScore = new int[4, 5];
            for (int i = 0; i < 4;i++ )
            {
                for (int j = 0; j < 5;j++ )
                {
                    int score=tupleScoreTable[(int)changedTuples[i,j]]-tupleScoreTable[(int)formerTuples[i,j]];
                    changedScore[i, j] = score;
                }
            }

            //internal calculation
            int[,] changedScoreSum = new int[4, 9];
            for (int i = 0; i < 4;i++ )
            {
                for (int j = 0; j < 4;j++ )
                {
                    int sum=0;
                    for (int m=0;m<=j;m++)
                    {
                        sum+=changedScore[i,m];
                    }
                    changedScoreSum[i,j]=sum;
                }
                for (int j = 8; j > 4;j-- )
                {
                    int sum = 0;
                    for (int m=8;m>=j;m--)
                    {
                        sum += changedScore[i, m-4];
                    }
                    changedScoreSum[i, j] = sum;
                }
            }
            //update center point,occupied point's score is 0
            scoreTable[pos.Col, pos.Row] = 0;
            //update general points
            //horizontal
            for (col = (pos.Col >= 4?pos.Col-4:0);
                col <= (pos.Col <=10?pos.Col+4:14);
                col++)
            {
                if (scoreTable[col,pos.Row]!=0)//not occupied
                {
                    scoreTable[col, pos.Row] += changedScoreSum[0, col - pos.Col + 4];
                    if (scoreTable[col, pos.Row] < 0)
                    {
                        scoreTable[col, pos.Row] = 0;
                    }
                }
            }
            //vertical
            for (row = (pos.Row >= 4 ? pos.Row - 4 : 0);
                row <= (pos.Row <= 10 ? pos.Row + 4 : 14);
                row++)
            {
                if (scoreTable[pos.Col, row] != 0)//not occupied
                {
                    scoreTable[pos.Col, row] += changedScoreSum[1, row - pos.Row + 4];
                    if (scoreTable[pos.Col, row] < 0)
                    {
                        scoreTable[pos.Col, row] = 0;
                    }
                }
            }
            //backslash
            for (col = (pos.Col >= 4 ? pos.Col - 4 : 0),
                row = (pos.Row >= 4 ? pos.Row - 4 : 0);
                col <= (pos.Col <= 10 ? pos.Col + 4 : 14) &&
                row <= (pos.Row <= 10 ? pos.Row + 4 : 14);
                col++,row++)
            {
                if (scoreTable[col, row] != 0)//not occupied
                {
                    scoreTable[col, row] += changedScoreSum[2, row - pos.Row + 4];
                    if (scoreTable[col, row]<0)
                    {
                        scoreTable[col, row] = 0;
                    }
                }
            }
            //slash
            for (col = (pos.Col >= 4 ? pos.Col - 4 : 0),
                row = (pos.Row <= 10 ? pos.Row + 4 : 14);
                col <= (pos.Col <= 10 ? pos.Col + 4 : 14) &&
                row >= (pos.Row >= 4 ? pos.Row - 4 : 0);
                col++, row--)
            {
                if (scoreTable[col, row] != 0)//not occupied
                {
                    scoreTable[col, row] += changedScoreSum[3, col - pos.Col + 4];
                    if (scoreTable[col, row] < 0)
                    {
                        scoreTable[col, row] = 0;
                    }
                }
            }

            #endregion
        }
Пример #13
0
        //is forbidden
        private bool IsFobidden(ref IChessBoard chessBoard, Position point, PieceTypeEnum pieceType)
        {
            Referee platformCheck = new Referee();
            PlayStepResultEnum stepResult = platformCheck.Check(chessBoard, new ChessBoardPoint(14 - point.Row, point.Col), PieceTypeEnum.Black);
            //it seems the platform does not check four-three-three

            if (stepResult == PlayStepResultEnum.Four_Four ||
               stepResult == PlayStepResultEnum.Three_Three ||
               stepResult == PlayStepResultEnum.Overline)
            {
                if (pieceType == PieceTypeEnum.Black)
                {
                    return true;
                }
                else
                {
                    //white priority vs. black forbidden
                    //if this position is black-forbidden,generally white should not be put here
                    //but if is advantaged enough for white,it should
                    if (PlayStepResultEnum.Win == platformCheck.Check(chessBoard, new ChessBoardPoint(14 - point.Row, point.Col), PieceTypeEnum.White))
                    {
                        return false;
                    }
                    else
                    {
                        return true;
                    }
                }
            }
            return false;
        }
Пример #14
0
        public ChessBoardPoint GetNextStep(IChessBoard chessBoard, PieceTypeEnum pieceType, int stepIndex, PlayStep? prevStep)
        {
            int[] tupleScoreTable = new int[11] { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            //initialize tuple score table
            if (stepIndex % 2 == 0)//even step is first hand,i.e. the black side
            {
                if (stepIndex == 0)
                {
                    return ChessBoardPoint.TENGEN;
                }
                else if(stepIndex==2)
                {
                    Position[][] classicalOpen = new Position[8][];
                    //0:white is on left side of Tengen
                    classicalOpen[0]=new Position[21]{
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position()};
                    //1:white is on up side of Tengen
                    classicalOpen[1]=new Position[21]{
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position()};
                    //2:white is on right side of Tengen
                    classicalOpen[2]=new Position[21]{
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position()};
                    //3:white is on bottom side of Tengen
                    classicalOpen[3]=new Position[21]{
                        new Position(8,8),new Position(9,7),new Position(7,8),new Position(7,9),
                        new Position(8,9),new Position(6,9),new Position(5,8),new Position(6,8),
                        new Position(6,7),new Position(5,7),new Position(9,9),new Position(5,5),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position()};
                    //4:white is on topleft corner of Tengen
                    classicalOpen[4]=new Position[25]{
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position()};
                    //5:white is on topright corner of Tengen
                    classicalOpen[5]=new Position[25]{
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position()};
                    //6:white is on bottomright corner of Tengen
                    classicalOpen[6]=new Position[25]{
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position()};
                    //7:white is on bottomleft corner of Tengen
                    classicalOpen[7] = new Position[25]{
                        new Position(6,6),new Position(7,5),new Position(7,6),new Position(6,5),
                        new Position(8,5),new Position(6,8),new Position(9,5),new Position(7,9),
                        new Position(5,5),new Position(5,6),new Position(7,8),new Position(5,8),
                        new Position(5,9),new Position(8,5),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position(),new Position(),new Position(),new Position(),
                        new Position()};

                    Position whiteFirst = new Position(14-prevStep.Value.Location.RowIndex, prevStep.Value.Location.ColumnIndex);
                    switch ()
                    {
                    case :
                        break;
                    }
                }
                tupleScoreTable[1] = 35;
                tupleScoreTable[2] = 800;
                tupleScoreTable[3] = 15000;
                tupleScoreTable[4] = 800000;
                tupleScoreTable[5] = 15;
                tupleScoreTable[6] = 400;
                tupleScoreTable[7] = 1800;
                tupleScoreTable[8] = 100000;
            }
            else//odd step is back hand,i.e. the white side
            {
                tupleScoreTable[1] = 15;
                tupleScoreTable[2] = 400;
                tupleScoreTable[3] = 1800;
                tupleScoreTable[4] = 100000;
                tupleScoreTable[5] = 35;
                tupleScoreTable[6] = 800;
                tupleScoreTable[7] = 15000;
                tupleScoreTable[8] = 800000;
            }

            //extended board,with virtual points
            ExtendedPointStateEnum[,] exPointStates = new ExtendedPointStateEnum[23, 23];
            for (int row = 0; row < 23; row++)
            {
                for (int col = 0; col < 23; col++)
                {
                    if (row < 4 || row > 18 || col < 4 || col > 18)
                    {
                        exPointStates[row, col] = ExtendedPointStateEnum.Virtual;
                    }
                    else
                    {
                        exPointStates[row, col] = (ExtendedPointStateEnum)chessBoard.GetPointState(14 - (row - 4), col - 4);
                    }
                }
            }

            int[,] scoreTable = new int[15, 15];

            /// <summary>calculate type of every tuple</summary>
            /// <description>In order to give a clear train of thought,
            /// I used an intuitionistic method to do this work.
            /// But this results in not efficient.
            /// Every tuple is calculated for twice.
            /// But it's easy to modify it:two ends of a tuple own the same tuple
            /// I'll modify it in next version ,where efficiency becomes bottleneck.
            /// </description>
            //every point indexs 8 tuples around it
            TupleType[, ,] tupleTable = new TupleType[15, 15, 8];
            for (int row = 4; row < 19; row++)
            {
                for (int col = 4; col < 19; col++)
                {
                    int[] white = new int[8];//white points in a tuple
                    int[] black = new int[8];//black points in a tuple
                    #region ---check tuples of every direction
                    //left ,index 0
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row, col - i] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 0] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row, col - i] == ExtendedPointStateEnum.Black)
                        {
                            black[0]++;
                        }
                        else if (exPointStates[row, col - i] == ExtendedPointStateEnum.White)
                        {
                            white[0]++;
                        }
                    }
                    //top left,index 1
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row - i, col - i] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 1] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row - i, col - i] == ExtendedPointStateEnum.Black)
                        {
                            black[1]++;
                        }
                        else if (exPointStates[row - i, col - i] == ExtendedPointStateEnum.White)
                        {
                            white[1]++;
                        }
                    }
                    //up ,index 2
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row - i, col] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 2] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row - i, col] == ExtendedPointStateEnum.Black)
                        {
                            black[2]++;
                        }
                        else if (exPointStates[row - i, col] == ExtendedPointStateEnum.White)
                        {
                            white[2]++;
                        }
                    }
                    //top right,index 3
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row - i, col + i] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 3] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row - i, col + i] == ExtendedPointStateEnum.Black)
                        {
                            black[3]++;
                        }
                        else if (exPointStates[row - i, col + i] == ExtendedPointStateEnum.White)
                        {
                            white[3]++;
                        }
                    }
                    //right,index 4
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row, col + i] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 4] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row, col + i] == ExtendedPointStateEnum.Black)
                        {
                            black[4]++;
                        }
                        else if (exPointStates[row, col + i] == ExtendedPointStateEnum.White)
                        {
                            white[4]++;
                        }
                    }
                    //bottom right,index 5
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row + i, col + i] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 5] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row + i, col + i] == ExtendedPointStateEnum.Black)
                        {
                            black[5]++;
                        }
                        else if (exPointStates[row + i, col + i] == ExtendedPointStateEnum.White)
                        {
                            white[5]++;
                        }
                    }
                    //bottom,index 6
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row + i, col] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 6] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row + i, col] == ExtendedPointStateEnum.Black)
                        {
                            black[6]++;
                        }
                        else if (exPointStates[row + i, col] == ExtendedPointStateEnum.White)
                        {
                            white[6]++;
                        }
                    }
                    //bottom left,index 7
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row + i, col - i] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 7] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row + i, col - i] == ExtendedPointStateEnum.Black)
                        {
                            black[7]++;
                        }
                        else if (exPointStates[row + i, col - i] == ExtendedPointStateEnum.White)
                        {
                            white[7]++;
                        }
                    }
                    #endregion //check tuples of every direction

                    //decide tuple type
                    for (int i = 0; i < 8; i++)
                    {
                        //already assigned
                        if (tupleTable[row - 4, col - 4, i] == TupleType.Virtual)
                        {
                            continue;
                        }
                        if (white[i] > 0 && black[i] > 0)
                        {
                            tupleTable[row - 4, col - 4, i] = TupleType.Polluted;
                        }
                        else if (white[i] == 0 && black[i] == 0)
                        {
                            tupleTable[row - 4, col - 4, i] = TupleType.Blank;
                        }
                        else if (white[i] == 0)
                        {
                            tupleTable[row - 4, col - 4, i] = (TupleType)black[i];
                        }
                        else
                        {
                            tupleTable[row - 4, col - 4, i] = (TupleType)(white[i] + 4);
                        }
                    }
                }
            }
            #region ---scoreTable calculate
            //calculate score table . using symmetry
            //top left corner
            for (int row = 0; row < 8; row++)
            {
                for (int col = 0; col < 8; col++)
                {
                    if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank)
                    {
                        //this situation has been considered
                        //scoreTable[row,col]=0;
                        continue;
                    }
                    for (int m = 0; m < 5; m++)
                    {
                        if (row >= m)//top right
                        {
                            scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col + m, 7]];
                        }
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col, 2]];//bottom
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col + m, 1]];//bottom right
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col + m, 0]];//right
                    }
                }
            }
            //top right corner
            for (int row = 0; row < 8; row++)
            {
                for (int col = 8; col < 15; col++)
                {
                    if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank)
                    {
                        //this situation has been considered
                        //scoreTable[row,col]=0;
                        continue;
                    }
                    for (int m = 0; m < 5; m++)
                    {
                        if (row >= m)//top left
                        {
                            scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col - m, 5]];
                        }
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col, 2]];//bottom
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col - m, 3]];//bottom left
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col - m, 4]];//left
                    }
                }
            }
            //bottom left corner
            for (int row = 8; row < 15; row++)
            {
                for (int col = 0; col < 8; col++)
                {
                    if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank)
                    {
                        //this situation has been considered
                        //scoreTable[row,col]=0;
                        continue;
                    }
                    for (int m = 0; m < 5; m++)
                    {
                        if (row + m < 15)//bottom right
                        {
                            scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col + m, 1]];
                        }
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col, 6]];//top
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col + m, 7]];//top right
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col + m, 0]];//right
                    }
                }
            }
            //bottom right corner
            for (int row = 8; row < 15; row++)
            {
                for (int col = 8; col < 15; col++)
                {
                    if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank)
                    {
                        //this situation has been considered
                        //scoreTable[row,col]=0;
                        continue;
                    }
                    for (int m = 0; m < 5; m++)
                    {
                        if (row + m < 15)//bottom left
                        {
                            scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col - m, 3]];
                        }
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col, 6]];//top
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col - m, 5]];//top left
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col - m, 4]];//left
                    }
                }
            }
            #endregion //scoreTable

            //select best position
            List<Position> bestList = new List<Position>();

            //select first valid point
            Position first = new Position(0, 0);
            //all the point is forbidden.connot happen
            //while (IsFobidden(first))
            //{
            //    while (IsFobidden(first))
            //    {
            //        if (first.Col<14)
            //        {
            //            first.Col++;
            //        }
            //        else
            //        {
            //            break;
            //        }
            //    }
            //    if (first.Row<14)
            //    {
            //        first.Row++;
            //    }
            //    else
            //    {
            //        break;
            //    }
            //}
            while (IsFobidden(ref chessBoard, first, pieceType))
            {
                if (first.Col < 14)
                {
                    first.Col++;
                }
                else if (first.Row < 14)
                {
                    first.Row++;
                    first.Col = 0;
                }
                else
                {
                    return new ChessBoardPoint(-1, -1);
                }
            }
            bestList.Add(first);

            Referee checkWin = new Referee();
            //select best points
            for (int row = 0; row < 15; row++)
            {
                for (int col = 0; col < 15; col++)
                {
                    if (scoreTable[row, col] > scoreTable[bestList[0].Row, bestList[0].Col])
                    {
                        Position best = new Position(row, col);
                        if (!IsFobidden(ref chessBoard, best, pieceType))
                        {
                            bestList.Clear();
                            bestList.Add(best);
                        }

                    }
                    else if (scoreTable[row, col] == scoreTable[bestList[0].Row, bestList[0].Col])
                    {
                        Position best = new Position(row, col);
                        if (!IsFobidden(ref chessBoard, best, pieceType))
                        {
                            bestList.Add(best);
                        }
                    }
                }
            }
            //there is no best .connot happen
            if (bestList.Count == 0)
            {
                return new ChessBoardPoint(-1, -1);
            }
            Position ret = bestList[(new Random()).Next(bestList.Count)];
            return new ChessBoardPoint(14 - ret.Row, ret.Col);
        }
Пример #15
0
 public void UpdateScoreTableTest()
 {
     PlayStrategy_Accessor target = new PlayStrategy_Accessor(); // TODO: 初始化为适当的值
     IChessBoard chessBoard = null; // TODO: 初始化为适当的值
     IChessBoard chessBoardExpected = null; // TODO: 初始化为适当的值
     Position pos = null; // TODO: 初始化为适当的值
     PieceTypeEnum pieceType = new PieceTypeEnum(); // TODO: 初始化为适当的值
     target.UpdateScoreTable(ref chessBoard, pos, pieceType);
     Assert.AreEqual(chessBoardExpected, chessBoard);
     Assert.Inconclusive("无法验证不返回值的方法。");
 }
Пример #16
0
        public List<string> GetPiecesOfType(PlayerTypeEnum player, PieceTypeEnum piece)
        {
            List<string> s = new List<string>();

            for (int row = 0; row < 8; row++)
            {
                for (int col = 0; col < 8; col++)
                {
                    ChessPiece p = _boardState[row, col];
                    if (p == null || p.Player != player || p.Type != piece)
                        continue;

                    string notation = NotationHelper.Translate(row, col);
                    s.Add(notation);
                }
            }

            return s;
        }
Пример #17
0
        /// <summary>
        /// update score table
        /// </summary>
        /// <param name="scoreTable"></param>
        /// <param name="col">columnIndex of new joined chess</param>
        /// <param name="row">rowIndex of new joined chess</param>
        private void UpdateScoreTable(ref IChessBoard chessBoard, Position pos, PieceTypeEnum pieceType)
        {
            //could not happen

/*            if (chessBoard.GetPointState(pos.Col,pos.Row)!=PointStateEnum.Blank)
 *          {
 *              return;
 *          }
 */
            #region ---partial board

            //get all the 32 piece states surrounding this position
            ExtendedPointStateEnum[,] pointState = new ExtendedPointStateEnum[4, 9];

            int row, col;
            //horizontal
            for (col = pos.Col - 4; col < pos.Col + 5; col++)
            {
                if (col < 0 || col > 14)
                {
                    pointState[0, col - pos.Col + 4] = ExtendedPointStateEnum.Virtual;
                }
                else
                {
                    pointState[0, col - pos.Col + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(pos.Row, col);
                }
            }
            //vertical
            for (row = pos.Row - 4; row < pos.Row + 5; row++)
            {
                if (row < 0 || row > 14)
                {
                    pointState[1, row - pos.Row + 4] = ExtendedPointStateEnum.Virtual;
                }
                else
                {
                    pointState[1, row - pos.Row + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(row, pos.Col);
                }
            }
            //backslash
            for (row = pos.Row - 4, col = pos.Col - 4; row < pos.Row + 5; row++, col++)
            {
                if (row < 0 || row > 14 || col < 0 || col > 14)
                {
                    pointState[2, row - pos.Row + 4] = ExtendedPointStateEnum.Virtual;
                }
                else
                {
                    pointState[2, row - pos.Row + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(row, col);
                }
            }
            //slash
            for (row = pos.Row + 4, col = pos.Col - 4; row > pos.Row - 5; row--, col++)
            {
                if (row < 0 || row > 14 || col < 0 || col > 14)
                {
                    pointState[3, col - pos.Col + 4] = ExtendedPointStateEnum.Virtual;
                }
                else
                {
                    pointState[3, col - pos.Col + 4] = (ExtendedPointStateEnum)chessBoard.GetPointState(col, col);
                }
            }
            //assume the center of partial board is empty
            for (int m = 0; m < 4; m++)
            {
                pointState[m, 4] = ExtendedPointStateEnum.Blank;
            }

            #endregion


            #region ---recognize formerTuples
            //recognize types of all the 20 Tuples .
            TupleType[,] formerTuples  = new TupleType[4, 5];
            TupleType[,] changedTuples = new TupleType[4, 5];

            int white, black, blank;
            for (int i = 0; i < 4; i++)
            {
                int start  = 0;
                int finish = 0;
                //deal with virtual tuples from front
                for (int j = 0; j < 4; j++)
                {
                    if (pointState[i, j] == ExtendedPointStateEnum.Virtual)
                    {
                        changedTuples[i, j] = formerTuples[i, j] = TupleType.Virtual;
                    }
                    else
                    {
                        start = j;
                        break;//jump inner layer loop
                    }
                }
                //deal with virtual tuples from back
                for (int j = 8; j >= 5; j--)
                {
                    if (pointState[i, j] == ExtendedPointStateEnum.Virtual)
                    {
                        changedTuples[i, j - 4] = formerTuples[i, j - 4] = TupleType.Virtual;
                    }
                    else
                    {
                        finish = j;
                        break;//jump inner layer loop
                    }
                }

                white = black = blank = 0;
                //start recognize general tuples,deal with first four points
                for (int j = start; j < start + 4; j++)
                {
                    if (pointState[i, j] == ExtendedPointStateEnum.Blank)
                    {
                        blank++;
                    }
                    else if (pointState[i, j] == ExtendedPointStateEnum.Black)
                    {
                        black++;
                    }
                    else if (pointState[i, j] == ExtendedPointStateEnum.White)
                    {
                        white++;
                    }
                }
                //tuples recognition sliding
                for (int j = start + 4; j <= finish; j++)
                {
                    if (pointState[i, j] == ExtendedPointStateEnum.Blank)
                    {
                        blank++;
                    }
                    else if (pointState[i, j] == ExtendedPointStateEnum.Black)
                    {
                        black++;
                    }
                    else if (pointState[i, j] == ExtendedPointStateEnum.White)
                    {
                        white++;
                    }
                    //deal with formerTuples
                    if (black > 0 && white > 0)
                    {
                        formerTuples[i, j - 4] = TupleType.Polluted;
                    }
                    else if (black == 0 && white == 0)
                    {
                        formerTuples[i, j - 4] = TupleType.Blank;
                    }
                    else if (black == 0)
                    {
                        formerTuples[i, j - 4] = (TupleType)(white + 4);
                    }
                    else
                    {
                        formerTuples[i, j - 4] = (TupleType)black;
                    }
                    //deal with changedTuples,increase for change
                    if (pieceType == PieceTypeEnum.Black)
                    {
                        black++;
                    }
                    else
                    {
                        white++;
                    }
                    //recognize
                    if (black > 0 && white > 0)
                    {
                        changedTuples[i, j - 4] = TupleType.Polluted;
                    }
                    else if (black == 0 && white == 0)
                    {
                        changedTuples[i, j - 4] = TupleType.Blank;
                    }
                    else if (black == 0)
                    {
                        changedTuples[i, j - 4] = (TupleType)(white + 4);
                    }
                    else
                    {
                        changedTuples[i, j - 4] = (TupleType)black;
                    }
                    //deal with changedTuples,decrease
                    if (pieceType == PieceTypeEnum.Black)
                    {
                        black--;
                    }
                    else
                    {
                        white--;
                    }

                    //slide to next tuple ,so the first of current tuple should be dropped
                    if (pointState[i, j - 4] == ExtendedPointStateEnum.Blank)
                    {
                        blank--;
                    }
                    else if (pointState[i, j - 4] == ExtendedPointStateEnum.Black)
                    {
                        black--;
                    }
                    else if (pointState[i, j - 4] == ExtendedPointStateEnum.White)
                    {
                        white--;
                    }
                }
            }
            #endregion

            #region ---update scores of correlative points

            //score changed caused by this chess
            int[,] changedScore = new int[4, 5];
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    int score = tupleScoreTable[(int)changedTuples[i, j]] - tupleScoreTable[(int)formerTuples[i, j]];
                    changedScore[i, j] = score;
                }
            }

            //internal calculation
            int[,] changedScoreSum = new int[4, 9];
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    int sum = 0;
                    for (int m = 0; m <= j; m++)
                    {
                        sum += changedScore[i, m];
                    }
                    changedScoreSum[i, j] = sum;
                }
                for (int j = 8; j > 4; j--)
                {
                    int sum = 0;
                    for (int m = 8; m >= j; m--)
                    {
                        sum += changedScore[i, m - 4];
                    }
                    changedScoreSum[i, j] = sum;
                }
            }
            //update center point,occupied point's score is 0
            scoreTable[pos.Col, pos.Row] = 0;
            //update general points
            //horizontal
            for (col = (pos.Col >= 4?pos.Col - 4:0);
                 col <= (pos.Col <= 10?pos.Col + 4:14);
                 col++)
            {
                if (scoreTable[col, pos.Row] != 0)//not occupied
                {
                    scoreTable[col, pos.Row] += changedScoreSum[0, col - pos.Col + 4];
                    if (scoreTable[col, pos.Row] < 0)
                    {
                        scoreTable[col, pos.Row] = 0;
                    }
                }
            }
            //vertical
            for (row = (pos.Row >= 4 ? pos.Row - 4 : 0);
                 row <= (pos.Row <= 10 ? pos.Row + 4 : 14);
                 row++)
            {
                if (scoreTable[pos.Col, row] != 0)//not occupied
                {
                    scoreTable[pos.Col, row] += changedScoreSum[1, row - pos.Row + 4];
                    if (scoreTable[pos.Col, row] < 0)
                    {
                        scoreTable[pos.Col, row] = 0;
                    }
                }
            }
            //backslash
            for (col = (pos.Col >= 4 ? pos.Col - 4 : 0),
                 row = (pos.Row >= 4 ? pos.Row - 4 : 0);
                 col <= (pos.Col <= 10 ? pos.Col + 4 : 14) &&
                 row <= (pos.Row <= 10 ? pos.Row + 4 : 14);
                 col++, row++)
            {
                if (scoreTable[col, row] != 0)//not occupied
                {
                    scoreTable[col, row] += changedScoreSum[2, row - pos.Row + 4];
                    if (scoreTable[col, row] < 0)
                    {
                        scoreTable[col, row] = 0;
                    }
                }
            }
            //slash
            for (col = (pos.Col >= 4 ? pos.Col - 4 : 0),
                 row = (pos.Row <= 10 ? pos.Row + 4 : 14);
                 col <= (pos.Col <= 10 ? pos.Col + 4 : 14) &&
                 row >= (pos.Row >= 4 ? pos.Row - 4 : 0);
                 col++, row--)
            {
                if (scoreTable[col, row] != 0)//not occupied
                {
                    scoreTable[col, row] += changedScoreSum[3, col - pos.Col + 4];
                    if (scoreTable[col, row] < 0)
                    {
                        scoreTable[col, row] = 0;
                    }
                }
            }

            #endregion
        }
Пример #18
0
        /// <summary>
        /// 获得当前五子棋策略的下一步落棋位置。
        /// </summary>
        /// <param name="chessBoard">五子棋棋盘对象。</param>
        /// <param name="pieceType">棋子的类型。</param>
        /// <param name="stepIndex">下一步落子操作的序号。</param>
        /// <param name="prevStep">包含对方上一步落子操作信息的走步对象。</param>
        /// <returns>下一步落棋的位置。</returns>
        public ChessBoardPoint GetNextStep(IChessBoard chessBoard, PieceTypeEnum pieceType, int stepIndex, PlayStep? prevStep)
        {
            //change the frame of axes to our(   |_  to |-  )
            //判断是否为黑方的第一手棋
            if (stepIndex == 0&&pieceType == PieceTypeEnum.Black )
            {
                // update score table
                UpdateScoreTable(ref chessBoard,new Position(7,7),PieceTypeEnum.Black);

                //如果是黑方的第一手棋,则总是返回天元
                return ChessBoardPoint.TENGEN;
            }else if(stepIndex==1&&pieceType==PieceTypeEnum.White){
                //change scoreTable to defensive order
                for (int i = 1; i < 5;i++ )
                {
                    int tmp = tupleScoreTable[i];
                    tupleScoreTable[i] = tupleScoreTable[i + 4];
                    tupleScoreTable[i + 4] = tmp;
                }
            }

            Position preStepPos = new Position(14 - prevStep.Value.Location.RowIndex, prevStep.Value.Location.ColumnIndex);

            //update score table for changes caused by previous step
            UpdateScoreTable(ref chessBoard, preStepPos,prevStep.Value.PieceType);

            // position to play chess
            Position bestPos = FindBestPos(ref chessBoard, prevStep.Value.PieceType);

            //update score table for changes caused by this step
            UpdateScoreTable(ref chessBoard,bestPos,prevStep.Value.PieceType==PieceTypeEnum.Black?PieceTypeEnum.White:PieceTypeEnum.Black);

            return new ChessBoardPoint(14-bestPos.Row,bestPos.Col);
        }
Пример #19
0
        public ChessBoardPoint GetNextStep(IChessBoard chessBoard, PieceTypeEnum pieceType, int stepIndex, PlayStep?prevStep)
        {
            int[] tupleScoreTable = new int[11] {
                7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            };
            //initialize tuple score table
            if (stepIndex % 2 == 0)//even step is first hand,i.e. the black side
            {
                if (stepIndex == 0)
                {
                    return(ChessBoardPoint.TENGEN);
                }
                else if (stepIndex == 2)
                {
                    Position[][] classicalOpen = new Position[8][];
                    //0:white is on left side of Tengen
                    classicalOpen[0] = new Position[21] {
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position()
                    };
                    //1:white is on up side of Tengen
                    classicalOpen[1] = new Position[21] {
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position()
                    };
                    //2:white is on right side of Tengen
                    classicalOpen[2] = new Position[21] {
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position()
                    };
                    //3:white is on bottom side of Tengen
                    classicalOpen[3] = new Position[21] {
                        new Position(8, 8), new Position(9, 7), new Position(7, 8), new Position(7, 9),
                        new Position(8, 9), new Position(6, 9), new Position(5, 8), new Position(6, 8),
                        new Position(6, 7), new Position(5, 7), new Position(9, 9), new Position(5, 5),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position()
                    };
                    //4:white is on topleft corner of Tengen
                    classicalOpen[4] = new Position[25] {
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position()
                    };
                    //5:white is on topright corner of Tengen
                    classicalOpen[5] = new Position[25] {
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position()
                    };
                    //6:white is on bottomright corner of Tengen
                    classicalOpen[6] = new Position[25] {
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position()
                    };
                    //7:white is on bottomleft corner of Tengen
                    classicalOpen[7] = new Position[25] {
                        new Position(6, 6), new Position(7, 5), new Position(7, 6), new Position(6, 5),
                        new Position(8, 5), new Position(6, 8), new Position(9, 5), new Position(7, 9),
                        new Position(5, 5), new Position(5, 6), new Position(7, 8), new Position(5, 8),
                        new Position(5, 9), new Position(8, 5), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position(), new Position(), new Position(), new Position(),
                        new Position()
                    };

                    Position whiteFirst = new Position(14 - prevStep.Value.Location.RowIndex, prevStep.Value.Location.ColumnIndex);
                    switch ()
                    {
                    case:
                        break;
                    }
                }
                tupleScoreTable[1] = 35;
                tupleScoreTable[2] = 800;
                tupleScoreTable[3] = 15000;
                tupleScoreTable[4] = 800000;
                tupleScoreTable[5] = 15;
                tupleScoreTable[6] = 400;
                tupleScoreTable[7] = 1800;
                tupleScoreTable[8] = 100000;
            }
            else//odd step is back hand,i.e. the white side
            {
                tupleScoreTable[1] = 15;
                tupleScoreTable[2] = 400;
                tupleScoreTable[3] = 1800;
                tupleScoreTable[4] = 100000;
                tupleScoreTable[5] = 35;
                tupleScoreTable[6] = 800;
                tupleScoreTable[7] = 15000;
                tupleScoreTable[8] = 800000;
            }

            //extended board,with virtual points
            ExtendedPointStateEnum[,] exPointStates = new ExtendedPointStateEnum[23, 23];
            for (int row = 0; row < 23; row++)
            {
                for (int col = 0; col < 23; col++)
                {
                    if (row < 4 || row > 18 || col < 4 || col > 18)
                    {
                        exPointStates[row, col] = ExtendedPointStateEnum.Virtual;
                    }
                    else
                    {
                        exPointStates[row, col] = (ExtendedPointStateEnum)chessBoard.GetPointState(14 - (row - 4), col - 4);
                    }
                }
            }

            int[,] scoreTable = new int[15, 15];

            /// <summary>calculate type of every tuple</summary>
            /// <description>In order to give a clear train of thought,
            /// I used an intuitionistic method to do this work.
            /// But this results in not efficient.
            /// Every tuple is calculated for twice.
            /// But it's easy to modify it:two ends of a tuple own the same tuple
            /// I'll modify it in next version ,where efficiency becomes bottleneck.
            /// </description>
            //every point indexs 8 tuples around it
            TupleType[, ,] tupleTable = new TupleType[15, 15, 8];
            for (int row = 4; row < 19; row++)
            {
                for (int col = 4; col < 19; col++)
                {
                    int[] white = new int[8]; //white points in a tuple
                    int[] black = new int[8]; //black points in a tuple
                    #region ---check tuples of every direction
                    //left ,index 0
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row, col - i] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 0] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row, col - i] == ExtendedPointStateEnum.Black)
                        {
                            black[0]++;
                        }
                        else if (exPointStates[row, col - i] == ExtendedPointStateEnum.White)
                        {
                            white[0]++;
                        }
                    }
                    //top left,index 1
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row - i, col - i] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 1] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row - i, col - i] == ExtendedPointStateEnum.Black)
                        {
                            black[1]++;
                        }
                        else if (exPointStates[row - i, col - i] == ExtendedPointStateEnum.White)
                        {
                            white[1]++;
                        }
                    }
                    //up ,index 2
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row - i, col] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 2] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row - i, col] == ExtendedPointStateEnum.Black)
                        {
                            black[2]++;
                        }
                        else if (exPointStates[row - i, col] == ExtendedPointStateEnum.White)
                        {
                            white[2]++;
                        }
                    }
                    //top right,index 3
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row - i, col + i] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 3] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row - i, col + i] == ExtendedPointStateEnum.Black)
                        {
                            black[3]++;
                        }
                        else if (exPointStates[row - i, col + i] == ExtendedPointStateEnum.White)
                        {
                            white[3]++;
                        }
                    }
                    //right,index 4
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row, col + i] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 4] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row, col + i] == ExtendedPointStateEnum.Black)
                        {
                            black[4]++;
                        }
                        else if (exPointStates[row, col + i] == ExtendedPointStateEnum.White)
                        {
                            white[4]++;
                        }
                    }
                    //bottom right,index 5
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row + i, col + i] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 5] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row + i, col + i] == ExtendedPointStateEnum.Black)
                        {
                            black[5]++;
                        }
                        else if (exPointStates[row + i, col + i] == ExtendedPointStateEnum.White)
                        {
                            white[5]++;
                        }
                    }
                    //bottom,index 6
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row + i, col] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 6] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row + i, col] == ExtendedPointStateEnum.Black)
                        {
                            black[6]++;
                        }
                        else if (exPointStates[row + i, col] == ExtendedPointStateEnum.White)
                        {
                            white[6]++;
                        }
                    }
                    //bottom left,index 7
                    for (int i = 0; i < 5; i++)
                    {
                        if (exPointStates[row + i, col - i] == ExtendedPointStateEnum.Virtual)
                        {
                            tupleTable[row - 4, col - 4, 7] = TupleType.Virtual;
                            break;
                        }
                        else if (exPointStates[row + i, col - i] == ExtendedPointStateEnum.Black)
                        {
                            black[7]++;
                        }
                        else if (exPointStates[row + i, col - i] == ExtendedPointStateEnum.White)
                        {
                            white[7]++;
                        }
                    }
                    #endregion //check tuples of every direction

                    //decide tuple type
                    for (int i = 0; i < 8; i++)
                    {
                        //already assigned
                        if (tupleTable[row - 4, col - 4, i] == TupleType.Virtual)
                        {
                            continue;
                        }
                        if (white[i] > 0 && black[i] > 0)
                        {
                            tupleTable[row - 4, col - 4, i] = TupleType.Polluted;
                        }
                        else if (white[i] == 0 && black[i] == 0)
                        {
                            tupleTable[row - 4, col - 4, i] = TupleType.Blank;
                        }
                        else if (white[i] == 0)
                        {
                            tupleTable[row - 4, col - 4, i] = (TupleType)black[i];
                        }
                        else
                        {
                            tupleTable[row - 4, col - 4, i] = (TupleType)(white[i] + 4);
                        }
                    }
                }
            }
            #region ---scoreTable calculate
            //calculate score table . using symmetry
            //top left corner
            for (int row = 0; row < 8; row++)
            {
                for (int col = 0; col < 8; col++)
                {
                    if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank)
                    {
                        //this situation has been considered
                        //scoreTable[row,col]=0;
                        continue;
                    }
                    for (int m = 0; m < 5; m++)
                    {
                        if (row >= m)//top right
                        {
                            scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col + m, 7]];
                        }
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col, 2]];     //bottom
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col + m, 1]]; //bottom right
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col + m, 0]];     //right
                    }
                }
            }
            //top right corner
            for (int row = 0; row < 8; row++)
            {
                for (int col = 8; col < 15; col++)
                {
                    if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank)
                    {
                        //this situation has been considered
                        //scoreTable[row,col]=0;
                        continue;
                    }
                    for (int m = 0; m < 5; m++)
                    {
                        if (row >= m)//top left
                        {
                            scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col - m, 5]];
                        }
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col, 2]];     //bottom
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col - m, 3]]; //bottom left
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col - m, 4]];     //left
                    }
                }
            }
            //bottom left corner
            for (int row = 8; row < 15; row++)
            {
                for (int col = 0; col < 8; col++)
                {
                    if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank)
                    {
                        //this situation has been considered
                        //scoreTable[row,col]=0;
                        continue;
                    }
                    for (int m = 0; m < 5; m++)
                    {
                        if (row + m < 15)//bottom right
                        {
                            scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col + m, 1]];
                        }
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col, 6]];     //top
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col + m, 7]]; //top right
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col + m, 0]];     //right
                    }
                }
            }
            //bottom right corner
            for (int row = 8; row < 15; row++)
            {
                for (int col = 8; col < 15; col++)
                {
                    if (exPointStates[row + 4, col + 4] != ExtendedPointStateEnum.Blank)
                    {
                        //this situation has been considered
                        //scoreTable[row,col]=0;
                        continue;
                    }
                    for (int m = 0; m < 5; m++)
                    {
                        if (row + m < 15)//bottom left
                        {
                            scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row + m, col - m, 3]];
                        }
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col, 6]];     //top
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row - m, col - m, 5]]; //top left
                        scoreTable[row, col] += tupleScoreTable[(int)tupleTable[row, col - m, 4]];     //left
                    }
                }
            }
            #endregion //scoreTable

            //select best position
            List <Position> bestList = new List <Position>();

            //select first valid point
            Position first = new Position(0, 0);
            //all the point is forbidden.connot happen
            //while (IsFobidden(first))
            //{
            //    while (IsFobidden(first))
            //    {
            //        if (first.Col<14)
            //        {
            //            first.Col++;
            //        }
            //        else
            //        {
            //            break;
            //        }
            //    }
            //    if (first.Row<14)
            //    {
            //        first.Row++;
            //    }
            //    else
            //    {
            //        break;
            //    }
            //}
            while (IsFobidden(ref chessBoard, first, pieceType))
            {
                if (first.Col < 14)
                {
                    first.Col++;
                }
                else if (first.Row < 14)
                {
                    first.Row++;
                    first.Col = 0;
                }
                else
                {
                    return(new ChessBoardPoint(-1, -1));
                }
            }
            bestList.Add(first);

            Referee checkWin = new Referee();
            //select best points
            for (int row = 0; row < 15; row++)
            {
                for (int col = 0; col < 15; col++)
                {
                    if (scoreTable[row, col] > scoreTable[bestList[0].Row, bestList[0].Col])
                    {
                        Position best = new Position(row, col);
                        if (!IsFobidden(ref chessBoard, best, pieceType))
                        {
                            bestList.Clear();
                            bestList.Add(best);
                        }
                    }
                    else if (scoreTable[row, col] == scoreTable[bestList[0].Row, bestList[0].Col])
                    {
                        Position best = new Position(row, col);
                        if (!IsFobidden(ref chessBoard, best, pieceType))
                        {
                            bestList.Add(best);
                        }
                    }
                }
            }
            //there is no best .connot happen
            if (bestList.Count == 0)
            {
                return(new ChessBoardPoint(-1, -1));
            }
            Position ret = bestList[(new Random()).Next(bestList.Count)];
            return(new ChessBoardPoint(14 - ret.Row, ret.Col));
        }