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