F r o b W o r l d J CS 351 F'13 Second Individual Project See (T.2) for dates and deliverables See (S.13) for changes. Document version 0.9 Last revision: Sat Oct 5 09:41:22 2013 ------------------------------------------------- Table of Contents (S.0) Artificial Life Research (S.1) FrobWorld Research Summary (S.2) FrobWorld Technical Description (S.3) Properties of the world (S.4) Properties of Things (S.5) Properties of Genotypes (S.6) Frob behavior generation (S.7) Grass behavior generation (S.8) Summary of parameters (S.9) Generation of an initial world (S.10) Details about Frob genetics and reproduction (S.11) Deliverables (S.12) Available resources (S.13) Document Information ------------------------------------------------- CS351 Fall 2013 Program 2: FrobWorldJ ((S.0)) Artificial Life Research ((S.0.1)) Answer the following two questions, providing supporting data: ((S.0.1.1)) Q1: Over 25 runs, how many initially random populations of frobs survive for a specified number of days? ((S.0.1.2)) Q2: Of the populations that survive that long, what is the mean and standard deviation of their final metabolic rates? ((S.0.1.3)) Implementing the FrobWorld program, described below, will be of value in answering these questions. The 'specified number of days' is given by MAX_SIMULATION_LENGTH (S.8.2). F r o b W o r l d i n J a v a ((S.1)) Summary of Proposed Research ((S.1.1)) There is a tradeoff between species that 'live fast and die young' and those that take a more measured approach to life. On the one hand, species with high metabolic rates may grow and therefore reproduce more rapidly that more sedate species, but on the other hand, such 'fast' species may be more likely to exhaust their environmental resources and become extinct. This research investigates what can happen when fast and slow species compete head to head. ((S.2)) FrobWorld Technical Description ((S.2.1)) Program Usage ((S.2.1.1)) The final deliverable program is named 'FrobWorld.jar'. It can be run in two modes, 'interactive' and 'batch'. ((S.2.1.2)) Interactive mode. To run 'FrobWorld.jar' in interactive mode, simply type: $ java -jar FrobWorld.jar ((S.2.1.2.1)) In interactive mode, FrobWorld.jar draws a graphical representation of the world in a top-level window, then generates an initial population and simulates their evolution. Whenever a population becomes extinct, or survives for MAX_SIMULATION_LENGTH simulated days (S.8.2), the world is cleared, and a new simulation is begun. The program exits when the user closes the top-level window. ((S.2.1.3)) Batch mode. To run 'FrobWorld.jar' in batch mode, simply type: $ java -jar FrobWorld.jar batch datafile ((S.2.1.3.1)) In batch mode, FrobWorld.jar does not perform any display. Instead, it reads standard input to determine how many simulation runs to perform, and performs that many runs, writing summary data about each run to standard output. ((S.2.1.3.2)) The inputfile for batch mode can take either of two forms, called 'runcount' and 'runthese'. ((S.2.1.3.3)) A 'runcount' input file contains one line consisting of a single integer greater than zero. Reading an integer greater than zero suffices to indicated that the file is a 'runcount' file. To process a runcount file, FrobWorld.jar just performs the number of simulations indicated, starting from a random initial setup each time, and writing out summary data to the output. ((S.2.1.3.4)) A 'runthese' input file begins with a line containing a 0, and this suffices to distinguish it from a 'runcount' file. In a runthese file, following the 0 are any number of non-zero seed values, followed by another 0. To process a runthese file, FrobWorld.jar performs one simulation for each seed value, using the given number to seed the random number generator before constructing the initial world for the simulation. When FrobWorld.jar reads a zero-valued seed, it terminates. ((S.2.1.3.4.1)) It can be quite helpful for debugging -- and simply curiousity -- to provide a way to feed a particular seed value in when running FrobWorld.jar in interactive mode, so one can watch a particular simulation unfold. This document, however, does not specify any particular way in which that could or should be accomplished. ((S.2.1.3.5)) Summary data for a simulation should include, at a minimum, the random number seed used to generate that particular simulation, and the number of days that the Frobs survived. Much other information could be usefully included once the program is working, of course. ((S.2.2)) Basic design elements. ((S.2.2.1)) FrobWorld is an event-driven simulation controlled by a fast priority queue algorithm. This organization makes it easy to implement the notion of varying 'metabolic' rates simply by adjusting the period between when each entity 'wakes up' and takes an action. ((S.2.2.2)) FrobWorld is a simple, fixed-size, 2-dimensional grid. Each location in the world can be empty, or can contain either a Rock, a Grass, or a Frob. ((S.2.2.3)) Rocks represent obstacles that Frobs must avoid bumping into for greatest success. They are immobile and unchanging, so their 'metabolic rate' is effectively zero. ((S.2.2.4)) Grass is the food supply for the Frobs. To simulate the fact that Grass grows spontaneously given just sunlight, the metabolic rate of Grass is set to be negative, causing them to increase in mass spontaneously over time. When a Grass reaches a specific size, it splits in two, if there aren't too many Grasses already around (see (S.3.3.3) for the exact conditions). If a Grass can't split because of crowding, it discards the excess mass and permanently slows its metabolic rate. Since the main focus of this research is the behavior of the Frobs, the growth, reproduction, and behavior of Grasses is all pre-fixed and constant, so they require no genotype and do not evolve. ((S.2.2.5)) Frobs are herbivores, mobile creatures that must find Grass to eat or they die. They are capable of sensing what is in the locations immediately adjacent to them north, south, east, and west, and their choice of action is to (attempt to) move in one of those directions. ((S.2.2.6)) When a Frob event begins, before it attempts to move, it must pay its metabolic tax. If paying the tax causes the Frob's mass to become less than or equal to zero, the Frob dies and is destroyed. ((S.2.2.7)) If a Frob pays its metabolic tax successfully, it then examines its four neighboring locations, and, using its genetic information, chooses which direction to attempt to move. See (S.10.3) for details. ((S.2.2.7.1)) DESIGN THOUGHT: It is probably wise to leave the processing of the genetic information until relatively later in the development. Nearly all of the system can be constructed and tested just by having the Frobs make a random choice of move for (S.2.2.7). ((S.2.2.8)) The effect of a Frob action depends on what is in the destination location. For a Frob 'foo': ((S.2.2.8.1)) If the location is empty, then foo enters it, and the Frob event is finished. ((S.2.2.8.2)) If the location contains a Grass, foo eats it and then enters. Eating a Grass causes all the Grass' mass to be transferred to foo, and the Grass to be deleted. If eating the Grass causes foo to equal of exceed its birthmass, then after it enters, it splits to produce an offspring, which enters the location foo just exited. Whether or not a birth occurs, the Frob event is then finished. ((S.2.2.8.3)) If the location contains a Rock, foo is 'hurt' by the move attempt, paying a mass penalty equal to the simulation parameter ROCK_BUMP_PENALTY. If paying the penalty causes foo's mass to become less than or equal to zero, then foo dies and is destroyed. If foo does not die, then it remains where it was before attempting to move. Either way, the Frob event is finished. ((S.2.2.8.4)) If the location contains another Frob 'bar', then 'bar' is hurt by the move attempt, paying a mass penalty equal to the simulation parameter FROB_HIT_PENALTY. If paying the penalty causes bar's mass to become less than or equal to zero, then bar dies and is destroyed. Whether or not bar dies, foo remains where it was before attempting to move, and the Frob event is finished. ------------------------------------------------- ((S.3)) Properties of the world ((S.3.1)) The World is a 2-dimensional array of WORLD_WIDTH by WORLD_HEIGHT 'locations'. (See (S.8.2) for more on WORLD_WIDTH and WORLD_HEIGHT). ((S.3.2)) Locations. ((S.3.2.1)) Each location has an address consisting of an x and y value within the world array. For example, if WORLD_WIDTH is 50 and WORLD_HEIGHT is 25, then x coordinates ranges from 0..49 and y coordinates range from 0..24. Visually, x increases left to right, and y increases top to bottom, so the indexing scheme overall looks like: (0,0) (1,0) ... (48,0) (49,0) (0,1) (1,1) (48,1) (49,1) ... ... (0,23) (1,23) (48,23) (49,23) (0,24) (1,24) ... (48,24) (49,24) ((S.3.2.2)) The world is framed by Rocks, meaning that the following locations contain rocks: (0,y) (49,y) (x,0) (x,24) for 0<=x<50 and 0<=y<25. These locations are called 'edge locations'. ((S.3.2.3)) Non-edge locations, when the difference is important, are called 'interior locations'. ((S.3.2.4)) Since all edge locations contain Rocks, Grass and Frobs can only occupy interior locations. ((S.3.3)) Neighborhood ((S.3.3.1)) The neighborhood of an interior location 'x' consists of the four locations adjacent to 'x', i.e., the locations marked by 'NSEW' here: .N. WxE .S. ((S.3.3.2)) The neighborhood defines what a Frob is able to sense, and where it is able to attempt to move. ((S.3.3.3)) The neighborhood also defines where a Grass may produce an offspring when it needs to split. At that time, if the neighborhood contains less than GRASS_CROWD_LIMIT (S.8.2) grasses, and one or more empty neighborhood locations are available, then one of the empty locations is selected at random for the location of the offspring. Note that only grasses are significant in determining the GRASS_CROWD_LIMIT condition -- e.g., a grass hemmed in by rocks and frobs can still split if there's an empty location. ((S.3.3.3.1)) When the Grass attempts to split, if GRASS_CROWD_LIMIT or more grasses are already in the neighborhood, or no empty locations at all are available, then (1) no offspring is created, (2) the mass of the Grass is set to its birthmass, and (3) its update period is doubled, up to a maximum of GRASS_MAX_UPDATE_PERIOD. ((S.3.3.3.2)) Otherwise, a Grass offspring is created in the randomly-selected empty location, following the guidelines of (S.4.2.1.2), (S.4.2.1.3), and (S.4.2.1.5) for determining the offspring initial properties and the impact on the parent. ((S.3.4)) Contents of Locations ((S.3.4.1)) Each of the locations of the world contains either ((S.3.4.1.1)) Nothing, ((S.3.4.1.2)) One Rock, ((S.3.4.1.3)) One Grass, ((S.3.4.1.4)) One Frob. ------------------------------------------------- ((S.4)) Properties of Things ((S.4.1)) A 'Thing' is either a Rock or a Grass or a Frob. ((S.4.1.1)) All Things possess the following property: ((S.4.1.1.1)) Location: An x,y position in the world. ((S.4.2)) Properties of Beings A 'Being' is either a Grass or a Frob, but not a Rock. ((S.4.2.1)) All Beings possess the following properties: ((S.4.2.1.1)) Mass: An integer >= 0. Any action that would cause the Mass of a Being to become zero or negative causes the Being to be destroyed. ((S.4.2.1.2)) BirthMass: An integer > 0. Any action that would cause the Mass of a Being to become greater than its BirthMass causes the Being to attempt to produce an offspring. ((S.4.2.1.3)) BirthPercent: An integer from 0 to 100. When a Being successfully produces an offspring, the BirthPercent determines what percentage of its Mass it given to the offspring. A BirthPercent of 0 causes the offspring to begin with no Mass, so it will die the first time it runs. A BirthPercent of 100 causes the offspring to receive all the Mass of the parent, so the parent will die, at the latest, the next time it runs. ((S.4.2.1.4)) UpdatePeriod: An integer > 0. When a Being has finished an event, the UpdatePeriod determines how much time will pass before the Being runs again. ((S.4.2.1.5)) NextUpdate: An integer > 0. The 'day' of the next time a Being will run. When a new Being is created, its NextUpdate is set to the current day (called 'today') plus a random number from 0 to its UpdatePeriod (inclusive). ((S.4.2.1.6)) MassTaxMills: An integer. A component of a Being's mass adjustment per day, expressed in 'mills' of mass, where 1 mill equals 1 part in 1000 (or equivalently, 0.1%). When a Being begins an event, its Mass is adjusted by a tax formula as follows: Mass -= MassTaxMills*UpdatePeriod/1000+FixedOverhead; ((S.4.2.1.6.1)) Depending on the sign of MassTaxMills, this may cause the Mass to become zero or less, in which case the Being dies, or to become greater than or equal to BirthMass, in which the Being attempts to produce an offspring. Note that FixedOverhead always tends to decrease the Mass, regardless of the sign of MassTaxMills. ((S.4.2.1.7)) The value of FixedOverhead is different for different types of Beings. See GRASS_FIXED_OVERHEAD and FROB_FIXED_OVERHEAD in (S.8.2). ((S.4.3)) Properties of Grass ((S.4.3.1)) Grass contains no other properties beyond the fact that it is a Being and a Thing. All Grasses have specific, constant values for the following elements: ((S.4.3.1.1)) BirthMass: See GRASS_BIRTH_MASS in (S.8.2). ((S.4.3.1.2)) BirthPercent: See GRASS_BIRTH_PERCENT in (S.8.2) ((S.4.3.1.3)) UpdatePeriod: See GRASS_UPDATE_PERIOD in (S.8.2) ((S.4.3.1.4)) MassTaxMills: See GRASS_MASS_TAX_MILLS in (S.8.2) ((S.4.4)) Properties of Frobs ((S.4.4.1)) In addition to the properties associated with being a Being and a Thing, a Frob contains the following properties: ((S.4.4.1.1)) MassTaxMills: See FROB_MASS_TAX_MILLS in (S.8.2) ((S.4.4.1.2)) Genes: An instance of a Genotype. ------------------------------------------------- ((S.5)) Properties of Genotypes. ((S.5.1)) Frobs possess a Genotype that controls some aspects of their behavior, and allows them to evolve over time. ((S.5.2)) A Genotype consists of an array 'dna' of DNA_LENGTH (S.10.1) of unsigned bytes. See (S.10) for more specific information on this topic. The interpretation of the 'dna', loosely speaking, is as follows: ((S.5.2.1)) dna[0]: Determines the Frob's BirthMass. (S.10.2.2.1) ((S.5.2.2)) dna[1]: Determines the Frob's BirthPercent. (S.10.2.2.2) ((S.5.2.3)) dna[2]: Determines the Frob's UpdatePeriod, (S.10.2.2.3) ((S.5.2.4)) dna[3]-dna[6]: Determines the Frob's preference for moving North given that location contains nothing (dna[3]), a Rock (dna[4]), a Grass (dna[5]), or a Frob (dna[6]). (S.10.3) ((S.5.2.5)) dna[7]-dna[10]: Determines the Frob's preference for moving South. (S.10.3) ((S.5.2.6)) dna[11]-dna[14]: Determines the Frob's preference for moving East. (S.10.3) ((S.5.2.7)) dna[15]-dna[18]: Determines the Frob's preference for moving West. (S.10.3) ------------------------------------------------- ((S.6)) Frob behavior generation ((S.6.1)) A Frob action involves the following steps: ((S.6.1.1)) Paying the mass tax. The Frob's mass is altered by this assignment: mass -= ((int) (masstax*updateperiod))+FROB_FIXED_OVERHEAD; ((S.6.1.1.1)) If this adjustment causes the mass to be less than or equal to zero, the Frob dies and the action is concluded. ((S.6.1.2)) Choosing an action. This part of the Frob action depends on its genetic information as follows: ((S.6.1.2.1)) This topic is covered in (S.10.3). ((S.6.1.2.2)) DESIGN THOUGHT: For starters, just choose action N,S,E,W uniformly at random. The behavior of such 'fixed random Frobs' is a good test case (and a natural strawman for comparing to the 'evolving Frobs'.) ((S.6.1.3)) Attempting the move. The effect of a Frob move attempt from one location (call it 'at') depends on the contents of the destination location (call it 'dest') as follows: ((S.6.1.3.1)) Dest is empty. Result: The Frob leaves 'at' and enters 'dest'. ((S.6.1.3.2)) Dest contains a Grass. Result: The Frob eats the grass. The mass of the Grass is transferred to the Frob (up to the Frob's birthmass; any excess is discarded), the Grass is deleted, and the Frob leaves 'at' and enters 'dest'. ((S.6.1.3.3)) Dest contains a Rock. Result: The Frob loses ROCK_BUMP_PENALTY mass (down to zero). The Frob remains in 'at'. ((S.6.1.3.4)) Dest contains a Frob: Result: The Frob in 'dest' loses FROB_HIT_PENALTY mass (down to zero). If the resulting mass is less than or equal to zero, the Frob in 'dest' dies and is deleted. Either way, however, the Frob in 'at' *remains* in 'at'. ((S.6.1.4)) After the move attempt (or move, if it occurred). If the Frob's mass is less than or equal to zero, the Frob dies and is deleted. Otherwise, if the Frob's mass is greater than or equal to its birthmass, and it actually entered 'dest' it generates an offspring 'behind it' in 'at' (S.6.2). ((S.6.1.5)) Rescheduling. If the Frob is still alive at the end of the action, it schedules its next action for updateperiod days in the future. ((S.6.2)) Frob Offspring generation ((S.6.2.1)) Initial mass. The creation of a Frob offspring involves a transfer of mass from the parent (now at 'dest') to the new offspring (created at 'at'). The amount of mass transferred is given by masstransfer = */100 ((S.6.2.1.1)) The parent loses exactly this amount, and the offspring begins with exactly this amount. ((S.6.2.1.2)) For extreme values of (especially in combination with low values of birthmass) it is possible that this masstransfer will cause either the parent's mass to become zero, or the offspring's mass to begin at zero. If this happens, the zero-massed individual *will* survive until its next (or first) turn, unless it is hit by another frob in the meantime. ((S.6.2.2)) Inheritance and mutation: See (S.10.4). ((S.6.2.2.1)) DESIGN THOUGHT: For debugging and strawman purposes, create offspring by copying the parent's BirthMass, BirthPercent, and UpdatePeriod without change. ((S.6.2.3)) Offspring scheduling. The offspring's first action is scheduled for today plus a random number from 1 to the offspring's UpdatePeriod (inclusive). ((S.7)) Grass behavior generation ((S.7.1)) A single action on the part of a grass involves the following steps, in order. ((S.7.1.1)) 'Pay' mass tax: mass -= GRASS_MAX_TAX_MILLS*UpdatePeriod/1000+GRASS_FIXED_OVERHEAD; Since the masstax for Grass is negative, so long as GRASS_MAX_TAX_MILLS*updateperiod is greater that GRASS_FIXED_OVERHEAD (S.8.2), this will cause a Grass's mass to increase. ((S.7.1.2)) If the Grass mass is now less than or equal to zero, the Grass dies and is destroyed. (We don't expect the parameters to be set so this will happen, but we should handle the case correctly just because parameters *might be* set, intentionally or inadvertently, so that the mass tax for grass is negative.) ((S.7.1.3)) Otherwise, if the Grass mass is now strictly greater than the birthmass, the grass attempts to 'split' (S.3.3.3). ((S.7.1.4)) The Grass event is now concluded, and it is scheduled for another event at today+updateperiod -- the current simulated day plus the Grasses current update period. (The update period for all Grasses starts out at GRASS_UPDATE_PERIOD when the grass is created, but can increase due to failed splitting attempts (S.3.3.3.1). ------------------------------------------------- ((S.8)) Summary of parameters ((S.8.1)) There are a lot of parameters that control the simulation. The following declarations provide suggested names for them, and PRELIMINARY values for them. ((S.8.1.1)) It is CERTAIN that some or many of the the specific numbers here will change. ((S.8.1.2)) It is LIKELY that some of the numbers will change in ways that means they could have been eliminated, e.g., an additive constant becoming 0 or a multiplicative constant becoming 1, but nonetheless the simulation code must remain correct regardless of what the specific values are. ((S.8.1.3)) It is UNLIKELY, but POSSIBLE, that additional parameters will be added to this list. ((S.8.2)) Parameter names and version 1.0 parameter values // Simulation parameters WORLD_WIDTH = 50, // World Width WORLD_HEIGHT = 25, // World Height MAX_SIMULATION_LENGTH = 10000, // Time to quit even if frobs still live ROCK_BUMP_PENALTY = 30, // Mass penalty when Frob hits Rock FROB_HIT_PENALTY = 10, // Mass penalty (of hittee) when Frob hits Frob INIT_FROBS = 40, // Number of Frobs in initial world INIT_GRASSES = 40, // Number of Grasses in initial world INIT_ROCKS = 50, // Number of interior Rocks in initial world GRASS_FIXED_OVERHEAD = 0, // Grass fixed mass cost per action GRASS_GENESIS_MASS = 10, // Initial Grass mass GRASS_BIRTH_MASS = 30, // Mass at which Grasses wish to split GRASS_UPDATE_PERIOD = 10, // Days between Grass activities GRASS_CROWD_LIMIT = 2, // 4-neighborhood Grass count for no splitting GRASS_MAX_UPDATE_PERIOD = 100, // Max inactive days on failed splitting GRASS_BIRTH_PERCENT = 40, // Percent of mass given to offspring at split FROB_FIXED_OVERHEAD = 3, // Frob fixed mass cost per action FROB_GENESIS_MASS = 100, // Initial Frob mass DNA_MUTATION_ODDS_PER_BYTE = 20, // 1-in-this chance of a bit flip per byte GRASS_MASS_TAX_MILLS = -20, // Grass mass loss per day FROB_MASS_TAX_MILLS = 10, // Frob mass loss per day ------------------------------------------------- ((S.9)) Generation of an initial world ((S.9.1)) A simulation is initialized with the following steps: ((S.9.1.1)) The world is emptied. The simulation time is set to day 0. ((S.9.1.2)) Rocks are created at all edge locations. ((S.9.1.3)) INIT_ROCKS Rocks are created at random unoccupied interior locations. ((S.9.1.4)) INIT_GRASSES Grasses are created at random unoccupied interior locations. Each Grass begins with GRASS_GENESIS_MASS mass. Each Grasses first event is scheduled as if it were an offspring born on day 0. ((S.9.1.5)) INIT_FROBS Frobs are created at random unoccupied interior locations. Each Frob has random genetic information and begins with FROB_GENESIS_MASS mass. Each Frob's first event is scheduled as if it were an offspring born on day 0. ((S.10)) Details about Frob genetics and reproduction ((S.10.1)) Layout of dna. Names for (most of) the bytes of dna, and its overall size, is given by: Names and positions of dna fields DNA_BIRTH_MASS=0, // dna[0] controls birthmass DNA_BIRTH_PERCENT=1, // dna[1] controls birthpercent DNA_UPDATE_PERIOD=2, // dna[2] controls updperiod DNA_NORTH_PREFS=3, // dna[3..6] controls north prefs DNA_EMPTY_OFFSET=0, // so,e.g., dna[DNA_NORTH_PREFS+DNA_ROCK_OFFSET] DNA_ROCK_OFFSET=1, // is how much this frob likes to move DNA_GRASS_OFFSET=2, // north when there's a rock there DNA_FROB_OFFSET=3, // likewise for empty, grass, another frob DNA_SOUTH_PREFS=7, // base index for south preferences DNA_EAST_PREFS=11, // ditto, east DNA_WEST_PREFS=15, // ditto, west DNA_LENGTH=19 // OVERALL LENGTH OF DNA ((S.10.2)) The exact rules by which the dna determines the 'birth properties' -- update period, birth mass, and birth percent -- of a new Frob are given in (S.10.2.2). So far as possible, these rules should be treated like the constant parameters of (S.8.2). --- the rules themselves may change in detail, and so it should be easy to update simulation code for rule changes here. ((S.10.2.1)) (This section intentionally left blank). ((S.10.2.2)) Version 1.0 Rules for determining Birth Properties from dna. These rules may change in detail as more simulation experience is gained -- for example, the specific numbers may change, or a '%' might become a '/' or vice-versa -- but they will NOT change to depend on other information. Only one byte of dna, plus numeric constants and arithmetic operators, will be involved in each rule. ((S.10.2.2.1)) Frob int BirthMass: dna[DNA_BIRTH_MASS]/2+20 ((S.10.2.2.2)) Frob int BirthPercent: dna[DNA_BIRTH_PERCENT]*100/255 ((S.10.2.2.3)) Frob int UpdatePeriod: dna[DNA_UPDATE_PERIOD]%32+5 ((S.10.3)) Rules for determining Frob choice of action. ((S.10.3.1)) A frob acts in frobworld by choosing a direction from NORTH, SOUTH, EAST, or WEST, and then attempting to move in that direction. Whether or not the move actually occurs, and in general what happens when a move attempt is made, is described in (S.6.1.3). ((S.10.3.2)) There are four 'segments' of dna involved in action selection, one segment for each possible move direction. They are called the 'prefs' segments, because they determine a frob's 'preferences' for moving in that direction. ((S.10.3.2.1)) The beginnings of the prefs segments are at indices DNA_NORTH_PREFS, DNA_SOUTH_PREFS, DNA_EAST_PREFS, and DNA_WEST_PREFS (S.10.1). Each prefs segment is four bytes long, and the four bytes within a segment are named DNA_EMPTY_OFFSET, DNA_ROCK_OFFSET, DNA_GRASS_OFFSET, and DNA_FROB_OFFSET (S.10.1). ((S.10.3.2.2)) So, for example dna[DNA_NORTH_PREFS+DNA_ROCK_OFFSET] contains the Frob's genetic preference for moving North when there is a rock in the next location North (hopefully that would evolve to be a small value), while dna[DNA_WEST_PREFS+DNA_EMPTY_OFFSET] contains its preference for moving West when there is nothing in the next location West. ((S.10.3.2.3)) Overall, therefore, there are sixteen bytes of genetic information *potentially* involved in Frob action selection -- four directions by four possible contents of the location in that direction. ((S.10.3.2.4)) In any *specific* Frob action selection, only four of those bytes are relevant, one each from the north, south, east, and west prefs segments, depending on what is *actually* in those neighboring locations. ((S.10.3.3)) So to select an action, the frob performs the following steps. ((S.10.3.3.1)) Examine the neighborhood and find out what is in each location -- EMPTY, ROCK, GRASS, or FROB. ((S.10.3.3.2)) Look up the corresponding values in its prefs segments, and add 1 to each. This produces a 'current preferences' of four numbers, one number each for North, South, East, and West, and with each number ranging 1..256. ((S.10.3.3.3)) Pick a direction at random *weighted* by the four directional preference values. That direction is the selected action. ((S.10.3.3.3.1)) For example, suppose a Frob's prefs segments have the following values: NORTH EMPTY 64 ROCK 123 GRASS 6 FROB 97 SOUTH EMPTY 38 ROCK 12 GRASS 201 FROB 59 EAST EMPTY 0 ROCK 37 GRASS 195 FROB 159 WEST EMPTY 101 ROCK 3 GRASS 7 FROB 251 ((S.10.3.3.3.2)) If the Frob examines its neighborhood and finds a Grass to the North and the rest all empty, then its current preferences would be (7,39,1,102) for (North, South, East, West). ((S.10.3.3.3.3)) The Frob now needs to select an action at random but weighted by its current preferences. This can be done by ((S.10.3.3.3.3.1)) summing up the current preferences (yielding 7+39+1+102=149 in the example); ((S.10.3.3.3.3.2)) choosing a random number from 0..-1 (in the example, 0..148, with the random call yielding, say, 57); and ((S.10.3.3.3.3.3)) decrementing the chosen random number by each directional preference value in turn and selecting the direction that made the decremented value negative (so, 57-7 -> 50>=0, so North isn't selected; then 50-39 -> 11>=, so South isn't selected; then 11-1 ->10>=0, so East isn't selected; then 10-102 -> -92<0, so West is selected). ((S.10.4)) Frob dna inheritance and mutation ((S.10.4.1)) When a 'parent' Frob splits to create an 'offspring' Frob, the offspring Frob gets a copy of the parent's dna, but it is not necessarily an exact copy -- there may be errors introduced, 'mutations' that cause the offspring to have somewhat different properties than the parent. ((S.10.4.2)) Mutation can be implemented by first copying the parent dna to the offspring exactly, and then 'messing it up a bit' in a specific way. ((S.10.4.3)) Mutation is governed by a single parameter: DNA_MUTATION_ODDS_PER_BYTE (S.8.2). Assuming the offspring Frob now has an exact copy of the parent dna, the parameter is used as follows: ((S.10.4.4)) For each of the DNA_LENGTH bytes of offspring dna, a random number from 0..DNA_MUTATION_ODDS_PER_BYTE-1 is drawn. If the number drawn == 0, then a mutation occurs in that byte, otherwise it remains equal to the corresponding byte in the parent dna. If a mutation does occur, then exactly one of the 8 bits in the byte, chosen at random, is flipped. ((S.10.4.5)) Note that the 'birth properties' of an offspring Frob (S.10.2.2) depend on the offspring's dna *after mutation has been performed*. In other words, the offspring dna must be copied and mutated from the parent dna *before* the offspring's birthmass, birthpercent, and updateperiod are computed. ------------------------------------------------- ((S.11)) Deliverables ((S.11.1)) See (T.2) in the associated spec-dates.txt document for exact dates and deliverables. Some brief introductory notes are given here. ((S.11.1.1)) P2D1 ((S.11.1.1.1)) P2D1 Mission #1: Basic Priority Queue. ((S.11.1.1.1.1)) Implement an 'from-scratch' intrusive priority queue following the requirements in spec-pq.txt and the supplied interfaces. ((S.11.1.1.1.1.1)) Note your priority queue is _NOT_ allowed to use any of the Java Collection classes! Of course that means no PriorityQueue, but it ALSO means: no List, LinkedList, or ArrayList; no Map, HashMap, or TreeMap; and so on. You can use primitive types and arrays, ans Strings if you need them for messaging, and the supplied interfaces. ((S.11.1.1.1.2)) What makes the priority queue of P2D1 'basic' is that the 'delete' operation is not required. ((S.11.1.1.2)) P2D1 Mission #2: Simulation design ((S.11.1.1.2.1)) Based on your understanding of the spec, develop an initial class design for the FrobWorld simulation. ((S.11.1.1.2.1.1)) NOTE: You are not 'chained' to this initial design! You are allowed -- even expected -- to modify this class design later. ((S.11.1.1.2.1.2)) Develop UML class diagrams and descriptive text as need to explain your design. ((S.11.1.2)) P2D2 ((S.11.1.2.1)) P2D2 Mission #1: Advanced Priority Queue. ((S.11.1.2.1.1)) Extend your basic 'from-scratch' intrusive priority queue following the requirements in spec-pq.txt and the supplied interfaces to support O(log n) deletion of arbitrary elements from the PQ. ((S.11.1.2.2)) P2D2 Mission #2: Basic Simulation Implementation ((S.11.1.2.2.1)) Using your PQ implementation as the central data structure, produce an implementation of the FrobWorld discrete event simulation that includes everything except the Frobs. The World must be initialized appropriately with Rocks and Grass, and the Grass must grow properly according to spec. ((S.11.1.2.2.2)) Develop a simple driver that accepts a random number seed on the command line, and prints the final, end-of-simulation World state to standard output, using 'R' for Rocks, 'G' for grass, and ' ' for unoccupied spaces. ((S.11.1.2.2.3)) Build a runnable JAR file that includes both source and object files and that runs the (S.11.1.2.2.2) driver when executed. ((S.11.1.3)) P2D3 ((S.11.1.3.1)) P2D3 Mission #1: Full Simulation ((S.11.1.3.1.1)) Complete your FrobWorld simulation by adding Frobs, Genotypes, and Frob behavioral and evolutionary mechanisms as per spec. ((S.11.1.3.1.2)) Develop a basic GUI to display simulations in progress. Build FrobWorld.jar to operate as per (S.2.1). ((S.11.1.3.2)) P2D3 Mission #2: Artificial Life Research ((S.11.1.3.2.1)) Use your full simulation to gather appropriate data to answer the (S.0) questions. Produce a final report (a single PDF) reporting your results with appropriate graphs and text discussion. ------------------------------------------------- ((S.12)) Available resources ((S.12.1)) Now available: ((S.12.1.1)) spec-dates.txt: Timeline and deadlines ((S.12.1.2)) spec-pq.txt: Background about intrusive priority queues ((S.12.1.3)) spec-simulation.txt: This file ((S.12.1.4)) P2PQ.jar: A JAR file containing: ((S.12.1.4.1)) interface com.putable.pqueue.PQueue, to be used AS-IS ((S.12.1.4.2)) interface com.putable.pqueue.PQAble, to be used AS-IS ((S.12.1.4.3)) abstract class com.putable.pqueue.AbstractPQAble, to be used AS-IS ------------------------------------------------- ((S.13)) Document Information ((S.13.1)) This is Version 0.9 of the new FrobWorld document, released Sat Oct 5 09:28:08 2013.