헬린코린이

Third Project 본문

Project/Team Project

Third Project

HCD 2022. 12. 6. 16:47
package hirdproject;

import java.util.ArrayList;
import java.util.Scanner;

public class finall {
    static int NUM = 101; // 음료에 들어갈 PK값. 101부터 시작
    static final int PW = 1234; // 관리자 비밀번호 // removeDrink()에서 사용
    
    public static void main(String[] args) {
        ArrayList<Drink> datas = new ArrayList<>(); // 메뉴판
        
        setMenus(datas);

        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("=============================");
            System.out.println("=============================");
            System.out.println("========= JAVApresso ========");
            System.out.println("=============================");
            System.out.println("=============================");
            System.out.println();
            System.out.println("1. 매장  | 2. 포장"); // 관리자 모드: 1234 입력
            System.out.print("입력 > ");
            int act = sc.nextInt();

            if (act == 1 || act == 2) { // 사용자 모드: 매장 혹은 포장
                // 커피/에이드 주문
                orderDrink(datas, act);
                System.out.println();
            } else if (act == PW) { // 관리자 모드: 비밀번호 1234
                while (true) {
                    System.out.println();
                    System.out.println("**** 관리자 모드 ****");
                    System.out.println("1. 재고 목록 보기");
                    System.out.println("2. 재고 수정");
                    System.out.println("3. 음료 품목 삭제");
                    System.out.println("4. 음료 품목 추가");
                    System.out.println("5. 관리자 모드 종료");
                    System.out.println("********************");
                    
                    System.out.print("입력 > ");
                    act = sc.nextInt();

                    // 입력값 유효성 검사

                    System.out.println();
                    if (act == 1) {
                        showMenus(datas); // 목록출력
                    } else if (act == 2) {
                        setStock(datas); // 재고 수정
                    } else if (act == 3) {
                        removeDrink(datas); // 음료 품목 삭제
                    } else if (act == 4) {
                        addDrink(datas); // 음료 품목 추가
                    } else if (act == 5) { // 관리자 모드 종료
                        System.out.println("관리자 모드를 종료합니다.");
                        break;
                    } else {
                        System.out.println("선택지 1 ~ 5 중 선택!");
                    }
                }

            } else {
                System.out.println("매장 또는 포장을 선택해주세요");
            }
        }
    }

    private static void addDrink(ArrayList<Drink> datas) {
        Scanner sc = new Scanner(System.in);

        System.out.println("* 품목 추가 *");

        int drinkType; // 커피/에이드 선택
        while (true) {
            System.out.println("1. 커피, 2. 에이드");
            System.out.println("입력 > ");
            drinkType = sc.nextInt();
            if(drinkType == 1 || drinkType == 2) {
                break;
            }
            System.out.println("잘못 입력하셨습니다. 다시 입력하세요.");
        }

        String name;
        while(true) {
            System.out.print("품목 이름 > ");
            name = sc.next();
            boolean isExist = false;
            for(Drink v : datas) {
                if(v.getName().equals(name)) {
                    isExist = true;
                    break;
                }
            }
            if(!isExist) {
                break;
            }
            System.out.println("이미 존재하는 메뉴입니다. 다시 입력하세요.");
        }
        
        int price;
        while(true) {
            System.out.print("가격 > ");
            price = sc.nextInt();
            if(price >= 1000) {
                break;
            }
            System.out.println("1000원 이상의 금액을 입력하세요.");
        }
        int count;
        while(true) {
            System.out.print("재고 > ");
            count = sc.nextInt();
            if(count > 0) {
                break;
            }
            System.out.println("1 이상의 재고 입력");
        }

        boolean isOnlyIced;
        while (true) { // OnlyIce 입력값 유효성 검사
            System.out.print("OnlyIce 여부(1.네, 2.아니오) > ");
            int onlyIce = sc.nextInt();

            if(onlyIce == 1){
                isOnlyIced = true;
                break;
            }
            else if(onlyIce == 2) {
                isOnlyIced = false;
                break;
            }
            System.out.println("잘못 입력하셨습니다. 다시 입력하세요.");
        }

        if(drinkType == 1) { // 커피 추가
            datas.add(new Coffee(name, price, NUM++, count, isOnlyIced));
        } else if(drinkType == 2) { // 에이드 추가
            datas.add(new Ade(name, price, NUM++, count, isOnlyIced));
        }

        System.out.println("* 추가 완료 *");
        System.out.println(datas.get(datas.size() - 1));
    }


    private static void removeDrink(ArrayList<Drink> datas) {
        Scanner sc = new Scanner(System.in);

        System.out.println("* 품목 삭제 *");

        Drink preDrink = null;

        // NUM 유효성 검사
        while(true) {
            showMenus(datas);
            System.out.print("번호 입력 > ");
            int num = sc.nextInt();
    
            preDrink = inputValidation(datas, num);

            if(preDrink != null) { // NUM 제대로 입력했을 경우
                break;
            }
            System.out.println("해당 NUM 없음. 다시 입력!!");
        }

        String targetName = preDrink.getName();
        System.out.println(targetName + "을(를) 정말 삭제하시겠습니까? (YES 입력시 삭제)");
        if(!sc.next().equals("YES")) { // YES 라고 입력하지 않았으면
            System.out.println("삭제가 취소되었습니다.");
            return; // removeDrink() 종료
        }

        System.out.print("관리자 비밀번호 입력 > "); 
        if(sc.nextInt() != PW) { // 입력값이 비밀번호와 일치하지 않은 경우
            System.out.println("※ 비밀번호가 틀렸습니다.");
            return;
        }

        datas.remove(preDrink);
        System.out.println();
        System.out.println("* " + targetName + " 품목 삭제 완료 *");
    }

    // 관리자 모드: 재고 수정
    private static void setStock(ArrayList<Drink> datas) {
        Scanner sc = new Scanner(System.in);

        System.out.println("* 재고 수정 *");

        Drink preDrink = null;
        
        // NUM 유효성 검사
        while(true) {
            showMenus(datas);
            System.out.print("번호 입력 > ");
            int num = sc.nextInt();
    
            preDrink = inputValidation(datas, num);

            if(preDrink != null) { // NUM 제대로 입력했을 경우
                break;
            }
            System.out.println("해당 NUM 없음. 다시 입력!!");
        }

        int count;
        while(true) {
            System.out.print("재고 > ");
            count = sc.nextInt();
            
            if(count >= 0) { // 0 이상의 정수 입력시
                break;
            }
            System.out.println("다시 입력해주세요.(0 이상의 정수만 입력)");
        }
        
        preDrink.setCount(count);

        System.out.println("* " + preDrink.getName() + "의 재고가 " + preDrink.getCount() + "잔으로 변경됨 *");
    }

    // 기본 메뉴 세팅하는 함수
    private static void setMenus(ArrayList<Drink> datas) {
        /*
         * 기본메뉴
         * M (L = M+1000)
         * 아메리카노 2000
         * 카페라떼 3000
         * 레몬에이드 4000
         * 자몽에이드 4000
         */
        datas.add(new Coffee("아메리카노", 2000, NUM++, 5, false)); // 아메리카노 추가
        datas.add(new Coffee("카페라떼", 3000, NUM++, 5, false)); // 카페라떼 추가
        datas.add(new Ade("레몬에이드", 4000, NUM++, 5, true)); // 레몬에이드 추가
        datas.add(new Ade("자몽에이드", 4000, NUM++, 5, true)); // 자몽에이드 추가
    }

    // 메뉴 보여주는 함수
    private static void showMenus(ArrayList<Drink> datas) {
        System.out.println();
        for (Drink v : datas) {
            System.out.println(v);
        }
        System.out.println("--------------------------------------");
    }

    // 사용자가 음료를 주문
    private static void orderDrink(ArrayList<Drink> datas, int act) {
        Scanner sc = new Scanner(System.in);

        Drink preDrink = null;

        // NUM 값 유효성 검사
        while (true) {
            // 메뉴 보여주기
            showMenus(datas);

            System.out.print("번호 입력 > ");
            int num = sc.nextInt();

            preDrink = inputValidation(datas, num); // NUM값 유효성 검사

            if (preDrink != null) { // 제대로 선택했으면 while 탈출
                break;
            }
            System.out.println(num + " 에 해당하는 음료 없음! 다시 입력해주세요");
        }

        // 재고 확인. (현재 1잔만 주문가능하므로) 재고가 1보다 작을 시 orderDrink() 함수 종료
        if (preDrink.getCount() < 1) {
            System.out.println(preDrink.getName() + "의 재고가 부족합니다.");
            return;
        }

        // 재고가 있는 경우
        // 1. 매장, 2. 포장
        preDrink.setTogo(false);
        if(act == 2) {
            preDrink.setTogo(true);
        }

        // 옵션 선택
        choiceOption(preDrink); // 커피인 경우: 사이즈, hot/ice 선택
                                // 에이드인 경우: 사이즈 선택

        System.out.println("결제하시겠습니까? \"YES\" 입력");
        System.out.println("취소시 처음으로 돌아갑니다.");
        String ans = sc.next();

        if (!ans.equals("YES")) {
            System.out.println("결제 취소되었습니다.");
            return;
        }

        // 결제 금액(할인 적용 금액)
        int result = preDrink.sell();

        System.out.println((preDrink.isCold() ? "ICE" : "HOT") + " " + preDrink.getName() + " " + preDrink.getSize() + " " + result + "원 결제되었습니다.");
        preDrink.setSize('M'); // 다시 사이즈 M으로 set
        
        System.out.println();
        preDrink.smells(); 
        System.out.println();
    }

    // 입력값 int act 유효성 검사. 존재하지 않는 값인 경우 null 반환
    private static Drink inputValidation(ArrayList<Drink> datas, int num) {
        // num 값 유효성 검사.
        Drink preDrink = null; // 선택된 음료
        for (Drink v : datas) {
            if (v.getNUM() == num) { // 입력받은 num값과 맞는 NUM이 있으면
                preDrink = v; // 그 드링크를 preDrink에 대입
                break;
            }
        }
        return preDrink;
    }

    // 옵션 선택 함수. orderDrink() 함수 안에서 쓰임
    private static void choiceOption(Drink preDrink) {
        Scanner sc = new Scanner(System.in);

        // 커피 = 사이즈, hot/ice
        // 에이드 = 사이즈
        // if(isCold)

        System.out.println("--- 옵션 선택 ---");

        while (true) { // 옵션 유효성 검사: 사이즈
            System.out.println("* 사이즈 선택 *");
            System.out.println("1. M 사이즈");
            System.out.println("2. L 사이즈 (1000원 추가됩니다.)");
            System.out.print("입력 > ");
            int act = sc.nextInt(); // 1. M, 2. L

            if (act == 1) {
                preDrink.setSize('M');
                //System.out.println(" 로그 : M사이즈 선택");
                break;
            } else if (act == 2) {
                preDrink.setSize('L');
                //System.out.println(" 로그 : L사이즈 선택");
                break;
            } else {
                System.out.println("사이즈 선택(1 또는 2): 다시 입력하세요.");
            }
        }

        System.out.println();

        if (!preDrink.isOnlyIced()) { // 뜨/아 고를수 있는 경우 == 에이드가 아닌 경우 => 커피인 경우
            // 커피인 경우 핫/아이스 선택
            while (true) { // 옵션 유효성 검사: HOT/ICE
                System.out.println("* HOT/ICE 선택 :");
                System.out.println("1. HOT");
                System.out.println("2. ICE");
                System.out.print("입력 > ");
                int act = sc.nextInt();

                if (act == 1) {
                    preDrink.setCold(false);
                    break;
                } else if (act == 2) {
                    preDrink.setCold(true);
                    break;
                } else {
                    System.out.println("HOT/ICE 선택(1 또는 2): 다시 입력하세요.");
                }
            }
        }
    }
}

