Finished Lab2

fix: update test.sh

feat: reformat and remote BaseShopEvent

chore: add comments
This commit is contained in:
YADUNAND PREM 2022-09-01 11:37:00 +08:00 committed by Yadunand Prem
parent ed77b0e10f
commit ae8e984866
12 changed files with 219 additions and 139 deletions

3
.gitignore vendored
View File

@ -1,3 +1,6 @@
Lab1.pdf
*.class
checkstyle.jar
cs2030_checks.xml

View File

@ -1,30 +1,51 @@
/**
* The ArrivalEvent is an Event which handles the arrival of a customer
* It decides whether a customer should go into queue or go to a counter
* It also allocates a counter to the customer. This event thus returns either a
* DepartureEvent or a ServiceBeginEvent
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
class ArrivalEvent extends BaseShopEvent {
class ArrivalEvent extends Event {
double serviceTime;
private Customer customer;
private Shop shop;
public ArrivalEvent(double time, Customer customer, Shop shop, double serviceTime) {
super(time, customer, shop);
this.serviceTime = serviceTime;
public ArrivalEvent(Customer customer, Shop shop) {
super(customer.getArrivalTIme());
this.customer = customer;
this.shop = shop;
}
@Override
public Event[] simulate() {
ShopCounter availableCounter = this.shop.getAvailableCounter();
// check if counters are available. If none, push customer to queue if not full.
// If full, customer departs
if (availableCounter == null) {
if (this.shop.getQueue().isFull()) {
return new Event[] { new DepartureEvent(this.getTime(), customer, shop) };
}
Queue queue = this.shop.getQueue();
System.out
.println(String.format("%s: %s joined queue %s",
super.toString(),
this.customer, queue));
queue.enq(customer);
return new Event[] {};
}
return new Event[] {
new ServiceBeginEvent(this.getTime(), customer, shop, this.serviceTime, availableCounter) };
new ServiceBeginEvent(this.getTime(), customer, shop, availableCounter) };
}
@Override
public String toString() {
return super.toString() + String.format(": %s arrives", this.customer);
return String.format("%s: %s arrived %s",
super.toString(),
this.customer,
this.shop.getQueue());
}
}

View File

@ -1,22 +0,0 @@
/**
* This class encapsulates an event in the shop
* simulation. Your task is to replace this
* class with new classes, following proper OOP principles.
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
abstract class BaseShopEvent extends Event {
final Customer customer;
Shop shop;
public BaseShopEvent(double time, Customer customer, Shop shop) {
super(time);
this.customer = customer;
this.shop = shop;
}
}

View File

@ -1,17 +1,34 @@
/**
* This is a data class which holds information about the Customer.
* It has a incrementing counter for the customer id;
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
public class Customer {
final private int id;
private static int lastId = 0;
public Customer(int id) {
this.id = id;
private final int id;
private final double serviceTime;
private final double arrivalTIme;
public Customer(double serviceTime, double arrivalTime) {
this.id = lastId++;
this.serviceTime = serviceTime;
this.arrivalTIme = arrivalTime;
}
public double getServiceTime() {
return this.serviceTime;
}
public double getArrivalTIme() {
return arrivalTIme;
}
@Override
public String toString() {
return "Customer " + id;
return "C" + id;
}
}

View File

@ -1,22 +1,45 @@
/**
* The DepartureEvent is an Event which handles the end of a service.
* It handles allocating customers in queue to a counter.
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
class DepartureEvent extends BaseShopEvent {
class DepartureEvent extends Event {
private ShopCounter counter;
private Customer customer;
private Shop shop;
public DepartureEvent(double time, Customer customer, Shop shop) {
super(time, customer, shop);
super(time);
this.customer = customer;
this.shop = shop;
}
public DepartureEvent(double time, Customer customer, Shop shop, ShopCounter counter) {
super(time);
this.customer = customer;
this.shop = shop;
this.counter = counter;
}
@Override
public String toString() {
return super.toString()
+ String.format(": %s departed", this.customer);
return String.format("%s: %s departed", super.toString(), this.customer);
}
@Override
public Event[] simulate() {
// when customer departs, check if there are customers in queue
if (this.shop.getQueue().isEmpty() || this.counter == null) {
return new Event[] {};
}
Customer c = (Customer) this.shop.getQueue().deq();
return new Event[] {
new ServiceBeginEvent(this.getTime(), c, this.shop, this.counter),
};
}
}

View File

@ -59,7 +59,8 @@ class Queue {
/**
* Remove the object from the queue.
*
* @return null if the queue is empty; the object removed from the queue otherwise.
* @return null if the queue is empty; the object removed from the queue
* otherwise.
*/
public Object deq() {
if (this.isEmpty()) {

View File

@ -1,15 +1,20 @@
/**
* The ServiceBeginEvent is an Event which handles the starting of a service.
* It handles occupying a counter and also generating a serviceEndEvent
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
class ServiceBeginEvent extends BaseShopEvent {
class ServiceBeginEvent extends Event {
double serviceTime;
ShopCounter counter;
private ShopCounter counter;
private Customer customer;
private Shop shop;
public ServiceBeginEvent(double time, Customer customer, Shop shop, double serviceTime, ShopCounter counter) {
super(time, customer, shop);
this.serviceTime = serviceTime;
public ServiceBeginEvent(double time, Customer customer, Shop shop, ShopCounter counter) {
super(time);
this.customer = customer;
this.shop = shop;
this.counter = counter;
}
@ -22,7 +27,7 @@ class ServiceBeginEvent extends BaseShopEvent {
@Override
public Event[] simulate() {
this.counter.occupy();
double endTime = this.getTime() + this.serviceTime;
double endTime = this.getTime() + this.customer.getServiceTime();
return new Event[] {
new ServiceEndEvent(endTime, this.customer, this.shop, this.counter) };
}

View File

@ -1,13 +1,20 @@
/**
* The ServiceEndEvent is an Event which handles the end of a service.
* It handles freeing the counter and also generating a departure event
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
class ServiceEndEvent extends BaseShopEvent {
class ServiceEndEvent extends Event {
ShopCounter counter;
private ShopCounter counter;
private Customer customer;
private Shop shop;
public ServiceEndEvent(double time, Customer customer, Shop shop, ShopCounter counter) {
super(time, customer, shop);
super(time);
this.customer = customer;
this.shop = shop;
this.counter = counter;
}
@ -20,6 +27,6 @@ class ServiceEndEvent extends BaseShopEvent {
@Override
public Event[] simulate() {
this.counter.free();
return new Event[] { new DepartureEvent(this.getTime(), customer, shop) };
return new Event[] { new DepartureEvent(this.getTime(), customer, shop, counter) };
}
}

View File

@ -1,19 +1,40 @@
/**
* Shop is a data class which holds information about a shop.
* It stores the list of counters and the queue in which new customers can join.
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
public class Shop {
private ShopCounter[] counters;
private Queue queue;
public Shop(ShopCounter[] counters) {
this.counters = counters;
public Shop(int numOfCounters, int queueSize) {
this.counters = new ShopCounter[numOfCounters];
for (int i = 0; i < numOfCounters; i++) {
this.counters[i] = new ShopCounter();
}
this.queue = new Queue(queueSize);
}
/**
* getAvailableCounter returns the first available counter it finds.
* If there are none, returns null
*
* @return the available counter or null if none found
*/
public ShopCounter getAvailableCounter() {
for (int i = 0; i < this.counters.length; i++) {
if (this.counters[i].isAvailable())
if (this.counters[i].isAvailable()) {
return counters[i];
}
}
return null;
}
public Queue getQueue() {
return queue;
}
}

View File

@ -1,9 +1,14 @@
/**
* This is a data class which holds information about a counter. It has a
* incrementing counter for the conuter Id.
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
public class ShopCounter {
final private int id;
private static int lastId;
private final int id;
private boolean available;
public boolean isAvailable() {
@ -18,14 +23,14 @@ public class ShopCounter {
this.available = true;
}
public ShopCounter(int id) {
this.id = id;
public ShopCounter() {
this.id = lastId++;
this.available = true;
}
@Override
public String toString() {
return "Counter " + id;
return "S" + id;
}
}

View File

@ -26,19 +26,15 @@ class ShopSimulation extends Simulation {
public ShopSimulation(Scanner sc) {
initEvents = new Event[sc.nextInt()];
int numOfCounters = sc.nextInt();
int maxQueueSize = sc.nextInt();
ShopCounter[] availableCounters = new ShopCounter[numOfCounters];
for (int i = 0; i < numOfCounters; i++) {
availableCounters[i] = new ShopCounter(i);
}
Shop shop = new Shop(availableCounters);
Shop shop = new Shop(numOfCounters, maxQueueSize);
int id = 0;
while (sc.hasNextDouble()) {
double arrivalTime = sc.nextDouble();
double serviceTime = sc.nextDouble();
initEvents[id] = new ArrivalEvent(arrivalTime, new Customer(id), shop, serviceTime);
initEvents[id] = new ArrivalEvent(new Customer(serviceTime, arrivalTime), shop);
id += 1;
}
}

View File

@ -70,4 +70,7 @@ elif [ $num_failed -eq 0 ]
then
echo "$PROG: passed everything 🎉"
fi
# Run style checker
java -jar ./checkstyle.jar -c ./cs2030_checks.xml *.java
# vim:noexpandtab:sw=4:ts=4