001  (ns cc.journeyman.the-great-game.buildings.rectangular
002    "Build buildings with a generally rectangular floow plan.
003     
004     ## Motivations
005     
006     Right, the idea behind this namespace is many fold.
007  
008     1. To establish the broad principle of genetic buildings, by creating a
009        function which reproducibly creates reproducible buildings at specified
010        locations, such that different buildings are credibly varied but a
011        building at a specified location is always (modulo economic change) the
012        same.
013     2. Create good rectangular buildings, and investigate whether a single 
014        function can be used to create buildings of more than one family (e.g.
015        can it produce flat roofed, north African style, mud brick houses as
016        well as pitch roofed, half timbered northern European houses?)
017     3. Establish whether, in my current state of fairly severe mental illness,
018        I can actually produce any usable code at all.
019  
020     ## Key factors in the creation of a building
021  
022     ### Holding
023  
024     Every building is on a holding, and, indeed, what I mean by 'building' here
025     may well turn out to be 'the collection of all the permanent structures on
026     a holding. A holding is a polygonal area of the map which does not 
027     intersect with any other holding, but for the time being we'll make the 
028     simplifying assumption that every holding is a rectangular strip, and that
029     'urban' holdings are of a reasonably standard width (see Viking-period 
030     York) and length. Rural holdings (farms, ?wood lots) may be much larger.
031  
032     ### Terrain
033  
034     A building is made of the stuff of the place. In a forest, buildings will 
035     tend to be wooden; in a terrain with rocky outcrops -- normally found on 
036     steep slopes -- stone. On the flat lands where there's river mud, of brick,
037     cob, or wattle and daub. So to build a building we need to know the 
038     terrain. Terrain can be inferred from location but in practice this will 
039     be computationally expensive, so we'll pass terrain in as an argument to
040     the build function.
041  
042     For the time being we'll pass it in simply as a keyword from a defined set
043     of keywords; later it may be a more sophisticated data structure.
044  
045     ### Culture
046  
047     People of different cultures build distinctively different buildings, even
048     when using the same materials. So, in our world, a Japanese wooden house 
049     looks quite different from an Anglo Saxon stave house which looks quite 
050     different from a Canadian log cabin, even though the materials are much the
051     same and the tools available to build with are not much different.
052  
053     Culture can affect not just the overall shape of a building but also its 
054     finish and surface detail. For example, in many places in England, stone
055     buildings are typically left bare; in rural Scotland, typically painted 
056     white or in pastel shades; in Ireland, often quite vivid colours.
057  
058     People may also show religious or cultural symbols on their buildings.
059   
060     For all these reasons, we need to know the culture of the occupant when
061     creating a building. Again, this will initially be passed in as a keyword.
062  
063     ### Craft
064  
065     People in the game world have a craft, and some crafts will require 
066     different features in the building. In the broadly late-bronze-age-to
067     medieval period within which the game is set, residence and  workplace
068     are for most people pretty much the same.
069  
070     So a baker needs an oven, a smith a forge, and so on. All crafts who do
071     some degree retail trade will want a shop front as part of the ground 
072     floor of their dwelling. Merchants and bankers will probably have houses
073     that are a bit more showy than others.
074  
075     Whether the 'genetic buildings' idea will ever really produce suitable
076     buildings for aristons I don't know; it seems more likely that significant
077     strongholds (of which there will be relatively few) should all be hand
078     modelled rather than procedurally generated."
079    (:require [cc.journeyman.the-great-game.holdings.holding :refer [ProtoHolding]]
080              [cc.journeyman.the-great-game.location.location :refer [ProtoLocation]])
081    (:import [org.apache.commons.math3.random MersenneTwister]))
082  
083   
084  (def ^:dynamic *terrain-types* 
085    "Types of terrain which affect building families. TODO: This is a placeholder;
086     a more sophisticated model will be needed."
087    #{:arable :arid :forest :plateau :upland})
088  
089  (def ^:dynamic *cultures*
090    "Cultures which affect building families. TODO: placeholder"
091    #{:ariston :coastal :steppe-clans :western-clans :wild-herd})
092  
093  (def ^:dynamic *crafts*
094    "Crafts which affect building types in the game. See 
095     `Populating a game world`. TODO: placeholder"
096    #{:baker :banker :butcher :chancellor :innkeeper :lawyer :magus :merchant :miller :priest :scholar :smith :weaver})
097  
098  (def ^:dynamic *building-families* 
099    "Families of buildings.
100     
101     Each family has
102     
103     * terrain types to which it is appropriate;
104     * crafts to which it is appropriate;
105     * cultures to which it is appropriate. 
106     
107     Each generated building will be of one family, and will comprise modules 
108     taken only from that family."
109    {:pitched-rectangular {:terrains #{:arable :forest :upland}
110                           :crafts *crafts*
111                           :cultures #{:coastal :western-clans}
112                           :modules []}
113     :flatroof-rectangular {:terrains #{:arid :plateau}
114                            :crafts *crafts*
115                            :cultures #{:coastal}
116                            :modules []}})
117  
118  
119  (defn building-family
120    "A building family is essentially a collection of models of building modules
121     which can be assembled to create buildings of a particular structural and
122     architectural style."
123    [terrain culture craft gene]
124    (let [candidates (filter #(and
125                               ((:terrains %) terrain)
126                               ((:crafts %) craft)
127                               ((:cultures %) culture))
128                             (vals *building-families*))]
129      (nth candidates (mod (Math/abs (.nextInt gene)) (count candidates)))))
130  
131  (building-family :arable :coastal :baker (MersenneTwister. 5))
132  
133  (defn build! 
134    "Builds a building, and returns a data structure which represents it. In 
135     building the building, it adds a model of the building to the representation
136     of the world, so it does have a side effect."
137    [holding terrain culture craft size]
138    (if (satisfies? ProtoHolding holding)
139    (let [location (.building-origin holding)
140          gene (MersenneTwister. (int (+ (* (.easting location) 1000000) (.northing location))))
141          family (building-family terrain culture craft gene)]
142    (if 
143     (and (instance? ProtoLocation location) (:orientation location))
144      :stuff
145      :nonsense
146      ))
147      :froboz))
148  
149  ;; (def ol (cc.journeyman.the-great-game.location.location/OrientedLocation. 123.45 543.76 12.34 0.00 {}))
150