/// <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; }
/// <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; }