Exemple #1
0
        public void TestGetPoints()
        {
            var hex = new HexEdge(0, 0, 1, 0);
            var points = hex.GetPoints();
            Assert.AreEqual(2, points.Count, "A hex edge must have 2 points.");

            var msg = "Hex edge is missing a point.";
            Assert.IsTrue(points.Contains(new HexPoint(0, 0, 1, 0, 1, 1)), msg);
            Assert.IsTrue(points.Contains(new HexPoint(0, 0, 1, 0, 0, -1)), msg);
        }
Exemple #2
0
        public void TestGetEdges()
        {
            var hex = new HexEdge(0, 0, 1, 0);
            var edges = hex.GetHexagons();
            Assert.AreEqual(2, edges.Count, "A hex edge must have 2 hexagons.");

            string msg = "Hex edge is missing a hexagon.";
            Assert.IsTrue(edges.Contains(new Hexagon(0, 0)), msg);
            Assert.IsTrue(edges.Contains(new Hexagon(1, 0)), msg);
        }
Exemple #3
0
        public void TestGetNeighborEdges()
        {
            var hex = new HexEdge(0, 0, 1, 0);
            var neighbors = hex.GetNeighborEdges();
            Assert.AreEqual(4, neighbors.Count, "A hex edge must have 4 neighbors.");

            var msg = "Hex edge is missing a neighbor.";
            Assert.IsTrue(neighbors.Contains(new HexEdge(0, 0, 0, -1)), msg);
            Assert.IsTrue(neighbors.Contains(new HexEdge(1, 0, 0, -1)), msg);
            Assert.IsTrue(neighbors.Contains(new HexEdge(0, 0, 1, 1)), msg);
            Assert.IsTrue(neighbors.Contains(new HexEdge(1, 0, 1, 1)), msg);
        }
Exemple #4
0
        public void TestSerialize()
        {
            var edges = new HexEdge[]
            {
                new HexEdge(0, 0, 1, 0),
                new HexEdge(-2, -2, -1, -1),
                new HexEdge(int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue - 1),
                new HexEdge(int.MinValue, int.MinValue, int.MinValue, int.MinValue + 1),
            };

            foreach (var edge in edges)
            {
                var str = edge.ToString();
                var actual = new HexEdge();
                actual.FromString(str);
                Assert.AreEqual(edge, actual, "The FromString method must produce the exact object that called the ToString method.");
            }
        }
Exemple #5
0
 private PointF[] HexEdgeToAbsolutePoints(HexEdge hexEdge)
 {
     var h1 = HexagonToAbsolutePoints(hexEdge.Hex1);
     var h2 = HexagonToAbsolutePoints(hexEdge.Hex2);
     var linePoints = h1.Intersect(h2).ToArray();
     if (linePoints.Length == 2)
         return linePoints;
     return null;
 }
Exemple #6
0
 private void DrawRoad(Graphics gfx, HexEdge edge, Road road)
 {
     var linePoints = HexEdgeToAbsolutePoints(edge);
     if (linePoints != null)
     {
         Pen p1 = new Pen(Color.Black, 5f);
         Pen p2 = new Pen(PlayerToColor(road.Player), 4f);
         gfx.DrawLine(p1, linePoints[0], linePoints[1]);
         gfx.DrawLine(p2, linePoints[0], linePoints[1]);
         p1.Dispose();
         p2.Dispose();
     }
 }
Exemple #7
0
        private void DrawPort(Graphics gfx, HexEdge edge, Port port)
        {
            var linePoints = HexEdgeToAbsolutePoints(edge);
            if (linePoints != null)
            {
                Color c = port.Resource == ResourceTypes.None ? Color.Black : ResourceColorMap[port.Resource];
                Brush hb = new HatchBrush(HatchStyle.Wave, c, BoardColors.Water);
                Pen p = new Pen(c, 2f);
                Pen bp = new Pen(Color.Black, 1f);

                var box = linePoints.GetBoundingBox();
                gfx.DrawEllipse(bp, box.OffsetSize(2, 2));
                gfx.DrawEllipse(p, box);
                gfx.FillEllipse(hb, box);

                bp.Dispose();
                hb.Dispose();
                p.Dispose();
            }
        }
