#ifndef __INST_GEN_MARKOV_HPP_ #define __INST_GEN_MARKOV_HPP_ /* "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 "exhaust.hpp" #include "error.hpp" #include "rand.hpp" #include "inst_gen.hpp" #include #include #include /******* CInstGeneratorMarkov declaration ************************/ template class CHighLowField { public: CHighLowField() { _data = 0; } void set(const unsigned high=0) { _data = 0; set_high(high); } unsigned get_high() const { return _data >> HIGH_SHIFT; } void set_high(const unsigned high) { _data = (high << HIGH_SHIFT) | (_data & LOW_MASK); } unsigned get_low() const { return _data & LOW_MASK; } void set_low(const unsigned low) { _data = (_data & HIGH_MASK) | (low & LOW_MASK); } void inc_low() { // not super fast, but safeish unsigned low = get_low(); if(low == LOW_MASK) // overflow imminent? PANIC(MISC,"inc past field capability",NULL); set_low(low+1); } bool used() const { return (get_low() != 0); } unsigned get_data() const { return _data; } void set_data(const unsigned data) { _data = data; } private: static const unsigned intBITS = 31, // zero-based; that was a nasty bug to track down! HIGH_SHIFT = intBITS-BITS, HIGH_MASK = ((1< { public: void set(const unsigned i) { set_high(i); set_low(0); } void set(const OPCODE op,const MODIFIER mod) { set_high(_OP(op,mod)); set_low(0); } OPCODE get_opcode() const { return (OPCODE)(get_high() >> moBITS); } unsigned get_opcode_modifier() const { return get_high(); } void set_opcode(OPCODE op) { set_high(_OP(op,get_modifier())); } MODIFIER get_modifier() const { return (MODIFIER)(get_high() & moBITS); } void set_modifier(MODIFIER mod) { set_high(_OP(get_opcode(),mod)); } unsigned get_count() const { return get_low(); } void set_count(const unsigned count) { set_low(count); } void inc_count() { inc_low(); } bool used() const { return (get_low() != 0); } unsigned get_literal() const { return get_data(); } void set_literal(const unsigned data) { set_data(data); } }; template class CHighLowArray { public: typedef CHighLowField CData; CHighLowArray() { _count = 0; _data = 0; } ~CHighLowArray() { delete [] _data; } void init(unsigned count) { _count = count; delete [] _data; _data = new CData[_count]; } unsigned count() const { return _count; } CData &operator[](unsigned index) { check_bounds(index); return _data[index]; } CData operator[](unsigned index) const { check_bounds(index); return _data[index]; } unsigned used() const { unsigned count = 0; for(unsigned i=0; i<_count; i++) if(_data[i].used()) count++; return count; } unsigned calc_sum() { _sum = 0; for(unsigned i=0; i= _count)) PANIC(MISC,"array index out of bounds",NULL); } }; class CInstGeneratorMarkov: public CInstGenerator { public: CInstGeneratorMarkov(); virtual ~CInstGeneratorMarkov(); // actual query points virtual void suggest_instruction(insn_t &instruction,const MODE mode); // and saving virtual void write_ini(std::ostream &os); virtual void write_override_ini(std::ostream &os,const CInstGenerator *parent); // for creating new lookup files void init(const unsigned coresize); void load(const char *binfilename); void append(const char *rcfilename); void save(const char *binfilename) const; void dump(std::ostream &out) const; protected: virtual void read_ini_impl(INIFile &ini); virtual CInstGenerator *read_override_ini_impl(INIFile &ini); private: static const unsigned OPCODE_MODIFIER_LAST = _OP(OPCODE_LAST,MODIFIER_LAST), INVALID_INDEX = ~0; std::string _filename; bool readonly; unsigned CORESIZE, opcodes, opcode_modifiers; friend struct CFreq; struct CFreq { COpcodeModifier key; // markov for next instruction unsigned markovs, opcode_modifiers; COpcodeModifier *markov; unsigned used_markovs() const { unsigned count = 0; for(unsigned i=0; i addrmode_a, addrmode_b; CHighLowArray<16> a, b; } *opcode; unsigned used_opcodes() const { unsigned count = 0; for(unsigned i=0; i