1 2 #ifndef SPECIES_HPP 3 #define SPECIES_HPP 4 5 /* "Species" - a CoreWars evolver. Copyright (C) 2003 'Varfar' 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 1, or (at your option) any later 10 * version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22 /** 23 * species.h 24 * (c) Will Sutton, 2002 25 * the main header, exposes global information about the simulation; 26 * 27 * taxonomic groups -- in descending order -- are Kingdom, Phylum, Class, Order, Family, Genus, Species 28 * more detailed classifications -- in descending order -- are: 29 * domain 30 * superkingdom 31 * kingdom* 32 * subkingdom 33 * superphylum 34 * phylum* (plural phyla) 35 * subphylum 36 * infraphylum 37 * subterphylum 38 * superclass 39 * class* 40 * subclass 41 * infraclass 42 * subterclass 43 * supersection 44 * section 45 * subsection 46 * infrasection 47 * supercohort 48 * cohort 49 * subcohort 50 * infracohort 51 * subtercohort 52 * superorder 53 * order* 54 * suborder 55 * infraorder 56 * superfamily 57 * family* 58 * subfamily 59 * supertribe 60 * tribe 61 * subtribe 62 * genus* (plural genera) 63 * subgenus 64 * superspecies 65 * species* (plural species) 66 * geographical race (synonym race, subspecies) 67 * 68 * in this simplified simulation, only a few are used: 69 * 70 * CKingdom: a collection of genera 71 * CGenus: a collection of species 72 * CSpecies: a collection of warriors 73 * CWarrior : a warrior 74 * 75 * CSpecies come in two flavours; evolving species, and 'benchmark' species that assist in directing evolution 76 * by weighing scores. Both CSpecies and CWarriors can be queried as to whether they are 'evolving' or 'bench'. 77 * CSpecies and their CWarriors must have the same value for this 'evolving' flag. 78 **/ 79 80 /** global constants, expect compiler to treat this as #define **/ 81 82 static const bool 83 verbose = false, // lots of couts following program execution? 84 silent = false, 85 terse = !verbose && !silent, 86 metrics = true, // time fights to generate performance statistics? 87 safety_checks = true;// double check the warriors/core for corruption? 88 89 const int PROGRESS_MOD = 4; 90 extern int progress; 91 extern const char *progress_twiddle; 92 #ifdef SHOW_PROGRESS_TWIDDLE 93 #define PROGRESS_TWIDDLE cout << progress_twiddle[progress++ % PROGRESS_MOD] << '\r' << flush; 94 #else 95 #define PROGRESS_TWIDDLE 96 #endif 97 98 /* forwards */ 99 class CChromosomeType; 100 class CWarrior; 101 class CSpecies; 102 class CGenus; 103 class CKingdom; 104 class CResumeFile; 105 class CExecTrail; 106 107 #include "hook.hpp" 108 #include "exhaust.hpp" 109 #include "rand.hpp" 110 #include "ini.hpp" 111 112 #include "error.hpp" 113 #include "length.hpp" 114 #include "operand.hpp" 115 #include "fitness.hpp" 116 #include "inst_gen.hpp" 117 #include "reproduction.hpp" 118 119 #include <iostream> 120 121 #include <stdio.h> 122 123 extern const float VERSION; // actually in kingdom.cpp 124 125 #include "generation.hpp" 126 127 #include "chromosome.hpp" 128 #include "warrior.hpp" 129 130 class CSpecies: public CHookable { 131 public: 132 typedef unsigned int TUid; 133 CSpecies(CGenus *genus,const std::string &name,const bool evolving); // create an empty species 134 ~CSpecies(); 135 void clear(); /* this will delete all warriors from this species */ name() const136 std::string name() const { return _name; } 137 void read_ini(INIFile &ini); /* expects to be in the correct section */ 138 void write_ini(std::ostream &os); 139 void save(); is_evolving() const140 bool is_evolving() const { return _evolving; } is_bench() const141 bool is_bench() const { return !_evolving; } 142 int find(const CWarrior::TUid uid) const; // -1 if not found in this species size() const143 int size() const { return _num_warriors; } num_warriors() const144 int num_warriors() const { return size(); } /* returns a trivia number of warriors 'live' in this species at this time */ 145 void ready(); /* this will blank all fitness metrics preceeding the fighting of a species */ 146 int fight(CSpecies &enemy); /* this will actually do all the fights for a generation; returns number of rounds fought */ 147 CWarrior *selection(); /* this will do selection on all the warriors in this species; returns the best */ genus() const148 CGenus *genus() const { return _genus; } 149 CKingdom *kingdom() const; fitness() const150 CFitness *fitness() const { return _fitness; } length() const151 CLength *length() const { return _length; } freq() const152 CInstGenerator *freq() const { return _freq; } operands() const153 COperand *operands() const { return _operands; } reproduction() const154 CReproduction *reproduction() const { return _reproduction; } exec_trail() const155 CExecTrail *exec_trail() const { return _exec_trail; } fitness_weighting() const156 CFitness::NUM fitness_weighting() const { return _fitness_weighting; } uid() const157 TUid uid() const { return _uid; } 158 CWarrior *warrior(const CWarrior::TUid uid) const; /* fetch a particular warrior from this species; NULL if not present */ num_chromosomes() const159 unsigned int num_chromosomes() const { return _num_chromosomes; } start_chromosome() const160 unsigned int start_chromosome() const { return _start_chromosome; } 161 CChromosomeType *chromosome(const unsigned int i) const; 162 protected: 163 TUid _uid; 164 static TUid _uid_seq; 165 CResumeFile *_resume; 166 bool _resuming; 167 CWarrior **_warrior, // warriors in this species 168 **_next; // a holder while doing selection 169 bool *_survives; // a flag to keep track of who survives during selection 170 int _num_warriors; 171 std::string _name; 172 bool _evolving; /* immutable species are benchmarks only; they do not 'evolve' */ 173 CGenus *_genus; // parent 174 CFitness *_fitness; // might be referencing CGenus::_fitness if not overriden 175 CFitness::NUM _fitness_weighting; // a balance to magnify species with a small number of warriors 176 static const CFitness::NUM DEFAULT_FITNESS_WEIGHTING; 177 CLength *_length; // might be CGenus::_length if not overriden 178 CInstGenerator *_freq; // might be CGenus::_freq if not overriden 179 COperand *_operands; // might be CGenus::_operands if not overriden 180 CReproduction *_reproduction; // might be CGenus::_reproduction if not overriden 181 CExecTrail *_exec_trail; // might be null 182 CFitness::NUM _min, _sum; // these variables are used in rnd() for selection; see scores(..) 183 // subdivision of each warrior into chromosomes 184 bool _auto_chromosome; // wasn't there any chromosomes defined for this species? 185 unsigned int _num_chromosomes, _start_chromosome; 186 CChromosomeType **_chromosome; 187 /* This returns a random warrior index based upon fitness */ 188 int rnd() const; 189 /* This returns the minimum and sum (adjusted relative to min) scores for this species; 190 these are the numbers needed to do roulette selection of the warriors based upon fitness. 191 The min is actually 1 less than the true min, so even the worst warriors have a small chance 192 of being selected */ 193 int scores(CFitness::NUM &min,CFitness::NUM &sum) const; /* returns index of best too */ 194 /* this sorts the warriors into score order, best in 0 */ 195 void sort(); 196 }; 197 198 #include "genus.hpp" 199 200 //TODO: This seems to be a little bit back-to-front; we ought to pass a stream to a warrior and ask it to serialise? 201 202 class CSpeciesFile { 203 friend class CSpecies; 204 public: 205 CSpeciesFile(const std::string species,const CGeneration::NUM generation); 206 CSpeciesFile(const CSpecies &species,const CGeneration::NUM generation); 207 ~CSpeciesFile(); filename() const208 std::string const &filename() const { return _filename; } 209 protected: 210 CGeneration::NUM _num; 211 FILE *_f; 212 std::string _filename; 213 void set_filename(const std::string name,const CGeneration::NUM generation); 214 void open_file(); 215 typedef struct { 216 enum { // plenty of room for more flags in future 217 NONE = 0, 218 HAS_INFO = 1, 219 HAS_BENCH = 2 220 }; 221 unsigned short int options; 222 CWarrior::TUid uid, 223 mother, father; 224 CGeneration::NUM generation; 225 unsigned int num_chromosomes, start; 226 } HEADER; 227 static const int MAX_INFO_LEN = 256; 228 char _info[MAX_INFO_LEN]; 229 static const size_t 230 _header_size = sizeof(HEADER), 231 _insn_size = sizeof(insn_st); 232 void writeWarrior(const CWarrior &warrior); 233 void readWarrior(CWarrior &warrior); 234 }; 235 236 #include "kingdom.hpp" 237 238 #endif // ifndef SPECIES_HPP 239 240