본문 바로가기
Java

가위바위보 게임

by 지민재 2022. 5. 9.
반응형
SMALL
package homework;

import javax.swing.JOptionPane;

/**
 * 
 * 사용자의 입력값이 올바른지 검증 및 오류 횟수에 따른 프로그램 종료 기능 추가.
 */
public class Checker {

	private String input; //사용자 입력값
	private int faultCount; //사용자의 오류 카운터

	public Checker(String input) {
		super();
		this.input = input;
	}

	public boolean check() {
		boolean result = false;
		//사용자의 입력값이 배열중 하나인지 검색해본다..맞으면 true 리턴 하고 for 종료됨
		for (String str : Gawibawibo.strValues) {
			if (str.equals(input)) {
				return !result;
			}
		}
		//올바른 값이 아니기에 실수 횟수 업, 사용자에게 알럿띄우고, 결과 리턴함.
		faultCount++;
		showAlert();
		return result;

	}

	/*
	 *	가위바위보 아닌 다른 값 입력시 알럿 보여주고 오류가 5번 인 경우 프로그램 종료 기능 적용함. 
	 */
	private void showAlert() {
		if (faultCount >= 5) {
			//JOptionPane.showMessageDialog 는 화면에 메세지만 보여주는 객체의 메서드임. 두번째 파라미터가 내용임
			JOptionPane.showMessageDialog(null, "오류 횟수가 5회 넘어 프로그램을 종료 합니다");
			//아래코드는 명시적으로 실행중인 자바 프로그램을 종료시키는 코드임.
			System.exit(0);
		}
		JOptionPane.showMessageDialog(null, Gawibawibo.messages[2] + "\n 오류횟수 : " + faultCount);
		// check();
	}
	
	//사용자가 가위바위보를 잘못 입력후 재 입력시 setter.
	public void setInput(String input) {
		this.input = input;
	}

}
package homework;

import java.util.Random;

import javax.swing.JOptionPane;

/**
 *
 * 이클래스는 실제 게임을 진행 하는 클래스임.
 * 생성자로 사용자값 초기화 하고, init() 초기화 메서드를 통해 가위바위보를 수치로 변경함.
 *
 */
public class Gamer {
	
	private String input;//사용자 입력값
	private static int[] chgValue = {0,1,2};
	private Random random;
	private int gameResult;//0 무승부,1 유저 승, 2 컴 승
	private int com;//컴의 랜덤값. 사용자에게 결과를 보여주는 기능을 메인 클래스에서 하기 때문에 필드로 선언함.
	
	public Gamer(String input) {
		this.input = input;
		//사용자 값을 숫자로 변경하는 초기화 메서드 호출..일반적으로  init() 명으로 많이 사용함.
		init();
	}
	private void init() {
		//랜덤객체 초기화..이후 메서드만 호출하면 랜덤값 생성됨.
		random = new Random();
		for(int i = 0; i<chgValue.length; i++) {
			if(input.startsWith("가")) {
				play(chgValue[0]);
				return;
			}else if(input.startsWith("바")) {
				play(chgValue[1]);
				return;
			}else if(input.startsWith("보")) {
				play(chgValue[2]);
				return;
			}
		}
		
	}
	private void play(int userVal) {
		//컴퓨터 값 생성.
		com = random.nextInt(3);
		//조건 검색.
		if(userVal == com) {
			//무승부.
			gameResult = 0;
		}else if((userVal == 0 && com == 2) || (userVal == 1 && com == 0) || (userVal == 2 && com == 1)){//사용자가 이기는 조건 나열..
			//유저 승
			gameResult = 1;
		}else if((userVal == 0 && com == 1) || (userVal == 1 && com == 2) || (userVal == 2 && com == 0)){
			//컴퓨터 승..
			gameResult = 2;
		}
	}
	//메인클래스에서 게임 결과 확인시 필요
	public int getGameResult() {
		return gameResult;
	}
	//메인클래스에서 컴값 확인시 필요
	public int getCom() {
		return com;
	}
}
package homework;

/**
 * 
 * 이 클래스는 사용자의 게임 결과 정보를 유지하는 DTO 
 * 필요한 필드 선언후 setter, getter 모두 만들었지만 다 쓰이지는 않았음..
 * 필요에 따라 setter 에 로직 정의 
 *
 */
public class PlayerInfo {
	
