/* "Species" - a CoreWars evolver. Copyright (C) 2003 'Varfar' * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 1, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "chromosome.hpp" using namespace std; /***** CChromosome class implementation *******************/ /*** construction ***/ CChromosome::CChromosome(CWarrior *warrior,const unsigned int idx,const unsigned int len): _warrior(warrior), _idx(idx), _ofs(0), _len(len) { _type = _warrior->species()->chromosome(_idx); calc_ofs(); } /*** getters ***/ insn_t &CChromosome::code(unsigned i) const { if(safety_checks) if(i >= len()) PANIC(MISC,"instruction index in chromosome is out of bounds",NULL); return warrior()->warrior_t::code[_ofs+i]; } bool CChromosome::is_start() const { return (idx() == type()->species()->start_chromosome()); } unsigned CChromosome::start() const { // returns MAXLENGTH if warrior start is not in this chromosome if((_ofs <= _warrior->start) && ((_ofs+_len) > _warrior->start)) return (_warrior->start-_ofs); else return MAXLENGTH; } /*** setters ***/ void CChromosome::set_len(const unsigned int len) { _len = len; const unsigned int num = warrior()->species()->num_chromosomes(); for(unsigned int i=idx()+1; ichromosome(i)->calc_ofs(); } warrior()->calc_len(); } void CChromosome::rnd_len() { set_len(type()->length()->rnd()); // a random length within bounds } void CChromosome::clear() { for(unsigned int i=0; ispecies()->start_chromosome()) PANIC(MISC,"cannot set start in wrong chromosome",NULL); if(i >= len()) PANIC(MISC,"start is beyond end of chromosome",NULL); } warrior()->start = _ofs + i; } void CChromosome::check(const field_t coresize) const { // panics if not ok for(unsigned int i=0; i0) { CChromosome *prev = warrior()->chromosome(idx()-1); _ofs = prev->_ofs + prev->len(); } else { _ofs = 0; } if(safety_checks) if(_ofs + len() > MAXLENGTH) PANIC(MISC,"combined length of chromosomes too long",NULL); } /***** CChromosomeType class implementation ***************/ /*** construction ***/ void CChromosomeType::init() { _length = species()->length(); _freq = species()->freq(); _operands = species()->operands(); _reproduction = species()->reproduction(); } CChromosomeType::CChromosomeType(CSpecies *species) { // create an auto-chromosome shim _species = species; init(); _auto = true; _name = "auto"; } CChromosomeType::CChromosomeType(CSpecies *species,const char *name) { // create a user-ready shim _species = species; init(); _auto = false; _name = name; } void CChromosomeType::read_ini(INIFile &ini) { // anything to do? if(_auto) return; // seek in ini file if(!ini.seek(_name)) PANIC(MISC,_name.c_str(),"section expected"); // load some defaults; these might be overloaded _length = _length->read_override_ini(ini); _freq = CInstGenerator::read_override_ini(_freq,ini); _operands = COperand::read_override_ini(_operands,ini); _reproduction = _reproduction->read_override_ini(ini); } void CChromosomeType::write_ini(ostream &os) { // anything to do? if(_auto) return; // and write it os << '[' << _name << ']' << endl; _length->write_override_ini(os,species()->length()); _freq->write_override_ini(os,species()->freq()); _operands->write_override_ini(os,species()->operands()); _reproduction->write_override_ini(os,species()->reproduction()); }