1 /*
2  *  cEnvironment.h
3  *  Avida
4  *
5  *  Copyright 1999-2011 Michigan State University. All rights reserved.
6  *  Copyright 1993-2003 California Institute of Technology.
7  *
8  *
9  *  This file is part of Avida.
10  *
11  *  Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
12  *  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
13  *
14  *  Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public License along with Avida.
18  *  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 /*!  Classes to hold information about the environmentthat contains information
23      about resources and reactions (which allow rewards or punishments
24      to organisms doing certain tasks). */
25 
26 #ifndef cEnvironment_h
27 #define cEnvironment_h
28 
29 #include "cMutationRates.h"
30 #include "cReactionLib.h"
31 #include "cResourceLib.h"
32 #include "cString.h"
33 #include "cTaskLib.h"
34 #include "tList.h"
35 
36 #include <set>
37 
38 
39 namespace Avida {
40   class Feedback;
41 };
42 class cContextPhenotype;
43 class cContextReactionRequisite;
44 class cAvidaContext;
45 class cReaction;
46 class cReactionRequisite;
47 class cReactionProcess;
48 class cReactionResult;
49 class cStateGrid;
50 class cTaskContext;
51 class cWorld;
52 template <class T> class tArray;
53 template <class T> class tBuffer;
54 
55 using namespace Avida;
56 
57 
58 class cEnvironment
59 {
60 private:
61   cWorld* m_world;
62 
63   cMutationRates mut_rates;
64   cResourceLib resource_lib;
65   cReactionLib reaction_lib;
66   cTaskLib m_tasklib;
67 
68   int m_input_size;
69   int m_output_size;
70   bool m_true_rand;
71 
72   bool m_use_specific_inputs; // Use specific inputs, rather than generating random ones
73   tArray<int>  m_specific_inputs;
74 
75   unsigned int m_mask;
76 
77   tArray<cStateGrid*> m_state_grids;
78 
79 	std::set<int> possible_group_ids;
80   std::set<int> possible_target_ids;
81   std::set<int> possible_habitats;
82 
83 
84   cEnvironment(); // @not_implemented
85   cEnvironment(const cEnvironment&); // @not_implemented
86   cEnvironment& operator=(const cEnvironment&); // @not_implemented
87 
88 public:
89   cEnvironment(cWorld* world);
90   ~cEnvironment();
91 
92   bool Load(const cString& filename, const cString& working_dir, Feedback& feedback);
93   bool LoadLine(cString line, Feedback& feedback);  // Reads in a single environment configuration line
94 
95   // Interaction with the organisms
96   void SetupInputs(cAvidaContext& ctx, tArray<int>& input_array, bool random = true) const;
SetSpecificInputs(const tArray<int> in_input_array)97   void SetSpecificInputs(const tArray<int> in_input_array) { m_use_specific_inputs = true; m_specific_inputs = in_input_array; }
SetSpecificRandomMask(unsigned int mask)98   void SetSpecificRandomMask(unsigned int mask) { m_mask = mask; }
99   void SwapInputs(cAvidaContext& ctx, tArray<int>& src_input_array, tArray<int>& dest_input_array) const;
100 
101 
102   bool TestInput(cReactionResult& result, const tBuffer<int>& inputs,
103                  const tBuffer<int>& outputs, const tArray<double>& resource_count) const;
104 
105   bool TestOutput(cAvidaContext& ctx, cReactionResult& result, cTaskContext& taskctx,
106                   const tArray<int>& task_count, tArray<int>& reaction_count,
107                   const tArray<double>& resource_count, const tArray<double>& rbins_count,
108                   bool is_parasite=false, cContextPhenotype* context_phenotype = 0) const;
109 
110   // Accessors
GetNumTasks()111   int GetNumTasks() const { return m_tasklib.GetSize(); }
GetTask(int id)112   const cTaskEntry& GetTask(int id) const { return m_tasklib.GetTask(id); }
UseNeighborInput()113   bool UseNeighborInput() const { return m_tasklib.UseNeighborInput(); }
UseNeighborOutput()114   bool UseNeighborOutput() const { return m_tasklib.UseNeighborOutput(); }
GetMatchStringsFromTask()115   vector<cString> GetMatchStringsFromTask() { return m_tasklib.GetMatchStrings(); }
GetMatchString(int x)116   cString GetMatchString(int x) { return m_tasklib.GetMatchString(x); }
GetNumberOfMatchStrings()117   int GetNumberOfMatchStrings() { return m_tasklib.GetNumberOfMatchStrings(); }
118 
119 
GetNumReactions()120   int GetNumReactions() const { return reaction_lib.GetSize(); }
GetResourceLib()121   const cResourceLib& GetResourceLib() const { return resource_lib; }
GetReactionLib()122   const cReactionLib& GetReactionLib() const { return reaction_lib; }
GetMutRates()123   const cMutationRates& GetMutRates() const { return mut_rates; }
124 
GetResourceLib()125   cResourceLib& GetResourceLib() { return resource_lib; }
GetReactionLib()126   cReactionLib& GetReactionLib() { return reaction_lib; }
GetMutRates()127   cMutationRates& GetMutRates() { return mut_rates; }
128 
GetNumStateGrids()129   int GetNumStateGrids() const { return m_state_grids.GetSize(); }
GetStateGrid(int sg)130   const cStateGrid& GetStateGrid(int sg) const { return *m_state_grids[sg]; }
131 
GetInputSize()132   int GetInputSize()  const { return m_input_size; };
GetOutputSize()133   int GetOutputSize() const { return m_output_size; };
134 
135   const cString& GetReactionName(int reaction_id) const;
136   double GetReactionValue(int reaction_id);
137   bool SetReactionValue(cAvidaContext& ctx, const cString& name, double value);
138   bool SetReactionValueMult(const cString& name, double value_mult);
139   bool SetReactionInst(const cString& name, cString inst_name);
140   bool SetReactionMinTaskCount(const cString& name, int min_count);
141   bool SetReactionMaxTaskCount(const cString& name, int max_count);
142   bool SetReactionMinCount(const cString& name, int reaction_min_count);
143   bool SetReactionMaxCount(const cString& name, int reaction_max_count);
144   bool SetReactionTask(const cString& name, const cString& task);
145   bool SetResourceInflow(const cString& name, double _inflow );
146   bool SetResourceOutflow(const cString& name, double _outflow );
147 
AddGroupID(int new_id)148   void AddGroupID(int new_id) { possible_group_ids.insert(new_id); }
149   bool IsGroupID(int test_id);
GetGroupIDs()150   std::set<int> GetGroupIDs() { return possible_group_ids; }
151 
AddTargetID(int new_id)152   void AddTargetID(int new_id) { possible_target_ids.insert(new_id); }
153   bool IsTargetID(int test_id);
GetTargetIDs()154   std::set<int> GetTargetIDs() { return possible_target_ids; }
155 
AddHabitat(int new_habitat)156   void AddHabitat(int new_habitat) { possible_habitats.insert(new_habitat); }
157   bool IsHabitat(int test_habitat);
GetHabitats()158   std::set<int> GetHabitats() { return possible_habitats; }
159 
160 private:
161 
162   bool ParseSetting(cString entry, cString& var_name, cString& var_value, const cString& var_type, Feedback& feedback);
163   bool AssertInputInt(const cString& input, const cString& name, const cString& type, Feedback& feedback);
164   bool AssertInputDouble(const cString& input, const cString& name, const cString& type, Feedback& feedback);
165   bool AssertInputBool(const cString& input, const cString& name, const cString& type, Feedback& feedback);
166   bool AssertInputValid(void* input, const cString& name, const cString& type, const cString& value, Feedback& feedback);
167 
168   bool LoadReactionProcess(cReaction* reaction, cString desc, Feedback& feedback);
169   bool LoadReactionRequisite(cReaction* reaction, cString desc, Feedback& feedback);
170   bool LoadContextReactionRequisite(cReaction* reaction, cString desc, Feedback& feedback);
171   bool LoadResource(cString desc, Feedback& feedback);
172   bool LoadCell(cString desc, Feedback& feedback);
173   bool LoadReaction(cString desc, Feedback& feedback);
174   bool LoadStateGrid(cString desc, Feedback& feedback);
175   bool LoadSetActive(cString desc, Feedback& feedback);
176 
177   bool LoadDynamicResource(cString desc, Feedback& feedback);
178   bool LoadGradientResource(cString desc, Feedback& feedback);
179   double GetTaskProbability(cAvidaContext& ctx, cTaskContext& taskctx,
180 
181                             const tList<cReactionProcess>& req_proc, bool& force_mark_task) const;
182 
183   bool TestRequisites(cTaskContext& taskctx, const cReaction* cur_reaction, int task_count,
184                       const tArray<int>& reaction_count, const bool on_divide = false) const;
185   bool TestContextRequisites(const cReaction* cur_reaction, int task_count,
186                       const tArray<int>& reaction_count, const bool on_divide = false) const;
187   void DoProcesses(cAvidaContext& ctx, const tList<cReactionProcess>& process_list,
188                    const tArray<double>& resource_count, const tArray<double>& rbin_count,
189                    const double task_quality, const double task_probability,
190                    const int task_count, const int reaction_id,
191                    cReactionResult& result, cTaskContext& taskctx) const;
192 
193 };
194 
195 #endif
196