	private int win;
	private int draw;
	private int lose;
	private int total;
	private double win_Rate;
	
	//플레이 결과에 따른 승,패,무 를 자동 처리하는 메서드..메인 클래스에서 편하게 사용됨
	public void autoSet(int result) {
		if(result == 0) {//비김
			setDraw(1);
		}else if(result == 1) {//이김
			setWin(1);
		}else if(result == 2) {//짐
			setLose(1);
		}
	}
	public int getWin() {
		return win;
	}

	public void setWin(int win) {
		this.win += win;
		setTotal();
	}

	public int getDraw() {
		return draw;
	}

	public void setDraw(int draw) {
		this.draw += draw;
		setTotal();
	}

	public int getLose() {
		return lose;
	}

	public void setLose(int lose) {
		this.lose += lose;
		setTotal();
	}

	public int getTotal() {
		return total;
	}

	public void setTotal() {
		this.total = this.win + this.lose + this.draw;
		setWin_Rate();
	}

	//소숫점 2자리 까지만 표현하도록 String 객체의 메서드 사용함.
	public String getWin_Rate() {
		return String.format("%.2f", this.win_Rate);
	}

	public void setWin_Rate() {
		try {
			this.win_Rate = this.getWin() / (double)this.getTotal() * 100.0;
		}catch (ArithmeticException e) {
			this.win_Rate = 0;
			System.out.println("예외");
		}
		
	}
}
package homework;

import java.util.Arrays;

import javax.swing.JOptionPane;

public class Gawibawibo {

	// 사용할 객체 타입 필드 선언.
	static private Checker checker;
	static private Gamer gamer;
	static private PlayerInfo user;

	static private String input; //사용자의 입력값 변수. 상황에 따라 계속 사용해야 하기 때문에 필드로 선언.
	public static String strValues[] = { "가위", "바위", "보" };
	private static int com;

	// 메세지 출력 배열 생성.
	public static String[] messages = { "게임을 시작 합니다.(Y/N)", "가위바위보 중 하나 입력하세요.", "입력이 틀렸습니다. 다시 입력해주세요.",
			"게임을 다시 하시겠습니까?(Y/N)" };

	public static void main(String[] args) {
		//사용자에게 메세지출력 및 선택값 입력 받도록 한다.
		startMessage();
		
		//사용자의 입력값을 가지고 초기화 한다. 이후 값을 검증해서 목적에 따라 분기 시킨다..
		checker = new Checker(input);
		while (true) {
			
			// 값 검증할것.
			if (checker.check()) {// 올바른 값을 사용자가 넣었으니 게임 플레이..
				// gamer 생성자에 사용자 값 넣어주고 초기화...이후 생성자-->초기화메서드-->플레이메서드 의 호출 관계를 통해 자동으로 게임이 실행된다.
				gamer = new Gamer(input);
				
				//승패 결과 get..
				int result = gamer.getGameResult();
				//컴퓨터의 값 get..
				com = gamer.getCom();

				if (user == null) {//처음 게임플레이라면 객체 초기화 해주고..첫 게임이기에 객체 생성을 한것으로, 
					//게임 실행시마다 객체를 실행하면 누적 값을 유지 하기 어렵다. 해서 이후 게임부터는 Ref  변수를 이용해서 전적을 누적시킨다. 
					//객체가 할당되지 않을시엔 null 이 리턴된다.
					user = new PlayerInfo();
					//승패 전적을 자동으로 setting 하는 메서드 호출하여 전적 set.
					user.autoSet(result);
					//결과 메세지 화면에 뿌려준다.
					showMessage(result, user, com);
					//게임을 계속 할 지 여부를 확인한다.
					//아래 문자열중 \"Cancel\" 는 자바의 escape 문자로 역슬래쉬 옆에 t(tab), "(쌍따옴표) 등을 표기해줄때 사용한다.
					input = JOptionPane
							.showInputDialog("게임을 계속 하실려면 " + Arrays.toString(strValues) + " 중 하나를, 끝내려면 \"Cancel\" 누르세요.");
					//사용자가 새로운 값을 넣었으니 다시 체크..오류 값도 체크를 해야한다.
					checker.setInput(input);
					//만약 사용자가 cancel 을 누르면 null 이 리턴되므로 프로그램 종료시킨다.
					if(input == null) {
						programExit();
					}
				} else {// 그렇지 않다면 기존 사용자가 계속 게임을 하는 것이므로 setter 를 이용해서 정보만 누적한다.
					user.autoSet(result);
					showMessage(result, user, com);
					input = JOptionPane
							.showInputDialog("게임을 계속 하실려면 " + Arrays.toString(strValues) + " 중 하나를, 끝내려면 \"Cancel\" 누르세요.");
					checker.setInput(input);
					if(input == null) {
						programExit();
					}
				}
			}else {//가위바위보 가 아닌 이상한 값 넣었을떄..
				input = JOptionPane.showInputDialog(messages[1]);
				//사용자의 다른값을 checker 에 세팅한다...다시 루프로..
				checker.setInput(input); 
			}
		}
	}
	