Exemple #8
0
 /// <summary>
 /// Indicates if this edge is touching another edge.
 /// </summary>
 public bool IsTouching(HexEdge edge)
 {
     return GetNeighborEdges().Contains(edge);
 }
Exemple #9
0
        /// <summary>
        /// Places a road for the given player at the given location.
        /// If it's the initial placement phase of the game, the road is free.
        /// Otherwise, resources will be removed from the player.
        /// </summary>
        public ActionResult PlayerPlaceRoad(int playerId, HexEdge location)
        {
            var validation = ValidatePlayerAction(PlayerTurnState.PlacingRoad, playerId);
            if (validation.Failed) return validation;

            var pr = GetPlayerFromId(playerId);
            if (pr.Failed) return pr;
            var player = pr.Data;

            bool startOfGame = (_gameState == GameStates.InitialPlacement);

            // Make sure the player doesn't place too many roads in the intial placement phase
            if (startOfGame)
            {
                var buildingCount = _gameBoard.GetBuildingCountForPlayer(playerId);
                var roadCount = _gameBoard.GetRoadCountForPlayer(playerId);
                var maxRoads = buildingCount;
                if (roadCount >= maxRoads)
                    return ActionResult.CreateFailed("Cannot place more than 1 road per settlement during the initial placement phase.");
            }

            var placementValidation = _gameBoard.ValidateRoadPlacement(playerId, location, startOfGame);
            if (placementValidation.Failed) return placementValidation;

            var purchaseResult = player.Purchase(PurchasableItems.Road, startOfGame);
            if (purchaseResult.Failed) return purchaseResult;

            // We'll assume this succeeds because we already validated it.
            var placement = _gameBoard.PlaceRoad(player.Id, location, startOfGame);
            System.Diagnostics.Debug.Assert(placement.Succeeded);

            // When we place a road, do a check to see if we deserve the longest road.
            CheckForLongestRoad(playerId);

            // Update game and player states.
            if (_gameState == GameStates.InitialPlacement)
            {
                var buildingCount = _gameBoard.GetBuildingCountForPlayer(playerId);
                if (LastPlayerIsActive && buildingCount == 1)
                {
                    // The "last" player gets to place twice.
                    _playerTurnState = PlayerTurnState.PlacingBuilding;
                }
                else
                {
                    // Go to the next players turn.
                    AdvanceToNextPlayerTurn();
                }
            }
            else if (_gameState == GameStates.GameInProgress)
            {
                _playerTurnState = PlayerTurnState.TakeAction;
            }

            return ActionResult.CreateSuccess();
        }
Exemple #10
0
 private bool IsPlayerBuildingHere(int player, HexEdge edge)
 {
     foreach (var point in edge.GetPoints())
     {
         if (IsPlayerBuildingHere(player, point))
             return true;
     }
     return false;
 }
Exemple #11
0
 private bool IsEdgeInBoard(HexEdge edge)
 {
     return _validBoardEdges.Contains(edge);
 }
Exemple #12
0
 private IEnumerable<HexEdge> GetRoadPermutations(int player, HexEdge road, IEnumerable<HexEdge> allPlayerRoads, IEnumerable<HexEdge> excludeRoads)
 {
     return GetRoadPermutations(player, road, allPlayerRoads)
            .Where(e => !excludeRoads.Contains(e));
 }
Exemple #13
0
 private IEnumerable<HexEdge> GetRoadPermutations(int player, HexEdge road, IEnumerable<HexEdge> allPlayerRoads)
 {
     return road.GetNeighborEdges()
                .Where(e => allPlayerRoads.Contains(e) &&
                            !IsEnemyPlayerBuildingHere(player, road.GetNeighborPoint(e))); // An enemy building can cut off a road.
 }
