Log/2021 CodeSquad Cocoa

코드스쿼드 코코아 2주차 학습정리&회고 모음

vanss 2022. 9. 27. 16:08
본 글은 CodeSquad 프리코스인 Cocoa 과정을 보내며, 학습한 것과 회고했던 내용들을 정리 및 기록하기 위한 글입니다.

 

2021.11.08(월)

회고

  주말에 개념 정리.. 하려고 했는데 푹 쉬어 버렸다. 그래서 월요일이었지만 컨디션이 아주 좋았다. 오늘 했던 미션은 가계부, 홀짝 게임, 행맨 게임 3가지가 있었는데 그나마 난도가 낮아 보이는 홀짝 게임을 택했다. 코드는 하기와 같다.

import java.util.Scanner;

import static java.lang.Math.min;
import static java.lang.Math.pow;

public class OddOrEven {
    public static void main(String[] args) {
        OddOrEven oddoreven = new OddOrEven();
        oddoreven.play();
    }

    Scanner sc = inputPlayeName();

    int pnameCapital = 100;
    int rnameCpatial = 120;
    int roundcount = 1;

    private int play() {

        int rCountNum = rCountNum();

        String pInputOddEven = inputOddEven(sc, "홀,짝을 입력해주세요.");
        int bettingNum = inputBetnumover(sc, pnameCapital, rnameCpatial);

        String rOddEven = rCountnumJudge(rCountNum);


        if (pInputOddEven.equals(rOddEven)) {
            rnameCpatial = rBalanceLose(rnameCpatial, bettingNum, "현재 상대방의 잔액은 ");
            pnameCapital = pBalanceWin(pnameCapital, bettingNum, "현재 나의 잔액은 ");
        } else {
            pnameCapital = pBalanceLose(pnameCapital, bettingNum);
            rnameCpatial = rBalanceWin(rnameCpatial, bettingNum, "현재 상대방의 잔액은 ");
        }

        if (roundcount == 8 && rnameCpatial == 0) {
            playerWin(pnameCapital, roundcount);
        } else if (rnameCpatial == 0) {
            roundcount++;
            rnameCpatial = nextLevel(pnameCapital, roundcount);
            return play();
        } else if (pnameCapital == 0) {
            playerlose(pnameCapital, roundcount);
        } else {
            return play();
        }
        return pnameCapital;
    }

    private static Scanner inputPlayeName() {
        Scanner sc = new Scanner(System.in);
        String pname = inputOddEven(sc, "플레이어의 이름을 입력해주세요.");
        System.out.println("플레이어의 이름은 " + pname + " 입니다.");
        return sc;
    }

    private static int rCountNum() {
        int rCountNum;
        rCountNum = (int) (Math.random() * 20) + 1;
        return rCountNum;
    }

    private static String inputOddEven(Scanner sc, String s) {
        System.out.println(s);
        return sc.next();
    }

    private static int inputBetnumover(Scanner sc, int pnameCapital, int rnameCpatial) {
        int inputBetNum = getInputBetNum(sc);

        while (inputBetNum != 0) {
            if (inputBetNum > min(pnameCapital, rnameCpatial)) {
                System.out.println("베팅 금액을 초과하였습니다." + "\n" + min(pnameCapital, rnameCpatial) + " " + "이하로 입력해주세요.");
                inputBetNum = getInputBetNum(sc);
            } else {
                break;
            }
        }
        return inputBetNum;
    }

    private static int getInputBetNum(Scanner sc) {
        System.out.println("베팅 금액을 입력해주세요.");
        int inputBetNum = sc.nextInt();
        return inputBetNum;
    }

    private static String rCountnumJudge(int rCountNum) {
        String rOddEven;

        if (rCountNum % 2 == 0) {
            rOddEven = "짝";
        } else {
            rOddEven = "홀";
        }
        return rOddEven;
    }

    private static int rBalanceLose(int rnameCpatial, int bettingNum, String s) {
        rnameCpatial -= bettingNum;
        System.out.println(s + rnameCpatial + "입니다.");
        return rnameCpatial;
    }

    private static int pBalanceWin(int pnameCapital, int bettingNum, String s) {
        pnameCapital += bettingNum;
        System.out.println(s + pnameCapital + "입니다.");
        return pnameCapital;
    }

    private static int rBalanceWin(int rnameCpatial, int bettingNum, String s) {
        rnameCpatial = pBalanceWin(rnameCpatial, bettingNum, s);
        return rnameCpatial;
    }

    private static int pBalanceLose(int pnameCapital, int bettingNum) {
        pnameCapital = rBalanceLose(pnameCapital, bettingNum, "현재 나의 잔액은 ");
        return pnameCapital;
    }


