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 Lab1.pdf
*.class *.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 * @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2 * @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) { public ArrivalEvent(Customer customer, Shop shop) {
super(time, customer, shop); super(customer.getArrivalTIme());
this.serviceTime = serviceTime; 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, availableCounter) };
@Override }
public Event[] simulate() {
ShopCounter availableCounter = this.shop.getAvailableCounter();
if (availableCounter == null) {
return new Event[] { new DepartureEvent(this.getTime(), customer, shop) };
}
return new Event[] {
new ServiceBeginEvent(this.getTime(), customer, shop, this.serviceTime, availableCounter) };
} @Override
public String toString() {
@Override return String.format("%s: %s arrived %s",
public String toString() { super.toString(),
return super.toString() + String.format(": %s arrives", this.customer); 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 * @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2 * @version CS2030S AY22/23 Semester 2
*/ */
public class Customer { public class Customer {
final private int id; private static int lastId = 0;
public Customer(int id) { private final int id;
this.id = id; private final double serviceTime;
} private final double arrivalTIme;
@Override public Customer(double serviceTime, double arrivalTime) {
public String toString() { this.id = lastId++;
return "Customer " + id; this.serviceTime = serviceTime;
} this.arrivalTIme = arrivalTime;
}
public double getServiceTime() {
return this.serviceTime;
}
public double getArrivalTIme() {
return arrivalTIme;
}
@Override
public String toString() {
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 * @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2 * @version CS2030S AY22/23 Semester 2
*/ */
class DepartureEvent extends BaseShopEvent { class DepartureEvent extends Event {
public DepartureEvent(double time, Customer customer, Shop shop) { private ShopCounter counter;
super(time, customer, shop); private Customer customer;
private Shop shop;
public DepartureEvent(double time, Customer customer, Shop 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 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),
};
@Override }
public String toString() {
return super.toString()
+ String.format(": %s departed", this.customer);
}
@Override }
public Event[] simulate() {
return new Event[] {};
}
}

View File

@ -59,7 +59,8 @@ class Queue {
/** /**
* Remove the object from the 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() { public Object deq() {
if (this.isEmpty()) { if (this.isEmpty()) {
@ -101,8 +102,8 @@ class Queue {
/** /**
* Returns the string representation of the queue. * Returns the string representation of the queue.
* *
* @return A string consisting of the string representation of * @return A string consisting of the string representation of
* every object in the queue. * every object in the queue.
*/ */
@Override @Override
public String toString() { public String toString() {
@ -113,7 +114,7 @@ class Queue {
str += this.items[i] + " "; str += this.items[i] + " ";
i = (i + 1) % this.maxSize; i = (i + 1) % this.maxSize;
count++; count++;
} }
return str + "]"; return str + "]";
} }
} }

View File

@ -1,29 +1,34 @@
/** /**
* 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 * @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2 * @version CS2030S AY22/23 Semester 2
*/ */
class ServiceBeginEvent extends BaseShopEvent { class ServiceBeginEvent extends Event {
double serviceTime; private ShopCounter counter;
ShopCounter counter; private Customer customer;
private Shop shop;
public ServiceBeginEvent(double time, Customer customer, Shop shop, double serviceTime, ShopCounter counter) { public ServiceBeginEvent(double time, Customer customer, Shop shop, ShopCounter counter) {
super(time, customer, shop); super(time);
this.serviceTime = serviceTime; this.customer = customer;
this.counter = counter; this.shop = shop;
} this.counter = counter;
}
@Override @Override
public String toString() { public String toString() {
return super.toString() return super.toString()
+ String.format(": %s service begin (by %s)", this.customer, this.counter); + String.format(": %s service begin (by %s)", this.customer, this.counter);
} }
@Override @Override
public Event[] simulate() { public Event[] simulate() {
this.counter.occupy(); this.counter.occupy();
double endTime = this.getTime() + this.serviceTime; double endTime = this.getTime() + this.customer.getServiceTime();
return new Event[] { return new Event[] {
new ServiceEndEvent(endTime, this.customer, this.shop, this.counter) }; new ServiceEndEvent(endTime, this.customer, this.shop, this.counter) };
} }
} }

View File

@ -1,25 +1,32 @@
/** /**
* 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 * @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2 * @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) { public ServiceEndEvent(double time, Customer customer, Shop shop, ShopCounter counter) {
super(time, customer, shop); super(time);
this.counter = counter; this.customer = customer;
} this.shop = shop;
this.counter = counter;
}
@Override @Override
public String toString() { public String toString() {
return super.toString() return super.toString()
+ String.format(": %s service done (by %s)", this.customer, this.counter); + String.format(": %s service done (by %s)", this.customer, this.counter);
} }
@Override @Override
public Event[] simulate() { public Event[] simulate() {
this.counter.free(); 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 * @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2 * @version CS2030S AY22/23 Semester 2
*/ */
public class Shop { public class Shop {
private ShopCounter[] counters; private ShopCounter[] counters;
private Queue queue;
public Shop(ShopCounter[] counters) { public Shop(int numOfCounters, int queueSize) {
this.counters = counters; this.counters = new ShopCounter[numOfCounters];
for (int i = 0; i < numOfCounters; i++) {
this.counters[i] = new ShopCounter();
} }
public ShopCounter getAvailableCounter() { this.queue = new Queue(queueSize);
for (int i = 0; i < this.counters.length; i++) { }
if (this.counters[i].isAvailable())
return counters[i]; /**
} * getAvailableCounter returns the first available counter it finds.
return null; * 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()) {
return counters[i];
}
} }
return null;
}
public Queue getQueue() {
return queue;
}
} }

View File

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

View File

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

View File

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