Exemple #14
0
        /// <summary>
        /// Returns a success result if this is a valid placement for a road.
        /// </summary>
        public ActionResult ValidateRoadPlacement(int player, HexEdge edge, bool startOfGame)
        {
            if (!IsEdgeInBoard(edge))
            {
                return new ActionResult(false, string.Format("The road location {0} is out of bounds.", edge));
            }

            // Do not allow removing a road.
            if (_roads.ContainsKey(edge))
            {
                return new ActionResult(false, string.Format("The road location {0} is already used.", edge));
            }

            if (startOfGame)
            {
                // Make sure this is touching a settlement owned by this player. It's the start of the game.
                if (!IsPlayerBuildingHere(player, edge))
                {
                    return new ActionResult(false, String.Format("The road location {0} is not near a settlement.", edge));
                }
            }
            else
            {
                // We must be near a settlement, city, or another road.
                if (!IsPlayerBuildingHere(player, edge))
                {
                    bool isTouchingRoad = false;
                    foreach (var surroundingRoad in edge.GetNeighborEdges())
                    {
                        if (IsPlayerRoadHere(player, surroundingRoad))
                        {
                            isTouchingRoad = true;
                            break;
                        }
                    }
                    if (!isTouchingRoad)
                    {
                        return new ActionResult(false, string.Format("The road location {0} is not near a city, settlement, or road.", edge));
                    }
                }
            }
            return ActionResult.CreateSuccess();
        }
Exemple #15
0
 /// <summary>
 /// Places a new road onto the board.
 /// </summary>
 public ActionResult PlaceRoad(int player, HexEdge edge, bool startOfGame)
 {
     var validationResult = ValidateRoadPlacement(player, edge, startOfGame);
     if (validationResult.Failed) return validationResult;
     _roads[edge] = new Road(player);
     return ActionResult.CreateSuccess();
 }
Exemple #16
0
 /// <summary>
 /// Indicates if the hexagon contains the given edge.
 /// </summary>
 public bool ContainsEdge(HexEdge edge)
 {
     return GetEdges().Contains(edge);
 }
Exemple #17
0
 private bool IsPlayerRoadHere(int player, HexEdge edge)
 {
     if (_roads.ContainsKey(edge))
     {
         return (_roads[edge].Player == player);
     }
     return false;
 }
Exemple #18
0
 public SearchRoad(HexEdge edge, SearchRoad parent = null)
 {
     Edge = edge;
     Parent = parent;
 }
Exemple #19
0
        /// <summary>
        /// Places a road for the given player at the given location after the RoadBuilding card has been played.
        /// Can only be called by the active player.
        /// </summary>
        public ActionResult PlayerPlaceRoadForRoadBuilding(int playerId, HexEdge location)
        {
            var validation = ValidatePlayerAction(PlayerTurnState.RoadBuildingSelectingRoads, playerId);
            if (validation.Failed) return validation;

            var pr = GetPlayerFromId(playerId);
            if (pr.Failed) return pr;
            var player = pr.Data;

            // Make sure the player doesn't place too many roads
            if (_roadBuildingRoadsRemaining <= 0)
                return ActionResult.CreateFailed("Cannot place more than 2 roads with the RoadBuilding card.");

            var placementValidation = _gameBoard.ValidateRoadPlacement(playerId, location, false);
            if (placementValidation.Failed) return placementValidation;

            var purchaseResult = player.Purchase(PurchasableItems.Road, true);
            if (purchaseResult.Failed)
            {
                // If this failed, it means that the player has no more roads available. This turn state has to end.
                _roadBuildingRoadsRemaining = 0;
                _playerTurnState = PlayerTurnState.TakeAction;
                return purchaseResult;
            }

            var rr = _gameBoard.PlaceRoad(player.Id, location, false);
            if (rr.Failed) return rr;

            // When we place a road, do a check to see if we deserve the longest road.
            CheckForLongestRoad(playerId);

            _roadBuildingRoadsRemaining--;
            if (_roadBuildingRoadsRemaining <= 0)
            {
                _playerTurnState = PlayerTurnState.TakeAction;
            }

            return ActionResult.CreateSuccess();
        }
Exemple #20
0
 /// <summary>
 /// Gets the point which connects two edges.
 /// </summary>
 public HexPoint GetNeighborPoint(HexEdge neighborEdge)
 {
     var point = this.GetPoints().Intersect(neighborEdge.GetPoints()).ToList();
     if (point.Count != 1)
         throw new ArgumentException("Invalid neighbor edge.");
     return point[0];
 }