Blog

[Java]17_2 기초문법 - Java로 만든 CLI 숫자 야구 게임!!

Author
Summary
Java로 만든 CLI 숫자 야구 게임!!
Category
Study
Tags
Java
Favorite
Memory Date
2023/08/15
Cross Reference Study
Related Media
Related Thought
Related Lessons
tag
날짜
작성자
진행상황
진행 전
태그구분
6 more properties
프로그래밍을 한다는건 재밌는걸 만들기 너무 좋다. 재밌어서 자야되는데 계속 붙잡고 오류를 고치고 있다.
삘받아서 완성하고 잔다!! 가위바위보에 이은 야구게임ㅋㅋ
게임 처럼 보이게 하기 위해서 중간 중간 Thread로 딜레이를 줬다.
Thread.sleep(2000);
Java
복사
좀 더 역동적인 CLI 게임도 만들어보고싶다. 내가 어릴때 했던 추억의 MUD게임 같은것? 설계만 잘하면 할 수 있을 것 같은 생각이 든다.
우선 반복문과 조건문, 배열과 형변환, 파라미터 넘기기의 무한 궤도처럼 돌아간다. 생각보다 연습이 많이 된다.
정신없어 보이는 View 부분을 정리하기 위해서 showTopMenu(), showPlayerTurn() 처럼 메서드를 구분해서 넣어주었다. 안그래도 반복문이 어지러운데 저 어지러운 그래픽까지 더해지면 코드를 알아볼수가없었다.
전체 코드는 다음과 같다. 반복문에서 break로 탈출하는 곳들을 잘못 지정하거나 논리 조건을 잘못 지정하면 곧바로 에러가 발생한다. 오류도 보통 아래처럼 직접적인 원인을 확신할 수 없어서 잘 작성해야 한다.
Error코드
Execution failed for task ':Main.main()'.
Process 'command '/usr/local/Cellar/openjdk@17/17.0.8/libexec/openjdk.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
오늘 접한 오류중에 하나는 Scanner에 대한 것이 문제였다.
숫자 입력과 관련된 문제: 사용자로부터 숫자를 입력받는 부분에서 문제가 발생할 수 있습니다. sc.nextLine()을 통해 사용자 입력을 받고 있습니다. 이 때, 입력 버퍼에서 줄 바꿈 문자(\n)를 처리하기 위해 sc.nextLine()을 사용합니다. 그러나 입력 버퍼에 엔터 키 입력이 남아있을 경우 예상치 못한 동작을 할 수 있습니다. 따라서 sc.nextLine() 전에 sc.nextLine()을 사용하여 버퍼를 비우는 것이 좋습니다.
이거 생각보다 중요하다. 또한 무한 반복을 돌 때 전역 변수를 쓸지, 지역 변수를 쓸지 잘 생각해야 한다. 무한 반복이 진짜 무한 반복 될 수 있다.
메인 코드는 다음과 같다. 재밌는 미니 프로그래밍이었다.
Main.java
package JavaPrac2week; /* 💡 **Goal : 숫자야구 프로그램 만들기** - 컴퓨터는 0과 9 사이의 서로 다른 숫자 3개를 무작위로 뽑습니다. (ex) 123, 759 - 사용자는 컴퓨터가 뽑은 숫자를 맞추기 위해 시도합니다. - 컴퓨터는 사용자가 입력한 세자리 숫자에 대해서, 아래의 규칙대로 스트라이크(S)와 볼(B)를 알려줍니다. - 숫자의 값과 위치가 모두 일치하면 S - 숫자의 값은 일치하지만 위치가 틀렸으면 B - 기회는 무제한이며, 몇번의 시도 후에 맞췄는지 기록됩니다. - 숫자 3개를 모두 맞춘 경우, 게임을 종료합니다. * */ public class Main { public static void main(String[] args) throws InterruptedException { Solution solution = new Solution(); solution.run(); } }
Java
복사
앗 이제보니 cnt같은거로 횟수를 기록해야 한다. 이미 run()에서 무한반복으로 돌고 있으니 cnt변수를 선언하고 run()내부 while문에서 cnt를 =+해줘서 전역변수에 누적해야겠다. 성공 했을때 cnt회로 성공하셨습니다! 를 출력하면서 끝내면 될듯.
우선 현재 기능 구현부 클래스는 다음과 같다. 안쓰는 변수들도 많은데 내일 마무리 할 때 정리해야겠다.
package JavaPrac2week; import java.util.Random; import java.util.Scanner; public class Solution { //CPU Hold input int ranNum1; int calNum1; int ranNum2; int calNum2; int ranNum3; int calNum3; int tryNum; int[] cpuNum; //User Hold input String inputNumOrigin; int inputNumOriginParseInt; int inputNum1; int inputNum2; int inputNum3; int[] playerNum; //ouput String resultStr[]; //S, B int outputTryNum; Scanner sc = new Scanner(System.in); public Solution() { } void run() throws InterruptedException { while (true) { showTopMenu(); Thread.sleep(2000); int[] playerNum = inputPlayer(); Thread.sleep(2000); int[] cpuNum = inputCPU(); Thread.sleep(2000); String[] resultStr = calculate(cpuNum, playerNum); Thread.sleep(2000); output(resultStr); if (!tryAgain()) { break; } } } int[] inputCPU() throws InterruptedException { showCpuTurn(); //Thread.sleep(2000); System.out.println("========== 첫번째 공을 쳐봅니다. ========="); while (true) { ranNum1 = (int) Math.round((Math.random() * 9)); if (ranNum1 > 9 || ranNum1 < 0) { showCpuMistake(); continue; } else if (ranNum1 >= 0 || ranNum1 < 10) { //System.out.println("ranNum1 생성 완료 ==>" + ranNum2); break; } } //Thread.sleep(2000); System.out.println("========== 두번째 공을 쳐봅니다. ========="); while (true) { ranNum2 = (int) Math.round((Math.random() * 9)); if (ranNum2 > 9 || ranNum2 < 0) { showCpuMistake(); continue; } else if (ranNum2 >= 0 || ranNum2 < 10) { if (ranNum2 == ranNum1) { showCpuMistake(); continue; } //System.out.println("ranNum2 생성 완료 ==>" + ranNum2); break; } } //Thread.sleep(1000); System.out.println("========== 세번째 공을 쳐봅니다. ========="); while (true) { ranNum3 = (int) Math.round((Math.random() * 9)); if (ranNum3 > 9 || ranNum3 < 0) { showCpuMistake(); continue; } else if (ranNum3 >= 0 || ranNum3 < 10) { //System.out.println("ranNum3 생성 완료 ==>" + ranNum3); if (ranNum3 == ranNum1 && ranNum3 == ranNum2) { showCpuMistake(); continue; } break; } } int[] cpuNum = new int[3]; cpuNum[0] = ranNum1; cpuNum[1] = ranNum2; cpuNum[2] = ranNum3; return cpuNum; } int[] inputPlayer() { showPlayerTurn(); while (true) { inputNumOrigin = sc.nextLine(); inputNumOriginParseInt = Integer.parseInt(inputNumOrigin); if (inputNumOriginParseInt < 100 || inputNumOriginParseInt > 999) { showPlayerMistake1(); } else { inputNum1 = Integer.parseInt(inputNumOrigin.substring(0, 1)); inputNum2 = Integer.parseInt(inputNumOrigin.substring(1, 2)); inputNum3 = Integer.parseInt(inputNumOrigin.substring(2, 3)); if (inputNum1 == inputNum2 || inputNum1 == inputNum3 || inputNum2 == inputNum3) { showPlayerMistake2(); } else { break; } } } int[] playerNum = new int[3]; playerNum[0] = inputNum1; playerNum[1] = inputNum2; playerNum[2] = inputNum3; return playerNum; } String[] calculate(int[] cpuNum, int[] playerNum) { String[] resultStr = new String[3]; for (int i=0;i<3;i++) { if (cpuNum[i] == playerNum[i]) { System.out.println("================ Strike!! ================"); resultStr[i] = "S"; }else{ System.out.println("================= Ball!! ================="); resultStr[i] = "B"; } } return resultStr; } void output(String[] resultStr) throws InterruptedException { boolean flag = true; for(int i = 0; i < resultStr.length; i++){ if (resultStr[i].equals("S")) { flag = true; } else if (resultStr[i].equals("B")) { flag = false; break; } } if (flag){ System.out.println("삼진아웃! 모두 Strike!! Player가 이겼습니다."); } else if (!flag) { System.out.println("CPU에게 기회가있네요.. 처음부터 다시하죠?"); } } boolean tryAgain() throws InterruptedException { System.out.println(" [1] YES / [2] No Thanks "); tryNum = sc.nextInt(); // 전역 선언된 tryNum 변수에 값을 저장 sc.nextLine(); if (tryNum == 1) { System.out.println("게임을 다시 시작합니다."); return true; } else if (tryNum == 2) { System.out.println("즐거운 게임이었습니다!! 좋은 하루 되세요."); return false; } else { System.out.println("잘못된 접근입니다. 프로그램을 종료합니다."); return false; } } void showTopMenu() { System.out.println("=========================================="); System.out.println("<<<<<< Player VS CPU BASEBALL GAME >>>>>>>"); System.out.println("=========================================="); } void showPlayerTurn() { System.out.println("=========================================="); System.out.println("============== Player's Turn ============="); System.out.println("=========================================="); System.out.println("======= 3자리 숫자를 입력해 주세요 ======="); System.out.println("===== 숫자를 맞춰서 아웃 시킬겁니다. ====="); System.out.println("===== 중복 숫자는 허용되지 않습니다. ====="); System.out.println("=========================================="); System.out.print("ex)123==>"); } void showCpuTurn() { System.out.println("=========================================="); System.out.println("=============== CPU' s Turn =============="); System.out.println("=========================================="); System.out.println("======= CPU가 방망이를 휘두릅니다. ======="); System.out.println("========= 잠시만 기다려 주세요. =========="); System.out.println("=========================================="); } void showCpuMistake() { System.out.println("======= 미끄러져서 다시 하자네요;; ======="); } void showPlayerMistake1() { System.out.println("=== 숫자는 3자리를 입력해주세요 ex)123 ==="); } void showPlayerMistake2() { System.out.println("=== 중복된 숫자는 허용되지 않는다구요! ==="); System.out.println("=========== 다시 입력해주세요. ==========="); } }
Java
복사