예제 #1
0
        public void Do(Cell ply)
        {
            if (ply == null)
            {
                throw new ArgumentNullException("ply");
            }
            if (hasWinner)
            {
                throw new InvalidOperationException(string.Format("Position has winner, but the game isn't ended"));
            }
            if (innerBoards[ply.BoardIndex][ply.CellIndex] != Mark.Empty)
            {
                throw new InvalidOperationException(string.Format("Cannot mark, because target cell isn't empty: [{0},{1}]",
                                                                  ply.BoardIndex, ply.CellIndex));
            }
            if (history.Count > 0 && combinedBoard[history[history.Count - 1].CellIndex] == Mark.Empty && innerBoards[history[history.Count - 1].CellIndex].Any(t => t == Mark.Empty) && ply.BoardIndex != history[history.Count - 1].CellIndex)
            {
                throw new InvalidOperationException(string.Format("Invalid target board: [{0},{1}]",
                                                                  ply.BoardIndex, ply.CellIndex));
            }
            if (combinedBoard[ply.BoardIndex] != Mark.Empty)
            {
                throw new InvalidOperationException(string.Format("Closed target board: [{0},{1}]",
                                                                  ply.BoardIndex, ply.CellIndex));
            }

            innerBoards[ply.BoardIndex][ply.CellIndex] = nextMarkType;

            history.Add(ply);
            Update(ply);
            hashing.Modify(GetHashIndex(ply));
            nextMarkType = ChangeMark(nextMarkType);
            innerWinningChances[ply.BoardIndex] = ComputeWinningChance(ply.BoardIndex);
            score = CalculateScore();
        }
예제 #2
0
        public void Take(Ply ply)
        {
            if (ply == null)
            {
                throw new ArgumentNullException("ply");
            }
            if (IsEnded)
            {
                throw new InvalidOperationException("Position is closed");
            }
            if (HasWinner)
            {
                throw new InvalidOperationException(string.Format("Position has winner, but isn't closed"));
            }
            if (board[ply.Row, ply.Column] != Stone.Empty)
            {
                throw new InvalidOperationException(string.Format("Cannot do ply, because target cell isn't empty: [{0},{1}]",
                                                                  ply.Row, ply.Column));
            }
            board[ply.Row, ply.Column] = next;
            hashing.Modify(2 * (BoardSize * ply.Row + ply.Column) + (next == Stone.Black ? 0 : 1));
            history.Add(ply);

            if (IsWinningMove(ply))
            {
                winner = next;
                ChangeNext();
            }
            else
            {
                ChangeNext();
                UpdateScore(ply.Row, ply.Column);
            }


            for (int i = Math.Max(0, ply.Row - radius); i < Math.Min(BoardSize, ply.Row + radius + 1); i++)
            {
                for (int j = Math.Max(0, ply.Column - radius); j < Math.Min(BoardSize, ply.Column + radius + 1); j++)
                {
                    if (GetStone(i, j) == 0 && relevantEmptyCells[i, j] == 0)
                    {
                        relevantEmptyCells[i, j] = history.Count;
                    }
                }
            }
            relevantEmptyCells[ply.Row, ply.Column] *= -1;
        }
예제 #3
0
 public void Take(Ply ply)
 {
     if (winner != Disk.None)
     {
         throw new InvalidOperationException("Closed state");
     }
     if (ply.From == -1)
     {
         board[ply.To, 0] = next;
         heights[ply.To]  = 1;
         hashing.Modify(ZobristIndex(ply.To, 0, next));
     }
     else
     {
         Move(ply.From, ply.To, ply.Count);
     }
     history.Add(ply);
     ChangeNext();
 }