Class Board
In: lib/core/board.rb
Parent: Object

The central data structure for the game. This holds all the user game pieces (Cities, Settlements, Roads) and also all the admin pieces(Cards, Tiles etc.)

Methods

Attributes

card_pile  [R] 
expansion  [R]  The game definition that this board applies to
name  [R]  The human readable name for this board
nodes  [R] 
recomended_players  [R]  The number of recomended players for this board. (Range)
tiles  [R] 

Public Class methods

[Source]

# File lib/core/board.rb, line 310
  def initialize
    @tiles = {}
    @nodes = nil
    @roadEdges = [] #keep track of roads for performance
    @card_pile = DevelopmentCardBag.new
    initialize_hexes_and_ports
  end

Public Instance methods

A master list of all unique nodes on the board.

[Source]

# File lib/core/board.rb, line 363
  def all_nodes
    @nodes = @tiles.values.collect{|t| t.nodes }.flatten.uniq if not @nodes
    @nodes
  end

Finds the longest road in a specific direction

initial_direction
should be 1 or 0

This method takes a LONG time when there are > 50 connected roads of the same color. Other than that, it’s faster than the other way Returns an int

[Source]

# File lib/core/board.rb, line 393
  def find_longest_road(edge, initial_direction=nil, visitedNodes=[])
    if edge.road 
      color = edge.road.color
      nodes_to_visit = edge.nodes
      nodes_to_visit = [edge.nodes[initial_direction]] if initial_direction
      
      length = 0
      
      (nodes_to_visit - visitedNodes).each{|n|
        length += n.edges.collect{|e|
          if e != edge and e.road and e.road.color == color
            find_longest_road(e, nil, visitedNodes + [n])
          else  
            0
          end  
        }.max
      }
      length + 1
    end
  end

Get the Edge object at the given coordinates

x,y
The cartesian coordinates that specify a Hex
e
The edge number on that Hex

[Source]

# File lib/core/board.rb, line 360
  def getEdge(x, y, e) getTile(x,y).edges[e]; end

Get the Node object at the given coordinates

x,y
The cartesian coordinates that specify a Hex
n
The node number on that Hex

[Source]

# File lib/core/board.rb, line 355
  def getNode(x, y, n) getTile(x,y).nodes[n]; end

Get the Hex object at the given coordinates

[Source]

# File lib/core/board.rb, line 350
  def getTile(x, y) @tiles[[x,y]] end

gets a list of cards

[Source]

# File lib/core/board.rb, line 444
  def get_cards(number, color)
    result=[]
    for t in @tiles.values
      if t.number == number and not t.has_bandit
        for n in t.nodes
          if n.city and n.city.color == color
            case n.city
            when City then result += t.get_2_cards
            when Settlement then result << t.get_card
            end
          end
        end
      end
    end
    result
  end

gets the list of ports for this player

[Source]

# File lib/core/board.rb, line 437
  def get_ports(color)
    all_nodes().collect{|n| 
      n.port if n.city and n.city.color == color 
    }.compact
  end

[Source]

# File lib/core/board.rb, line 527
  def get_valid_city_spots(color)
    all_nodes.select{|node| node.city.class == Settlement and node.city.color == color}
  end

Get all the valid places to put a road. NOTE: if someone else builds a settlement, you can’t build a road through it.

touching_node
If specified, valid road spots MUST touch this node.

This is used during setup when players can only place a road touching the settlement they just placed.

[Source]

# File lib/core/board.rb, line 509
  def get_valid_road_spots(road_color, touching_node=nil)
    result=[]
    all_nodes.each{|n|
      if n.city and n.city.color == road_color
        result += n.edges.select{|e| not e.road}
      elsif not n.city
        for e in n.edges
          if e.road and e.road.color == road_color
            spaces = n.edges.select{|e| not e.road}
            result += spaces
          end
        end
      end
    }
    result = result.select{|e| e.nodes.include?(touching_node)} if touching_node
    result.uniq
  end

