예제 #1
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;
        }
예제 #2
0
        public IEnumerable <Stone> Enumerate(Ply from, Direction direction)
        {
            switch (direction)
            {
            case Direction.Up:
                for (int i = from.Row - 1; i >= 0; i--)
                {
                    yield return(board[i, from.Column]);
                }
                yield break;

            case Direction.Down:
                for (int i = from.Row + 1; i < BoardSize; i++)
                {
                    yield return(board[i, from.Column]);
                }
                yield break;

            case Direction.Left:
                for (int i = from.Column - 1; i >= 0; i--)
                {
                    yield return(board[from.Row, i]);
                }
                yield break;

            case Direction.Right:
                for (int i = from.Column + 1; i < BoardSize; i++)
                {
                    yield return(board[from.Row, i]);
                }
                yield break;

            case Direction.UpLeft:
                for (int i = 1; i <= Math.Min(from.Row, from.Column); i++)
                {
                    yield return(board[from.Row - i, from.Column - i]);
                }
                yield break;

            case Direction.DownRight:
                for (int i = 1; i < Math.Min(BoardSize - from.Row, BoardSize - from.Column); i++)
                {
                    yield return(board[from.Row + i, from.Column + i]);
                }
                yield break;

            case Direction.DownLeft:
                for (int i = 1; i < Math.Min(BoardSize - from.Row, from.Column + 1); i++)
                {
                    yield return(board[from.Row + i, from.Column - i]);
                }
                yield break;

            case Direction.UpRight:
                for (int i = 1; i < Math.Min(from.Row + 1, BoardSize - from.Column); i++)
                {
                    yield return(board[from.Row - i, from.Column + i]);
                }
                yield break;

            default: throw new InvalidOperationException(string.Format("Unknown direction: {0}!", direction));
            }
        }
예제 #3
0
        private bool IsWinningMove(Ply cell)
        {
            var cellValue     = board[cell.Row, cell.Column];
            int verticalCount = 1;

            foreach (var value in Enumerate(cell, Direction.Up))
            {
                if (value != cellValue)
                {
                    break;
                }
                verticalCount++;
            }
            foreach (var value in Enumerate(cell, Direction.Down))
            {
                if (value != cellValue)
                {
                    break;
                }
                verticalCount++;
            }
            if (verticalCount >= 5)
            {
                return(true);
            }
            int horizontalCount = 1;

            foreach (var value in Enumerate(cell, Direction.Left))
            {
                if (value != cellValue)
                {
                    break;
                }
                horizontalCount++;
            }
            foreach (var value in Enumerate(cell, Direction.Right))
            {
                if (value != cellValue)
                {
                    break;
                }
                horizontalCount++;
            }
            if (horizontalCount >= 5)
            {
                return(true);
            }
            int diagonalCount = 1;

            foreach (var value in Enumerate(cell, Direction.UpLeft))
            {
                if (value != cellValue)
                {
                    break;
                }
                diagonalCount++;
            }
            foreach (var value in Enumerate(cell, Direction.DownRight))
            {
                if (value != cellValue)
                {
                    break;
                }
                diagonalCount++;
            }
            if (diagonalCount >= 5)
            {
                return(true);
            }
            int reverseDiagonalCount = 1;

            foreach (var value in Enumerate(cell, Direction.DownLeft))
            {
                if (value != cellValue)
                {
                    break;
                }
                reverseDiagonalCount++;
            }
            foreach (var value in Enumerate(cell, Direction.UpRight))
            {
                if (value != cellValue)
                {
                    break;
                }
                reverseDiagonalCount++;
            }
            if (reverseDiagonalCount >= 5)
            {
                return(true);
            }
            return(false);
        }