본문 바로가기

STUDY/국비과정

[JAVA 웹 개발 공부] 국비지원 20, 21일차 - 팀프로젝트 <호텔 객실 예약 프로그램 만들기>

주제

 

호텔의 데스크 직원이 사용할 수 있는 호텔 객실 관리프로그램 만들기

 

1. 객실 정보

객실은 2층부터 5층까지 각 층마다 20개씩 있다.

방 번호는 3자리 정수이며, 첫자리는 층수를 의미한다. (201, 301, ... )

방 타입은 싱글과 더블이 있다.

*싱글 : 방번호의 끝자리 수는 홀수
*더블 : 방번호의 끝자리 수는 짝수

 

2. 기능

*현재 객실 상태를 확인 가능(예약중, 투숙중, 빈 객실)

*빈 객실 보기(몇 개 있는지, 몇 호실인지 알려주기)
*예약된 객실 보기(몇 개 있는지, 몇 호실인지 알려주기)
*투숙중인 객실 보기(몇 개 있는지, 몇 호실인지 알려주기)
*각 객실의 고객의 기본 정보(이름, 전화번호 등)를 확인 가능
*객실 상태 변경 기능(예약중 → 빈 객실)

 

 

프로그램 만들 때 생각하기

 

1. 프로그램 목적

2. 프로그램 최종사용자

3. 프로그램 사용환경

4. 프로그램 사용방법

5. 실제사례 공부

6. 구현할 기능의 타당성

7. 기능적 구축

어떤 기능을 만들고, 어떤 조작이 일어나는지 생각

8. 언어선택

9. 공유, 공개할 부분 설정

10. UI

입력값 처리방식

11. 데이터와 기능

데이터 → 클래스다이어그램으로 표현가능
기능 → 유스케이스 다이어그램으로 표현가능

 

 

다이어그램

 

 

 

과정

 

1. Guest 클래스 만들기

2. Room 클래스 만들기

3. Reserve 클래스 만들기

4. HotelManager 클래스 만들기

5. 기능 구현

6. 논리오류 확인

7. 수정 및 보완

 

 

Guest 클래스

 

*이름, 폰번호를 필드로 가짐

*생성자는 이름, 폰번호를 파라미터로 받기

*getters and setters, toString 만들기

 

 

Room 클래스

 

*방번호, 방타입, 현재 방상태, 게스트를 필드로 가짐

*생성자는 방번호를 파라미터로 받고, 나머지 값은 초기화 시켜주기

*getters and setters, toString 만들기

 

 

Reserve 클래스

 

*예약날짜, 방번호, 예약자이름, 예약자폰번호를 필드로 가짐

*생성자는 예약날짜, 방번호, 예약자이름, 예약자폰번호를 파라미터로 받기

*getters and setters, toString 만들기

 

 

HotelManager 클래스

 

*오늘날짜를 필드로 가짐 → 예약받을때 오늘이후의 날짜를 받기 위한 기준

*Reserve[](Reserve 타입의 배열) 선언 → 예약을 받으면(예약 객체 생성) 예약배열에 값을 참조

*Room[][](Room 타입의 이차원 배열) 생성

 

*Room 초기화 

생성한 Room[][] 배열을 초기화시켜주기(생성자를 통해 Room객체 생성 후 배열에 값을 저장)

(Room 생성자)
Room 클래스의 생성자는 방번호를 파라미터로 받고, 나머지 값은 초기화시켜주기
방번호 = 입력받은 방번호
끝자리 홀수(인덱스 짝수) = 싱글
끝자리 짝수(인덱스 홀수) = 더블
현재 방상태 = "빈방"
게스트 = new Guest("", "") // 게스트 객체 

(방번호) 
첫번째 인덱스값 = 층과 관련 / 두번째 인덱스값 = 층별로 방번호 관련
ex) Room[0][1] = 202 -> (0+2)x100+(1+1)=202

 

*현재 객실 보기