//최상위 클래스: Drink
abstract class Drink {
 private String name; // 음료의 이름. ex) 아메리카노, 카페라떼, 레몬에이드, 등등...
 private int price;  // 음료 가격. L 사이즈가 M 사이즈보다 1000원 비쌈
 private int NUM;    // PK. [101] 아메리카노, [102] 라떼, ...
 private int count; // 음료의 재고
 // 손님이 선택해야 할 사항
 private boolean isTogo; // 테이크아웃 여부. 포장일 시 true, 매장일 시 false
 private boolean isCold; // hot/ice 선택
 private boolean isOnlyIced; // 아이스만 있는 경우(핫 없음) true. 
 private char size; // M, L 중 선택

 private static final int TOGO_DISCOUNT = 500; // TOGO_DISCOUNT : 유지 보수를 위해 선언.

 public String getName() {
     return name;
 }

 public void setName(String name) {
     this.name = name;
 }

 public int getPrice() {
     return price;
 }

 public void setPrice(int price) {
     this.price = price;
 }

 public int getNUM() {
     return NUM;
 }

 public void setNUM(int nUM) {
     NUM = nUM;
 }

 public int getCount() {
     return count;
 }

 public void setCount(int count) {
     this.count = count;
 }

 public boolean isTogo() {
     return isTogo;
 }