    private static void playerWin(int pnameCapital, int i) {
        System.out.println("WIN!!");
        System.out.println("당신의 소지금은 " + pnameCapital + " 이며, 총 " + i + "라운드 진행되었습니다.");
    }

    private static int nextLevel(int pnameCapital, int roundcount) {
        int rnameCpatial;
        rnameCpatial = (int) (pnameCapital * pow(1.2, roundcount));
        System.out.println(roundcount + "라운드" + ">>" + "새로운 상대가 등장합니다.");
        return rnameCpatial;
    }

    private static void playerlose(int pnameCapital, int roundcount) {

        System.out.println("당신의 소지금은 " + pnameCapital + " 이며, 총 " + roundcount + "라운드 진행되었습니다.");
        System.out.println(" - Game Over - ");
    }

}

  최대한 객체생활체조를 지키며 해보려고 했는데, 아직 너무 지저분해 보인다. 내가 모르는 축약할 수 있는 함수나 다른 방법으로 가독성 높일 수 있는 방법이 있을 텐데 현재 나로선 저게 최선이다. 이전보다 나아진 게 있다면, 이전까지는 우선 코딩부터 시작하고 시작하면서 목표에 맞게 다시 수정하는 방식으로 진행했다면 이번에는 각 목표에서 필요한 기능들을 어떻게 구현할지 설계하고 각 기능부터 구현을 하였고 그 후 로직에 맞춰 다시 리팩터링 및 정렬을 하였다. 처음으로 이런 방식으로 진행해봤는데 꼬이는 거 없이 퍼즐 맞추듯이 딱딱 맞는 느낌이 들어 깔끔했다.
  오늘도 질문이 적었다.. 내일부터는 꼭 질문 하나씩은 하자 아무거나라도!


새롭게 배운 내용

(스터디에서 발췌한 내용)

  • 반복적으로 사용되는 객체를 어떻게 관리할 것인가.
    • ex) Scanner
    • 상태가 있는 객체는 항상 만들어야 한다.
      • 생성자를 사용하면 좋음.
      • 하지만 반복적으로 사용되는 객체가 상태를 가진다는 게 좋은 설계인가를 먼저 의심한다.
    • 상태가 없는 객체라면 메서드 영역에 정의될 수 있게 한 후 반복 사용한다.
      • hint. 싱글턴 패턴, 유틸 성 객체, Spring Bean

      1. 보통 자바에서는 문자열이 동일한지 비교할 때 ==보단 equals를 사용하여 체크한다. 이유는 ==는 문자열이 같은지 확인하는 것이 아닌 object가 동일한지를 체크하기 때문이다.
      2. Math.random() 함수 : 0.0보다 크고 1.0보다 작은 값을 랜덤 하게 추출한다. 정수 1~20 범위로 한정 지어 활용하려면 (int)(Math.random()*20)+1; 로 변경해줘야 한다.
      3. Math.min(a, b) 함수 : a와 b 값 중 적은 수를 리턴합니다.
      4. Math.pow(a, b) 함수 : a값의 b승 값을 리턴합니다.
      5. 디버깅! 확인하고자 하는 줄 왼쪽에 브레이크 포인트를 걸고 벌레 모양을 누른 뒤 상황에 맞춰 step into로 버그를 잡아낼 수 있다.(쏠쏠)

2021.11.09(화)

회고

  수업 때 박터지는 날이였다. 모르는 내용들이 뇌에 끊임없이 주입되어 과부화가 발생했다.. 그리고 어제 했던 홀짝게임의 피드백으로 (1. 메소드가 너무 많은것 2. 변수명, 메소드명의 대문자가 잘못 표기되어 있는것) 2가지를 받았는데 아직 1번 사항은 고치지 못하였다. 2번만 개선한 코드를 우선 하기에 적어 놓고 오늘 수업때 새롭게 배운 내용과 궁금한 내용들을 정리하도록 하겠다.(++클래스도 나눠봤다.)

package D3;

public class OddOrEven {

    public static void main(String[] args) {
        Play play = new Play();
        play.inputData();
    }
}
package D3;

import java.util.Scanner;

import static java.lang.Math.min;
import static java.lang.Math.pow;

public class Play {
    private Scanner sc = inputPlayerName();

    private int playerCapital = 100;
    private int computerCapital = 120;
    private int stageCount = 1;

