This repository was archived by the owner on Nov 30, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
PersonAgent
Matthew Pohlmann edited this page Jan 1, 2014
·
1 revision
####Description All-purpose class for describing every person in SimCity201. When entering a structure or moving about the city the person takes on one or more roles, determining his/her behavior.
####Class Signature
public class PersonAgent extends Agent implements Person {}####Data
String name;
CityPanel panel;
PersonState state;
Semaphore animation;
List<Role> roles;
PassengerRole passengerRole;
List<Action> planner;
Action currentAction;
CityTime time;
CityTime wakeupTime;
CityTime sleepTime;
double moneyOnHand;
int hungerLevel;
boolean hungerEnabled;
Vehicle vehicle;
Structure home;
Structure workplace;
Intention job;
CityTime workTime;
Structure currentLocation;
int bankAccountNumber;
List<ItemRequest> marketChecklist;
List<ItemRequest> inventory;
boolean tryToBuyCar;public enum Intention {
None,
ResidenceSleep,
ResidenceEat,
ResidenceRelax,
ResidenceLandLord,
ResidencePayRent,
BankTeller,
BankGuard,
BankWithdrawMoneyCustomer,
BankDepositMoneyCustomer,
BankTakeOutLoan,
BankWithdrawMoneyBusiness,
BankDepositMoneyBusiness,
MarketManager,
MarketEmployee,
MarketConsumerGoods,
MarketConsumerCar,
RestaurantCook,
RestaurantHost,
RestaurantWaiter,
RestaurantCashier,
RestaurantCustomer
};private class Action {
Structure location;
Intention intent;
boolean active;
};private enum PersonState {
Sleeping,
Awake,
AtWork,
Relaxing;
};####Scheduler
if passengerRole.active then,
passengerRole.pickAndExecuteAnAction();
return true;if state != Relaxing && Ǝ Role r in roles ∋ r.active then,
return r.pickAndExecuteAnAction();if Ǝ Action a in planner ∋ a.active then,
performAction(a);
return true;if Ǝ Action a in planner then,
goToLocation(a);
return true;if state = Sleeping && time != Weekend && time = wakeupTime then,
state = Awake;
// If you need to pay rent
if home != null && home.isApartment then,
addActionToPlanner(Intention.ResidencePayRent, home, true);
// The Residence Role will determine if there's enough time to eat at a Restaurant, or if eating at home is better
addActionToPlanner(ResidenceEat, home, false);
return trueif state = Sleeping && time == Weekend && time == wakeupTime + 90 minutes then,
state = Awake;
addActionToPlanner(ResidenceEat, home, false);
return trueif state = Awake || Relaxing && time > workTime && time < workTime + 90 && time != Weekend then,
if addActionToPlanner(job, workplace, true) then,
state = AtWork;
return true;if state = Awake || Relaxing && time >= sleepTime then,
passengerRole.msgStopRoaming();
planner.clear();
state = Sleeping;
addActionToPlanner(ResidenceSleep, home, false);
return true;if state = Awake || Relaxing && moneyOnHand <= MONEYTHRESHOLD then,
boolean performAction = true;
if Ǝ Action a in planner ∋ a.intent = BankWithdrawMoneyCustomer then,
performAction = false;
if performAction && CityDirectory.getInstance().getBanks().size() > 0 then,
addActionToPlanner(BankWithdrawMoneyCustomer, CityDirectory.getInstance().getRandomOpenBank(), false);
state = PersonState.Awake;
return true;if state = Awake && currentLocation != home && hungerLevel >= HUNGRY then,
boolean performAction = true;
if Ǝ Action a in planner ∋ a.intent = RestaurantCustomer then,
performAction = false;
if performAction && CityDirectory.getInstance().getRestaurants().size() > 0 then,
boolean starving = hungerLevel >= STARVING;
addActionToPlanner(RestaurantCustomer, CityDirectory.getInstance().getRandomOpenRestaurant(), starving);
return true;if state = Awake || Relaxing && marketChecklist.size() > 0 then,
boolean performAction = true;
if Ǝ Action a in planner ∋ a.intent = MarketConsumerGoods then,
performAction = false;
if performAction && CityDirectory.getInstance().getMarkets().size() > 0 then,
addActionToPlanner(MarketConsumerGoods, CityDirectory.getInstance().getRandomOpenMarket(), false);
state = Awake;
return true;if state = Awake || Relaxing && home != null && currentLocation == home && hungerLevel >= HUNGRY then,
boolean performAction = true;
if Ǝ Action a in planner ∋ a.intent = ResidenceEat then,
performAction = false;
if performAction then,
boolean starving = hungerLevel >= STARVING;
if addActionToPlanner(ResidenceEat, home, starving) then,
state = Awake;
return true;if state = Awake || Relaxing && tryToBuyCar then,
boolean performAction = true;
if Ǝ Action a in planner ∋ a.intent = MarketConsumerCar then,
performAction = false;
if performAction then,
if addActionToPlanner(MarketConsumerCar, market, false) then,
state = Awake;
tryToBuyCar = false;
return true;if state = Awake then,
if addActionToPlanner(ResidenceRelax, home, false) then,
state = Relaxing;
return true;if state = Awake && !passengerRole.isRoaming() then,
currentAction = null;
passengerRole.setActive(true);
passengerRole.startRoaming();####Messages
// Updates the time so this Person can make appropriate time-based decisions
public void msgUpdateTime(CityTime newTime) {
int minutesPassed = newTime - time;
hungerLevel += (state == Sleeping) ? HUNGERPERMINUTE / 2 * minutesPassed : HUNGERPERMINUTE * minutesPassed;
time.day = day;
time.hour = hour;
time.minute = minute;
stateChanged();
}####Actions
public void goToLocation(Action a) {
a.active = true;
if (!pasengerRole.isAtLocation(a.location)) {
passengerRole.msgGoTo(a.location);
currentLocation = null;
passengerRole.setActive(true);
}
}private void performAction(Action a) {
Role newRole = a.location.getRole(a.intent);
if (newRole == null) {
planner.remove(a);
return;
}
boolean haveRole = false;
for (Role r : roles) {
if (r.getClass().isInstance(newRole)) {
r.setPerson(this);
r.startInteraction(a.intent);
r.setActive(true);
haveRole = true;
break;
}
}
if (!haveRole) {
roles.add(newRole);
newRole.setPerson(this);
newRole.startInteraction(a.intent);
newRole.setActive(true);
}
currentAction = a;
planner.remove(a);
}private boolean addActionToPlanner(Intention intent, Structure location, boolean highPriority) {
if (intent == null || intent == Intention.None || location == null) {
return false;
}
Action temp = new Action();
temp.location = location;
temp.intent = intent;
if (!highPriority) {
planner.add(temp);
} else {
planner.add(0, temp);
}
return true;
}####Role-Related
public void removeRole(Role toRemove) {
roles.remove(toRemove);
}public void goOffWork() {
this.state = PersonState.Awake;
}public void justAte() {
this.hungerLevel = FULL;
}public void addMoney(double amount) {
this.moneyOnHand += amount;
}public void removeMoney(double amount) {
this.moneyOnHand -= amount;
}public void doneMoving(Structure newLocation) {
currentLocation = newLocation;
}public void addIntermediateActions(Role from, LinkedList<Intention> intents, boolean returnToCurrentAction) {
// Deactivate sending Role
if (from != null) {
from.setActive(false);
}
int numActivities = intents.size();
boolean succeeded = false;
while (intents.size() > 0) {
// Create a new action with high priority and put it at front of planner
Intention intent = intents.removeLast();
switch (intent) {
case ResidenceSleep: succeeded = this.addActionToPlanner(intent, home, true); break;
case ResidenceEat: succeeded = this.addActionToPlanner(intent, home, true); break;
case BankWithdrawMoneyCustomer: succeeded = this.addActionToPlanner(intent, CityDirectory.getInstance().getRandomBank(), true); break;
case BankDepositMoneyCustomer: succeeded = this.addActionToPlanner(intent, CityDirectory.getInstance().getRandomBank(), true); break;
case BankTakeOutLoan: succeeded = this.addActionToPlanner(intent, CityDirectory.getInstance().getRandomBank(), true); break;
case BankWithdrawMoneyBusiness: succeeded = this.addActionToPlanner(intent, CityDirectory.getInstance().getRandomBank(), true); break;
case BankDepositMoneyBusiness: succeeded = this.addActionToPlanner(intent, CityDirectory.getInstance().getRandomBank(), true); break;
case MarketConsumerGoods: succeeded = this.addActionToPlanner(intent, CityDirectory.getInstance().getRandomMarket(), true); break;
case MarketConsumerCar: succeeded = this.addActionToPlanner(intent, CityDirectory.getInstance().getRandomMarket(), true); break;
case RestaurantCustomer: succeeded = this.addActionToPlanner(intent, CityDirectory.getInstance().getRandomRestaurant(), true); break;
default: {
return;
}
}
}
// If Role requests that the PersonAgent return after, add that action back at the correct position
if (returnToCurrentAction && succeeded) {
currentAction.active = false;
planner.add(numActivities, currentAction);
} else if (returnToCurrentACtion && !succeeded) {
currentAction.active = false;
planner.add(numActivities - 1, currentAction);
}
}