예제 #1
0
        public OthelloAppService(IEventAggregator ea, string blackAI, string whiteAI)
        {
            ea_    = ea;
            board_ = new BitBoard(34628173824, 68853694464);
            teban_ = Teban.Black;
            switch (blackAI)
            {
            case "RandomMoveAI":
                blackAI_ = new RandomMoveAI();
                break;

            case "MonteCarloAI":
                blackAI_ = new MonteCarloAI(10000);
                break;

            default:
                break;
            }
            switch (whiteAI)
            {
            case "RandomMoveAI":
                whiteAI_ = new RandomMoveAI();
                break;

            case "MonteCarloAI":
                whiteAI_ = new MonteCarloAI(10000);
                break;

            default:
                break;
            }
        }
예제 #2
0
        public static Position DecidePositionRandom(Teban teban, IBoard board)
        {
            var legalList = board.GetLegalPosistionList(teban);

            return(legalList.Count != 0
                ? legalList[Random.Next(legalList.Count)]
                : throw (new ArgumentException("合法手が存在しません", nameof(legalList))));
        }
예제 #3
0
        public List <Position> GetLegalPosistionList(Teban teban)
        {
            var legalBoard = LegalBoard(teban);
            var ll         = new List <Position>();

            while (legalBoard != 0)
            {
                var bitPosition = legalBoard & (~legalBoard + 1);
                ll.Add(ToPosition(bitPosition));
                legalBoard &= ~bitPosition;
            }
            return(ll);
        }
예제 #4
0
        private void SwitchTeban()
        {
            switch (teban_)
            {
            case Teban.Black:
                teban_ = Teban.White;
                break;

            case Teban.White:
                teban_ = Teban.Black;
                break;

            default:
                break;
            }
        }
예제 #5
0
 private (int blackStone, int whiteStone) Play(Teban teban, IBoard board)
 {
     while (true)
     {
         if (board.GetLegalPosistionList(teban).Count == 0)
         {
             teban = SwitchTeban(teban);
             if (board.GetLegalPosistionList(teban).Count == 0)
             {
                 break;
             }
         }
         board = board.PutTurn(teban, AIUtility.DecidePositionRandom(teban, board));
         teban = SwitchTeban(teban);
     }
     return(board.CountBlackStone(), board.CountWhiteStone());
 }
예제 #6
0
        public Position DecideMove(Teban teban, IBoard board)
        {
            var tebanTemp = teban;

            var legalList  = board.GetLegalPosistionList(teban);
            var countArray = new int[legalList.Count];

            for (var i = 0; i < repeatCount_; i++)
            {
                teban = tebanTemp;
                var rem = i % legalList.Count;
                board            = board.PutTurn(teban, legalList[rem]);
                teban            = SwitchTeban(teban);
                (var bs, var ws) = Play(teban, board);
                countArray[rem] += bs >= ws ? 1 : 0;
            }
            return(tebanTemp == Teban.Black
                ? legalList[Array.IndexOf(countArray, countArray.Max())]
                : legalList[Array.IndexOf(countArray, countArray.Min())]);
        }
예제 #7
0
        public IBoard PutTurn(Teban teban, Position position)
        {
            ulong playerBoard;
            ulong opponentBoard;

            if (teban == Teban.Black)
            {
                playerBoard   = blackBoard_;
                opponentBoard = whiteBoard_;
            }
            else
            {
                playerBoard   = whiteBoard_;
                opponentBoard = blackBoard_;
            }

            ulong rev = 0;

            for (var dir = 0; dir < 8; dir++)
            {
                ulong rev_ = 0;
                var   mask = Transfer(position, dir);
                while (mask != 0 && ((mask & opponentBoard) != 0))
                {
                    rev_ |= mask;
                    mask  = Transfer(ToPosition(mask), dir);
                }
                if ((mask & playerBoard) != 0)
                {
                    rev |= rev_;
                }
            }
            playerBoard   ^= ToBitPosition(position) | rev;
            opponentBoard ^= rev;
            return(teban == Teban.Black ?
                   new BitBoard(playerBoard, opponentBoard) :
                   new BitBoard(opponentBoard, playerBoard));
        }
예제 #8
0
 private Teban SwitchTeban(Teban teban)
 {
     return(teban == Teban.Black
         ? Teban.White : Teban.Black);
 }
예제 #9
0
 public Position DecideMove(Teban teban, IBoard board)
 {
     return(AIUtility.DecidePositionRandom(teban, board));
 }
예제 #10
0
        public bool IsLegal(Teban teban, Position position)
        {
            var legalList = GetLegalPosistionList(teban);

            return(legalList.Contains(position));
        }
예제 #11
0
        /// <summary>
        /// 合法手のbitのみが立ったビットボードを返す
        /// </summary>
        /// <param name="teban"></param>
        /// <returns></returns>
        private ulong LegalBoard(Teban teban)
        {
            ulong playerBoard;
            ulong opponentBoard;

            if (teban == Teban.Black)
            {
                playerBoard   = blackBoard_;
                opponentBoard = whiteBoard_;
            }
            else
            {
                playerBoard   = whiteBoard_;
                opponentBoard = blackBoard_;
            }
            //左右方向の番兵
            var hb = opponentBoard & 0x7e7e7e7e7e7e7e7e;
            //上下方向の番兵
            var vb = opponentBoard & 0x00ffffffffffff00;
            //全方向の番兵
            var ab = opponentBoard & 0x007e7e7e7e7e7e00;
            //石がない場所にbitを立てたビットボード
            var blank = ~(playerBoard | opponentBoard);

            //各8方向にそれぞれ6回シフトし隣に相手の石がある石についてbitを立てる

            //左方向
            var t = hb & (playerBoard << 1);

            for (var i = 0; i < 5; i++)
            {
                t |= hb & (t << 1);
            }
            var legalBoard = blank & (t << 1);

            //右方向
            t = hb & (playerBoard >> 1);
            for (var i = 0; i < 5; i++)
            {
                t |= hb & (t >> 1);
            }
            legalBoard |= blank & (t >> 1);
            //上方向
            t = vb & (playerBoard << 8);
            for (var i = 0; i < 5; i++)
            {
                t |= vb & (t << 8);
            }
            legalBoard |= blank & (t << 8);
            //下方向
            t = vb & (playerBoard >> 8);
            for (var i = 0; i < 5; i++)
            {
                t |= vb & (t >> 8);
            }
            legalBoard |= blank & (t >> 8);
            //左下方向
            t = ab & (playerBoard << 9);
            for (var i = 0; i < 5; i++)
            {
                t |= ab & (t << 9);
            }
            legalBoard |= blank & (t << 9);
            //右上方向
            t = ab & (playerBoard << 7);
            for (var i = 0; i < 5; i++)
            {
                t |= ab & (t << 7);
            }
            legalBoard |= blank & (t << 7);
            //左下方向
            t = ab & (playerBoard >> 7);
            for (var i = 0; i < 5; i++)
            {
                t |= ab & (t >> 7);
            }
            legalBoard |= blank & (t >> 7);
            //右下方向
            t = ab & (playerBoard >> 9);
            for (var i = 0; i < 5; i++)
            {
                t |= ab & (t >> 9);
            }
            legalBoard |= blank & (t >> 9);

            return(legalBoard);
        }