By Peter Lin, Theodore Preduta, Larry Yuan

Please note: This assignment was originally written in HTML instead of Markdown. Due to color requirements, none of the code can be syntax highlighted.

This tutorial is based on the concepts discussed in the original Don’t Fear the OOP by the late Johannes Claerbout. Unfortunately, the original is not very family friendly and therefore cannot be taught in schools. My group has re-written the original in a more PG manner by using a different example: Minecraft Villages.

In this tutorial, as with the original, there will be three colors of text indicating different levels. Green text gives a pure English understanding of the code, yellow text gives a closer to code explanation and red text gives Java code that implements the concept.

Minecraft is one of the most successful games of all time, and is very popular with children and teenagers. Villages in Minecraft are like real world villages, with buildings, non-playable characters (NPCs) and other creatures.

Every Minecraft Village has different types of creatures and buildings: Villagers, Iron Golems, Villager Houses, Blacksmith Buildings, Churches, and Farms.


Village
	Has a certain number of villagers
	Has a certain number of iron golems
	Has a certain number of houses
	Has a certain number of blacksmith buildings
	Has a certain number of churches
	Has a certain number of farms
	Is located somewhere

A typical minecraft village would have
	Number of villagers = 24
	Number of iron golems = 2
	Number of houses = 24
	Number of blacksmith buildings = 1
	Number of churches = 2
	Number of farms = 2
	Location = (0, 0) 

public class Village
{
	int villagers;
	int ironGolems;
	int houses;
	int blacksmithBuildings;
	int churches;
	int farms;
	int locationX;
	int locationY;
	int locationZ;

	public Village(int x, int y, int z)
	{
		villagers = 14;
		ironGolems = 0;
		houses = 12;
		blacksmithBuildings = 1;
		churches = 1;
		farms = 2;
		locationX = x;
		locationY = y;
		locationZ = z;
	}
}

The great trade This story takes place within the village, with one villager, and a player


Main Raid
	Village genericVillage is a new Village
	The number of villagers is 8
	The number of iron golems is 0
	The number of houses is 8
	The number of blacksmith buildings is 1
	The number of churches is 1
	The number of farms is 3
	The location is (420, -666)

public class Trade
{
	public static void main(String[] args)
	{
		Village genericVillage = new Village(420, -666, 10);
		genericVillage.villagers = 8;
		genericVillage.ironGolems = 0;
		genericVillage.houses = 8;
		genericVillage.farms = 3;
	}
}

All entities have a hitbox size, name, unique ID, type, location, rotation, and health;


Entities
	Have a certain size
	Have a certain health
	Have a certain name
	Have a certain unique ID
	Have a certain type
	Have a certain location
	Have a certain rotation

A standard entity would start with
	A hitbox size of 1x1x2 (LxWxH) (measured in blocks)
	A health of 20
	An empty name

public class Entity 
{
	String name;
	long id;
	int type;
	double locationX;
	double locationY;
	double locationZ;
	double sizeLength;
	double sizeWidth;
	double sizeHeight;
	double rotationYaw;
	double rotationPitch;
	int health;

public Entity(int t, long i, String n) 
{
	name = n;
	id = i;
	type = t;
	locationX = 0.0;
	locationY = 0.0;
	locationZ = 0.0;
	sizeLength = 1.0;
	sizeWidth = 1.0;
	sizeHeight = 2.0;
	rotationYaw = 0.0;
	rotationPitch = 0.0;
	health = 20;
	}
}

Entities need the ability to change their current position (aka to move) to be able to interact with each other. We can implement a simple moveTo method to change an entity's coordinates and their rotation.


moveTo
	Sets the current position of the entity to a target position

public void moveTo(double x, double y, double z, double p, double y) 
{
	locationX = x;
	locationY = y;
	locationZ = z;
	rotationYaw = y;
	rotationPitch = p;
}


Players are based on the idea of entities, in fact, they are a type of entity. They are identical, except they have an inventory space which can be used to store items. A player starts out with an empty inventory, but can gain items over time.


