-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMacro.java
More file actions
147 lines (133 loc) · 6.48 KB
/
Macro.java
File metadata and controls
147 lines (133 loc) · 6.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import java.awt.Point;
import java.util.ArrayList;
import java.util.Random;
public class Macro extends Agent implements AgentInterface {
private static int IDBASE = 0;
private double macSpeed;
private double macDivRate;
private boolean readyToDivide; //a flag indicating that the cell has completed
//it's cell growth and is ready to divide if enough bacts surround it
private int minBactToDivide; //min surrounding Bacs req'd for division
public Macro(double startTime, double macSpeed, double macDivRate, int minBactToDivide, Random rng) {
type = Agent.AgentType.MACROPHAGE;
//Construct a Macrophage at startTime w/ movement speed macSpeed
ID = IDBASE++;
this.macSpeed = macSpeed;
this.macDivRate = macDivRate;
this.minBactToDivide = minBactToDivide;
readyToDivide=false;
cal[0] = new Event(this, startTime + Agent.exponential(macSpeed, rng), Event.EventType.MOVE);
cal[1] = new Event(this, Double.MAX_VALUE, Event.EventType.EAT);
cal[2] = new Event(this, startTime + Agent.exponential(macDivRate, rng), Event.EventType.DIVIDE);
cal[3] = new Event(this, Double.MAX_VALUE, Event.EventType.STARVE);
cal[4] = new Event(this, Double.MAX_VALUE, Event.EventType.UNDEF);
row = col = -1; //should be overwritten as soon as the Mac is placed in the landscape
}
public Macro(double macSpeed, double macDivRate, int minBactToDivide, Random rng) {
this(0.0, macSpeed, macDivRate, minBactToDivide, rng);
}
public boolean readyToDivide() {
return readyToDivide;
}
public double getDivRate() {
return macDivRate;
}
public void move(Cell[][] landscape, Random rng) {
//number of possible destinations: 8 - neighbors
ArrayList<Point> bac_coord = new ArrayList<Point>();
ArrayList<Point> nomacro_coord = new ArrayList<Point>();
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) {
continue;
}//don't consider the current pos as a move dest.
int r = (row + i + landscape.length) % landscape.length;
int c = (col + j + landscape[0].length) % landscape[0].length;
if (landscape[r][c].hasBacterium()) {
bac_coord.add(new Point(r, c));
}
if (!landscape[r][c].hasMacrophage()) {
nomacro_coord.add(new Point(r, c));
}
}
}
if (bac_coord.size() > 0) {//if there's bacs in our Moore neighborhood
int dest = rng.nextInt(bac_coord.size()); //pick one at random
Point dest_point = bac_coord.get(dest);
landscape[row][col].removeMacrophage(); //take me out of the current spot
landscape[dest_point.x][dest_point.y].occupy(this); //put me in the dest spot
cal[1] = new Event(this, cal[0].time, Event.EventType.EAT);
} else if (nomacro_coord.size() > 0) {//else if there's a spot w/ no macs
int dest = rng.nextInt(nomacro_coord.size()); //pick one at random
Point dest_point = nomacro_coord.get(dest);
landscape[row][col].removeMacrophage(); //take me out of the current spot
landscape[dest_point.x][dest_point.y].occupy(this); //put me in the dest spot
}
cal[0] = new Event(this, cal[0].time + Agent.exponential(macSpeed, rng), Event.EventType.MOVE);
//^^schedule another movement
}
public void eat(Cell[][] landscape, ArrayList<Agent> bacList) {
if (landscape[row][col].hasBacterium()) {
bacList.remove(landscape[row][col].removeBacterium());
//^^remove the bact from the landscape and the bacList
} else {
//throw new RuntimeException("attempted to eat absent bacterium");
System.out.print("");//well, it's too late now.
}
}
//Override Agent's divide method, even though Macs can't divide
public void divide(Cell[][] landscape, ArrayList<Agent> bacList,
ArrayList<Agent> macList, Random rng) {
if (isSurrounded(landscape)) {
ArrayList<Point> nomac_coord = new ArrayList<Point>();
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) {
continue;
}//don't consider the current pos
int r = (row + i + landscape.length) % landscape.length;
int c = (col + j + landscape[0].length) % landscape[0].length;
if (!landscape[r][c].hasMacrophage()) {
nomac_coord.add(new Point(r, c));
}
}
}
if (nomac_coord.size() > 0) {
int dest = rng.nextInt(nomac_coord.size()); //pick one at random
Point dest_point = nomac_coord.get(dest);
Macro daughter = new Macro(cal[2].time, macSpeed, macDivRate, minBactToDivide, rng);
Cell cl = landscape[dest_point.x][dest_point.y];
cl.occupy(daughter);
macList.add(daughter);
if(cl.hasBacterium()){
daughter.putEvent(new Event(daughter,cal[2].time,Event.EventType.EAT));
}
}
readyToDivide = false;
cal[2] = new Event(this, cal[2].time + Agent.exponential(macDivRate, rng), Event.EventType.DIVIDE);
} else {
readyToDivide = true;
cal[2] = new Event(this, Double.MAX_VALUE, Event.EventType.DIVIDE);//postpone division indefinitely
}
}
//Override Agent's starve method, even though Macs can't starve
public void starve(Cell[][] landscape, ArrayList<Agent> bacList) {
throw new RuntimeException("Macs can't starve yet");
}
public boolean isSurrounded(Cell[][] landscape) {
int bactCount = 0;
for (int i = -1; i <= 1; i++) { //count the number of neighboring bacteria
for (int j = -1; j <= 1; j++) {
if (i == j && i == 0) {
continue;
} //skip mac's cell
int r = (row + i + landscape.length) % landscape.length;
int c = (col + j + landscape[0].length) % landscape[0].length;
if (landscape[r][c].hasBacterium()) {
bactCount++;
}
}
}
return (bactCount >= minBactToDivide);
}
}