    public int inputData() {
        int computerRandomNum = selectComputerRandomNum();

        String playerInputOddEven = inputOddEven(sc, "홀,짝을 입력해주세요.");
        int betMoney = checkBetMoney(sc, playerCapital, computerCapital);

        String computerOddEven = checkOddEven(computerRandomNum);

        if (playerInputOddEven.equals(computerOddEven)) {
            computerCapital = computerLose(computerCapital, betMoney, "현재 상대방의 잔액은 ");
            playerCapital = playerWin(playerCapital, betMoney, "현재 나의 잔액은 ");
        } else {
            playerCapital = playerLose(playerCapital, betMoney);
            computerCapital = computerWin(computerCapital, betMoney, "현재 상대방의 잔액은 ");
        }

        if (stageCount == 8 && computerCapital == 0) {
            playerWin(playerCapital, stageCount);
        } else if (computerCapital == 0) {
            stageCount++;
            computerCapital = nextLevel(playerCapital, stageCount);
            return inputData();
        } else if (playerCapital == 0) {
            playerlose(playerCapital, stageCount);
        } else {
            return inputData();
        }
        return playerCapital;
    }

    private static Scanner inputPlayerName() {
        Scanner sc = new Scanner(System.in);
        String playerName = inputOddEven(sc, "플레이어의 이름을 입력해주세요.");
        System.out.println("플레이어의 이름은 " + playerName + " 입니다.");
        return sc;
    }

    private static int selectComputerRandomNum() {
        int computerRandomNum;
        computerRandomNum = (int) (Math.random() * 20) + 1;
        return computerRandomNum;
    }

    private static String inputOddEven(Scanner sc, String s) {
        System.out.println(s);
        return sc.next();
    }

    private static int checkBetMoney(Scanner sc, int playerCapital, int computerCapital) {
        int validBetMoney = getInputBetMoney(sc);

        while (validBetMoney != 0) {
            if (validBetMoney > min(playerCapital, computerCapital)) {
                System.out.println("베팅 금액을 초과하였습니다." + "\n" + min(playerCapital, computerCapital) + " " + "이하로 입력해주세요.");
                validBetMoney = getInputBetMoney(sc);
            } else {
                break;
            }
        }
        return validBetMoney;
    }

    private static int getInputBetMoney(Scanner sc) {
        System.out.println("베팅 금액을 입력해주세요.");
        int inputBetMoney = sc.nextInt();
        return inputBetMoney;
    }

    private static String checkOddEven(int n) {
        String computerOddEven;

        if (n % 2 == 0) {
            computerOddEven = "짝";
        } else {
            computerOddEven = "홀";
        }
        return computerOddEven;
    }

    private static int computerLose(int computerCapital, int betMoney, String s) {
        computerCapital -= betMoney;
        System.out.println(s + computerCapital + "입니다.");
        return computerCapital;
    }

    private static int playerWin(int playerCapital, int betMoney, String s) {
        playerCapital += betMoney;
        System.out.println(s + playerCapital + "입니다.");
        return playerCapital;
    }

    private static int computerWin(int computerCaptial, int betMoney, String s) {
        computerCaptial = playerWin(computerCaptial, betMoney, s);
        return computerCaptial;
    }

    private static int playerLose(int playerCaptial, int betMoney) {
        playerCaptial = computerLose(playerCaptial, betMoney, "현재 나의 잔액은 ");
        return playerCaptial;
    }


    private static void playerWin(int playerCapital, int i) {
        System.out.println("WIN!!");
        System.out.println("당신의 소지금은 " + playerCapital + " 이며, 총 " + i + "라운드 진행되었습니다.");
    }

    private static int nextLevel(int playerCapital, int roundCount) {
        int computerCapital;
        computerCapital = (int) (playerCapital * pow(1.2, roundCount));
        System.out.println(roundCount + "라운드" + ">>" + "새로운 상대가 등장합니다.");
        return computerCapital;
    }

    private static void playerlose(int playerCaptial, int roundCount) {

        System.out.println("당신의 소지금은 " + playerCaptial + " 이며, 총 " + roundCount + "라운드 진행되었습니다.");
        System.out.println(" - Game Over - ");
    }
}

새롭게 배운 내용

커밋을 의미 있게 쓰자 (메서드 한 기능 구현당, 최대한 제목에서 다 알 수 있도록 참고:udacity 커밋 가이드)

예약어에 대해 생각해보자 (예약어로 될만한 단어로 선언하지 않기)

커밋 전, 코드 리 포맷은 필수다. (커밋 시 형식은 '한 줄 요약 제목 / <한 줄 띄기> / 상세 내용' 순으로 추천)

메서드가 많아지면 클래스로 분리하기.

코테 준비는 '알고리즘 문제 해결 전략' 책을 추천.

클래스 이름 첫 글자는 꼭 대문자로.

구현전에 주석으로 단계별로 정리해보기 -> 그다음에 메서드명 정리해보기

메서드는 매개변수와 리턴 값으로 통신한다.

반복문은 CPU의 빠른 작업 속도를 활용하고 코드의 간결화를 위해 사용한다.

