Pertemuan 13 OOP - Abstraksi & Simulasi Fox & Rabit
Nama : Kadek Fajar Pramartha Yasodana
NRP : 5025231185
Kelas : PBO A
Abstraksi & Simulasi Fox & Rabit
1. Tuliskan implementasi dari program kecil Abstract Class Makhluk hidup yang diwariskan kepada manusia, hewan, dan tumbuhan
Source Code : GitHub
Pada soal nomor ini, kita hanya perlu membuat sebuah abstract class makhluk hidup dengan beberapa metode abstrak juga. Setelah itu kita inherit classnya menjadi beberapa subclass Manusia, Hewan, dan Tumbuhan. Terdapat beberapa class seperti
MakhlukHidup.java
protected String name;
public MakhlukHidup(String name)
{
this.name = name;
}
public abstract void doSomething();
public abstract void grow();
public abstract void breathe();
}
Class ini merupakan class yang sebagai template sebuah class makhluk hidup. dengan beberapa method yang harus di override oleh subclassnya yaitu doSomething, grow, dan breathe
Manusia.java
public Manusia(String name)
{
super(name);
}
@Override
public void doSomething() {
System.out.println(name + " sedang berbicara dengan temannya");
}
@Override
public void grow() {
System.out.println(name + " membutuhkan asupan protein dan nutrisi yang cukup");
}
@Override
public void breathe() {
System.out.println(name + " membutuhkan oksigen untuk bernafas");
}
}
Melakukan inheritance dari class MakhlukHidup, dengan override methodnya layaknya seorang manusia.
Hewan.java
public Hewan(String name)
{
super(name);
}
@Override
public void doSomething() {
System.out.println(name + " sedang berlari dengan 4 kaki");
}
@Override
public void breathe() {
System.out.println(name + " membutuhkan oksigen untuk bernapas");
}
@Override
public void grow() {
System.out.println(name + " membutuhkan rumput untuk dimakan");
}
}
Melakukan inheritance dari class MakhlukHidup, dengan override methodnya layaknya seekor hewan.
Tumbuhan.java
public Tumbuhan(String name)
{
super(name);
}
@Override
public void doSomething() {
System.out.println(name + " sedang melakukan fotosintesis");
}
@Override
public void grow() {
System.out.println(name + " membutuhkan siraman air yang cukup dan tanah yang subur");
}
@Override
public void breathe() {
System.out.println(name + " menghirup CO2 pada siang hari untuk melakukan fotosintesis, menghirup O2 pada malam hari untuk merubah glukosa menjadi energi");
}
}
Melakukan inheritance dari class MakhlukHidup, dengan override methodnya layaknya sebuah tumbuhan.
Hasil
2. Pelajari dan baca simulasi Foxes and Rabbit yang ada di buku. Kemudian buat program perubahan dari struktur class umum menjadi bentuk Abstract Class.
import com.badlogic.gdx.graphics.Color;
public abstract class Animal extends GameObject {
protected boolean alive;
protected int age;
protected int maxAge;
protected int minBreedAge;
protected Simulator simulator;
protected boolean breeded = false;
protected int breedRandom;
protected int breedMinAmount;
protected int breedMaxAmount;
public Animal(Simulator simulator, Location location)
{
this.location = location;
this.simulator = simulator;
}
public abstract void act();
}
import com.badlogic.gdx.graphics.Color;
public class Carrot extends Food {
public Carrot(Simulator simulator, Location location)
{
super(simulator, location);
simulatorColor = Color.ORANGE;
eaten = false;
}
@Override
public void act() {
}
}
import java.util.List;
public class Field {
private int width;
private int height;
private GameObject[][] objects;
public Field(int width, int height)
{
objects = new GameObject[width][height];
this.width = width;
this.height = height;
}
public GameObject getObjectAt(int x, int y)
{
return objects[x][y];
}
public boolean withinBounds(int x, int y)
{
return x >= 0 && y >= 0 && x < width && y < height;
}
public boolean setObjectAt(int x, int y, GameObject obj)
{
if(!withinBounds(x, y))
{
return false;
}
if(objects[x][y] == null)
{
objects[x][y] = obj;
return true;
}
else if(obj == null)
{
objects[x][y] = null;
return true;
}
return false;
}
public void getNeighbouringObjects(List<GameObject> outObj, GameObject currentObj, int checkSize)
{
if(currentObj == null)
{
return;
}
int startX = currentObj.location.getCol() - checkSize;
int endX = currentObj.location.getCol() + checkSize;
int startY = currentObj.location.getRow() - checkSize;
int endY = currentObj.location.getRow() + checkSize;
for(int x = startX; x <= endX; x++)
{
for(int y = startY; y <= endY; y++)
{
if(!withinBounds(x, y)) continue;
GameObject obj = getObjectAt(x, y);
if(obj != null && obj != currentObj)
{
outObj.add(obj);
}
}
}
}
public int getWidth()
{
return width;
}
public int getHeight()
{
return height;
}
public boolean getFreeLocation(Location location)
{
int tries = 100;
if(!withinBounds(location.getCol(), location.getRow()))
{
location.set(0, 0);
}
while (objects[location.getCol()][location.getRow()] != null)
{
tries--;
if(tries <= 0)
{
return false;
}
int colBefore = location.getCol();
int rowBefore = location.getRow();
location.translate(Utility.randInt(-1, 1), Utility.randInt(-1, 1));
if(!withinBounds(location.getCol(), location.getRow()))
{
location.set(colBefore, rowBefore);
}
}
return true;
}
}
import com.badlogic.gdx.graphics.Color;
public abstract class Food extends GameObject {
protected boolean eaten;
protected Simulator simulator;
public Food(Simulator simulator, Location location)
{
this.simulator = simulator;
this.location = location;
}
public abstract void act();
}
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.MathUtils;
import java.util.ArrayList;
public class Fox extends Animal {
private ArrayList<GameObject> searchList = new ArrayList<>();
public Fox(Simulator simulator, Location location)
{
super(simulator, location);
maxAge = 50;
simulatorColor = Color.RED;
alive = true;
breedRandom = 15;
minBreedAge = 20;
breedMinAmount = 1;
breedMaxAmount = 3;
}
@Override
public void act() {
age++;
if(age > maxAge)
{
alive = false;
return;
}
simulator.getField().getNeighbouringObjects(searchList, this, 1);
boolean ate = false;
for(int i = 0; i < searchList.size(); i++)
{
if(searchList.get(i) instanceof Rabbit)
{
Rabbit rabbit = (Rabbit) searchList.get(i);
if(!rabbit.alive) continue;
rabbit.alive = false;
age = MathUtils.clamp(age - 20, 0, 999);
ate = true;
break;
}
else if(age > minBreedAge && searchList.get(i) instanceof Fox && !breeded && Utility.randInt(0, breedRandom) == 0)
{
Fox fox = (Fox) searchList.get(i);
if(!fox.alive) continue;
fox.breeded = true;
int spawnAmount = Utility.randInt(breedMinAmount, breedMaxAmount);
for(int j = 0; j < spawnAmount; j++)
simulator.addSpawnInformation(new Fox(simulator, new Location(location.getCol(), location.getRow())));
}
}
breeded = false;
searchList.clear();
if(!ate && Utility.randInt(0, 2) == 0)
{
setLocationSyncronize(simulator.getField(), location.getCol() + Utility.randInt(-1, 2), location.getRow() + Utility.randInt(-1, 2));
}
}
}
import com.badlogic.gdx.graphics.Color;
public abstract class GameObject {
protected Color simulatorColor;
protected Location location;
public Color getSimulatorColor()
{
return simulatorColor;
}
public boolean setLocationSyncronize(Field field, int col, int row)
{
if(!field.withinBounds(col, row))
{
return false;
}
GameObject otherObj = field.getObjectAt(location.getCol(), location.getRow());
if(otherObj == this && field.getObjectAt(col, row) == null)
{
field.setObjectAt(location.getCol(), location.getRow(), null);
field.setObjectAt(col, row, this);
location.set(col, row);
return true;
}
return false;
}
}
public class Location {
private int col;
private int row;
public Location(int col, int row)
{
this.col = col;
this.row = row;
}
public void translate(int col, int row)
{
this.col += col;
this.row += row;
}
public void set(int col, int row)
{
this.col = col;
this.row = row;
}
public int getCol()
{
return col;
}
public int getRow()
{
return row;
}
}
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.ScreenUtils;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import org.w3c.dom.Text;
import java.awt.*;
/** {@link com.badlogic.gdx.ApplicationListener} implementation shared by all platforms. */
public class Main implements ApplicationListener {
private SpriteBatch batch;
private Viewport viewport;
private OrthographicCamera camera;
private static Main singleton;
//Sprites
private Texture whitePixelTexture;
private Texture gridTexture;
//Others
private Simulator simulator;
@Override
public void create() {
singleton = this;
batch = new SpriteBatch();
camera = new OrthographicCamera(1200f, 1000f);
viewport = new FitViewport(1200f, 1000f, camera);
Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
pixmap.setColor(1f, 1f, 1f, 1f);
pixmap.drawPixel(0, 0, new Color(1f, 1f, 1f, 1f).toIntBits());
whitePixelTexture = new Texture(pixmap);
pixmap.dispose();
pixmap = new Pixmap(10, 10, Pixmap.Format.RGBA8888);
pixmap.setColor(0f, 0f, 0f, 1f);
pixmap.fill();
pixmap.setColor(1f, 1f, 1f, 1f);
pixmap.fillRectangle(1, 1, 8, 8);
gridTexture = new Texture(pixmap);
pixmap.dispose();
simulator = new Simulator();
}
public static Texture getWhitePixelTexture()
{
return singleton.whitePixelTexture;
}
public static Texture getGridTexture()
{
return singleton.gridTexture;
}
@Override
public void render() {
ScreenUtils.clear(0f, 0f, 0f, 1f);
viewport.apply();
simulator.setupDraw(camera);
batch.setProjectionMatrix(viewport.getCamera().combined);
batch.begin();
simulator.draw(batch, camera);
batch.end();
}
@Override
public void resize(int width, int height) {
viewport.update(width, height, true);
}
@Override
public void dispose() {
batch.dispose();
whitePixelTexture.dispose();
}
@Override
public void pause() {
}
@Override
public void resume() {
}
}
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.MathUtils;
import java.util.ArrayList;
public class Rabbit extends Animal {
private ArrayList<GameObject> searchList = new ArrayList<>();
public Rabbit(Simulator simulator, Location location)
{
super(simulator, location);
maxAge = 30;
simulatorColor = Color.BLUE;
alive = true;
minBreedAge = 15;
breedRandom = 8;
breedMinAmount = 1;
breedMaxAmount = 5;
}
@Override
public void act() {
age++;
if(age > maxAge)
{
alive = false;
return;
}
simulator.getField().getNeighbouringObjects(searchList, this, 1);
boolean ate = false;
for(int i = 0; i < searchList.size(); i++)
{
if(searchList.get(i) instanceof Carrot)
{
Carrot carrot = (Carrot) searchList.get(i);
if(carrot.eaten) continue;
carrot.eaten = true;
age = MathUtils.clamp(age - 20, 0, 999);
ate = true;
break;
}
else if(age > minBreedAge && searchList.get(i) instanceof Rabbit && !breeded && Utility.randInt(0, breedRandom) == 0)
{
Rabbit rabbit = (Rabbit) searchList.get(i);
if(!rabbit.alive) continue;
rabbit.breeded = true;
int spawnAmount = Utility.randInt(breedMinAmount, breedMaxAmount);
for(int j = 0; j < spawnAmount; j++)
simulator.addSpawnInformation(new Rabbit(simulator, new Location(location.getCol(), location.getRow())));
}
}
searchList.clear();
if(!ate && Utility.randInt(0, 2) == 0)
{
setLocationSyncronize(simulator.getField(), location.getCol() + Utility.randInt(-1, 2), location.getRow() + Utility.randInt(-1, 2));
}
}
}
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class Simulator {
private Field field;
private float passedDelta;
private float updateSecond = 1f;
private final float scale = 10f;
private final int width = 100;
private final int height = 80;
private HashSet<Animal> animalList = new HashSet<>();
private HashSet<Food> foodList = new HashSet<>();
private ArrayList<Object> removeObjList = new ArrayList<>();
private ArrayList<SpawnInformation> spawnInformations = new ArrayList<>();
public Simulator()
{
field = new Field(width, height);
new Utility();
spawnIntialPopulation();
}
protected Field getField()
{
return field;
}
private void spawnIntialPopulation()
{
int rabbitAmount = Utility.randInt(50, 70);
int foxAmount = Utility.randInt(30, 40);
int carrotAmount = Utility.randInt(80, 150);
for(int i = 0; i < foxAmount; i++)
{
Fox fox = new Fox(this, new Location(Utility.randInt(0, width - 1), Utility.randInt(0, height - 1)));
SpawnInformation info = new SpawnInformation(fox);
spawnInformations.add(info);
}
for(int i = 0; i < rabbitAmount; i++)
{
Rabbit rabbit = new Rabbit(this, new Location(Utility.randInt(0, width - 1), Utility.randInt(0, height - 1)));
SpawnInformation info = new SpawnInformation(rabbit);
spawnInformations.add(info);
}
for(int i = 0; i < carrotAmount; i++)
{
Carrot carrot = new Carrot(this, new Location(Utility.randInt(0, width - 1), Utility.randInt(0, height - 1)));
SpawnInformation info = new SpawnInformation(carrot);
spawnInformations.add(info);
}
}
private void update()
{
passedDelta += Gdx.graphics.getDeltaTime();
if(passedDelta >= updateSecond)
{
passedDelta -= updateSecond;
simulateOneStep();
}
}
private void simulateOneStep()
{
//Act
for(Animal animal : animalList)
{
if(!animal.alive) continue;
animal.act();
}
for(Food food : foodList)
{
if(food.eaten) continue;
food.act();
}
//Clear
for(Animal animal : animalList)
{
if(!animal.alive)
{
removeObjList.add(animal);
}
}
for(Food food : foodList)
{
if(food.eaten)
{
removeObjList.add(food);
}
}
for(Object obj : removeObjList)
{
GameObject gameObject = (GameObject)obj;
field.setObjectAt(gameObject.location.getCol(), gameObject.location.getRow(), null);
animalList.remove(obj);
foodList.remove(obj);
}
removeObjList.clear();
//Add
for(SpawnInformation spawnInformation : spawnInformations)
{
GameObject obj = spawnInformation.getObject();
if(field.getFreeLocation(obj.location))
{
if(obj instanceof Animal)
{
Animal animal = (Animal) obj;
animalList.add(animal);
}
else if(obj instanceof Food)
{
Food food = (Food) obj;
foodList.add(food);
}
field.setObjectAt(obj.location.getCol(), obj.location.getRow(), obj);
}
}
spawnInformations.clear();
System.out.println("Animals Amount : " + animalList.size());
System.out.println("Food Amount : " + foodList.size());
}
public void addSpawnInformation(GameObject object)
{
spawnInformations.add(new SpawnInformation(object));
}
public void setupDraw(OrthographicCamera camera)
{
camera.position.set(width / 2f * scale - (scale / 2f), height / 2f * scale - (scale / 2f), 0f);
}
public void draw(SpriteBatch batch, OrthographicCamera camera)
{
update();
batch.setColor(0f, 0f, 0f, 1f);
centerDraw(batch, Main.getWhitePixelTexture(), camera.position.x, camera.position.y, camera.viewportWidth, camera.viewportHeight);
batch.setColor(1f, 1f, 1f, 1f);
centerDraw(batch, Main.getGridTexture(), 0f, 0f, 10f, 10f);
for(int x = 0; x < width; x++)
{
for(int y = 0; y < height; y++)
{
centerDraw(batch, Main.getGridTexture(), x * scale, y * scale, scale, scale);
}
}
for(int x = 0; x < width; x++)
{
for(int y = 0; y < height; y++)
{
GameObject obj = field.getObjectAt(x, y);
if(obj == null)
{
continue;
}
batch.setColor(obj.getSimulatorColor());
centerDraw(batch, Main.getWhitePixelTexture(), x * scale, y * scale, scale, scale);
}
}
}
public void centerDraw(SpriteBatch batch, Texture texture, float x, float y, float width, float height)
{
x -= width / 2f;
y -= height / 2f;
batch.draw(texture, x, y, width, height);
}
}
public class SpawnInformation {
private GameObject object;
public SpawnInformation(GameObject obj)
{
this.object = obj;
}
public GameObject getObject()
{
return object;
}
}
import java.util.Random;
public class Utility {
private static Utility singleton;
private Random randomizer = new Random();
public Utility()
{
singleton = this;
}
public static int randInt(int min, int max)
{
return singleton.randomizer.nextInt(min, max);
}
}
Comments
Post a Comment