# cc/journeyman/the_great_game/buildings/rectangular.clj

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