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