 public void setTogo(boolean isTogo) {
     this.isTogo = isTogo;
 }

 public boolean isCold() {
     return isCold;
 }

 public void setCold(boolean isCold) {
     this.isCold = isCold;
 }

 public char getSize() {
     return size;
 }

 public void setSize(char size) {
     this.size = size;
 }

 public boolean isOnlyIced() {
     return isOnlyIced;
 }

 public void setOnlyIced(boolean isOnlyIced) {
     this.isOnlyIced = isOnlyIced;
 }

 abstract void smells(); // Ade, Coffee 클래스에서 오버라이딩 할 추상메서드. Ade는 향긋한 향, Coffee는 고소한 향

 // 할인, 사이즈 반영해 최종 결제 금액 리턴
 int sell() { 
     int result = this.price;

     if(this.isTogo) { // 포장일 시 500원 할인
         result -= Drink.TOGO_DISCOUNT;
     }
     if(this.size == 'L') { // L 사이즈일 시 +1000원
         result += 1000;
     }

     // 재고 수정
     this.count -= 1;

     return result;
 }

 Drink(String name, int price, int NUM, int count, boolean isOnlyIced) {
     this.name = name;
     this.price = price; // 기본 가격: M 사이즈 음료 가격.
     this.NUM = NUM;
     this.count = count;
     this.isTogo = false; // 테이크아웃 여부 기본값: 매장
     this.isCold = false;
     this.size = 'M' ; // 기본 사이즈: M
     this.isOnlyIced = isOnlyIced; // 아이스만 되는 메뉴
 }

