재밌고 어려운 IT를 이해해보자~!

CRUD설계 후 진행한 Team Project 본문

PROJECT

CRUD설계 후 진행한 Team Project

언제나즐거운IT 2023. 12. 13. 23:29

구매로직2개와 관리자기능이 있는 프로그램을 제작하는 프로젝트를 하게되었다!

관리자, 유저로 나뉘며 각각의 CRUD는 다음과 같다.

관리자 --

C - 선수추가

U - 선수 정보 변경

D - 선수 삭제

 

유저 --

R - 가격별 출력 

R - 능력치별 출력

R - 포지션별 출력

R - 검색기능

U - 구매

 

내가 맡은 부분은 선수 구매부분의 로직이다!

정렬을 한 후에 출력을 상태에서 유저입장에서 구매하기 쉽게 1 ~ list.size() 까지의 번호를 부여해주고 싶었는데

정렬을 한 후라서 생각보다 쉽지않았다.

생각을 하던중 나온 결론은 원본 객체리스트를 놔두고 새로운 객체리스트를 만들어서 인덱스대로 출력을 해주는 방법이 있었고 또하나는 출력을 하고 구매를 하는 과정에서 서브인덱스를 잠시동안 부여해주는 것 이었다!

 

이 서브인덱스는 축구선수 객체를 생성하면 -1로 초기화가 되고 축구선수를 정렬 후에 출력할때 출력 순서에 맞게 1부터 size()까지 서브인덱스가 일시적으로 부여된다. 그럼 유저는 그 서브인덱스를 선택해서 선수를 구매 할 수 있고  구매가 끝나면 서브인덱스는 모두 다시 -1로 초기화된다. 

 

단점으로는 서브인덱스라는 객체와 관계없는 멤버변수가 선언되지만, 정렬을 할때마다 새로운객체리스트를 생성하지 않아도 되어서 메모리를 아낄 수 있다! 

결론적으로는 채택되지 않은 아이디어지만, 그래도 잘 생각했던 것 같아서 포스팅 해본다 :D

 

이번팀프로젝트를 진행할때 팀원 한분이 전체적인 틀을 구성해주셨는데 와전 모듈화도 잘되어있고 유효성검사도 편하게 작성을 해주셨다. 처음엔 생소한 엄청난  모듈화였지만 그 틀에 맞춰서 코드를 작성하다보니 하나둘씩 눈에보이고 훨씬 깔끔해보이는 코드같았다! 

개인적으로 모듈화에대해서 많은 생각을 갖게된 프로젝트였다.

 

SubIndex를 사용한 출력코드

package fifaOnline;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;
class FootballPlayer {
	private int pk; // PK
	private String name;
	private String position;
	private int totalPower;
	private int price;
	private int ea;
	private int subIdx; // 가격,파워,포지션 별로 출력할때 유저가 구매할 번호 인덱스를 임시부여
 
 

