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; } }
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)))); }
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); }
private void SwitchTeban() { switch (teban_) { case Teban.Black: teban_ = Teban.White; break; case Teban.White: teban_ = Teban.Black; break; default: break; } }
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()); }
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())]); }
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)); }
private Teban SwitchTeban(Teban teban) { return(teban == Teban.Black ? Teban.White : Teban.Black); }
public Position DecideMove(Teban teban, IBoard board) { return(AIUtility.DecidePositionRandom(teban, board)); }
public bool IsLegal(Teban teban, Position position) { var legalList = GetLegalPosistionList(teban); return(legalList.Contains(position)); }
/// <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); }