예제 #1
0
 /// <summary>
 /// Build a settlement on the board
 /// If you try to build too close to another building a IllegalBuildPosition is thrown
 /// Must be called before BuildRoad, otherwise an IllegalActionException is thrown
 /// </summary>
 /// <param name="firstTile">The intersection</param>
 public void BuildSettlement(Intersection intersection)
 {
     if (settlementBuilt) throw new IllegalActionException("Only one settlement may be built in a turn during the startup");
     settlementPosition = intersection;
     controller.BuildFirstSettlement(player, intersection);
     settlementBuilt = true;
 }
예제 #2
0
파일: Board.cs 프로젝트: rasmusgreve/catan
        private Board(Tile[][] terrain, Dictionary<Edge, int> roads,
            Dictionary<Intersection, Piece> settlements, int robber,
            Harbor[] harbors, Intersection[] inter, Edge[] edges)
            : this()
        {
            this.allEdges = edges;
            this.allIntersections = inter;

            this.terrain = terrain;
            this.roads = roads;
            this.settlements = settlements;
            this.robberLocation = robber;
            this.harbors = harbors;
        }
예제 #3
0
        /// <summary>
        /// Let a player upgrade a settlement to a city
        /// If the player doesn't have enough resources to build a city a InsufficientResourcesException is thrown
        /// If the player tries to build at a position where he doesn't have a settlement a IllegalBuildPosition is thrown
        /// If the player doesn't have any more city pieces left to place a IllegalActionException is thrown
        /// The required resources are taken from the player and placed back at the resource bank
        /// The settlement previously on the location is given back to the player
        /// </summary>
        /// <param name="player">The player upgrading to a city</param>
        /// <param name="intersection">The intersection to upgrade to a city on</param>
        /// <returns></returns>
        public GameState BuildCity(Player player, Intersection intersection)
        {
            var r = player.Resources;
            if (!(r.Count(c => c == Resource.Ore) >= 3 && r.Count(c => c == Resource.Grain) >= 2))
                throw new InsufficientResourcesException("Not enough resources to buy a city");
            if (player.CitiesLeft == 0)
                throw new IllegalActionException("No more city pieces left of your color");

            Piece piece = board.GetPiece(intersection);
            if (piece == null || piece.Player != player.Id || piece.Token != Token.Settlement)
                throw new IllegalBuildPositionException("The chosen position does not contain one of your settlements");

            PayResource(player, Resource.Ore, 3);
            PayResource(player, Resource.Grain, 2);

            Log(new BuildPieceLogEvent(player.Id, Token.City, intersection));

            player.CitiesLeft--;
            player.SettlementsLeft++;

            board = board.PlacePiece(intersection, new Piece(Token.City, player.Id));
            return CurrentGamestate();
        }
예제 #4
0
 private IEnumerable<Intersection> GetEnds(Intersection inter, IBoard board)
 {
     return board.GetAdjacentEdges(inter).SelectMany(e => board.GetAdjacentIntersections(e)).Where(i => !i.Equals(inter));
 }
예제 #5
0
 private Edge GetEdgeBetween(Intersection first, Intersection second)
 {
     int[] result = first.ToArray().Where(i => second.ToArray().Contains(i)).ToArray();
     if (result.Length < 2) return null;
     return new Edge(result[0], result[1]);
 }
예제 #6
0
 private Edge FindBestRoad(Intersection from, IBoard board)
 {
     // find the best neighbor intersection and takes the edge to that
     return GetEdgeBetween(FindBestIntersection(GetEnds(from, board),board),from);
 }
예제 #7
0
 private int DifferentTypes(Intersection inter, IBoard board)
 {
     return inter.ToArray().Select(i => board.GetTile(i).Terrain).Where(t => t != Terrain.Water && t != Terrain.Desert).Distinct().Count();
 }