 @Override
 public String toString() { // toString 오버라이드. ex. [101] 아메리카노 L사이즈 3000원 (재고 5잔)
     return "[" + this.NUM + "] " + this.name + "  " + this.size + "사이즈 " + this.price + "원 (재고 " + this.count + "잔)";
 }

 @Override
 public boolean equals(Object obj) {
     if(obj instanceof Drink) {
         Drink drink = (Drink) obj;
         if(this.NUM == drink.NUM) {
             return true;
         }
         return false;
     }
     return false;
 }
}

//추상 클래스 Drink를 상속받는 Coffee 클래스
class Coffee extends Drink {
 @Override 
 void smells() { // 추상 클래스 Drink에 선언되어 있던 추상 메서드 smells(). 커피의 경우, ex) "아메리카노 냄새가 고소하게 풍긴다." 출력
     System.out.println("~~" + this.getName() + " 냄새가 고소하게 풍긴다.~~");
 } // 동적 바인딩
 
 Coffee(String name, int price, int NUM, int count, boolean isOnlyIced) {
     super(name, price, NUM, count, isOnlyIced);
 }
}

//추상 클래스 Drink를 상속받는 Ade 클래스
class Ade extends Drink {
 @Override
 void smells() { // 추상 클래스 Drink에 선언되어 있던 추상 메서드 smells(). 에이드의 경우, ex) "레몬에이드의 향긋한 냄새가 난다." 출력
     System.out.println("~~" + this.getName() + "의 향긋한 냄새가 난다.~~");
 } // 동적 바인딩

 Ade(String name, int price, int NUM, int count, boolean isOnlyIced) {
     super(name, price, NUM, count, isOnlyIced);
 }
}
Comments