	private static void programExit() {
		JOptionPane.showMessageDialog(null, "프로그램을 종료 합니다.", "프로그램 종료", JOptionPane.INFORMATION_MESSAGE);
		System.exit(0);
	}
	
	//처음 시작시 초기 메세지를 보여주고 사용자의 선택을 받는다.
	//y 또는 Y 일때만 다음으로 실행되고, 나머진 프로그램 종료
	private static void startMessage() {
		if (input == null) {
			//첫 메세지 출력후 게임 여부 확인한다.cancel 을 클릭하면 null 이 리턴되고, 값을 입력하면 문자열로 리턴된다.
			input = JOptionPane.showInputDialog(Arrays.toString(strValues) + messages[0]);
			// 대소문자 구분없이 문자열 값이 같은지 비교 메 서드 사용.equals() 는 대소문자 구분함.
			if (input.equalsIgnoreCase("y")) {
				//가위바위보 중 하나 넣으라고 했으나 다른값을 넣어도 검증하도록 설계
				input = JOptionPane.showInputDialog(messages[1]);
			} else if (input.equalsIgnoreCase("n")) {
				// 메세지 박스만 출력하는 GUI 호출.
				JOptionPane.showMessageDialog(null, "프로그램을 종료합니다");
				//아래 코드는 명시적으로 현재 실행중인 자바 프로그램을 종료하는 코드이다.
				System.exit(0);
			} else {// Y/N 아닌 다른 값 들어올 경우 처리..
				JOptionPane.showMessageDialog(null, "실행할 수 없는 명령어 입니다. 프로그램 종료합니다");
				System.exit(0);
			}
		}
	}

	/*
	 * 게임 결과 보여주는 메서드..
	 * 전적 정보는 사용자객체(PlayerInfo) 에 있기 때문에 파라미터로 받고, idx 는 승패에 대한 index, comValue 는 컴퓨터의 값.
	 */
	public static void showMessage(int idx, PlayerInfo user, int comValue) {
		if (idx == 0) {
			String msg = "비겼군요!! --> 사용자(" + input + ") : 컴퓨터(" + strValues[comValue] + ")\n" + "전적 --> "
					+ user.getTotal() + " : " + user.getWin() + "승 " + user.getDraw() + "무 " + user.getLose() + "패\n"
					+ "승률 --> " + user.getWin_Rate() + "%";

			//JOptionPane.showMessageDialog 는 msg 의 내용을 팝업으로 뿌려준다.
			JOptionPane.showMessageDialog(null, msg);
		} else if (idx == 1) {
			String msg = "이겼군요!! --> 사용자(" + input + ") : 컴퓨터(" + strValues[comValue] + ")\n" + "전적 --> "
					+ user.getTotal() + " : " + user.getWin() + "승 " + user.getDraw() + "무 " + user.getLose() + "패\n"
					+ "승률 --> " + user.getWin_Rate() + "%";

			JOptionPane.showMessageDialog(null, msg);
		}else if (idx == 2) {
			String msg = "졌군요!! --> 사용자(" + input + ") : 컴퓨터(" + strValues[comValue] + ")\n" + "전적 --> "
					+ user.getTotal() + " : " + user.getWin() + "승 " + user.getDraw() + "무 " + user.getLose() + "패\n"
					+ "승률 --> " + user.getWin_Rate() + "%";
			
			JOptionPane.showMessageDialog(null, msg);
		}
	}
}

'Java' 카테고리의 다른 글

Java 복습_2  (0) 2022.05.30
Java 복습_1  (0) 2022.05.29
예외처리  (0) 2022.05.02
ArrayListEx  (0) 2022.04.27
Java 학생 점수 받기  (0) 2022.04.10

댓글