예제 #8
0
파일: Board.cs 프로젝트: rasmusgreve/catan
        public Intersection[] GetAllIntersections()
        {
            if(allIntersections == null){
                List<Intersection> result = new List<Intersection>(22);
                for (int r = 0; r < 7; r++)
                {
                    for (int c = 0; c < Board.GetRowLength(r); c++)
                    {
                        Intersection south = null;
                        Intersection southeast = null;

                        if (r % 2 == 0)
                        {
                            if(r + 1 < 7 && c + 1 < Board.GetRowLength(r + 1))
                                south = new Intersection(GetTerrainIndex(r, c), GetTerrainIndex(r + 1, c), GetTerrainIndex(r + 1, c + 1));
                            if (r + 1 < 7 && c + 1 < Board.GetRowLength(r))
                                southeast = new Intersection(GetTerrainIndex(r, c), GetTerrainIndex(r, c + 1), GetTerrainIndex(r + 1, c + 1));
                        }
                        else
                        {
                            if (r + 1 < 7 && c - 1 >= 0 && c < 6)
                                south = new Intersection(GetTerrainIndex(r, c), GetTerrainIndex(r + 1, c - 1), GetTerrainIndex(r + 1, c));
                            if (r + 1 < 7 && c < 6)
                                southeast = new Intersection(GetTerrainIndex(r, c), GetTerrainIndex(r, c + 1), GetTerrainIndex(r + 1, c));
                        }

                        if (south != null && (GetTile(south.FirstTile).Terrain != Terrain.Water || GetTile(south.SecondTile).Terrain != Terrain.Water))
                            result.Add(south);
                        if (southeast != null && (GetTile(southeast.FirstTile).Terrain != Terrain.Water || GetTile(southeast.SecondTile).Terrain != Terrain.Water))
                            result.Add(southeast);
                    }
                }
                allIntersections = result.ToArray();

            }
            return allIntersections.ToArray();
        }
예제 #9
0
파일: Board.cs 프로젝트: rasmusgreve/catan
        public bool CanBuildPiece(Intersection intersection)
        {
            if (GetTile(intersection.FirstTile).Terrain == Terrain.Water && GetTile(intersection.SecondTile).Terrain == Terrain.Water && GetTile(intersection.ThirdTile).Terrain == Terrain.Water)
                return false;

            return !settlements.ContainsKey(intersection);
        }
예제 #10
0
파일: Board.cs 프로젝트: rasmusgreve/catan
 private void AddPiece(List<Piece> list, Intersection intersection)
 {
     Piece hit = this.GetPiece(intersection);
     if(hit != null) list.Add(hit);
 }
예제 #11
0
파일: Board.cs 프로젝트: rasmusgreve/catan
        private int CountRoadLengthFromIntersection(int playerID, Intersection curInt, HashSet<Edge> visited, HashSet<Edge> globalVisited)
        {
            // check for break
            Piece curPiece = GetPiece(curInt);
            if(curPiece != null && curPiece.Player != playerID) return 0; // no more edges this direction

            // find connections
            var edgesOut = GetAdjacentEdges(curInt).Where(e => !visited.Contains(e) && GetRoad(e) == playerID).ToArray(); // temp array

            int highest = 0;
            foreach (var edge in edgesOut)
            {
                // add edges to visited
                visited.Add(edge);
                globalVisited.Add(edge);

                Intersection otherEnd = GetAdjacentIntersections(edge).First(i => !i.Equals(curInt));
                int depthSearch = CountRoadLengthFromIntersection(playerID, otherEnd, visited, globalVisited);

                if (1 + depthSearch > highest) highest = 1 + depthSearch;

                visited.Remove(edge);
            }

            return highest;
        }
예제 #12
0
파일: Board.cs 프로젝트: rasmusgreve/catan
 public IBoard PlacePiece(Intersection intersection, Piece p)
 {
     var newSettlements = new Dictionary<Intersection, Piece>(settlements);
     newSettlements[intersection] = p;
     return new Board(terrain, new Dictionary<Edge, int>(roads), newSettlements, robberLocation, harbors, allIntersections, allEdges);
 }
예제 #13
0
파일: Board.cs 프로젝트: rasmusgreve/catan
 public bool HasNoNeighbors(Intersection intersection)
 {
     return GetAdjacentEdges(intersection).
         SelectMany(edge => GetAdjacentIntersections(edge)).
         All(inter => inter.Equals(intersection) || GetPiece(inter) == null);
 }
예제 #14
0
파일: Board.cs 프로젝트: rasmusgreve/catan
 public Piece GetPiece(Intersection intersection)
 {
     return settlements.ContainsKey(intersection) ? settlements[intersection] : null;
 }
예제 #15
0
 private int GetScore(Intersection inter, IBoard board)
 {
     return Chances(board.GetTile(inter.FirstTile).Value) +
             Chances(board.GetTile(inter.SecondTile).Value) +
             Chances(board.GetTile(inter.ThirdTile).Value);
 }