Room[][] 배열의 요소에 접근 → room[i][j]의 현재 방상태를 알아내기(room[i][j].getRoomStatus())
→ 각 방의 방상태에 맞게(○:빈방 ●:예약중 X:체크인) 출력하기(if문 사용)

[현재 객실 보기]
오늘날짜: 2022-11-28
(○:빈방  ●:예약중  X:체크인)
201호:○  202호:● . . . 220호:○
301호:X   302호:○ . . . 320호:○
401호:○  402호:○ . . . 420호:○
501호:○  502호:○ . . . 520호:○

 

*예약하기

예약을 받을 때마다 Reserve[]의 길이를 늘려주고 
새예약을 Reserve 인스턴스화해서 마지막 자리에 값을 참조하기

(예약받기 전)
Reserve[] reserve = new Reserve[0]; 
// 예약배열 초기화(예약배열 길이 = 0)

(예약받은 후)
reserve = Arrays.copyOf(기존의reserve배열, 기존의reserve배열 길이 + 1); 
// 기존의 reserve배열을 길이를 하나 늘리면서 복사해줌
reserve[기존의reserve배열의 길이] = newReserve; 
// 새로운 예약(Reserve타입)을 받고 길이를 늘려서 복사해준 reserve 배열에 
// 마지막 index값을 newReserve로 참조해줌

(추가로 해줄것)
예약 날짜가 오늘일 경우, 해당 room의 현재 방상태 '예약중'으로 변경, Guest 생성 후 room에 넣어주기

 

*예약 중복 확인

예약할 때 입력받은 날짜와 방번호가 같은지 확인
reserve[i].getReserveDate().isEqual(date) && reserve[i].getReserveRoomNo() == roomNo

같으면 return false
다르면 return true

 

*날짜 범위 확인

날짜를 int 타입으로 입력받기 → 년도, 월의 범위 확인 
→ 년도, 월, 1일로 날짜 설정 후 해당 월의 마지막일 구하기
→ 일의 범위도 확인
→ 오늘이거나 오늘 이후의 날짜인지 확인 

날짜범위가 문제없으면 return true;
날짜범위가 잘못되었으면 return false;

 

*예약 내역 보기(날짜선택)

날짜입력받기 → int 타입으로 6자리 숫자 입력받고 숫자를 연산(/%)를 통해 년도, 월, 일 구하기
→ LocalDate 타입으로 만들기 → 메소드 호출할때 파라미터로 전달하기 
→ 예약배열(reserve)에 있는 요소(참조된 Reserve 객체)중 같은 날짜가 존재할 경우 예약있음
→ 예약돼있는 방은 예약완료되었음을 알려주고, 예약없는 방은 예약가능하다는것을 알려주기

2022-11-28
[예약날짜: 2022-11-28, 방번호: 201, 예약자 성함: 11, 예약자 연락처: 01012345678]
[예약날짜: 2022-11-28, 방번호: 302, 예약자 성함: 22, 예약자 연락처: 01098765432]
(○:예약가능  X:예약완료)
201:X  202:○ . . . 219:○ 220:○
301:○ 302:X  . . . 319:○ 320:○  
401:○ 402:○ . . . 419:○ 420:○  
501:○ 502:○ . . . 519:○ 520:○

 

*예약 내역 보기(방선택)

방번호 입력받기 →
→ 예약배열(reserve)에 있는 요소(참조된 Reserve 객체)중 같은 방번호가 존재할 경우 예약있음
→ 예약돼있는 날짜는 예약완료되었음을 알려주고, 예약없는 날짜는 예약가능하다는것을 알려주기