Player extends the idea of Entity
	A Player
		Has an inventory
		Can store up to 36 items in a 4x9 grid

	For a given Player
		He will have an inventory storing the items he currently possesses

public class Player extends Entity
{
	int[][] inventory;

	public Player(String n, long i) 
	{
		name = n;
		type = 2;
		id = i;
		inventory = new int[9][4];
	}
}

As mentioned, players are a type of entity. You can say that the idea of a player extends the idea of an entity, as written in the code. In this situation, the Player class is a subclass of the Entity class and inherits all Entity methods and variables.

Villagers are based on the idea of entities. They are identical, except they have some additional qualities, namely they have trades and home locations (where they return to at night). A villager starts out its life with only two trades available, but will unlock more over time.


Villager extends the idea of Entity

	A Villager
	Has trades
		Has a home location
	
	For a given Villager
		He will have a home location
		He will start out having two trades available

public class Villager extends Entity
{
	String[] trades;
	int homeLocationX;
	int homeLocationY;
	int homeLocationZ;

	public Villager(String n, String[] t, int x, int y, int z, long i) 
	{
		name = n;
		trades = t;
		type = 1;
		id = i;
		homeLocationX = x;
		homeLocationY = y;
homeLocationZ = z;
	}
}

Players should only be allowed to interact with villagers if they are within reaching range (4 blocks diagonally). We can create a private method in the villager class to check for this.


checkDistance
	returns true if the player is within 4 blocks

private boolean isInRange(Player p)
{
	double xLength = Math.pow(locationX - p.locationX, 2);
	double yLength = Math.pow(locationY - p.locationY, 2);
	double zLength = Math.pow(locationZ - p.locationZ, 2);
	return (4 >= Math.sqrt(zLength + xLength + yLength));
}

This uses the Pythagorean theorem to calculate the distance from the player, and then compares it with 4.

Whenever the player trades with a villager, another trade is added, and items are exchanged between the player and the villager.


doTrade
	Adds a trade to the list of trades that the villager has available

public void doTrade(int tradeID, Player p, int itemPos, String newTrade)
{
	if (isInRange(p)) return;
	appendToTrades(newTrade); // appends new trade to the trade array
	// removes item from player's inventory, and replaces it with the new item
	processTrade(tradeID, itemPos, p);
}


If a player opens up the trade window, the trades will be displayed.


getTrades
	gets the trades that the villager has.

public String[] getTrades(Player p) 
{
	if (isInRange(p)) return null;
		return trades;
}

Here is the main plot of the village story: There is a village that exists at the coordinates (420, -666) that has 8 villagers. A player named bob goes up to a villager and trades with him.


Here is the main plot of the village story:

Village genericVillage is a new Village
	The number of villagers is 8
	The number of iron golems is 2
	The number of houses is 8
	The number of blacksmith buildings is 1
	The number of churches is 1
	The number of farms is 3
	The location is (420, -666, 10) 

There are 8 villagers
	Each one has a unique name (V0-7)
	Each one has unique trades (set to null for simplicity here)
	Their home is in the village
	Their position is in the village

There is a player
	Its name is “Bob”
	His inventory starts out empty (full of zeros)

Bob moves within range of V0
Bob trades nothing (item with id 0) for item of id 1 (we can call that stone)

public class Trade
{
	public static void main(String[] args)
	{
		// set up village
		Village genericVillage = new Village(420, -666, 10);
		genericVillage.villagers = 8;
		genericVillage.ironGolems = 2;
		genericVillage.houses = 8;
		genericVillage.farms = 3;
		
		// set up villagers
		Villager[] residents = new Villager[genericVillage.villagers];
		for (int v = 0; v < genericVillage.villagers; v++)
		{
			String[] trades = {“0,1”, “0,2”};
			residents[v] = new Villager(“V”+v, trades, 420, -666, i);
			residents[v].moveTo(420, -666, 10, 0.0, 0.0);
		}
		
		// set up player
		Player b = new Player(“Bob”, 100);

		// do the storyline
		b.moveTo(420, -666, 10, 0.0, 0.0);
		residents[0].doTrade(0, b, 0, “1,3”);
	}
}