조건문은 일종의 필터로 검증작업에 활용된다.

Return의 2가지 의미 (1. 메서드를 종료한다. / 2. 호출한 쪽으로 값을 반환한다.)

Return을 쓰는 이유 : 메서드 간의 통신 즉, 상호작용을 위해서

메서드는 한 번에 한 가지 일을 하고 메서드가 모여 프로그램을 완성함.

객체는 무조건 클래스에서 만들어지는 게 아니다.(자바에서만 그럼)

행동은 상태를 항상 변화시키고, 행동은 다른 객체의 상태를 변화시킨다.

클래스를 잘 쪼개서 만드는 것 -> 객체지향 프로그래밍 또는 설계라고 한다.

객체지향 프로그램은 아주 커다란 프로그램 만들기에 용이하고, 유지보수에 좋다.

그럼 함수형은 왜 요새 많이 쓰나?(인터넷의 발달과 빅데이터 시대가 오면서 연산속도가 중요해짐)

메서드 만들 때 무조건 기본은 'private'이다.

궁금한 내용

2차원 배열이란?

this. 가 뭐지?(객체 생성 시 this.x에서 x를 참조하도록 함)

메서드 선언할때 final이 뭐지?

getter와 setter는 뭐지?

향상된 for문이란 무엇이지?

메소드 영역, JVM 메모리란?

런타임 인셉션으로 인해 throw를 씀 <- 이게 무슨 소리지?

hasnext가 뭐지?

Call By Value와 Call By Reference의 핵심이란?

어떤 함수를 호출하는 과정에서 인자(Argument)를 함수의 매개변수(Parameter)에 넘기게 되는 과정에서 어떤 방식으로 넘기느냐를 설명하는 문장

Call by Value : argument를 복제하여, Parameter에 대입함

Call by Reference : Parameter가 원본 argumnet를 직접 참조함. 따라서 함수의 작업 과정에서 parameter의 변화는 argument에 영향을 미친다.

Argument와 Parameter의 차이는?


  Q1. 2차원 배열이란?

  • 다차원 배열중의 하나로, 배열 요소로 다른 배열을 가지는 배열을 의미한다.
    (2차원 배열은 배열 요소로 1차원 배열을 가지는 배열이다.)
  • 자바에서는 2차원 배열을 나타내는 타입을 따로 제공하지 않으므로, 1차원 배열을 활용하여 표기한다.

문법으로 표기하기
1) 타입[][] 배열 이름;
2) 타입 배열 이름[][];
3) 타입[] 배열 이름[];

 

그림으로 도식화한 2차원 배열

예제 1(배열 선언과 동시에 초기화하는 방법)
int [][] arr = {
{10, 20, 30},
{40, 50, 60}
}
실행결과
10 20 30
40 50 60

예제 2(가변 배열 : 행마다 다른 길이의 배열을 요소로 저장할 수 있다.)
int [][] arr = {
{10, 20},
{30, 40, 50},
{60, 70}
}
실행결과
10 20
30 40 50
60 70

 


2021.11.14(일)

회고

  이번 주는 다른 시험을 같이 준비하느라 저번 주보다 코코아 과정에 많이 집중을 못한 거 같다. 끝나고 나서 돌아보니 그렇게 준비할 필요가 없었던 시험이었는데... JK가 말씀하셨던 어정쩡하게 쉴 거면 푹 쉬어라 라는 말이 떠오르는 시점이었다.
  해서 오늘은 목요일에 했던 수업 중에 배우고 몰랐던 내용들을 정리해보기로 했다. 시간이 되면 화요일에 썼던 회고 내용 보충도 해야겠다.


새롭게 배운 내용

자바는 항상 메인 메서드로 시작한다.

메인 메서드 안에 변수는 stack에 올라간다.

'new'는 주소를 생성하는 게 아니라 객체를 생성한다.(객체를 생성하고 주소 값을 가리킨다.)

static 변수란
1) 클래스 공통으로 1개 생긴다.
2) 모든 클래스들이 공통으로 가지는 공통 변수이다.
3) 메서드 영역에 별도의 static영역에 들어간다.

static 변수는 객체를 생성하지 않아도 쓸 수 있다.(heap 영역이 아니다.)

지역변수는 자동으로 초기화가 되지 않기 때문에 초기화하지 않고 사용할 때 에러가 발생한다.

static 메서드 = 객체 생성 없이 사용할 때 쓴다.

인스턴스 변수는 객체 없이 있을 수 없는 변수다.

this는 인스턴스다.(나 자신의 인스턴스에 대한 참조 변수이다.)

궁금한 내용

형 변환이란?

멤버 변수 / 클래스 변수 / 인스턴스 변수란?