[예약날짜: 2022-11-28, 방번호: 201, 예약자 성함: 11, 예약자 연락처: 01012345678]
(○:예약가능  X:예약완료)
2022-11-28:X    2022-11-29:○   2022-11-30:○   2022-12-01:○   2022-12-02:○   
2022-12-03:○   2022-12-04:○   2022-12-05:○   2022-12-06:○   2022-12-07:○   
2022-12-08:○   2022-12-09:○   2022-12-10:○   2022-12-11:○   2022-12-12:○   
2022-12-13:○   2022-12-14:○   2022-12-15:○   2022-12-16:○   2022-12-17:○   
2022-12-18:○   2022-12-19:○   2022-12-20:○   2022-12-21:○   2022-12-22:○   
2022-12-23:○   2022-12-24:○   2022-12-25:○   2022-12-26:○   2022-12-27:○

 

*체크인(이름입력)

이름 입력받기 
→ 예약배열에 예약자 이름과 같은 이름이 있는지 확인(for문 이용) 
→ reserve[i].getReserveRoomNo()를 통해서 방번호 구하기
→ room 배열의 요소의 방상태를 체크인으로 변경
room[indexFloor][indexNum].setRoomStatus("체크인");

→ 예약배열에 예약자 이름이 없을 경우 예약내역이 없다고 알려주기

 

*체크인(룸넘버)

방번호 입력받기 → 방번호를 통해서 room 이차원 배열의 인덱스값 구하기
→ 해당하는 room배열의 요소의 방상태를 '체크인'으로 바꿔주기
room[indexFloor][indexNum].setRoomStatus("체크인");

 

*체크아웃(현재 방 상태 변경: 체크인 -> 체크아웃)

방번호 입력받기 → 방번호를 통해서 room 이차원 배열의 인덱스값 구하기
→ 해당하는 room배열의 요소의 방상태를 '빈방'으로 바꿔주기, 게스트의 정보도 바꿔주기
room[indexFloor][indexNum].setRoomStatus("빈방");
room[indexFloor][indexNum].setGuest(new Guest("", ""));

 

*객실 정보 보기

for문 안 for문을 통해 room 이차원배열의 요소에 접근하기
→ toString을 통해서 room 에 대한 정보 출력하기

[객실 정보 보기]
2층
[방번호: 201, 방타입: single, 현재 객실 상태: 예약중, 고객정보[이름: 11, 폰번호: 01012345678]]
[방번호: 202, 방타입: double, 현재 객실 상태: 빈방, 고객정보[이름: , 폰번호: ]]
. . .

 

*main 메소드

입력받기 위해 Scanner 사용

reserve 예약배열 생성

roomSet() 메소드를 이용하여 룸 초기화해주기

while문을 이용해서 반복해서 작업이 수행되게 만들어주기

기능을 선택할 수 있게 리스트를 출력해주고 선택받기

switch문을 통해서 입력받은 값에 맞는 기능을 메소드 호출하여 수행하기

Scanner scan = new Scanner(System.in);
reserve = new Reserve[0]; // 예약 배열 생성
roomSet(); // 룸 초기화(메서드 호출)
. . .
while (go) {
       System.out.printf("1.현재 객실 보기 \n2.예약하기\n3.예약 내역 보기\n4.체크인\n5.체크아웃
       \n6.객실 정보 보기\n0.프로그램 종료\n");
       . . .
       switch (user) {
       case 1:
              break;
​
       . . .
​
       case 0:
              break;
       }
}

 

 

클래스별 필드와 메소드

 

클래스명
Guest
필드
인스턴스변수
private String name;
private String phoneNumber;
메소드
생성자
public Guest(String name, String phoneNumber) {
       this.name = name;
       this.phoneNumber = phoneNumber;
}
Getters and Setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPhoneNumber() { return phoneNumber; }
public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; }
toString()
public String toString() { return "[이름: " + name + ", 폰번호: " + phoneNumber + "]"; }
클래스명
Room
필드
인스턴스변수
private int roomNo;
private String roomType;
private String roomStatus;
private Guest guest;
메소드
생성자
public Room(int roomNo) {
       this.roomNo = roomNo;
       if(roomNo % 2 == 0) { roomType = "double"; }
       else { roomType = "single"; }
       roomStatus = "빈방";
       guest = new Guest("", "");
}
Getters and Setters
public int getRoomNo() { return roomNo; }
public void setRoomNo(int roomNo) { this.roomNo = roomNo; }
public String getRoomType() { return roomType; }
public void setRoomType(String roomType) { this.roomType = roomType; }
public String getRoomStatus() { return roomStatus; }
public void setRoomStatus(String roomStatus) { this.roomStatus = roomStatus; }
public Guest getGuest() { return guest; }
public void setGuest(Guest guest) { this.guest = guest; }
toString()
public String toString() { return "[방번호: " + roomNo + ", 방타입: " + roomType
                                                 + ", 현재 객실 상태: " + roomStatus + ", 고객정보" + guest +"]";}
