/// <summary>
        /// プログラムのメインスレッド。
        /// </summary>
        public void Run()
        {
            var rand = new Random();

            var board = new Board();
            board.Init();

            var cc = new ChessClock();
            cc.Init();

            var ai1 = new ByHandCount();
            var ai2 = new ReversiAI2();
            int forestalling = rand.Next(2);

            var ai = forestalling == 0 ? new AIInterface[] { ai1, ai2 } : new AIInterface[] { ai2, ai1 };

            Console.WriteLine("Started battle: {0} VS {1}", ai[0].Name, ai[1].Name);

            Console.WriteLine("Forestalling is {0}", ai[0].Name);

            foreach (var a in ai) cc.Register(a);

            var i = 0;

            board.PutBoard();

            int passcount = 0;

            while (board.Living)
            {
                var point = cc.RunClock(ai[i%2], board);

                if (!board.Living) break;

                if (!board.IsNormalPosition(point[0], point[1]))
                {
                    Console.WriteLine(" {0} Passed", ai[i % 2].Name);

                    board.Pass();
                    passcount++;
                    if (passcount == 2) break;
                }
                else
                {
                    Console.WriteLine(" {0} Placed ({1}, {2}) ", ai[i % 2].Name, point[0], point[1]);

                    passcount = 0;
                    board.PutStoneWithReverse(point[0], point[1], board.HandStone);
                }

                board.PutBoard();
                i++;
            }

            var arr = board.CountStones();

            Console.WriteLine("Black:{0} White:{1}", arr[0], arr[1]);

            Console.WriteLine(string.Format("{0} ({1})", board.Winner, arr[0] == arr[1] ? "" : arr[0] > arr[1] ? ai[0].Name : ai[1].Name));
        }
        /// <summary>
        /// 実際にAIを走らせてタイムを計測します。
        /// </summary>
        /// <param name="runner">AI</param>
        /// <param name="orig">盤面</param>
        /// <returns>AIの着手</returns>
        public int[] RunClock(AIInterface runner, Board orig)
        {
            //AI始動
            var res = RunProgram(runner, new Board(orig));

            if (timers[runner] < 0)
            {
                Logger.String(string.Format(" {0} Timed out.", runner.Name));
                orig.Shutdown();
            }

            return res.Result;
        }
Exemple #3
0
 /// <summary>
 /// コピーコンストラクタ。
 /// </summary>
 /// <param name="original">元となる盤面</param>
 public Board(Board original)
 {
     Init();
     for (int y = 0; y < REnvironment.BoardY; y++)
     {
         for (int x = 0; x < REnvironment.BoardX; x++)
         {
             PutStone(x, y, original.Ref(x, y));
         }
     }
     this.Hand = original.Hand;
     this.Living = original.Living;
     this.ForceLoser = original.ForceLoser;
 }
        public int[] Solve(Board board)
        {
            var placeable = new List<int[]>();

            for (int i = 0; i < REnvironment.BoardX; i++)
            {
                for (int j = 0; j < REnvironment.BoardY; j++)
                {
                    var res = board.GetPutParam(i, j, board.HandStone);
                    if (res.CanPlace)
                    {
                        placeable.Add(new int[]{ i, j });
                    }
                }
            }

            if(placeable.Count == 0) return new int[] { -1, -1 };

            return placeable[rand.Next(placeable.Count)];
        }
        private async Task<int[]> RunProgram(AIInterface runner, Board orig)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();

            var task = Task.FromResult<int[]>(runner.Solve(orig));

            var res = await task;

            sw.Stop();

            long time = sw.ElapsedMilliseconds / 1000;

            if (time > handSec)
            {
                timers[runner] -= (time - handSec);
            }

            Logger.String(string.Format(" {0} used {1} seconds({3} ms), Left {2} seconds", runner.Name, time, timers[runner], sw.ElapsedMilliseconds));

            return res;
        }
        public void Eval(Node node, Stone me)
        {
            Board.ReverseParam param = node.Board.PutStoneWithReverse(node.Place[0], node.Place[1], node.Board.HandStone);

            if (!param.CanPlace)
            {
                dict[string.Format("{0},{1}", node.Parent[0], node.Parent[1])] = int.MinValue / 2;
                return;
            }

            node.Depth -= 1;

            List<int[]> placeable = node.Board.PlaceablePoints;

            int placeableCount = placeable.Count;
            placeableCount *= placeableCount;

            //自身の評価

            if (node.Board.HandStone == me)
                node.Value += placeableCount;
            else
                node.Value -= placeableCount;

            dict[string.Format("{0},{1}", node.Parent[0], node.Parent[1])] += node.Value;

            //Console.WriteLine("{0},{1} Changed => {2}", node.Parent[0], node.Parent[1], node.Value);

            //次に置ける場所がない
            if (placeable.Count == 0)
            {
                if (node.Board.HandStone == me) //自分の番でパスするのは
                    dict[string.Format("{0},{1}", node.Parent[0], node.Parent[1])] = int.MinValue / 2; //最悪なのでその先は探索しない
                else
                {
                    //相手の番でパスする
                    Board past = new Board(node.Board);

                    past.Pass();

                    //かつ自分もパス
                    if (past.PlaceablePoints.Count == 0)
                    {
                        past.Pass();
                        int[] Counts = past.CountStones();
                        switch (me)
                        {
                            case Stone.Black:
                                {
                                    if (Counts[0] > Counts[1]) //両方共パスして勝っているなら
                                        dict[string.Format("{0},{1}", node.Parent[0], node.Parent[1])] = int.MaxValue / 2; //最高
                                    break;
                                }
                            case Stone.White:
                                {
                                    if(Counts[0] < Counts[1])
                                        dict[string.Format("{0},{1}", node.Parent[0], node.Parent[1])] = int.MaxValue / 2;
                                    break;
                                }
                        }
                    }
                    else
                    {
                        //自分はパスしない(相手にだけパスさせる)なら
                        dict[string.Format("{0},{1}", node.Parent[0], node.Parent[1])] += 100; //評価を上げる
                    }
                }
            }

            //Console.WriteLine("{0},{1} Changed => {2}", node.Parent[0], node.Parent[1], node.Value);

            //次の世代を生成

            foreach (var n in placeable)
            {
                Node next = new Node() { Parent = node.Parent, Place = n, Board = new Board(node.Board), Depth = node.Depth, Value = node.Value };
                _queue.Enqueue(next);
            }
        }
        public int[] Solve(Board board)
        {
            _queue = new Queue<Node>();
            dict = new Dictionary<string, int>();

            List<int[]> list = board.PlaceablePoints;

            if (list.Count == 0) return new int[] { -1, -1 };

            foreach (var v in list)
            {
                dict.Add(string.Format("{0},{1}", v[0], v[1]), 0);
                _queue.Enqueue(new Node { Parent = v, Place = v, Board = new Board(board), Depth = 5, Value = 0 });
            }

            Search(board.HandStone);

            int max      = int.MinValue / 4;
            int[] result = new int[]{-1, -1};

            foreach (var v in dict)
            {
                if (v.Value > max)
                {
                    max = v.Value;
                    result = v.Key.Split(',').Select(int.Parse).ToArray();
                }
            }

            Console.WriteLine(string.Format("Selected ({0}, {1}) => {2}", result[0], result[1], max));

            GC.Collect(); //メモリがやばい

            return result;
        }