예제 #16
0
        /// <summary>
        /// Let a player build a settlement without a requirement for connectivity and free of charge
        /// The settlement still has to follow the distance rule and cannot be placed on top of another building
        /// </summary>
        /// <param name="player">The player placing the settlement</param>
        /// <param name="intersection">The intersection to build a settlement on</param>
        public GameState BuildFirstSettlement(Player player, Intersection intersection)
        {
            if (board.GetPiece(intersection) != null)
                throw new IllegalBuildPositionException("The chosen position is occupied by another building");
            if (!board.HasNoNeighbors(intersection))
                throw new IllegalBuildPositionException("The chosen position violates the distance rule");
            if (!board.CanBuildPiece(intersection))
                throw new IllegalBuildPositionException("The chosen position is not valid");

            player.SettlementsLeft--;
            board = board.PlacePiece(intersection, new Piece(Token.Settlement, player.Id));
            return CurrentGamestate();
        }
예제 #17
0
 //Building
 public GameState BuildSettlement(Intersection intersection)
 {
     if (!valid) throw new IllegalActionException("Tried to perform an action on an invalid GameAction");
     if (!isAfterDieRoll) throw new IllegalActionException("Tried to build before the die roll");
     return controller.BuildSettlement(player, intersection);
 }
예제 #18
0
        /// <summary>
        /// Let a player build a settlement
        /// If the player doesn't have enough resources to build a settlement a InsufficientResourcesException is thrown
        /// If the player tries to build too close to another building, or not connected to a road a IllegalBuildPosition is thrown
        /// If the player doesn't have any more settlement pieces left to place a IllegalActionException is thrown
        /// The required resources are taken from the player and placed back at the resource bank
        /// If the settlement is placed at a harbor, the harbor can be used immediately (rules p. 7 - footnote 12)
        /// </summary>
        /// <param name="player">The player building a settlement</param>
        /// <param name="inter">The intersection to build a settlement on</param>
        /// <returns></returns>
        public GameState BuildSettlement(Player player, Intersection inter)
        {
            var r = player.Resources;
            if (!(r.Contains(Resource.Grain) && r.Contains(Resource.Wool) && r.Contains(Resource.Brick) && r.Contains(Resource.Lumber)))
                throw new InsufficientResourcesException("Not enough resources to buy a settlement");
            if (player.SettlementsLeft == 0)
                throw new IllegalActionException("No more settlement pieces left of your color");
            if (board.GetPiece(inter) != null)
                throw new IllegalBuildPositionException("The chosen position is occupied by another building");
            if (!board.HasNoNeighbors(inter))
                throw new IllegalBuildPositionException("The chosen position violates the distance rule");
            if (board.GetRoad(new Edge(inter.FirstTile,inter.SecondTile)) != player.Id
                && board.GetRoad(new Edge(inter.FirstTile,inter.ThirdTile)) != player.Id
                && board.GetRoad(new Edge(inter.SecondTile, inter.ThirdTile)) != player.Id)
                throw new IllegalBuildPositionException("The chosen position has no road leading to it");

            if (!board.CanBuildPiece(inter))
                throw new IllegalBuildPositionException("The chosen position is not valid");

            PayResource(player, Resource.Grain);
            PayResource(player, Resource.Wool);
            PayResource(player, Resource.Brick);
            PayResource(player, Resource.Lumber);

            Log(new BuildPieceLogEvent(player.Id, Token.Settlement, inter));

            player.SettlementsLeft--;
            board = board.PlacePiece(inter, new Piece(Token.Settlement, player.Id));
            UpdateLongestRoad();
            return CurrentGamestate();
        }
예제 #19
0
 public BuildPieceLogEvent(int player, Token piece, Intersection position)
 {
     Player = player;
     Piece = piece;
     this.Position = position;
 }
예제 #20
0
파일: Board.cs 프로젝트: rasmusgreve/catan
 public Edge[] GetAdjacentEdges(Intersection intersection)
 {
     List<Edge> result = new List<Edge>(3);
     if (IsLegalEdge(new Edge(intersection.FirstTile, intersection.SecondTile))) result.Add(new Edge(intersection.FirstTile,intersection.SecondTile));
     if (IsLegalEdge(new Edge(intersection.SecondTile, intersection.ThirdTile))) result.Add(new Edge(intersection.SecondTile, intersection.ThirdTile));
     if (IsLegalEdge(new Edge(intersection.FirstTile, intersection.ThirdTile))) result.Add(new Edge(intersection.FirstTile, intersection.ThirdTile));
     return result.ToArray();
 }