1 /* "Species" - a CoreWars evolver.  Copyright (C) 2003 'Varfar'
2  *
3  * This program is free software; you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by the Free
5  * Software Foundation; either version 1, or (at your option) any later
6  * version.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 675 Mass Ave, Cambridge, MA 02139, USA.
16  */
17 
18 #include "operand.hpp"
19 
20 // concrete implementation headers
21 #include "operand_distribution.hpp"
22 #include "operand_table.hpp"
23 
24 #include "species.hpp"
25 #include "rand.hpp"
26 
27 //#include <string.h>
28 
29 /************ COperand implementation ****************************/
30 
31 const char *COperand::IMPL_DESC[COperand::IMPL_LAST] = { "distribution","table" };
32 const char *COperand::TYPE_KEY = "operands";
33 
impl_desc(const COperand::IMPL type)34 const char *COperand::impl_desc(const COperand::IMPL type) {
35 	if((type >= 0) && (type < IMPL_LAST))
36 		return IMPL_DESC[type];
37 	return 0; // bad
38 }
39 
desc_to_impl(const char * desc)40 COperand::IMPL COperand::desc_to_impl(const char *desc) {
41 	for(int i=0; i<IMPL_LAST; i++) {
42 		if(strcasecmp(desc,IMPL_DESC[i])==0)
43 			return (IMPL)i;
44 	}
45 	PANIC(MISC,"bad ",type_key());
46 }
47 
COperand(const field_t coresize)48 COperand::COperand(const field_t coresize) {
49 	_coresize = coresize;
50 }
51 
NewDefault(const field_t coresize)52 COperand *COperand::NewDefault(const field_t coresize) {
53 	return new COperandDistribution(coresize);
54 }
55 
read_ini(INIFile & ini,const field_t coresize)56 COperand *COperand::read_ini(INIFile &ini,const field_t coresize) {
57 	KeyValuePair *kvp;
58 	COperand *ret;
59 	// identify which implementation, based upon keywords
60 	kvp = ini.get(type_key());
61 	if(0 == kvp) { // not specified? we have a default..
62 		ret = NewDefault(coresize);
63 	} else {
64 		switch(desc_to_impl(kvp->getValueAsChar())) {
65 			case DISTRIBUTION:
66 				ret = new COperandDistribution(coresize);
67 				break;
68 			case TABLE:
69 				ret = new COperandTable(coresize);
70 				break;
71 			default:
72 				PANIC(MISC,kvp->getValueAsChar(),type_key());
73 		}
74 	}
75 	ret->read_ini_impl(ini);
76 	return ret;
77 }
78 
read_override_ini(COperand * gen,INIFile & ini)79 COperand *COperand::read_override_ini(COperand *gen,INIFile &ini) {
80 	KeyValuePair *kvp;
81 	COperand *ret;
82 	// identify which implementation, based upon keywords
83 	kvp = ini.get(type_key());
84 	if(0 == kvp) return gen; // nothing to do?
85 	switch(desc_to_impl(kvp->getValueAsChar())) {
86 		case DISTRIBUTION:
87 			if(same_type(gen,ret)) {
88 				ret =  new COperandDistribution((COperandDistribution&)*gen);
89 				ret->read_override_ini_impl(ini);
90 			} else {
91 				ret = new COperandDistribution(ret->_coresize);
92 				ret->read_ini_impl(ini);
93 			}
94 			break;
95 		case TABLE:
96 			if(same_type(gen,ret)) {
97 				ret =  new COperandTable((COperandTable&)*gen);
98 				ret->read_override_ini_impl(ini);
99 			} else {
100 				ret = new COperandTable(ret->_coresize);
101 				ret->read_ini_impl(ini);
102 			}
103 			break;
104 		default:
105 			PANIC(MISC,kvp->getValueAsChar(),type_key());
106 	}
107 	return ret;
108 }
109