コード例 #1
0
        public void AllocateGivenArea(BoardPoint head, BoardPoint tail, int allocationId)
        {
            var allocationArea = this.Slice((head.X, head.Y), (tail.X, tail.Y));

            foreach (var c in allocationArea)
            {
                _board[c.x, c.y] = allocationId;
            }
        }
コード例 #2
0
        public bool IsPointInRange(BoardPoint point)
        {
            if (point.X < 0 || point.Y < 0)
            {
                return(false);
            }
            if (point.X < _boardSize && point.Y < _boardSize)
            {
                return(true);
            }

            return(false);
        }
コード例 #3
0
        public bool IsOccupied(BoardPoint point)
        {
            if (!IsPointInRange(point))
            {
                throw new ArgumentException($"{nameof(point)} is not in range.");
            }

            var objectId = _board[point.X, point.Y];

            if (objectId == null)
            {
                return(false);
            }

            return(true);
        }
コード例 #4
0
        public (int allocationId, BoardPoint head, BoardPoint tail)? AllocateRandomAvailableArea(int size, int objectId)
        {
            var rand = new Random(DateTime.UtcNow.Millisecond);
            Dictionary <(int x, int y), bool> scannedSoFar = new Dictionary <(int x, int y), bool>();
            int maxSpotsOnBoard = (this._boardSize * this._boardSize);

            lock (_randomAreaAllocationLock)
            {
                //First available random area that can house as much as {size} either at X or Y axis, forward or backward
                //As Non-Deterministic as possible, starts the search from a random point,
                //axis and back-forward search direction are determined at run-tim randomly.
                while (scannedSoFar.Count != (maxSpotsOnBoard))
                {
                    int x = rand.Next(0, _boardSize);
                    int y = rand.Next(0, _boardSize);

                    if (IsPointAvailable(x, y) && !scannedSoFar.ContainsKey((x, y)))
                    {
                        //Prioritize vertical search?
                        bool colFirst = GetRandomBool(rand);
                        //Prioritize going forward first?
                        bool forwardDirectionFirst = GetRandomBool(rand);

                        var tail = FindRandomTail(x, y, size, colFirst, forwardDirectionFirst, 0);

                        if (tail.HasValue)//random area found
                        {
                            //Allocate the area
                            var allocationId = -(objectId);

                            var head = new BoardPoint(x, y);
                            AllocateGivenArea(head, tail.Value, allocationId);

                            //Return allocation Key, head and tail
                            return(allocationId, new BoardPoint(x, y), tail.Value);
                        }
                    }

                    scannedSoFar.TryAdd((x, y), true);
                }
            }

            return(null); //No available place for allocation with given size
        }
コード例 #5
0
        public void Shoot(BoardPoint target)
        {
            //Validate target
            if (!_board.IsPointInRange(target))
            {
                ApplyChange(new BattleShipOperationFailed(Id, "Target is out of the Board Range"));
                return;
            }

            if (_shotsTaken.Any(s => s.Equals(target)))
            {
                ApplyChange(new BattleShipOperationFailed(Id, "Target already Shot"));
                return;
            }

            if (IsHit(target))
            {
                var shipId = _board.GetObjectIdOnBoard(target.X, target.Y);
                var ship   = this._ships[shipId.Value];

                ApplyChange(new ShipHit(Id, target, ship.Name));

                if (ship.IsSunk())
                {
                    ApplyChange(new ShipSunk(Id, ship.Name));
                    if (HasPlayerWon())
                    {
                        ApplyChange(new AllShipsSunk(Id));
                    }
                }
            }
            else
            {
                ApplyChange(new ShotMissed(Id, target));
            }
        }
コード例 #6
0
 private bool IsHit(BoardPoint target)
 {
     return(_board.IsOccupied(target));
 }