1 #ifndef __INST_GEN_HPP__ 2 #define __INST_GEN_HPP__ 3 4 /* "Species" - a CoreWars evolver. Copyright (C) 2003 'Varfar' 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 1, or (at your option) any later 9 * version. 10 * 11 * This program is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 * more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 21 #include "exhaust.hpp" 22 #include "ini.hpp" 23 #include <ostream> 24 25 class CChromosome; // forward 26 27 /* to implement a generator: 28 * 1) derive publically from CInstGenerator 29 * 1) give it an identifier in the EImpl enumeration 30 * 2) make the constructor set the _type member 31 * 3) make CInstGenerator factories understand this new implementation and how to identify it 32 * 4) implement the read_ini/write_ini functionality 33 */ 34 35 class CInstGenerator { // an abstract class, use the factory to get an implementation 36 public: 37 enum MODE { 38 FORWARD, 39 INSERT, 40 MODE_LAST 41 }; ~CInstGenerator()42 virtual ~CInstGenerator() {} 43 // factory 44 static CInstGenerator *read_ini(INIFile &ini); // create a new implementation 45 static CInstGenerator *read_override_ini(CInstGenerator *gen,INIFile &ini); /* loads an implementation; 46 if the ini specifies a new implementation: if the type is the same as the parent, it will load a diff; 47 if the type is different, all values must be specified */ 48 // this sets the 'cursor' that suggestions will be based upon chromosome() const49 CChromosome *chromosome() const { return _chromosome; } set_chromosome(CChromosome * chromosome)50 void set_chromosome(CChromosome *chromosome) { _chromosome = chromosome; } set_chromosome_index(unsigned index)51 void set_chromosome_index(unsigned index) { _index = index; } 52 // actual query points 53 virtual void suggest_instruction(insn_t &instruction,const MODE mode) = 0; 54 // and saving 55 virtual void write_ini(std::ostream &os) = 0; 56 virtual void write_override_ini(std::ostream &os,const CInstGenerator *parent) = 0; 57 // misc same_type(const CInstGenerator * gen1,const CInstGenerator * gen2)58 static bool same_type(const CInstGenerator *gen1,const CInstGenerator *gen2) { return (gen1->type() == gen2->type()); } opcode_allowed(const OPCODE opcode) const59 bool opcode_allowed(const OPCODE opcode) const { return _opcode_allowed[opcode]; } 60 protected: 61 CInstGenerator(); 62 enum IMPL { // all implementations must be listed here 63 WEIGHTED_RANDOM, 64 MARKOV, 65 MARKOV_2, 66 IMPL_LAST 67 } _type; 68 static const char *impl_desc(const IMPL type); 69 static IMPL desc_to_impl(const char *desc); type() const70 const IMPL type() const { return _type; } 71 virtual void read_ini_impl(INIFile &ini) = 0; 72 virtual CInstGenerator *read_override_ini_impl(INIFile &ini) = 0; index() const73 unsigned index() const { return _index; } 74 void generate_completely_random(insn_t &instruction) const; // utility 75 // this stuff here is useful for any subclasses wishing to limit opcodes; recommended but not essential 76 void read_opcode_allowed(INIFile &ini); 77 void write_opcode_allowed(std::ostream &os,const CInstGenerator *parent = 0) const; 78 private: 79 bool _opcode_allowed[OPCODE_LAST]; 80 static const char *IMPL_DESC[IMPL_LAST]; 81 CChromosome *_chromosome; 82 unsigned _index; 83 }; 84 85 #endif // ifndef __INST_GEN_HPP__ 86 87