I am making a simple programm that allows people to checkin and out a hotel (for my CS class).
What I need to be able to do is check in a person in a room. There are four rooms. How can i make it so that when someone is checked in, the next person that checks in will check in room 2.
i have the following already:
class Hotel {
Room room1, room2, room3, room4;
Hotel() {
room1 = new Room();
room2 = new Room();
room3 = new Room();
room4 = new Room();
}
static checkIn() {
Scanner sc = new Scanner(System.in);
System.out.print("naam:");
String invoer2 = sc.nextLine();
if (room1.guest == null) {
room1.guestst = invoer2;
System.out.println("Guest " + room1.guest + " gets room 1");
return;
} else {
System.out.println("no rom");
}
return;
}
}
class Room {
static int count;
String guest;
Room() {
guest = null;
count--;
}
Room(String newGuest) {
guest = newGuest;
count++;
}
}
class Guest {
String name;
Guest(String newName) {
name = newName;
}
}
To start off, a Hotel has more than one Room. Depending on what you've learnt as far, you should be using an array to hold all Room instances
Room[] rooms;
Hotel() {
rooms = new Room[4];
}
or an ArrayList
List<Room> rooms;
Hotel() {
rooms = new ArrayList<Room>();
}
See also:
Arrays tutorial
Collections tutorial
Update as per your comment: just check every room if it has a guest until you find a room without a guest (like as in real world!). Pseudo:
if there is no guest in room1, then use room1;
else if there is no guest in room2, then use room2;
else if there is no guest in room3, then use room3;
else if there is no guest in room4, then use room4;
else say "sorry, no rooms left!";
This is by the way easier to do in a simple loop when you use an array.
for each room, check if there is no guest in room, then use room;
if there is no room, then say "sorry, no rooms left!";
Oh, don't forget to make the guest null when s/he leaves the room. This will make the room eligible for reuse.
See also:
if-then-else statements
for statement
class Hotel {
Room room1, room2, room3, room4;
Hotel() {
room1 = new Room();
room2 = new Room();
room3 = new Room();
room4 = new Room();
}
}
If you haven't learned an Array yet.
But an Array (or ArrayList) is a better way to do this.
a comment on the static (also noticed by Ishtar).
If you make checkIn static on the Hotel class (and not instance) you are saying that checkIn is the same over all hotels, and not just your hotel. That suggests that if you have 5 hotels, each with its own rooms, all the rooms are alike. So you could checkIn in hotel 1 and get a room from hotel 2. That's really not what you want to do.
public class Hotel {
// stuff
// Check a guest into this hotel
public Room instanceCheckIn(Guest guest) {
//stuff
}
// Check a guest into one of our hotels. It doesn't matter to which
// particular hotel this room belongs :)
public static Room staticCheckIn(Guest guest) {
//stuff
}
}
Usage:
Hotel instanceHotel = new Hotel();
// check a guest into a room of this hotel (instanceHotel)
instanceHotel.instanceCheckIn(someGuest);
// Check a guest into one of the rooms of our hotels
Hotel.staticCheckIn(someGuest);
// Error: cannot call a non-static method on a class
Hotel.instanceCheckIn(someGuest);
// Technically OK, but incredibly bad taste. You suggest something
// is happening with this hotel (called instanceHotel) but in stead
// your actually working on all hotels together (shared data).
instanceHotel.staticCheckIn(someGuest);
In general it's a very good habit to not use static unless you really need it. It suggests something is broken in your domain model. That does not mean you should not use it, but realize that it has a particular odor. (public static void main(String[] args) is of course a special case).
the next person that checks in will
check in room 2
This can't be done right now. Your hotel only has one room! It should have more, 3 for example:
class Hotel {
Kamer kamer1;
Kamer kamer2;
Kamer kamer3;
Hotel (){
kamer1 = new Kamer();
kamer2 = new Kamer();
kamer3 = new Kamer();
}
}
Or better use arraylist
class Hotel {
ArrayList<Kamer> kamers;
Hotel (){
kamers = new ArrayList<Kamer>();//make room-list
kamers.add( new Kamer() );//add one room
kamers.add( new Kamer() );//add one room
kamers.add( new Kamer() );//add one room
//more?
}
}
If you need a hotel with 3 rooms, just call: new Hotel();.
static void checkIn() {
Kamer k1 = new Kamer(g1.naam);
Why are you making a new room when someone wants to check in? You can't just build a new room if you need one, right? If you remove the static you can use the fields kamer1, kamer2 (or kamers if you used the ArrayList).
void checkIn()
{
if (kamer1.guest==null)
//kamer1 is available!
//
//
Related
I am trying to write a program that contains many classes and in one class called "Dorm",I have an arrayList of Blocks,and in the "Block" class,I have an arrayList of Rooms,and in the "Room" class,I have an arrayList of "Students".
I am trying to access the number of available rooms(the rooms that at least have one empty space) through another class called the "Manager class". I have been told that I can just create another arrayList in the manager class to be used as a pointer and search up the empty rooms of the whole dormitory.
My question is,how is this going to work?
ps:This is what I wrote:
public static void availableRooms() { //Shows the available rooms in the dormitory.
Dorms dormitory = new Dorms();
Room room1 = new Room();
for(int i=0;i<dormitory.getBlocks().size();i++)
for(int j=0;j<Block.getRoomList().size();j++) {
if(!(room1.getStudentList().get(room1.getRoomCapacity()).equals(null)))
System.out.print("/t" + room1.getStudentList().get(i) + "/t");
}
}
My code isn't complete yet,so I'm not sure if it works...
Could you share your code/tentative? and clearly specify what's not working?
This being said, unless tied to specific constraints, one should make use of encapsulation and single responsibility principle (see SOLID on wiki) by keeping implementation details private and delegating tasks to the more relevant classes.
You may have something like:
class Dorm {
private List<Block> blocks = ...
...
public int getAvailableRooms() {
int total = 0;
for (Block b : blocks) {
total += b.getAvailableRooms();
}
return total;
}
}
class Block {
private List<Room> rooms = ....
...
public int getAvailableRooms() {
int total = 0;
for (Room r : rooms) {
if (! r.isFull()) {
total++;
}
}
}
class Room {
private int capacity = ...
private List<Student> students = ..
...
public boolean isFull() {
return capacity == students.size();
}
}
Where the Manager class, holding (an) instance(s) of Dorm, just make use of the getAvailableRooms() method which behind the scene delegate to the underlining Blocks and aggregate result... and so on.
Basically I want to create linked lists for people firstly when they sign up for a game. This is done by a method signUp(String name).Eg, John becomes a member when he has signed up.
The instance he becomes a member, and anyone else so I think I'd need lots of lists, I want to create a list for him for when he gets game invites. Eg, create a new linked list linkedList johnsGameInvites = new linkedList();. I also want to create another list linkedList johnsFriends = new linkedList();. This goes for anyone so say Sam would be samsGameInvites and samsFriends etc.
My code so far:
linkedList members = new linkedList();
//Method to sign people up
public boolean signUp(String name) {
if(members.isInMyList(name)) {
System.out.println("That name is already taken.");
return false;
}
else {
members.addToMyList(name);
System.out.println("That name will now be registered.");
//NEW CODE//
Person gameMember = new Person(name)
return true;
}
}
//Method to send game invite
public boolean sendGameInvite(String requester, String receiver) {
//Checking if the two people are signed up
if(!members.isInMyList(requester) || !members.isInMyList(receiver)) {
System.out.println("One or both of these people are not signed up.");
return false;
}
else {
//NEW CODE//
gameMember.addToMyList(requester);
System.out.println("A request will now be sent to " + receiver + "'s account.");
return true;
}
}
My next method I would do is to send friend requests between players.
Could anyone write some code to show me how to make a MemberList and then other lists involving the names of the people who sign up and then how to use them in the game invites and friend requests methods? I'm pretty sure I need to make a Member object that contains a name and then a list of names but I don't know how to do it.
Thanks
You probably want to create a separate class to hold that information. For example:
public class Person {
String name;
LinkedList<Invites> gameInvites; //replace "Invites" with whatever type of object you intend to fill this with
LinkedList<Person> friends;
public Person(String name) {
this.name = name;
gameInvites = new LinkedList<>();
friends = new LinkedList<>();
}
}
You could then include methods relevant to Person objects by including them in the Person class instead of the main class. In your main method, you can now create a LinkedList<Person> that will hold all the people and their info.
I have a class named "Game" in Java, and the aim/goal is to reach a certain room, the "throne" room. When the throne room is reached the game ends.
public class Game {
// fields
private Room currentRoom;
private boolean finished;
private Room throne;
/**
* Create the game and initialise its internal map.
*/
public Game()
{
finished = false;
createRooms();
}
/**
* Create all the rooms and link their exits together.
*/
private void createRooms()
{
Room gate, graveyard, church, crypt, entrance, hall, kitchen, buttery, greathall, staircase,
dungeon, topstaircase, throne, solar, wardrobe, privy;
// create the rooms
gate = new Room("outside the old gate of the castle");
graveyard = new Room("on a wind-swept gaveyard");
church = new Room("in a small ancient church");
throne = new Room("in the throne room with golden walls");
// other rooms ...
// initialize room exits
gate.setExit("north", graveyard);
throne.setExit("south", topstaircase);
// other exits ...
}
}
To go in one direction/room :
public String goRoom(String direction)
{
assert direction != null : "Game.goRoom gets null direction";
// Try to leave current room.
Room nextRoom = currentRoom.getExit(direction);
if (nextRoom == null) {
return "There is no exit in that direction!";
} else {
currentRoom = nextRoom;
return currentRoom.getLongDescription();
}
}
To go into a specific room to end the game i.e "throne" room here's what I did :
if (currentRoom.equals(throne)) {
finished = true;
return "Congrats you have reached the throne room";
}
But I keep getting this error : cannot find symbol - variable throne
This is a project based on the "Object first with Java using blueJ"
Instead of declaring the Room throne in your private void createRooms(), you can declare it as a field, so right after the constructor you can say Room throne;, you can then still initialize it in your createRooms method.
You could consider making it final because it won't change anymore and that clearly states the intention
In this case I wouldn't pass it to the next parameter, to me it would make sense to have it as a field
Edit: on the topic of your unreachable statement comment, what I suspect you're doing is checking for the finished state of the game after your following code:
} else {
currentRoom = nextRoom;
return currentRoom.getLongDescription();
}
Because you're already returning from the method here, you're never actually checking for the end state of the game.
You are storing your Rooms as local variables. These variables are deleted as soon as your method terminates, so the Rooms will disappear.
To solve this, you should declare your variables at the class level:
public class Game {
private Room currentRoom;
private boolean finished;
private Room Goal;
private Map<String, Room> rooms;
public Game() {
finished = false;
rooms = new HashMap<>();
createRooms();
}
//....
private void createRooms() {
rooms.put("gate", new Room("outside the old gate at the castle"));
//similar for other rooms
//...
}
Then, you can access your rooms by defining a function
public Room getRoom(String roomName) {
if (rooms.containsKey(roomName))
return rooms.get(roomName);
throw new IllegalArgumentException("No such room: " + roomName);
}
For example:
if (currentRoom.equals(getRoom("throne")) {
finished = true;
return "Congrats you have reached the throne room";
}
If goRoom() is not in Game, you will need to get an instance of Game first, and then call getRoom() on that instance.
But I keep getting this error : "cannot find symbol - variable
throne". I believe i need a field somewhere but I am unsure where and
how this is useful.
You are getting this error because variable throne is a local variable whose scope is just inside the method it is declared
private void createRooms()
{
Room gate, graveyard, church, crypt, entrance, hall, kitchen, buttery, greathall, staircase,
dungeon, topstaircase, throne, solar, wardrobe, privy;
// create the rooms
gate = new Room("outside the old gate of the castle");
graveyard = new Room("on a wind-swept gaveyard");
church = new Room("in a small ancient church");
throne = new Room("in the throne room with golden walls");// local variable
// other rooms ...
// initialise room exits
gate.setExit("north", graveyard);
throne.setExit("south", topstaircase);
// other exits ...
}
Now Instead of making it local you can make it as instance variable or class variable so it can be accessible , if you wish to make this variable as private instance variable then provide getters and setters to access this variable's value .
I'm trying to take one parameter from the parent class of Car and add it to my array (carsParked), how can i do this?
Parent Class
public class Car
{
protected String regNo; //Car registration number
protected String owner; //Name of the owner
protected String carColor;
/** Creates a Car object
* #param rNo - registration number
* #param own - name of the owner
**/
public Car (String rNo, String own, String carColour)
{
regNo = rNo;
owner = own;
carColor = carColour;
}
/** #return The car registration number
**/
public String getRegNo()
{
return regNo;
}
/** #return A String representation of the car details
**/
public String getAsString()
{
return "Car: " + regNo + "\nColor: " + carColor;
}
public String getColor()
{
return carColor;
}
}
Child Class
public class Carpark extends Car
{
private String location; // Location of the Car Park
private int capacity; // Capacity of the Car Park - how many cars it can hold
private int carsIn; // Number of cars currently in the Car Park
private String[] carsParked;
/** Constructor for Carparks
* #param loc - the Location of the Carpark
* #param cap - the Capacity of the Carpark
*/
public Carpark (String locations, int room)
{
location = locations;
capacity = room;
}
/** Records entry of a car into the car park */
public void driveIn()
{
carsIn = carsIn + 1;
}
/** Records the departure of a car from the car park */
public void driveOut()
{
carsIn = carsIn - 1;
}
/** Returns a String representation of information about the carpark */
public String getAsString()
{
return location + "\nCapacity: " + capacity +
" Currently parked: " + carsIn +
"\n*************************\n";
}
}
Last Question Method
public String getCarsByColor (String carColour)
{
for (int num = 0; num < carsParked.length; num++)
{
if ( carColour.equals(carsParked[num]) )
{
System.out.print (carsParked[num]);
}
}
return carColour;
}
I have this so far so that if "red" is put in the parameters, it would list all the cars with the color red and it's corresponding information but does not seem to work ~_~.
You seem to have the wrong relationship here: a car park is not a car. I would recommend against using inheritance in either direction between these classes. And Carpark should probably just have an array or collection of cars.
Also note that the parameter carsIn isn't necessary - just get the length of the array of cars (or size() if it's a Collection).
Edit: Okay, ignoring the inheritance part, it seems like it makes sense to add cars when driveIn is called, and remove them when driveOut is called.
driveIn should probably take a Car as an argument, so the method can access the parameter you want to store (personally I would just store Car references, but fine). Since we're going to be adding and removing these parameters, it'll be much easier to use a List that can resize itself instead of an array, like ArrayList. For example:
private final List<String> carsRegNosParked = new ArrayList<String>();
public void driveIn(Car car) {
carsRegNosParked.add(car.getRegNo());
}
It's less clear what driveOut should do. It could take a specific registration number to remove:
public void driveOut(String regNo) {
carsRegNosParked.remove(regNo);
}
Or it could just indiscriminately remove a car, say the first car added:
public void driveOut() {
if (!carsRegNosParked.isEmpty()) {
carsRegNosParked.remove(0);
}
}
Note the difference between remove(Object) and remove(int).
First change carsParked to a list. So:
private String[] carsParked;
becomes
private List<String> carsParked;
Then in you constructor initialize it to an empty list by doing:
carsParked = new ArrayList();
Then in your drive in method, make it take a car parameter and pull the param you want:
public void driveIn(Car car) {
carsParked.add(car.getRegNo());
}
Also you do not need to keep track of the number of cars this way. Since you could always do carsParked.size() to find out.
Now I would probably change that list to be List<Car> instead of string and just dump the whole car in there. Sure you may only need one item right now, but who knows down the road, maybe you will need something else.
EDIT:
Sure you could do it with an simple array. The issue with that is sizing. Say you initially create an array of size 5, when you go to add the 6 item you will need to create a new larger array, copy the original data, then add the new item. Just more work. Now if the idea is you have a carpark, and it can have X number of spots then you initilize your array to that size from the begining.
public Carpark (String locations, int room){
location = locations;
capacity = room;
//this creates an array with the max number of spots
carsParked = new String[capacity];
//also good idea to init
carsIn = 0; //initial number of cars parked
}
then in your driveIn() method:
public void driveIn(Car car) {
carsParked[carsIn] =car.getRegNo();
carsIn=carsIn+1;
}
now driveOut()
public void driveOut(Car car) {
//loop through the array until we find the car
for (int i=0; i < carsParked.length; i=i+1){
if (car.getRegNo().equals(carsParked[i])){
//we found the car, so set the space null
carsParked[i] = null;
carsIn=carsIn-1;
//stop looping now
break;
}
}
}
Looks nice doesn't it. Well no it is not. Now the driveIn will not work, since we have null spots scattered all over the place. How do we fix it:
public void driveIn(Car car) {
//loop through the array until we find a null spot,
//then park the car
for (int i=0; i < carsParked.length; i=i+1){
if (carsParked[i] == null){
//we found the car, so set the space null
carsParked[i] = car.getRegNo();
carsIn=carsIn+1;
//stop looping now
break;
}
}
}
It could still be improved further. I would probably still change String[] carsParked to Car[] carsParked as to not throw away information.
I would also change the driveIn and driveOut methods to return booleans to indicate if the successfully parked or un-parked a car.
Final Edit:
Okay, if you want to keep track of what cars are parked in the car park and which spot they are in you need to know enough about each car to make it unique. In your case you may only need regNo. So when you call driveIn or driveOut you have to pass that information so we can store it at the appropriate index (parking spot) in the array. Otherwise all you will know is a car was parked somewhere, or that a car left. Not which spots are open.
So in short the parameter Car car in those two methods contain the information needed to uniquely identify each car that is being parked, or is leaving. Without it the car park instance would have no clue who is currently parked, or where they are parked.
I'm going to build a hotel table.
But I'm having problems when trying to implement this in Java.
My hotel has Level(int id) x Room(int id) x Field(String status, int counter)
The same in php would look like:
$level=1; $room=2;
if(isset($hotel[$level][$room])) {
print("Room: ".$level*100+$room);
print(", Status: ".$hotel[$level][$room]['status']);
print(", Total clients:".$hotel[$level][$room]['counter']);
}
And this print returns me(if room exist):
"Room: 102, Status: Reserved, Total clients: 8";
Now I want to have the same in JAVA.
But the problem is, that I'm not able to build this:
int[][][] my hotel;
Because, I have the different types in my multi-dimensional array.
I tried to make sth like this:
Map<String, List<String>> myHotel = new HashMap<String, List<String>>();
Or:
List<List<List<String>>> myHotel;
But
out.println(
myHotel.get(1).get(2).get("status") + "\n" +
out.println(myHotel.get(1).get(2).get("status"));
Or even:
out.println("Status:" +
myHotel.get(1).get(2).get(0) + "\tClients:" +
myHotel.get(1).get(2).get(1)
);
Also how to put elements. I'm thinking about sth like:
WHEN it's a MAP table:
myHotel.put(1).add(2).add(0, "Reserved"));
// But better would be:
// myHotel.put(1).add(2).add("status", "Reserved"));
Or WHEN it's a List<List<List<String>>>:
myHotel.add(1).add(2).add(0, "Reserved"));
// But better would be:
// myHotel.add(1).add(2).add("status", "Reserved"));
Thanks for helping :)
I'd probably model the hotel as an object Hotel, the room as an object Room etc. rather than stacking everything together in a multi-tiered collection. That becomes very verbose very quickly, and as soon as you change the relationships then that change is reflected throughout your code.
Each object then contains references to its components (Hotel contains a list of Rooms etc.). Once you do this I think everything should become a lot clearer. Furthermore your Hotel object understands how to find Rooms, the Room objects understand how to get its attributes and your calling code becomes a lot less verbose, and a lot less dependent on the Hotel/Room implementation. e.g. you can do this:
Hotel hotel = new Hotel();
Set<Room> rooms = hotel.getFreeRooms(RoomType.NON_SMOKING);
and so your objects do the work for you (the client) rather than you navigating the object hierarchy and doing the work yourself.
That's the ultimate goal of OO. As soon as I find myself putting together collections of collections, that's often an indicator that a new object class is required.
You should create proper classes
import java.util.*;
class Hotel {
public List<Level> levels = new ArrayList<Level>();
}
class Level {
public List<Room> rooms = new ArrayList<Room>();
}
class Room {
public Status status = Status.FREE;
public int counter = 0;
}
enum Status {
FREE, OCCUPIED
}
and then you use
Hotel hotel = new Hotel();
hotel.levels.add(new Level());
hotel.levels.get(0).rooms.add(new Room());
Room room = hotel.levels.get(0).rooms.get(0);
room.status = Status.OCCUPIED;
room.counter = 8;
et cetera...
NB: of course, OO purists will no come and tell you that all these fields need to be private and only be accessed through accessors. But I'd say it's okay if you start with this most simple design and later, as you learn more Java, evolve it to something more complex.
class HotelRoom{
int roomnumber;
int level;
boolean reserved;
int clientCount;
public int getUniqueNumber(){
return roomnumber + level*100;
}
}
...
HotelRoom[][] hotel = new HotelRoom[floorCount][roomCount];
HotelRoom myRoom = hotel[floor][room];
System.out.print("room: " + myRoom.getUniqueNumber());
System.out.print(", Status: " myRoom.reserved);
System.out.print(", Total clients: " myRoom.clientCount);
Your design is pretty crazy, by the way.
Since level and room number is the key, I would represent room as a value object like this (at a minimum):
class Room {
public static enum Status {RESERVED, AVAILABLE}
private Status status;
private int numberOfPersons;
// Getters and setters
}
And the key as:
class RoomKey {
private int levelNumber;
private int roomNumber;
public RoomKey(int levelNumber, int roomNumber) {
this.leveNumber = levelNumber;
this.roomNumber = roomNumber;
}
}
And keep the data in a Map like:
Map<RoomKey, Room> rooms = getRoomMap();
Room room = rooms.get(new RoomKey(levelNumber, roomNumber))