	// 선수 생성시 default subIdx -1 로설정 
	FootballPlayer(int pk, String name, String position, int totalPower, int price, int ea) {
		this(pk, name, position, totalPower, price, ea, -1);
	}
	FootballPlayer(int pk, String name, String position, int totalPower, int price, int ea, int subIdx) {
		this.pk = pk;
		this.name = name;
		this.position = position;
		this.totalPower = totalPower;
		this.price = price;
		this.ea = ea;
		this.subIdx = subIdx;
	}
	public int getPk() {
		return pk;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPosition() {
		return position;
	}
	public void setPosition(String position) {
		this.position = position;
	}
	public int getTotalPower() {
		return totalPower;
	}
	public void setTotalPower(int totalPower) {
		this.totalPower = totalPower;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public int getEa() {
		return ea;
	}
	public void setEa(int ea) {
		this.ea = ea;
	}
	public int getSubIdx() {
		return subIdx;
	}
	public void setSubIdx(int subIdx) {
		this.subIdx = subIdx;
	}
	@Override // 유저한테 PK 안보이도록 설정
	public String toString() {
		if (FootballMarket.checkManageMode) {
			return "FootballPlayer [pk=" + pk + ", name=" + name + ", position=" + position + ", totalPower="
					+ totalPower + ", price=" + price + ", ea=" + ea + "]";
		} else {
			return "FootballPlayer [name=" + name + ", position=" + position + ", totalPower=" + totalPower + ", price="
					+ price + ", ea=" + ea + "]";
		}
	}
	public void sell() {
		this.ea--;
		System.out.println(this.name + " 구매완료!");
	}
	// 삽입정렬을 사용해서 모듈화하려고 했으나 어려워서 익명객체(클래스), Comparator, sort 기능 활용...
	public static Comparator<FootballPlayer> byPrice = new Comparator<FootballPlayer>() {
		@Override
		public int compare(FootballPlayer p1, FootballPlayer p2) {
			return p1.price - p2.price;
		}
	};
	public static Comparator<FootballPlayer> byTotalPower = new Comparator<FootballPlayer>() {
		@Override
		public int compare(FootballPlayer p1, FootballPlayer p2) {
			return p1.totalPower - p2.totalPower;
		}
	};
	public static Comparator<FootballPlayer> byPk = new Comparator<FootballPlayer>() {
		@Override
		public int compare(FootballPlayer p1, FootballPlayer p2) {
			return p1.pk - p2.pk;
		}
	};
	public static Comparator<FootballPlayer> byName = new Comparator<FootballPlayer>() {
		@Override
		public int compare(FootballPlayer p1, FootballPlayer p2) {
			return p1.name.compareTo(p2.name);
		}
	};
}
public class FootballMarket {
	public static int select;
	public final static int MANAGERMODE = 123;
	public static Scanner sc = new Scanner(System.in);
	public static ArrayList<FootballPlayer> datas = new ArrayList<FootballPlayer>();
	public static int PK = 1001;
	public static boolean checkManageMode = false; // 관리자모드인지 상태 확인
	/*
	 * Utils
	 */
	// 문자열 입력받기
	public static String getString(String msg) {
		System.out.print(msg);
		return sc.next();
	}
	// 번호 입력받기
	public static int getNum(String msg) {
		System.out.print(msg);
		return sc.nextInt();
	}
	/*
	 * 선수 구매하기
	 */
	// players: 선수 목록
	// index: 구매할 선수 번호
	// num: 구매 수량
	// 반환값: true -> 성공, false -> 실패
	public static boolean buy(ArrayList<FootballPlayer> players, int index, int num) {
		return false;
	}
	// 관리자 모드 시작
	public static void execManagerMode() { // 관리자 모드 실행
		FootballMarket.checkManageMode = true;
		System.out.println("관리자 모드입니다.");
		printManagermode();
	}
	public static String getPosition(String msg) { // 포지션 입력 및 유효성 검사
		System.out.print(msg);
		System.out.println("(FW / MF / DF/ GK) >> ");
		while (true) {
			String position = sc.next();
			if (position.equals("FW") || position.equals("MF") || position.equals("DF") || position.equals("GK")) {
				return position;
			}
			System.out.println("포지션은 FW, MF, DF, GK 중에만 입력하실 수 있습니다.");
			System.out.print("다시 입력해주세요 >> ");
		}
	}
	public static int getNum(String msg, int min, int max) { // 숫자 입력 및 유효성 검사
		System.out.print(msg);
		System.out.print("(" + min + " ~ " + max + ") >> ");
		while (true) {
			try {
				int chooseNum = sc.nextInt();
				if (chooseNum >= min && chooseNum <= max) {
					return chooseNum;
				} else {
					System.out.println(min + "과 " + max + "사이의 값만 입력 가능합니다.");
				}
			} catch (Exception e) {
				System.out.println(min + "과 " + max + " 사이의 '정수'만 입력가능합니다.");
				sc.nextLine();
			}
		}
	}
	public static void printAllFootballPlayer() { // 선수 모두 출력 ( 정보 변경이나 삭제에서 목록을 띄우기 위함)
		for (FootballPlayer data : datas) {
			System.out.println(data);
		}
	}
	public static void printManagermode() { // 관리자 메인 메뉴
		while (true) {
			System.out.println("1. 선수 추가");
			System.out.println("2. 선수 정보 변경");
			System.out.println("3. 선수 삭제");
			System.out.println("0. 관리자 모드 종료");
			if (chooseManagermenu() == 0) {
				checkManageMode = false;
				break;
			}
		}
	}
	public static int chooseManagermenu() { // 관리자 메인 메뉴 번호 선택
		int action = getNum("번호를 입력해주세요", 0, 3);
		if (action == 1) {
			addFootballPlayer();
		} else if (action == 2) {
			updateFootballPlayer();
		} else if (action == 3) {
			deleteFootballPlayer();
		} else if (action == 0) {
			System.out.println("관리자모드를 종료합니다...");
		}
		return action;
	}
	public static boolean checkListEmpty() { // 배열리스트가 비어있는지 검사
		if (datas.size() == 0) {
			System.out.println("등록된 선수가 없습니다...");
			return true;
		}
		return false;
	}
	public static void deleteFootballPlayer() { // 선수 삭제
		if (!checkListEmpty()) {
			datas.sort(FootballPlayer.byPk);
			printAllFootballPlayer();
			int i = checkPlayerPk();
			datas.remove(i);
		}
	}
	public static int checkPlayerPk() { // PK 유효성 검사
		while (true) {
			try {
				int changePlayer = getNum("변경할 선수의 PK를 입력해주세요 >>");
				for (int i = 0; i < datas.size(); i++) {
					if (datas.get(i).getPk() == changePlayer) {
						return i;
					}
				}
				System.out.println("유효하지 않은 PK입니다.");
			} catch (Exception e) {
				System.out.println("정수를 입력해주세요");
				sc.nextLine();
			}
		}
	}
	public static void checkUpdatePrice(int i) {
		while (true) {
			int price = getNum("새로운 가격을 입력해주세요", 1000, 10000);
			if (price != datas.get(i).getPrice()) {
				datas.get(i).setPrice(price);
				break;
			} else {
				System.out.println("같은 가격은 입력하실 수 없습니다.");
			}
		}
	}
	public static void checkUpdateTotalPower(int i) {
		while (true) {
			int power = getNum("새로운 능력치를 입력해주세요", 40, 100);
			if (power != datas.get(i).getTotalPower()) {
				datas.get(i).setTotalPower(power);
				break;
			} else {
				System.out.println("같은 능력치는 입력하실 수 없습니다.");
			}
		}
	}
	public static void checkUpdateEa(int i) {
		while (true) {
			int ea = getNum("새로운 수량을 입력해주세요", 1, 10);
			if (ea != datas.get(i).getEa()) {
				datas.get(i).setEa(ea);
				break;
			} else {
				System.out.println("같은 수량으로는 입력하실 수 없습니다.");
			}
		}
	}
	public static void updateFootballPlayer() { // 선수 정보 변경
		if (!checkListEmpty()) {
			datas.sort(FootballPlayer.byPk);
			printAllFootballPlayer();
			int i = checkPlayerPk();
			System.out.println("1. 가격 변경");
			System.out.println("2. 능력치 변경");
			System.out.println("3. 수량 변경");
			select = getNum("어떤정보를 변경하시겠습니까?", 1, 3);
			if (select == 1) {
				checkUpdatePrice(i);
			} else if (select == 2) {
				checkUpdateTotalPower(i);
			} else if (select == 3) {
				checkUpdateEa(i);
			}
		}
	}
	public static void addFootballPlayer() { // 선수 추가
		System.out.println("선수를 추가합니다.");
		String name = getString("이름을 입력해주세요 >> ");
		String position = getPosition("포지션을 입력해주세요");
		int totalPower = getNum("능력치를 입력해주세요", 40, 100);
		int price = getNum("가격을 입력해주세요", 1000, 10000);
		int ea = getNum("수량을 입력해주세요", 1, 10);
		datas.add(new FootballPlayer(PK++, name, position, totalPower, price, ea));
	}
	// 관리자 모드 끝

	/*
	 * 출력시 유저를위한 새로운 subIdx 부여
	 * 출력이 끝나고 메인메뉴로 돌아오면 -1로 초기화 따라서 해당 선수 재고만 줄어든다.
	 * 선택한선수 재고가 0이면 "재고가 없습니다." 출력후 재선택
	 * 선택한 포지션의 모든선수 재고가 0이면 "모든 ?? 포지션 선수 재고가 없습니다." 출력 후 메인메뉴 
	 * 포지션별로 등록된 선수가 없으면 "현재 등록된 ?? 포지션 선수가 없습니다." 출력 후 메인메뉴  
	 * 가격별출력시 등록된 선수가 없으면 "등록된 선수가 없습니다..." 출력 후 메인메뉴 
	 * 출력시 유저를위한 새로운 subIdx 부여 출력이 끝나고 메인메뉴로 돌아오면 -1로 초기화 따라서 해당 선수 재고만 줄어든다. 선택한선수
	 * 재고가 0이면 "재고가 없습니다." 출력후 재선택 선택한 포지션의 모든선수 재고가 0이면 "모든 ?? 포지션 선수 재고가 없습니다." 출력
	 * 후 메인메뉴 포지션별로 등록된 선수가 없으면 "현재 등록된 ?? 포지션 선수가 없습니다." 출력 후 메인메뉴 가격별출력시 등록된 선수가
	 * 없으면 "등록된 선수가 없습니다..." 출력 후 메인메뉴
	 */

	public static void printByPrice() {
		if (!checkListEmpty()) {
			datas.sort(FootballPlayer.byPrice);
			FootballMarket.sellByPricenPower();
		}
	}
	public static void printByTotalPower() {
		if (!checkListEmpty()) {
			datas.sort(FootballPlayer.byTotalPower);
			FootballMarket.sellByPricenPower();
		}
	}
	public static void printByPosition() {
		if (!checkListEmpty()) {
			// default 정렬 이름
			System.out.println("1. FW");
			System.out.println("2. MF");
			System.out.println("3. DF");
			System.out.println("4. GK");
			while (true) {
				select = getNum("번호를 입력해주세요", 1, 4);
				if (select == 1) {
					// FW 출력 후 구매
					FootballMarket.sellByPosition("FW");
					break;
				} else if (select == 2) {
					// MF 출력
					FootballMarket.sellByPosition("MF");
					break;
				} else if (select == 3) {
					// DF 출력
					FootballMarket.sellByPosition("DF");
					break;
				} else if (select == 4) {
					// GK 출력
					FootballMarket.sellByPosition("GK");
					break;
				}
			}
		}
	}
	public static void searchByName() {
		if (!checkListEmpty()) {
			String name = FootballMarket.getString("검색하실 이름을 입력해주세요 >>");
			boolean flag = false;
			for (int i = 0; i < datas.size(); i++) {
				if (datas.get(i).getName().equals(name)) {
					System.out.println(datas.get(i));
					flag = true;
					break;
				}
			}
			if (!flag) {
				System.out.println("없는 선수 입니다.");
			}
		}
	}
	// TODO 비슷한 기능인데 모듈화를 못하겠습니다.
	public static void sellByPricenPower() {
		while (true) {
			int i;
			int subIdx = 0;
			int eaCnt = 0;
			for (i = 0; i < datas.size(); i++) {
				eaCnt += datas.get(i).getEa();
			}
			if (eaCnt <= 0) {
				for (i = 0; i < datas.size(); i++) {
					datas.get(i).setSubIdx(subIdx++);
					System.out.print((datas.get(i).getSubIdx() + 1) + ". ");
					System.out.println(datas.get(i));
				}
				System.out.println("현재 모든선수 재고가 없습니다.");
				break;
			}
			else {
				for (i = 0; i < datas.size(); i++) {
					datas.get(i).setSubIdx(subIdx++);
					System.out.print((datas.get(i).getSubIdx() + 1) + ". ");
					System.out.println(datas.get(i));
				}
				FootballMarket.select = getNum("구매하실 선수 번호를 입력해주세요", 1, subIdx);
				boolean flag = false;
				for (i = 0; i < datas.size(); i++) {
					if (datas.get(i).getSubIdx() == FootballMarket.select - 1) {
						if (datas.get(i).getEa() > 0) {
							flag = true;
							break;
						}
					}
				}
				if (!flag) {
					System.out.println("재고가 없습니다.");
					continue;
				}
				datas.get(i).sell();
				for (i = 0; i < datas.size(); i++) {
					datas.get(i).setSubIdx(-1);
				}
				break;
			}
		}
	}
	public static void sellByPosition(String position) {
		while (true) {
			int i;
			int subIdx = 0;
			int eaCnt = 0; //포지션별 선수재고가 모두 0인지 확인하기 위한 변수
			datas.sort(FootballPlayer.byName); // default 정렬 이름 ?
			// 포지션별로 재고확인
			for (i = 0; i < datas.size(); i++) {
				if (datas.get(i).getPosition().equals(position)) {
					eaCnt += datas.get(i).getEa();
				}
			}
			// 포지션별로 모든재고가 0이면 
			if (eaCnt <= 0) {
				for (i = 0; i < datas.size(); i++) {
					if (datas.get(i).getPosition().equals(position)) {
						datas.get(i).setSubIdx(subIdx++);
						System.out.print((datas.get(i).getSubIdx() + 1) + ". ");
						System.out.println(datas.get(i));
					}
				}
				// 재고는 없더라도 등록된 선수는 있는지 확인.
				if (subIdx == 0) {
					System.out.println("현재 등록된 " + position + "포지션 선수가 없습니다.");
					break;
				}
				//등록된 선수는 있고 재고만 없으면
				System.out.println("현재 " + position + "포지션 재고가 없습니다.");
				break;
			}
			

			else {
				//출력 시 subIdx를 임시부여하고 유저가 subIdx를 입력해 구매하도록 출력
				for (i = 0; i < datas.size(); i++) {
					if (datas.get(i).getPosition().equals(position)) {
						datas.get(i).setSubIdx(subIdx++);
						System.out.print((datas.get(i).getSubIdx() + 1) + ". ");
						System.out.println(datas.get(i));
					}
				}
				FootballMarket.select = getNum("구매하실 선수 번호를 입력해주세요", 1, subIdx);
				boolean flag = false;
				for (i = 0; i < datas.size(); i++) {
					if (datas.get(i).getSubIdx() == FootballMarket.select - 1) {
						if (datas.get(i).getEa() > 0) {
							flag = true;
							break;
						}
					}
				}
				if (!flag) {
					System.out.println("재고가 없습니다.");
					continue;
				}
				datas.get(i).sell();
				

				// 화면 나갈때 모든선수 SubIdx 초기화 => 그대로 두면 다음 출력할 때 구분이 불가
				for (i = 0; i < datas.size(); i++) {
					datas.get(i).setSubIdx(-1);

				}
				break;
			}
		}
	}
	/*
	 * Main Page
	 */
	public static void printMainPage() {
		System.out.println("====================");
		System.out.println("  Football 이적 시장");
		System.out.println("====================");
		System.out.println("1. 가격별 출력");
		System.out.println("2. 능력치별 출력");
		System.out.println("3. 포지션별 출력");
		System.out.println("4. 검색 기능");
		System.out.println("0. 프로그램 종료");
		System.out.println("===================");
	}
	public static void controller() {
		select = getNum("번호를 입력해주세요 >> ");
		if (select == 0) {
			System.out.println("프로그램을 종료합니다..");
		} else if (select == 1) {
			// 가격별 출력
			printByPrice();
		} else if (select == 2) {
			// 능력치별 출력
			printByTotalPower();
		} else if (select == 3) {
			// 포지션별 출력
			printByPosition();
		} else if (select == 4) {
			// 검색 기능
			searchByName();
		} else if (select == MANAGERMODE) {
			// 관리자 모드
			execManagerMode();
		} else if (select < 0 || select > 4) {
			// validation 처리
			System.out.println("유효하지 않은 입력입니다\n다시 입력해주세요\n");
		}
	}
	public static void addSameple() {
		datas.add(new FootballPlayer(PK++, "메시", "FW", 50, 1000, 1));
		datas.add(new FootballPlayer(PK++, "호날두", "FW", 60, 5000, 1));
		datas.add(new FootballPlayer(PK++, "손흥민", "FW", 100, 2000, 1));
		datas.add(new FootballPlayer(PK++, "드록바", "FW", 70, 3000, 2));
		datas.add(new FootballPlayer(PK++, "루니", "MF", 90, 3000, 1));
		datas.add(new FootballPlayer(PK++, "데 헤아", "GK", 50, 3000, 1));
		datas.add(new FootballPlayer(PK++, "김민재", "DF", 50, 3000, 1));
	}
	public static void run() {
		FootballMarket.addSameple();
		while (true) {
			printMainPage();
			controller();
			if (select == 0)
				break;
		}
	}
	public static void main(String[] args) {
		run();
	}
}

 

최종코드

package fifaOnline;

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

class FootballPlayer { // 축구선수 클래스
	private int pk; // PK, 객체 고유 id로 사용
	private String name; // 선수 이름
	private String position; // 선수 포지션
	private int totalPower; // 선수 능력치
	private int price; // 가격
	private int ea; // 수량

	FootballPlayer(int pk, String name, String position, int totalPower, int price, int ea) {
		this.pk = pk;
		this.name = name;
		this.position = position; // FW, MF, DF, GK
		this.totalPower = totalPower;
		this.price = price;
		this.ea = ea;
	}

	public int getPk() {
		return pk;
	}

	public String getName() {
		return name;
	}

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

	public String getPosition() {
		return position;
	}

	public void setPosition(String position) {
		this.position = position;
	}

	public int getTotalPower() {
		return totalPower;
	}

	public void setTotalPower(int totalPower) {
		this.totalPower = totalPower;
	}

	public int getPrice() {
		return price;
	}

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

	public int getEa() {
		return ea;
	}

	public void setEa(int ea) {
		this.ea = ea;
	}

	@Override // 유저한테 PK 안보이도록 설정
	public String toString() {
		String ret = "[" + position + " " + name + " 능력치 : " + totalPower + ", " + price + "$";
		if (this.ea == 0) {
			return ret + ", 재고없음]";
		} else {
			return ret + ", 수량=" + ea + "]";
		}
	}

	public void sell(int cnt) {
		this.ea -= cnt;
	}

	public static Comparator<FootballPlayer> byPrice = new Comparator<FootballPlayer>() {
		@Override
		public int compare(FootballPlayer p1, FootballPlayer p2) {
			return p2.price - p1.price;
		}
	};

	public static Comparator<FootballPlayer> byTotalPower = new Comparator<FootballPlayer>() {
		@Override
		public int compare(FootballPlayer p1, FootballPlayer p2) {
			return p2.totalPower - p1.totalPower;
		}
	};

	public static Comparator<FootballPlayer> byPk = new Comparator<FootballPlayer>() {
		@Override
		public int compare(FootballPlayer p1, FootballPlayer p2) {
			return p2.pk - p1.pk;
		}
	};

	public static Comparator<FootballPlayer> byName = new Comparator<FootballPlayer>() {
		@Override
		public int compare(FootballPlayer p1, FootballPlayer p2) {
			return p2.name.compareTo(p1.name);
		}
	};
}

public class FootballMarket {

	public static int PK = 1001; // 객체가 만들어질떄마다 ++
	public final static int MANAGERMODE = 231121;
	public static Scanner sc = new Scanner(System.in);
	public static ArrayList<FootballPlayer> datas = new ArrayList<FootballPlayer>();

	/*
	 * Utils
	 */

	// 문자열 입력받기
	public static String inputString(String msg) {
		System.out.print(msg);
		return sc.next();
	}

	// 포지션 입력받기 및 유효성 검사
	public static String getPosition(String msg) {
		System.out.print(msg);
		System.out.print("(FW / MF / DF / GK) >> ");
		while (true) {
			String position = sc.next();
			if (position.equals("FW") || position.equals("MF") || position.equals("DF") || position.equals("GK")) {
				return position;
			}
			System.out.println("포지션은 FW, MF, DF, GK 중에만 입력하실 수 있습니다.");
			System.out.print("다시 입력해주세요 >> ");
		}
	}

	// Y or N 입력받기 및 유효성 검사
	public static String getAnswer(String msg) {
		System.out.print(msg);
		while (true) {
			String answer = sc.next();
			if (answer.equals("Y") || answer.equals("N")) {
				return answer;
			}
			System.out.println("Y 또는 N 만 입력 가능합니다.");
			System.out.print("다시 입력해주세요 >> ");
		}
	}

	/*
	 * Football Player Buy
	 */

	public static void buy(ArrayList<FootballPlayer> players) {
		int eaCnt = 0;
		for (int i = 0; i < players.size(); i++) {
			eaCnt += players.get(i).getEa();
		}
		if (eaCnt <= 0) {
			System.out.println("등록된 모든 선수의 재고가 없습니다.");
			return;
		}
		while (true) {

			int choiceNum = inputNum("구매할 선수 번호 입력 ", 1, players.size());
			if (players.get(choiceNum - 1).getEa() <= 0) {
				System.out.println("해당선수 재고가 없습니다.");
				continue;
			}

			int cnt = inputNum("구입할 수량 입력 ", 1, players.get(choiceNum - 1).getEa());
			System.out.println(cnt + "개를 구입하시겠습니까 ?");

			String answer = getAnswer("Y or N >> ");
			if (answer.equals("Y")) {
				System.out.println(players.get(choiceNum - 1).getName() + " " + cnt + "개 구입완료!");
				players.get(choiceNum - 1).sell(cnt);
			} else {
				System.out.println("구입 취소");
			}
			break;
		}
	}

	/*
	 * Manager Mode
	 */

	// 선수 모두 출력 ( 정보 변경이나 삭제에서 목록을 띄우기 위함)
	public static void printAllFootballPlayer() {

		for (int i = 0; i < datas.size(); i++) {
			System.out.println("[PK-" + datas.get(i).getPk() + "] " + datas.get(i));
		}
	}

	// 관리자 모드 실행
	public static void execManagerMode() {
		System.out.println("관리자 모드입니다");
		printManagermode();
	}

	// 관리자 메인 메뉴
	public static void printManagermode() {
		while (true) {
			System.out.println("1. 선수 추가");
			System.out.println("2. 선수 정보 변경");
			System.out.println("3. 선수 삭제");
			System.out.println("0. 관리자 모드 종료");
			if (chooseManagermenu() == 0) {
				break;
			}
		}
	}

	// 관리자 메인 메뉴 번호 선택
	public static int chooseManagermenu() {
		int action = inputNum("번호를 입력해주세요", 0, 3);
		if (action == 1) { // 선수 추가
			addFootballPlayer();
		} else if (action == 2) { // 선수정보 변경
			updateFootballPlayer();
		} else if (action == 3) { // 선수 삭제
			deleteFootballPlayer();
		} else if (action == 0) { // 사용자화면으로 이동
			System.out.println("관리자모드를 종료합니다...");
		}
		return action;
	}

	// 가격 변경
	public static void UpdatePrice(int i) {
		while (true) {
			int price = inputNum("새로운 가격을 입력해주세요", 1000, 10000);
			if (price != datas.get(i).getPrice()) {
				datas.get(i).setPrice(price);
				System.out.println(datas.get(i).getName() + "선수 " + datas.get(i).getPrice() + "원 변경완료!");
				break;
			} else {
				System.out.println("같은 가격은 입력하실 수 없습니다.");
			}
		}
	}

	// 능력치 변경
	public static void UpdateTotalPower(int i) {
		while (true) {
			int power = inputNum("새로운 능력치를 입력해주세요", 40, 100);
			if (power != datas.get(i).getTotalPower()) {
				datas.get(i).setTotalPower(power);
				System.out.println(datas.get(i).getName() + "선수 능력치 " + datas.get(i).getTotalPower() + " 변경완료!");
				break;
			} else {
				System.out.println("같은 능력치는 입력하실 수 없습니다.");
			}

		}
	}

	// 수량 변경
	public static void UpdateEa(int i) {
		while (true) {
			int ea = inputNum("새로운 수량을 입력해주세요", 1, 10);
			if (ea != datas.get(i).getEa()) {
				datas.get(i).setEa(ea);
				System.out.println(datas.get(i).getName() + "선수 재고 " + datas.get(i).getEa() + "개 변경완료!");
				break;
			} else {
				System.out.println("같은 수량으로는 입력하실 수 없습니다.");
			}
		}

	}

	// PK 유효성 검사
	public static int inputIndex() {
		int i = 0;
		while (true) {
			try {
				int firstPK = datas.get(0).getPk(); // datas리스트는 원본데이터로 순서를 섞지않고 PK는 항상 증가하는 방식으로 추가됩니다.
				int lastPK = datas.get(datas.size() - 1).getPk();
				int changePlayer = inputNum("선수의 PK를 입력해주세요 ", firstPK, lastPK);// 수정, 현진 =>
				for (i = 0; i < datas.size(); i++) { // datas리스트의 0번째 인덱스 PK값 부터
					if (datas.get(i).getPk() == changePlayer) { // datas리스트의 마지막 인덱스 PK값은
						System.out.println("선택된 선수 : [" + datas.get(i).getName() + "]");
						return i; // datas리스트의 size()-1을 해주어야
									// 리스트의 마지막 인덱스 PK값이 됩니다.
					}
				}
				System.out.println("유효하지 않은 PK입니다.");
			} catch (Exception e) {
				System.out.println("정수를 입력해주세요");
				sc.nextLine();
			}
		}
	}

	// 선수 정보 변경
	public static void updateFootballPlayer() {
		if (!checkListEmpty()) {
			printAllFootballPlayer();
			int i = inputIndex();
			System.out.println("1. 가격 변경");
			System.out.println("2. 능력치 변경");
			System.out.println("3. 수량 변경");
			int select = inputNum("어떤정보를 변경하시겠습니까?", 1, 3);
			if (select == 1) {
				UpdatePrice(i);
			} else if (select == 2) {
				UpdateTotalPower(i);
			} else if (select == 3) {
				UpdateEa(i);
			}
		}
	}

	// 배열리스트가 비어있는지 검사
	public static boolean checkListEmpty() {
		if (datas.size() <= 0) {
			System.out.println("등록된 선수가 없습니다...");
			return true;
		}
		return false;
	}

	// 선수 삭제
	public static void deleteFootballPlayer() {
		if (!checkListEmpty()) {
			printAllFootballPlayer();
			int i = inputIndex();
			String name = datas.get(i).getName();
			datas.remove(i);
			System.out.println(name + " 선수삭제 성공!");
		}
	}

	// 선수 추가
	public static void addFootballPlayer() {
		System.out.println("선수를 추가합니다.");
		String name = inputString("이름을 입력해주세요 >> ");
		String position = getPosition("포지션을 입력해주세요");
		int totalPower = inputNum("능력치를 입력해주세요", 40, 100);
		int price = inputNum("가격을 입력해주세요", 1000, 10000);
		int ea = inputNum("수량을 입력해주세요", 1, 10);
		datas.add(new FootballPlayer(PK++, name, position, totalPower, price, ea));
		System.out.println(name + " 선수 " + ea + "개 등록 성공!");
	}

	/*
	 * Functions
	 */

	// 가격별 출력
	public static void printByPrice() {
		if (!checkListEmpty()) {
			ArrayList<FootballPlayer> tmpDatas = new ArrayList<FootballPlayer>(datas);
			tmpDatas.sort(FootballPlayer.byPrice);
			for (int i = 0; i < tmpDatas.size(); i++) {
				System.out.println((i + 1) + ". " + tmpDatas.get(i));
			}
			buy(tmpDatas);
		}
	}

	// 능력치별 출력
	public static void printByTotalPower() {
		if (!checkListEmpty()) {
			ArrayList<FootballPlayer> tmpDatas = new ArrayList<FootballPlayer>(datas);
			tmpDatas.sort(FootballPlayer.byTotalPower);
			for (int i = 0; i < tmpDatas.size(); i++) {
				System.out.println((i + 1) + ". " + tmpDatas.get(i));
			}
			buy(tmpDatas);
		}
	}

	public static void printByMainPosition(ArrayList<FootballPlayer> players, String position) { // 포지션 입력 // 배열 넣기
		// 배열 하나 만든다 tmpDatas
		ArrayList<FootballPlayer> tmpDatas = new ArrayList<FootballPlayer>();
		int i = 0;
		for (FootballPlayer player : players) {
			if (player.getPosition().equals(position)) { // 포지션을 선택한다
				tmpDatas.add(player); // 선택된 포지션을 배열 안으로 넣는다
				System.out.println((i + 1) + ". " + player); // 선택된 포지션 출력
				i++;
			}
		}
		buy(tmpDatas);
	}

	public static void printByMainPositionPage() {
		System.out.println("포지션을 선택해주세요"); // 포지션 번호로 선택
		System.out.println("1. FW");
		System.out.println("2. MF");
		System.out.println("3. DF");
		System.out.println("4. GK");
		System.out.println("0. 종료");
	}

	// 포지션별 출력
	public static void printByPosition() { // 선수 포지션별로 출력하기
		while (true) {
			printByMainPositionPage(); // 포지션 선택창
			int action = inputNum("번호를 입력해주세요", 0, 4); // 포지션 번호로 선택
			if (action == 0) {
				System.out.println("포지션 선택을 나갑니다."); // 포지션 선택 종료
				break;
			} else {
				String selectedPosition = ""; // 선택된 포지션을 저장할 변수
				// 선택된 포지션 설정
				if (action == 1) {
					selectedPosition = "FW"; // 모듈화를 통해 간단하게 표현 FW 선택
				} else if (action == 2) {
					selectedPosition = "MF"; // MF 선택
				} else if (action == 3) {
					selectedPosition = "DF";
				} else if (action == 4) {
					selectedPosition = "GK";
				}
				System.out.println(selectedPosition + " 포지션 선수 목록"); // 선택된 포지션 출력
				printByMainPosition(datas, selectedPosition); // 선수 출력
			}
		}
	}

	public static void searchByName() {
		if (!checkListEmpty()) {
			String name = inputString("선수 이름을 입력해주세요 >> ");
			boolean found = false;
			for (FootballPlayer data : datas) {
				if (data.getName().contains(name)) { // "호날두".contains("호");
					System.out.println(data);
					found = true;
				}
			}
			if (!found) {
				System.out.println("해당 이름을 가진 선수가 없습니다.");
			}
		}
	}

	// 번호 입력받기 및 범위 유효성 검사 (수정, 현진 => 오버로딩 삭제 => 결합도 ↓, 응집도 ↑ => 좋은 코드)
	public static int inputNum(String msg, int min, int max) {
		System.out.print(msg); // min 최소값, max최대값을 사용자에게 출력하기 위해 사용된 변수
		String rangeStr;
		if (min == max) {
			rangeStr = "( " + min + " )";
		} else {
			rangeStr = "(" + min + " ~ " + max + ")";
		}
		System.out.print(rangeStr + " >> ");
		while (true) {
			try {
				int chooseNum = sc.nextInt();
				if (chooseNum >= min && chooseNum <= max) {
					return chooseNum;
				} else if (chooseNum == MANAGERMODE) {
					return chooseNum;
				} else {
					System.out.print(rangeStr + " 입력 가능합니다. >>");
				}
			} catch (Exception e) {
				System.out.print("'정수'만 입력가능합니다. >>");
				sc.nextLine();
			}
		}
	}

	/*
	 * Main Page
	 */

	public static void printMainPage() {
		System.out.println("=====================");
		System.out.println("⚽ Football 이적 시장 ⚽");
		System.out.println("=====================");
		System.out.println("1. 가격별 출력");
		System.out.println("2. 능력치별 출력");
		System.out.println("3. 포지션별 출력");
		System.out.println("4. 검색 기능");
		System.out.println("0. 프로그램 종료");
		System.out.println("======================");
	}

	public static int controller() {
		int select = inputNum("번호를 입력해주세요 ", 0, 4);
		if (select == 0) {
			System.out.println("프로그램을 종료합니다..");
		} else if (select == 1) {
			// 가격별 출력
			printByPrice();
		} else if (select == 2) {
			// 능력치별 출력
			printByTotalPower();
		} else if (select == 3) {
			// 포지션별 출력
			printByPosition();
		} else if (select == 4) {
			// 검색 기능
			searchByName();
		} else if (select == MANAGERMODE) { // 231121
			// 관리자 모드
			execManagerMode();
		} else if (select < 0 || select > 4) {
			// validation 처리
			System.out.println("유효하지 않은 입력입니다\n다시 입력해주세요\n");
		}
		return select;
	}

	public static void run() {
		while (true) {
			printMainPage();
			int select = controller();
			if (select == 0) {
				break;
			}
		}
	}

	public static void main(String[] args) {

		datas.add(new FootballPlayer(PK++, "호날두", "FW", 87, 8700, 5));
		datas.add(new FootballPlayer(PK++, "메시", "FW", 86, 8600, 4));
		datas.add(new FootballPlayer(PK++, "손흥민", "FW", 83, 8300, 7));
		datas.add(new FootballPlayer(PK++, "김덕배", "MF", 85, 8500, 2));
		datas.add(new FootballPlayer(PK++, "박지성", "MF", 81, 8100, 3));
		datas.add(new FootballPlayer(PK++, "이강인", "MF", 77, 7700, 7));
		datas.add(new FootballPlayer(PK++, "에브라", "DF", 83, 8300, 6));
		datas.add(new FootballPlayer(PK++, "김민재", "DF", 79, 7900, 4));
		datas.add(new FootballPlayer(PK++, "말디니", "DF", 84, 8400, 3));
		datas.add(new FootballPlayer(PK++, "알베스", "DF", 83, 8300, 3));
		datas.add(new FootballPlayer(PK++, "이운재", "GK", 83, 8300, 3));

		run();

	}
}

'PROJECT' 카테고리의 다른 글

MyPage 및 Report 정리 [TEAM PROJECT]  (0) 2024.01.30
MVC 패턴, DB를 활용한 Team Project Part. 1  (0) 2024.01.13
상속을 이용한 팀프로젝트  (0) 2023.12.05
Comments