주차관리 시스템

|
import java.util.Scanner;

public class park {
	private String carNum;
	private int inTime;
	private int outTime;

// 빈칸에 차량번호를 Empty 로 정해줌으로써 
// 빈칸찾기를 할때 carNum String이 
// Empty인지 비교해준다. 

	private Park() {
		this.carNum = "Empty";
		this.inTime = 0;
		this.outTime = 0;
	}

	private Park(String carNum, int inTime) {
		this.carNum = carNum;
		this.inTime = inTime;
	}

	private Park(Park park) {
		this.carNum = park.carNum;
		this.inTime = park.inTime;
	}

// 파크 배열을 준비하고 메뉴를 보여주는 showMenu 
// 메소드를 실행한다. 
	public static void init() {
		int size = 3;
		Park[] parkList = new Park[size];
		for (int i = 0; i < parkList.length; i++) {
			parkList[i] = new Park();
		}
		showMenu(parkList);
	}

// 무한루프로 메뉴를 보여주고 
// 사용자의 선택에 따라서 
// 입차를 담당하는 method, 
// 출차를 담당하는 method, 
// 종료를 선택할 수 있게 한다. 
	private static void showMenu(Park[] parkList) {
		Scanner scan = new Scanner(System.in);
		while (true) {
			System.out.println("=========================");
			System.out.println("주차장관리프로그램");
			System.out.println("=========================");
			System.out.println("1. 입차 2. 출차 3. 종료");
			System.out.print("선택: ");
			int choice = scan.nextInt();
			if (choice == 3) {
				System.out.println("사용해주셔서 감사합니다.");
				break;
			} else if (choice == 1) {
				startPark(parkList, scan);
			} else if (choice == 2) {
				endPark(parkList, scan);
			} else {
				System.out.println("잘못 누르셨습니다.");
			}
		}
		scan.close();
	}

// 입차를 시작하는 메소드 
	private static void startPark(Park[] parkList, Scanner scan) {
// 먼저 빈 공간이 존재하는지 체크하고 
// 빈 공간이 존재하면 입고를 시작한다. 
		if (checkEmptySpot(parkList)) {
//Park의 객체 newCar를 insertCarNum 메소드와 insertInTime 메소드에서  
//각각 받아온 유효한 String carNum과 int inTime을 이용하여 초기화한다. 
//초기화 시에는 parameter가 있는 생성자로 초기화 해준다. 
			Park newCar = new Park(insertCarNum(parkList, scan), insertInTime(scan));
//park 배열인 parkList의 빈 공간에 윗줄에서 생성된 newCar를 넣어준다. 
			insertPark(newCar, parkList);

		} else {
// 빈 공간이 존재하지 않으므로 사용자에게 알려주고 
// 메뉴로 돌아간다. 
			System.out.println("자리가 꽉찼습니다.");
		}
	}

// 배열을 돌면서 carNum이 empty인 곳이 있는지 찾는다 
	private static boolean checkEmptySpot(Park[] parkList) {
		boolean isEmpty = false;
		for (int i = 0; i < parkList.length; i++) {
//해당 칸의 carNum 이 Empty, 즉 빈 공간이므로 
//isEmpty 를 true로 바꿔주고 break를 통해 
//for 반복문을 종료한다. 
			if (parkList[i].carNum.equals("Empty")) {
				isEmpty = true;
				break;
			}
		}
		return isEmpty;
	}

// 차량 번호가 입고된 기록이 있는지 체크해서 
// 없으면 해당 번호를 리턴해주고 
// 있으면 계속 루프를 돌면서 입력을 받는다. 
	private static String insertCarNum(Park[] parkList, Scanner scan) {
		scan.nextLine();
		System.out.print("차량 번호를 입력해 주세요: ");
		String carNum = scan.nextLine();
//입력받은 carNum을 validateCarNum 메소드를 통해서 
//이미 입고된 번호인지를 체크를 하여 
//입고가 된 기록이 없는 번호가 들어올 때까지 
//사용자에게 입력을 요구한다. 
		while (validateCarNum(carNum, parkList)) {
			System.out.println("이미 입고된 차량입니다.");
			System.out.print("차량 번호를 다시 입력해 주세요: ");
			carNum = scan.nextLine();
		}
//while문을 통과하면 carNum이 중복된 번호가 아니므로 
//리턴하여 Park(String, int) 의 String으로 쓸 수 있게 한다. 
		return carNum;
	}

// 입력한 carNum이 입고된 기록이 있는지 확인한다. 
	private static boolean validateCarNum(String carNum, Park[] parkList) {
		boolean isAlreadyIn = false;
		for (int i = 0; i < parkList.length; i++) {
//배열을 돌면서 parameter로 넘어온 carNum이 
//해당 칸의 carNum과 같을 시에는 
//중복된 번호 이므로 isAlreadyIn을 true로 바꾸고 
//리턴해준다. 
			if (parkList[i].carNum.equals(carNum)) {
				isAlreadyIn = true;
				break;
			}
		}
		return isAlreadyIn;
	}

// 시간을 입력받아 유효한 시간을 리턴해준다. 
	private static int insertInTime(Scanner scan) {
		System.out.print("입고 시간을 입력해주세요: ");
		int inTime = scan.nextInt();
//입력받은 inTime을 validateTime 메소드로  
//올바른 시간인지 확인한다. 
//단 validateTime 메소드가 올바른 시간인 경우 
//true를 리턴하므로 반전연산자인 ! 연산자를 붙여서 
//true는 false로, false는 true로 반전시켜서 
//잘못 입력된 시간일 경우에만 while 반복문에 들어가게 한다. 
		while (!validateTime(inTime)) {
			System.out.println("잘못된 시간 형식입니다.");
			System.out.print("입고 시간을 입력해주세요: ");
			inTime = scan.nextInt();
		}
		return inTime;
	}

// 시간이 올바른 형태인지 확인하는 메소드 
	private static boolean validateTime(int inTime) {
		boolean isTimeCorrect = false;

//4자리 숫자가 넘어 올시 
//앞의 두자리와 뒤의 두자리를 분리하려면 
//앞의 두자리는 100으로 나눈 값을, 
//뒤의 두자리는 100으로 나눈 나머지 값을 
//넣어준다. 
//앞의 두자리는 시간이, 뒤의 두자리는 분이 된다. 
		int hour = inTime / 100;
		int min = inTime % 100;

//시간과 분이 유효한지 체크한다. 
//시간은 0~23, 분은 0~59 만 유효하기 때문에 
//&& 연산을 통해 hour는 -1보다 크고 24 보다 작은(0~23) 경우에만 
//분은 -1보다 크고 60보다 작은(0~59) 경우를 모두 만족할 때에만 
//isTimeCorrect를 true로 바꾼다. 
		if (hour > -1 && hour < 24 && min > -1 && min < 60) {
			isTimeCorrect = true;
		}
		return isTimeCorrect;
	}

//차량을 입고하는 메소드 
	private static void insertPark(Park newCar, Park[] parkList) {
		for (int i = 0; i < parkList.length; i++) {
//parameter로 넘어온 newCar를 parkList의 요소 중에서 carNum이 
//Empty 인 곳에 넣는다. 
			if (parkList[i].carNum.equals("Empty")) {
				parkList[i] = newCar;
//단 여기서 넣자마자 break를 해야하는데 
//break가 없으면 넣은 이후에도 반복 되면서 
//모든 빈칸에 newCar를 넣기 때문에 
//1번만 실행해도 모든 칸이 다 꽉차서 
//더이상 주차를 할 수 없게 된다. 
				break;
			}
		}
	}

// 차량 출고 메소드의 시작지점. 
	private static void endPark(Park[] parkList, Scanner scan) {
// 주차장이 비어있는지 확인한다. 
		if (checkParkExist(parkList)) {
// 주차된 차량이 1대라도 존재하므로 차량 번호를 통해 
// 해당 차량의 정보를 받아온다. 
			Park outCar = new Park(retrievePark(parkList, scan));
// 차량의 출차시간을 기록한다. 
			outCar.outTime = insertOutTime(outCar, scan);
// 요금 계산 
			calcRate(outCar);
// 나간 차량의 자리를 비어준다. 
			removeOutCar(parkList, outCar);
		} else {
// 주차된 차량이 없으므로 사용자에게 메시지를 띄우고 
// 메뉴로 돌아간다. 
			System.out.println();
			System.out.println("주차된 차량이 없습니다.");
			System.out.println();
		}
	}

// 주차장이 비어있는지 확인하는 메소드 
	private static boolean checkParkExist(Park[] parkList) {
		boolean isExist = false;
// parkList 배열을 쭉 돌면서 carNum이 "Empty"가 아닌 
// 요소가 존재하는지를 찾는다. 
		for (int i = 0; i < parkList.length; i++) {
			if (!parkList[i].carNum.equals("Empty")) {
				isExist = true;
			}
		}
		return isExist;
	}

// 입고된 차량의 정보를 받아오는 메소드 
	private static Park retrievePark(Park[] parkList, Scanner scan) {
		scan.nextLine();
		Park outCar = new Park();
		System.out.print("출고할 차량번호를 입력해주세요: ");
		String carNum = scan.nextLine();
// validateCarNum 메소드를 통해서 입력한 차량 번호가 
// 리스트에 없으면 없다고 말해주고 다시 입력하라고 
// 사용자에게 지시한다. 
		while (!validateCarNum(carNum, parkList)) {
			System.out.println("입고된 기록이 없는 번호입니다.");
			System.out.print("출고할 차량번호를 다시 입력해주세요: ");
			carNum = scan.nextLine();
		}
// while문을 통과할 시에는 해당 번호가 리스트에 존재하므로 
// 그 번호와 같은 parkList의 요소를 outCar에 담아서 
// 리턴해준다. 
		for (int i = 0; i < parkList.length; i++) {
			if (parkList[i].carNum.equals(carNum)) {
				outCar = parkList[i];
			}
		}
		return outCar;
	}

// 출고 시간을 저장하는 메소드 
	private static int insertOutTime(Park outCar, Scanner scan) {
		System.out.print("출고 시간을 입력해주세요: ");
		int outTime = scan.nextInt();
// 출고 시간이 올바른 형태인지 확인하고 
// 올바른 형태가 아니면 다시 입력하라고 
// 사용자에게 시킨다. 
		while (!validateTime(outCar, outTime)) {
			System.out.println("잘못된 시간 형식입니다.");
			System.out.print("출고 시간을 입력해주세요: ");
			outTime = scan.nextInt();
		}
		return outTime;
	}

// 출고 시간이 유효한지 체크하는 메소드 
	private static boolean validateTime(Park outCar, int outTime) {
		boolean isOutTimeCorrect = false;
// 아까 전 inTime의 유효성을 체크했던 메소드로 outTime도 
// 체크를 하고 거기에 && 연산자를 통해서 outTime이 outCar에 
// 저장된 inTime보다 큰지도 같이 확인한다. 
		if (validateTime(outTime) && outTime > outCar.inTime) {
			isOutTimeCorrect = true;
		}
		return isOutTimeCorrect;
	}

// 요금을 계산하는 메소드 
	private static void calcRate(Park outCar) {
// 시간의 차이를 계산한다 
		int hourDiff = outCar.outTime / 100 - outCar.inTime / 100;
// 분의 차이를 계산한다. 
		int minDiff = outCar.outTime % 100 - outCar.inTime % 100;

// 총 분의 시간을 계산하고 10분당 1000원으로 계산한 후 
// 출력한다. 
		int totDiff = hourDiff * 60 + minDiff;
		int rateStd = 1000;
		int rate = totDiff / 10 * rateStd;
		System.out.println("총 주차요금은 " + rate + "원입니다.");
	}

// 나간 차의 자리를 비어주는 메소드 
	private static void removeOutCar(Park[] parkList, Park outCar) {
// parkList 배열을 돌면서 해당 칸의 carNum이 
// outCar(나가는 차)의 번호와 같으면 
// 해당칸에 기본 생성자를 호출해서 
// carNum은 "Empty", inTime과 outTime은 0으로 초기화해준다. 
		for (int i = 0; i < parkList.length; i++) {
			if (parkList[i].carNum.equals(outCar.carNum)) {
				parkList[i] = new Park();
			}
		}

	}
}

'Java' 카테고리의 다른 글

유효범위  (0) 2019.05.23
객체 지향 프로그래밍  (0) 2019.05.21
예약어  (0) 2019.05.19
반복문  (0) 2019.05.17
배열  (0) 2019.05.17
And