Gets a list of Nodes that settlements can be placed on.

roadConstraint
A boolean that ensures that settlements can only be placed

on pre-existing roads. For SetupTurns, this should be false. (Players don’t need to connect settlements to roads during setup. )

roadColor
The color of the road to constrain against. For a normal turn,

you need to ask which spots are valid for your player’s color.

[Source]

# File lib/core/board.rb, line 490
  def get_valid_settlement_spots(roadConstraint, roadColor)
    all_nodes.select{|n| 
      ##make sure there are no cities in the adjecent nodes
      is2AwayFromCities = (not n.get_adjecent_nodes.find{|n2| n2.city})
  
      if roadConstraint
        hasAdjecentRoad = n.edges.find{|e| e.road and e.road.color == roadColor}
        hasAdjecentRoad and is2AwayFromCities and not n.city
      else 
        is2AwayFromCities and not n.city
      end
    }.uniq
  end

[Source]

# File lib/core/board.rb, line 414
  def has_longest_road?(color)
    maxs = {}
    maxs.default = 0
#    for e in @roadEdges
#      i = longest_road(e)
#      color2 = e.road.color
#      maxs[color2] = i if i>maxs[color2] and i >= 5
#    end
    
    for e in @roadEdges
      for road_length in e.road_lengths
        color2 = e.road.color
        maxs[color2] = road_length if road_length>maxs[color2] and road_length>=5
      end
    end
    winners = maxs.keys.select{|k| maxs[k]==maxs.values.max}
    
    #only 1 player can have longest road
    #if more than 1 player has the longest road, than neither of them count
    winners.length == 1 and winners[0] == color
  end

[Source]

# File lib/core/board.rb, line 318
  def initialize_hexes_and_ports
    @recomended_players = 3..4
    @expansion = StandardGame.new
    @name = 'Standard Board'
    
    bag = TileBag.new
    coords = [[-2,1],[-2,2],[-2,3],
              [-1,0],[-1,1],[-1,2],[-1,3],
              [0,0],[0,1],[0,2],[0,3],[0,4],
              [1,0],[1,1],[1,2],[1,3],
              [2,1],[2,2],[2,3]]
    for c in coords
      @tiles[c] = bag.get_hex
      @tiles[c].coords = c
    end
    connectTiles

    #Ports
    #each one is a tile coord + the edge number to put the port on
    coords = [[1,0,0], [2,1,1], [2,2,2], [1,3,2], 
      [0,4,3], [-1,3,4], [-2,2,4],[-2,1,5],[-1,0,0]]
    
    for x,y,edge in coords
      portEdge = getTile(x, y).edges[edge]
      port = bag.get_port
      for n in portEdge.nodes
        n.port = port
      end
    end  
  end

returns an int

[Source]

# File lib/core/board.rb, line 369
  def longest_road(edge, visitedNodes=[])
    if edge.road 
      color = edge.road.color
      
      length = 0
      (edge.nodes - visitedNodes).each{|n|
        max = 0
        n.edges.each{|e|
          if e != edge and e.road and e.road.color == color
            sub_length = longest_road(e, visitedNodes + [n])
            max = sub_length if sub_length > max
          end  
        }
        length += max
      }
      length + 1
    end
  end

place a city or a settlement

[Source]

# File lib/core/board.rb, line 477
  def place_city!(city, x, y, nodeNum)
    t = getTile(x, y)
    node = t.nodes[nodeNum]
    node.city = city
  end

[Source]

# File lib/core/board.rb, line 461
  def place_road!(road, tileX, tileY, edgeNum)
    t = getTile(tileX, tileY)
    edge = t.edges[edgeNum]
    edge.road = road
    @roadEdges << edge
    
    #update the longest road markers
    edge.visit_road do |e|
      e.road_lengths[0] = find_longest_road(e, 0)
      e.road_lengths[1] = find_longest_road(e, 1)
    end
    
    return edge
  end

[Validate]