Пример #1
0
        public GameTree MiniMax(GameTree tree, eStoneType player, int depth)
        {
            if (depth == 0)
            {
                // 自分自身を返す
                return tree;
            }
            else if (tree.GetEnableMoveNodes().Count == 0) // ゲーム終了
            {
                return tree;
            }


            // 本来置きたい手を置く場合は最も評価値の高い手を
            // 相手の手を置く場合は最も低い手を選ぶ

            bool to_max = (player == tree.StoneType);

            int top_value = 0;
            const int inf = (int)(1e9 + 7);
            if (to_max) top_value = -inf;
            else top_value = inf;

            Dictionary<int, List<GameTree>> dict = new Dictionary<int, List<GameTree>>();

            foreach (var node in tree.GetEnableMoveNodes())
            {
                int value = MiniMax(node, player, depth - 1).GetScoreDiff();
                if (player == eStoneType.White) value *= -1;

                if (to_max)
                {
                    if (value > top_value)
                    {
                        top_value = value;
                        dict.Add(value, new List<GameTree>());
                    }
                    if (value == top_value)
                    {
                        dict[value].Add(node);
                    }
                }
                else
                {
                    if (value < top_value)
                    {
                        top_value = value;
                        dict.Add(value, new List<GameTree>());
                    }
                    if (value == top_value)
                    {
                        dict[value].Add(node);
                    }
                }
            }

            // 最も良いやつからランダム
            int n = dict[top_value].Count;
            return dict[top_value][Random.Range(0, n)];
        }
Пример #2
0
 // ゲーム木を構成する
 public GameTree(Board board, eStoneType type, int pos, bool passed)
 {
     Board              = board;
     StoneType          = type;
     PrevPos            = pos;
     PrevPassed         = passed;
     enable_move_nodes_ = null;
     score              = null;
 }
Пример #3
0
        // 盤面に石を置いて得られる石の座標を取得する
        public static List <int> GetObtainStones(Board board, int pos, eStoneType type)
        {
            int x = pos % 8;
            int y = pos / 8;

            List <int> get_stones_ = new List <int>();

            for (int i = 0; i < 8; ++i)
            {
                bool       can     = false;
                List <int> new_pos = new List <int>();

                int j = 1;
                while (!can)
                {
                    int tx = x + j * dx[i];
                    int ty = y + j * dy[i];

                    if (tx < 0 || tx >= 8)
                    {
                        break;
                    }
                    if (ty < 0 || ty >= 8)
                    {
                        break;
                    }
                    int index = GetChipIndex(tx, ty);
                    if (board[index] == eStoneType.None)
                    {
                        break;
                    }
                    if (board[index] == type)
                    {
                        can = true;
                        break;
                    }
                    // 置く
                    new_pos.Add(index);
                    ++j;
                }

                if (can)
                {
                    foreach (var p in new_pos)
                    {
                        get_stones_.Add(p);
                    }
                }
            }

            // 自分自身
            get_stones_.Add(pos);

            return(get_stones_);
        }
Пример #4
0
        // ゲームを初期化する
        private void InitGame()
        {
            // 初期の盤面を作る
            Board board = MakeInitialBoard();

            // 先行後攻どっちか
            int player = Random.Range(0, 2);
            eStoneType stone = (player == 0) ? eStoneType.Black : eStoneType.White;

            // ゲーム木を生成する
            game_tree_ = new GameTree(board, stone, -1, false);
        }
Пример #5
0
        // 実際にシミュレーションする 勝ち 1 引き分け 0.5 負け 0
        // 自分相手の手はランダム
        public float SimulateRandomPlay(eStoneType player)
        {
            GameTree node = GameTree;
            int n = node.GetEnableMoveNodes().Count;
            while (n != 0)
            {
                node = new GameTree(node.GetEnableMoveNodes()[Random.Range(0, n)]);
                n = node.GetEnableMoveNodes().Count;
            }

            int ret = ReversiUtils.JudgeResult(node.Board);
            if (player == eStoneType.White) ret *= -1;
            return ret / 2f + 0.5f;
        }
Пример #6
0
        private int SimulateRandomPlay(GameTree tree, eStoneType player)
        {
            GameTree node = tree;
            int n = node.GetEnableMoveNodes().Count;
            // ゲームが終了するまでやる
            while(n != 0)
            {
                node = new GameTree(node.GetEnableMoveNodes()[Random.Range(0, n)]);
                n = node.GetEnableMoveNodes().Count;
            }

            int ret = ReversiUtils.JudgeResult(node.Board);
            if (player == eStoneType.White) ret *= -1;
            return ret;
        }
Пример #7
0
        // 実際にシミュレーションする 勝ち 1 引き分け 0.5 負け 0
        // 相手の手法を引数で渡す
        public float SimulateSelectedPlay(eStoneType player, BasePlayer opponent)
        {
            GameTree node = GameTree;
            int n = node.GetEnableMoveNodes().Count;
            while(n != 0)
            {
                // 自分の番ならランダムに 相手の番なら指定した手法を用いて考える
                if(node.StoneType == player) node = new GameTree(node.GetEnableMoveNodes()[Random.Range(0, n)]);
                else node = opponent.Play(node);
                n = node.GetEnableMoveNodes().Count;
            }

            int ret = ReversiUtils.JudgeResult(node.Board);
            if (player == eStoneType.White) ret *= -1;
            return ret / 2f + 0.5f;
        }
Пример #8
0
        // 現在の盤面から置くことのできる手を求める
        public static List <int> GetEnableHands(Board board, eStoneType next_type)
        {
            List <int> ret = new List <int>();

            for (int y = 0; y < 8; ++y)
            {
                for (int x = 0; x < 8; ++x)
                {
                    if (board[x, y] != eStoneType.None)
                    {
                        continue;
                    }

                    bool can = false;

                    for (int i = 0; i < 8; ++i)
                    {
                        if (can)
                        {
                            break;
                        }

                        int ty = y + dy[i];
                        int tx = x + dx[i];

                        if (ty < 0 || ty >= 8)
                        {
                            continue;
                        }
                        if (tx < 0 || tx >= 8)
                        {
                            continue;
                        }

                        if (board[tx, ty] == eStoneType.None || board[tx, ty] == next_type)
                        {
                            continue;
                        }

                        int j = 2;
                        while (!can)
                        {
                            int tty = y + j * dy[i];
                            int ttx = x + j * dx[i];

                            if (tty < 0 || tty >= 8)
                            {
                                break;
                            }
                            if (ttx < 0 || ttx >= 8)
                            {
                                break;
                            }
                            if (board[ttx, tty] == eStoneType.None)
                            {
                                break;
                            }
                            if (board[ttx, tty] == next_type)
                            {
                                can = true;
                            }
                            ++j;
                        }
                    }

                    if (can)
                    {
                        ret.Add(GetChipIndex(x, y));      // 置ける
                    }
                }
            }

            return(ret);
        }
Пример #9
0
 // 次の石のタイプを取得する
 public static eStoneType NextStone(eStoneType type)
 {
     return((type == eStoneType.Black) ? eStoneType.White : eStoneType.Black);
 }