클래스명
Reserve
필드
인스턴스변수
private LocalDate reserveDate;
private int reserveRoomNo;
private String guestName;
private String guestPhone;
메소드
생성자
public Reserve(LocalDate reserveDate, int reserveRoomNo, String guestName, String guestPhone) {
       this.reserveDate = reserveDate;
       this.reserveRoomNo = reserveRoomNo;
       this.guestName = guestName;
       this.guestPhone = guestPhone;
}
Getters and Setters
public LocalDate getReserveDate() { return reserveDate; }
public void setReserveDate(LocalDate reserveDate) { this.reserveDate = reserveDate; }
public int getReserveRoomNo() { return reserveRoomNo; }
public void setReserveRoomNo(int reserveRoomNo) { this.reserveRoomNo = reserveRoomNo; }
public String getGuestName() { return guestName; }
public void setGuestName(String guestName) { this.guestName = guestName; }
public String getGuestPhone() { return guestPhone; }
public void setGuestPhone(String guestPhone) { this.guestPhone = guestPhone; }
toString()
public String toString() { return "[예약날짜: " + reserveDate + ", 방번호: " + reserveRoomNo
                                          + ", 예약자 성함: " + guestName + ", 예약자 연락처: " + guestPhone + "]"; }
클래스명
HotelManager
필드
static변수
private static LocalDate today = LocalDate.now();
private static Reserve[] reserve;
private static Room[][] room = new Room[4][20];
메소드
static메소드
public static void roomSet() { // 룸 초기화 }
public static void showRoomStatus() { // 현재 객실 보기 }
public static Reserve[] reservation(Reserve newReserve, Reserve[] origin) { // 예약하기 }
public static boolean reserveCheck(LocalDate date, int roomNo) { // 예약 중복 확인 }
public static boolean dateCheck(int input) { // 날짜 범위 확인 }
public static void reserveInputDate(LocalDate date) { // 예약 내역 보기(날짜선택) }
public static void reserveInputRoom(int num) { // 예약 내역 보기(방선택) }
public static void checkInName(String name) { // 체크인(현재 방 상태 변경(이름입력)) }
public static void checkInRoom(int roomNum) { // 체크인(현재 방 상태 변경(방번호입력)) }
public static void checkOut(int roomNum) { // 체크아웃(현재 방 상태 변경) }
public static void showRoomInformation() { // 객실 정보 보기 }
main메소드
Scanner scan = new Scanner(System.in);
reserve = new Reserve[0]; // 예약 배열 생성
roomSet(); // 룸 초기화(메서드 호출)
. . .
while (go) {
       System.out.printf("1.현재 객실 보기 \n2.예약하기\n3.예약 내역 보기\n4.체크인\n5.체크아웃
       \n6.객실 정보 보기\n0.프로그램 종료\n");
       . . .
       switch (user) {
       case 1:
              break;
       . . .
       case 0:
              break;
       }
}

 

이슈 및 해결

 

1. 날짜개념

(문제) 예약받을 때 날짜를 입력받아, 예약 가능 여부를 알려주는 코드가 매우 복잡
(원인) Calendar 클래스의 기본 포맷을 변경하는 과정 및 오늘 날짜와 입력받는 날짜를 비교하는 과정이 복잡
(해결) Calendar 클래스보단 좀더 직관적이고 간단하며 시간정보가 포함하지않아 날짜 정보만을 다루기에 적합한 LocalDate 클래스를 사용
(결과) 가독성 증가 및 유지 보수에 용이

 

2. 날짜와 룸객체 연결하기

(문제) 방별로 예약받은 날짜들이 여러개 존재하는데 두개를 연결하는 부분에서 자꾸 오류가남

(해결) Reserve 라는 예약 클래스를 만들어서 날짜와 방번호를 같이 필드로 가지게 해줌

예약받은 날짜와 고객의 정보로 방번호를 찾을 수 있고, 예약받은 방번호와 고객의 정보로 예약날짜를 찾을 수 있음

 

3. 입력값 제한하기

(문제) 입력받아야 하는 값들이 많아서 잘못입력했을 때 오류가 남

(해결) 입력받는 값들을 범위체크와 여러가지 경우의 수를 생각해서 if문과 for문을 이용해 입력값 오류시 다시 받을 수 있게 함

 

4. 예약 내역 보기(방선택, 날짜선택) 논리오류

 

 

 

Guest 클래스

 

public class Guest {
	private String name;
	private String phoneNumber;
	public Guest(String name, String phoneNumber) {
		this.name = name;
		this.phoneNumber = phoneNumber;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPhoneNumber() {
		return phoneNumber;
	}
	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}
	@Override
	public String toString() {
		return "[이름: " + name + ", 폰번호: " + phoneNumber + "]";
	}
}

 

 

 

Room 클래스
public class Room {
	private int roomNo;
	private String roomType;
	private String roomStatus;
	private Guest guest;
	
	public Room(int roomNo) {
		this.roomNo = roomNo;
		if(roomNo % 2 == 0) {
			roomType = "double";
		} else {
			roomType = "single";
		}
		roomStatus = "빈방"; // 초기화한 후 예약받을 때 상태 변경
		guest = new Guest("", ""); // 초기화한 후 예약받을 때 게스트 만들기
	}
	
	public int getRoomNo() {
		return roomNo;
	}
	public void setRoomNo(int roomNo) {
		this.roomNo = roomNo;
	}
	public String getRoomType() {
		return roomType;
	}
	public void setRoomType(String roomType) {
		this.roomType = roomType;
	}
	public String getRoomStatus() {
		return roomStatus;
	}
	public void setRoomStatus(String roomStatus) {
		this.roomStatus = roomStatus;
	}
	public Guest getGuest() {
		return guest;
	}
	public void setGuest(Guest guest) {
		this.guest = guest;
	}
	@Override
	public String toString() {
		return "[방번호: " + roomNo + ", 방타입: " + roomType + ", 현재 객실 상태: " 
        		+ roomStatus + ", 고객정보" + guest +"]";
	}
}

 

 

 

Reserve 클래스
import java.time.LocalDate;

public class Reserve {
	private LocalDate reserveDate;
	private int reserveRoomNo;
	private String guestName;
	private String guestPhone;
	public Reserve(LocalDate reserveDate, int reserveRoomNo, String guestName, String guestPhone) {
		this.reserveDate = reserveDate;
		this.reserveRoomNo = reserveRoomNo;
		this.guestName = guestName;
		this.guestPhone = guestPhone;
	}
	public LocalDate getReserveDate() {
		return reserveDate;
	}
	public void setReserveDate(LocalDate reserveDate) {
		this.reserveDate = reserveDate;
	}
	public int getReserveRoomNo() {
		return reserveRoomNo;
	}
	public void setReserveRoomNo(int reserveRoomNo) {
		this.reserveRoomNo = reserveRoomNo;
	}
	public String getGuestName() {
		return guestName;
	}
	public void setGuestName(String guestName) {
		this.guestName = guestName;
	}
	public String getGuestPhone() {
		return guestPhone;
	}
	public void setGuestPhone(String guestPhone) {
		this.guestPhone = guestPhone;
	}
	@Override
	public String toString() {
		return "[예약날짜: " + reserveDate + ", 방번호: " + reserveRoomNo + ", 예약자 성함: " 
        		+ guestName + ", 예약자 연락처: " + guestPhone + "]";
	}
}

 

 

 

HotelManager 클래스
import java.time.LocalDate;
import java.util.Arrays;
import java.util.Scanner;

public class HotelManager {
	private static LocalDate today = LocalDate.now();
	private static Reserve[] reserve;
	private static Room[][] room = new Room[4][20];
	private static String booking1 = "○ ";
	private static String booking2 = "X ";
	private static String booking3 = "● ";
	
	// 룸 초기화
	public static void roomSet() {
		// 룸 객체 생성(생성자 파라미터: 룸번호)
		// 룸 번호 설정 Room[0][1] = 202 -> (0+2)x100+(1+1)=202
		for (int i = 0; i < room.length; i++) {
			for (int j = 0; j < room[i].length; j++) {
				int roomNo = (i + 2) * 100 + (j + 1);
					room[i][j] = new Room(roomNo);
			}
		}
	}
	
	// 현재 객실 보기
	public static void showRoomStatus() {
		System.out.println("오늘날짜: " + today);
		System.out.println("(○:빈방  ●:예약중  X:체크인)");
		for (int i = 0; i < room.length; i++) {
			for (int j = 0; j < room[i].length; j++) {
				String todayStatus = room[i][j].getRoomStatus();
				if (todayStatus.equals("체크인")) {
					System.out.print((i + 2) * 100 + (j + 1) + "호:" + booking2 + "  ");
				} else if (todayStatus.equals("예약중")) {
					System.out.print((i + 2) * 100 + (j + 1) + "호:" + booking3 + "  ");
				} else {
					System.out.print((i + 2) * 100 + (j + 1) + "호:" + booking1 + "  ");
				}
			} System.out.println();
		}
	}
	
	// 예약하기
	public static void reservation(Reserve newReserve, Reserve[] origin) {
		reserve = Arrays.copyOf(origin, origin.length + 1);
		reserve[origin.length] = newReserve;
		System.out.println("[예약완료]");
		int reserveRoomNo = newReserve.getReserveRoomNo();
		int indexFloor = reserveRoomNo / 100 - 2; 
		int indexNum = reserveRoomNo % 100 - 1;
		String guestName = reserve[origin.length].getGuestName();
		String guestPhone = reserve[origin.length].getGuestPhone();
		if (newReserve.getReserveDate().equals(today)) {
			room[indexFloor][indexNum].setGuest(new Guest(guestName, guestPhone));
			room[indexFloor][indexNum].setRoomStatus("예약중");
		}
		System.out.println(reserve[origin.length].toString());
	}
	
	// 예약 중복 확인
	public static boolean reserveCheck(LocalDate date, int roomNo) {
		for (int i = 0; i < reserve.length; i++) {
			if (reserve[i].getReserveDate().isEqual(date) && reserve[i].getReserveRoomNo() == roomNo) {
				System.out.println("이미 예약된 방입니다.");
				System.out.println("다시 예약해주세요.");
				return false;
			} 
		}
		return true;
	}
	
	// 날짜 범위 확인
	public static boolean dateCheck(int input) {
		int year = 2000 + (input / 10000);
		int month = input % 10000 / 100;
		int day = input % 100;
		if ((today.getYear() <= year && year <= today.getYear() + 1) 
				&& (1 <= month && month <= 12)) {
			LocalDate date = LocalDate.of(year, month, 1);
			int lengthOfMonth = date.lengthOfMonth();
			if (1 <= day && day <= lengthOfMonth) {
				date = LocalDate.of(year, month, day);
				if (!today.isAfter(date)) {
					return true;
				}
			}
		}
		return false;
	}
	
	// 예약 내역 보기(날짜선택)
	public static void reserveInputDate(LocalDate date) {
		System.out.println(date);
		for (int i = 0; i < reserve.length; i++) {
			if (date.equals(reserve[i].getReserveDate())) {
				System.out.println(reserve[i].toString());
			}
		}
		System.out.println("(○:예약가능  X:예약완료)");
		int roomNum = 0;
		for (int r = 0; r < reserve.length; r++) {
			if (date.equals(reserve[r].getReserveDate())) { // 입력날짜와 같은 예약이 존재할때 그 예약의 방번호 구하기
				roomNum = reserve[r].getReserveRoomNo();
			} 
		}
		for (int i = 0; i < room.length; i++) {
			for (int j = 0; j < room[i].length; j++) {
				if (room[i][j].getRoomNo() == roomNum) {
					System.out.print(room[i][j].getRoomNo() + ":" + booking2 + "  ");
				} else {
					System.out.print(room[i][j].getRoomNo() + ":" + booking1 + "  ");
				}
			}
			System.out.println();
		}
	}
	
	
	// 예약 내역 보기(방선택)
	public static void reserveInputRoom(int num) {
		for (int i = 0; i < reserve.length; i++) {
			if (reserve[i].getReserveRoomNo() == num) {
				System.out.println(reserve[i].toString());
			} 
		}
		System.out.println("(○:예약가능  X:예약완료)");
		
		
		for (int j = 0; j < 30; j++) {
			LocalDate date = today.plusDays(j);
			LocalDate reservedDate = LocalDate.of(2022, 1, 1);

			if (reserve.length == 0) {
				System.out.print(date + ":" + booking1 + "  ");
			}
			
			for (int i = 0; i < reserve.length; i++) {
				if (reserve[i].getReserveRoomNo() == num) {
					reservedDate = reserve[i].getReserveDate();
				} 
				if (date.equals(reservedDate)) {
					System.out.print(date + ":" + booking2 + "  ");
					j++;
					
				} else {
					System.out.print(date + ":" + booking1 + "  ");
				}
			} // 논리오류
			if ((j + 1) % 5 == 0) {
				System.out.println();
			}
		}
	}

	
	// 체크인(현재 방 상태 변경: 예약중, 빈방 -> 체크인)(이름입력)
	public static void checkInName(String name) {
		for (int i = 0; i < reserve.length; i++) {
			if (reserve[i].getGuestName().equals(name)) {
				int roomNum = reserve[i].getReserveRoomNo();
				int indexFloor = roomNum / 100 - 2; 
				int indexNum = roomNum % 100 - 1;
				room[indexFloor][indexNum].setRoomStatus("체크인");
				System.out.println("체크인 완료");
			} else {
				System.out.println("예약내역이 없습니다.");
			}
		}
	}
	
	// 체크인(룸넘버)
	public static void checkInRoom(int roomNum) {
		int indexFloor = roomNum / 100 - 2; 
		int indexNum = roomNum % 100 - 1;
		
		room[indexFloor][indexNum].setRoomStatus("체크인");
		System.out.println(room[indexFloor][indexNum].toString());
		System.out.println("체크인 완료");
		
		
	}

	// 체크아웃(현재 방 상태 변경: 체크인 -> 체크아웃)
	public static void checkOut(int roomNum) {
		int indexFloor = roomNum / 100 - 2; 
		int indexNum = roomNum % 100 - 1;
		room[indexFloor][indexNum].setRoomStatus("빈방");
		room[indexFloor][indexNum].setGuest(new Guest("", ""));
		System.out.println(room[indexFloor][indexNum].toString());
		System.out.println("체크아웃 완료");
	}
	
	// 객실 정보 보기
	public static void showRoomInformation() {
		for (int i = 0; i < room.length; i++) {
			System.out.println((i + 2) + "층");
			for (int j = 0; j < room[i].length; j++) {
				System.out.println(room[i][j].toString());
			}
		}
	}

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		// 예약 배열 생성
		reserve = new Reserve[0];
		// 룸 초기화
		roomSet();
	
		boolean go = true;
		while (go) {
			System.out.println("=============");
			System.out.printf("1.현재 객실 보기 \n2.예약하기\n3.예약 내역 보기\n4.체크인\n5.체크아웃\n6.객실 정보 보기\n0.프로그램 종료\n");
			System.out.println("=============");
			System.out.print("번호 입력: ");
			int user = scan.nextInt();
			System.out.println("=============");
			switch (user) {
			case 1:
				System.out.println("[현재 객실 보기]");
				showRoomStatus();
				break;
			case 2: 
				System.out.println("[예약하기]");
				// 날짜입력
				System.out.print("*날짜입력(6자리숫자): ");
				LocalDate inputDate = today;
				boolean dateGo = true;
				while (dateGo) { // 범위벗어날때 확인하기
					int date = scan.nextInt();
					if (dateCheck(date)) {
						int year = 2000 + (date / 10000);
						int month = date % 10000 / 100;
						int day = date % 100;
						inputDate = LocalDate.of(year, month, day);
						dateGo = false;
					} else {
						System.out.print("*다시입력해주세요(6자리숫자): ");
					}
				}
				// 방선택
				System.out.println("*방선택(홀수:싱글룸/짝수:더블룸)");
				System.out.print("-방번호 입력(201~520): ");
				int inputRoomNo = 0;
				boolean roomGo = true;
				while(roomGo) {
					inputRoomNo = scan.nextInt();
					int roomFloor = inputRoomNo / 100; 
					int roomNum = inputRoomNo % 100;
					if (2 <= roomFloor && roomFloor <= 5 && 0 < roomNum && roomNum <= 20) {
						roomGo = false;
					} else {
						System.out.print("다시입력해주세요(201~520): ");
					}
				}
				// 중복확인
				if (reserveCheck(inputDate, inputRoomNo)) {
					// 예약자 정보
					System.out.println("*예약자 정보 입력");
					System.out.print("-이름: ");
					String inputName = scan.next();
					System.out.print("-폰번호: ");
					String inputPhone = scan.next();
					// 예약
					reservation(new Reserve(inputDate, inputRoomNo, inputName, inputPhone), reserve);
				}
				break;
			case 3: 
				System.out.println("[예약 내역 보기]");
				System.out.println("1.날짜선택  2.방선택");
				System.out.print("번호 입력: ");
				int input = scan.nextInt();
				if (input == 1) {
					System.out.print("*날짜입력(6자리숫자): ");
					int date = scan.nextInt();
					if (dateCheck(date)) {
						int year = 2000 + (date / 10000);
						int month = date % 10000 / 100;
						int day = date % 100;
						inputDate = LocalDate.of(year, month, day);
						reserveInputDate(inputDate);
					} else {
						System.out.println("잘못된 입력입니다.");
					}
				} else if (input == 2) {
					System.out.print("*방번호 입력(201~520): ");
					int input2 = scan.nextInt();
					reserveInputRoom(input2);
				} else {
					System.out.println("잘못된 입력입니다.");
				}
				break;
			case 4: 
				System.out.println("[체크인]");
				System.out.println("1.예약자이름입력하기  2.방번호입력하기");
				System.out.print("번호 입력: ");
				int checkIn = scan.nextInt();
				if (checkIn == 1) {
					System.out.print("이름 입력: ");
					checkInName(scan.next());
				} else if (checkIn == 2) {
					System.out.print("방번호 입력(201~520): ");
					checkInRoom(scan.nextInt());
				} else {
					System.out.println("잘못된 입력입니다.");
				}
				break;
			case 5: 
				System.out.println("[체크아웃]");
				System.out.print("방번호 입력(201~520): ");
				checkOut(scan.nextInt());
				break;
			case 6: 
				System.out.println("[객실 정보 보기]");
				showRoomInformation();
				break;
			default:
				System.out.println("[프로그램 종료]");
				go = false;
				break;
			}
		}
	}
}