I just coded a version of WaTor, a population simulation game in which fish and sharks move around, breed, and eat each other. The rules are here: https://en.wikipedia.org/wiki/Wa-Tor. I am wondering, basically how I did and if there are better ways to do some of the things I am doing, specifically on the move methods for the sharks and the fish.
Here is my code:
Animal
package WaTor;
abstract class Animal {
private int x;
private int y;
private int type;
private int SIZE;
Animal(int xcoord, int ycoord, int t, int size) {
x=xcoord;
y=ycoord;
type=t;
SIZE = size;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getType() {
return type;
}
public void moveX(int dx) {
x = x + dx;
if(x > SIZE - 1) {
x = 0;
}
if(x < 0) {
x = SIZE - 1;
}
}
public void moveY(int dy) {
y = y + dy;
if(y > SIZE - 1) {
y = 0;
}
if(y < 0) {
y = SIZE - 1;
}
}
public void moveUp() {
moveX(-1);
}
public void moveDown() {
moveX(1);
}
public void moveLeft() {
moveY(-1);
}
public void moveRight() {
moveY(1);
}
abstract boolean canBreed();
abstract boolean hasStarved();
}
Fish
package WaTor;
import java.util.Random;
class Fish extends Animal {
private static final int TYPE = 1;
private static final int canBreed = 4;
private int breedAge;
Fish(int xcoord, int ycoord, int size) {
super(xcoord,ycoord,TYPE,size);
breedAge = 0;
}
public void moveUp() {
moveX(-1);
breedAge ++;
}
public void moveDown() {
moveX(1);
breedAge ++;
}
public void moveLeft() {
moveY(-1);
breedAge ++;
}
public void moveRight() {
moveY(1);
breedAge ++;
}
public boolean canBreed() {
return breedAge == canBreed;
}
public void incBreedAge() {
breedAge++;
}
public boolean hasStarved() {
return false;
}
}
Shark
package WaTor;
import java.util.Random;
class Shark extends Animal {
private static final int TYPE = 2;
private static final int hasStarved = 4;
private static final int canBreed = 2;
private int starveTime;
private int energy;
Shark(int xcoord, int ycoord, int size) {
super(xcoord,ycoord,TYPE,size);
starveTime = 0;
energy = 0;
}
public void moveUp() {
moveX(-1);
starveTime ++;
}
public void moveDown() {
moveX(1);
starveTime ++;
}
public void moveLeft() {
moveY(-1);
starveTime ++;
}
public void moveRight() {
moveY(1);
starveTime ++;
}
public boolean hasStarved() {
return starveTime == hasStarved;
}
public boolean canBreed() {
return energy == canBreed;
}
public void resetEnergy() {
energy = 0;
}
public void resetStarveTime() {
starveTime = 0;
}
public void incEnergy() {
energy++;
}
public void incStarveTime() {
starveTime++;
}
}
and Ocean
package WaTor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
class Ocean {
private Animal[][] ocean;
private int numFish;
private int numSharks;
private int SIZE;
private ArrayList<Fish> fish;
private ArrayList<Shark> sharks;
private ArrayList<Shark> sharksToRemove;
private ArrayList<Shark> sharksToAdd;
private ArrayList<Fish> fishToAdd;
private Random random;
Ocean(int size, int f, int s) {
SIZE = size;
numFish = f;
numSharks = s;
random = new Random();
ocean = new Animal[SIZE][SIZE];
fish = new ArrayList<Fish>();
sharks = new ArrayList<Shark>();
sharksToRemove = new ArrayList<Shark>();
sharksToAdd = new ArrayList<Shark>();
fishToAdd = new ArrayList<Fish>();
fillOcean();
for(Fish fishy : fish) {
addFish(fishy);
}
for(Shark sharky : sharks) {
addShark(sharky);
}
}
private void fillOcean() {
for (int i = 0; i < numFish; i++) {
int x = random.nextInt(SIZE);
int y = random.nextInt(SIZE);
addNewFish(x, y);
}
for (int j = 0; j < numSharks; j++) {
int x = random.nextInt(SIZE);
int y = random.nextInt(SIZE);
addNewShark(x, y);
}
}
private void addFish(Fish fish) {
ocean[fish.getX()][fish.getY()] = fish;
}
private void addShark(Shark shark) {
ocean[shark.getX()][shark.getY()] = shark;
}
private void addNewFish(int x, int y) {
Fish aFish = new Fish(x, y, SIZE);
if (!cantAdd(aFish)) {
fish.add(aFish);
} else {
x = random.nextInt(SIZE);
y = random.nextInt(SIZE);
addNewFish(x, y);
}
}
private void addNewShark(int x, int y) {
Shark bruce = new Shark(x, y, SIZE);
if (!cantAdd(bruce)) {
sharks.add(bruce);
} else {
x = random.nextInt(SIZE);
y = random.nextInt(SIZE);
addNewShark(x, y);
}
}
private boolean hasFishNeighborUp(Shark animal) {
for (Fish fishy : fish) {
if (((animal.getX() - 1) == fishy.getX())
&& (animal.getY() == fishy.getY())) {
fish.remove(fishy);
return true;
}
}
return false;
}
private boolean hasFishNeighborDown(Shark animal) {
for (Fish fishy : fish) {
if (((animal.getX() + 1) == fishy.getX())
&& (animal.getY() == fishy.getY())) {
fish.remove(fishy);
return true;
}
}
return false;
}
private boolean hasFishNeighborLeft(Shark animal) {
for (Fish fishy : fish) {
if ((animal.getX() == fishy.getX())
&& ((animal.getY() - 1) == fishy.getY())) {
fish.remove(fishy);
return true;
}
}
return false;
}
private boolean hasFishNeighborRight(Shark animal) {
for (Fish fishy : fish) {
if ((animal.getX() == fishy.getX())
&& ((animal.getY() + 1) == fishy.getY())) {
fish.remove(fishy);
return true;
}
}
return false;
}
private boolean hasNeighborUp(Animal animal) {
for (Fish fishy : fish) {
return (((animal.getX() - 1) == fishy.getX()) && (animal.getY() == fishy
.getY()));
}
for (Shark sharky : sharks) {
return (((animal.getX() - 1) == sharky.getX()) && (animal.getY() == sharky
.getY()));
}
return false;
}
private boolean hasNeighborDown(Animal animal) {
for (Fish fishy : fish) {
return (((animal.getX() + 1) == fishy.getX()) && (animal.getY() == fishy
.getY()));
}
for (Shark sharky : sharks) {
return (((animal.getX() + 1) == sharky.getX()) && (animal.getY() == sharky
.getY()));
}
return false;
}
private boolean hasNeighborLeft(Animal animal) {
for (Fish fishy : fish) {
return ((animal.getX() == fishy.getX()) && ((animal.getY() - 1) == fishy
.getY()));
}
for (Shark sharky : sharks) {
return ((animal.getX() == sharky.getX()) && ((animal.getY() - 1) == sharky
.getY()));
}
return false;
}
private boolean hasNeighborRight(Animal animal) {
for (Fish fishy : fish) {
return ((animal.getX() == fishy.getX()) && ((animal.getY() + 1) == fishy
.getY()));
}
for (Shark sharky : sharks) {
return ((animal.getX() == sharky.getX()) && ((animal.getY() + 1) == sharky
.getY()));
}
return false;
}
private boolean cantAdd(Animal animal) {
if(fish.size()==0 && sharks.size()==0) {
return false;
}
for (Fish fishy : fish) {
return (animal.getX() == fishy.getX())
&& (animal.getY() == fishy.getY());
}
if(sharks.size()==0) {
return false;
}
for (Shark sharky : sharks) {
return (animal.getX() == sharky.getX())
&& (animal.getY() == sharky.getY());
}
return false;
}
private void moveShark(Shark shark) {
int rand = random.nextInt(4);
if (hasFishNeighborUp(shark)) {
shark.moveUp();
shark.incEnergy();
shark.resetStarveTime();
} else if (hasFishNeighborDown(shark)) {
shark.moveDown();
shark.incEnergy();
shark.resetStarveTime();
} else if (hasFishNeighborLeft(shark)) {
shark.moveLeft();
shark.incEnergy();
shark.resetStarveTime();
} else if (hasFishNeighborRight(shark)) {
shark.moveRight();
shark.incEnergy();
shark.resetStarveTime();
} else if (!hasFishNeighborUp(shark) && !hasFishNeighborDown(shark)
&& !hasFishNeighborLeft(shark) && !hasFishNeighborRight(shark)) {
if(hasNeighborUp(shark) && hasNeighborDown(shark) && hasNeighborLeft(shark) && hasNeighborRight(shark)) {
shark.incStarveTime();
}
else if(rand==0 && !hasNeighborUp(shark)) {
shark.moveUp();
shark.incStarveTime();
}
else if(rand==0 && hasNeighborUp(shark)) {
rand = 1;
}
else if(rand==1 && !hasNeighborDown(shark)) {
shark.moveDown();
shark.incStarveTime();
}
else if(rand==1 && hasNeighborDown(shark)) {
rand = 2;
}
else if(rand==2 && !hasNeighborLeft(shark)) {
shark.moveLeft();
shark.incStarveTime();
}
else if(rand==2 && hasNeighborLeft(shark)) {
rand = 3;
}
else if(rand==3 && !hasNeighborRight(shark)) {
shark.moveRight();
shark.incStarveTime();
}
else if(rand==3 && hasNeighborRight(shark)) {
moveShark(shark);
}
}
}
public void moveFish(Fish fish) {
int rand = random.nextInt(4);
if(hasNeighborUp(fish) && hasNeighborDown(fish) && hasNeighborLeft(fish) && hasNeighborRight(fish)) {
fish.incBreedAge();
}
if(rand==0 && !hasNeighborUp(fish)) {
fish.moveUp();
fish.incBreedAge();
}
else if(rand==0 && hasNeighborUp(fish)) {
moveFish(fish);
}
else if(rand==1 && !hasNeighborDown(fish)) {
fish.moveDown();
fish.incBreedAge();
}
else if(rand==1 && hasNeighborDown(fish)) {
moveFish(fish);
}
else if (rand == 2 && !hasNeighborLeft(fish)) {
fish.moveLeft();
fish.incBreedAge();
}
else if(rand==2 && hasNeighborLeft(fish)) {
moveFish(fish);
}
else if(rand == 3 && !hasNeighborRight(fish)) {
fish.moveRight();
fish.incBreedAge();
}
else if(rand==3 && hasNeighborRight(fish)) {
moveFish(fish);
}
}
private void updateSharks() {
for(Shark sharky : sharks) {
if(sharky.hasStarved()) {
sharksToRemove.add(sharky);
}
else if(sharky.canBreed()) {
Shark newShark = new Shark(sharky.getX(),sharky.getY(), SIZE);
sharksToAdd.add(newShark);
}
moveShark(sharky);
}
for(Shark aShark : sharksToRemove) {
sharks.remove(aShark);
}
for(Shark theShark : sharksToAdd) {
sharks.add(theShark);
}
}
private void updateFish() {
for(Fish fishy : fish) {
if(fishy.canBreed()) {
Fish newFish = new Fish(fishy.getX(),fishy.getY(),SIZE);
fishToAdd.add(newFish);
}
moveFish(fishy);
}
for(Fish theFish : fishToAdd) {
fish.add(theFish);
}
}
public void update() {
for(int i=0; i<SIZE; i++) {
for(int j=0; j<SIZE; j++) {
ocean[i][j]=null;
}
}
updateSharks();
updateFish();
for(Fish fishy : fish) {
addFish(fishy);
}
for(Shark sharky : sharks) {
addShark(sharky);
}
}
public void print() {
for (int x = 0; x < ocean.length; x++) {
for (int y = 0; y < ocean[0].length; y++) {
if (ocean[x][y] == null) {
System.out.print(" 0 ");
} else {
System.out.print(" "+ocean[x][y].getType()+" ");
}
}
System.out.println("");
}
}
}