<예제1>
Q. 1부터 10까지의 합을 구하는 프로그램을 작성하시오
package com.step3;
// 변수는 몇 개가 필요한가요?
// 지변으로 할까, 전변으로 할까 아니면 둘 다 다 된다?
// 타입은 뭘로 하지?
public class for2 {
	
	public static void main(String[] args) {
		int i = 0;
		int hap = 0; 
        // 2를 주면 답에 영향이 있다 - 초기화 위치, 값 정확히
		for(i=1;i<=10;i=i+1) {
			hap = hap + i;
		}
		System.out.println(hap);
	}
}
  • 문제를 보고 먼저 파악해야할 것은?
    - 변수는 몇 개가 필요한가요?
    - 지변으로 할까, 전변으로 할까 아니면 둘 다 다 된다?
    - 타입은 뭘로 하지?
<예제2-for문 안에 if문>
package com.step3;

public class For3 {

	public static void main(String[] args) {
		int i = 0;
		int hap = 0; // 홀수의 합
		int hap1 = 1; // 짝수의 합
		for(i=1;i<11;i=i+1) {
			if(i%2==1) {
				hap = hap + i;
				System.out.println("홀수일 때: "+hap);
			} 
			else if(i%2==0) {
				hap1 = hap1 + i;
			}
			System.out.println(hap);
		}
		System.out.println("홀수의 최종 결과값은: "+hap);
		System.out.println("짝수의 최종 결과값은: "+hap1);
	}
}
<예제3>
package com.step3;

public class For4 {
	public static void main(String[] args) {
		int hap = 0;
		for(int i=1;i<11;i++) {
			if(i%3 == 0) { // 3의 배수
				hap = hap + i;
				System.out.println(hap);
			}
		}
		System.out.println("1부터 10까지 세면서 3의 배수의 합은? "+hap);
	}
}
<예제4-1: fizzbuzz게임>
- 5의 배수일 때 fizz 출력 / 7의 배수일 때 buzz 출력
- 5, 7의 공배수일 때 fizzbuzz 출력

package com.step3;

class FizzBuzz {
}
public class FizzBuzzGame {

	public static void main(String[] args) {
		int i = 1;
		int j = 0;
		// if문 괄호 안에는 조건문이 온다
        // 참인지 거짓인지를 판별할 수 있는 문장이 와야 함
		// &: 그리고(두 조건을 만족할 때만 true 리턴)
		if(i%5==0 & i%7==0) {
			System.out.println("fizzbuzz");
		}
		if(i>0 & j<1) {
			System.out.println("둘 다 참이면 ");
		}
		else {
			System.out.println("둘 중 하나라도 조건이 false이면 ");
		}
	}
}

🤦‍문제를 보고 생각해야할 점

  • 변수는 몇 개가 필요하지? 변수의 타입은?
  • for문 안에 if문이 오는거야? 아님 if문 안에 for문이 와야 하나요?
  • 조건을 따질 때 fizz를 먼저 따져야 하는지?
  • 아니면 fizzbuzz인 경우, 즉 5와 7의 공배수를 먼저 따져야 하는지?
  • 35는 5로 나누어 나머지가 0인지를 먼저 비교하면 fizz를 출력하므로 원하는 결과가 아니다
  • 조건을 따질 때도 순서가 결과에 영향이 있다
<예제4-2: fizzbuzz게임>
package com.step3;

public class C {

	public static void main(String[] args) {
		for(int i=1;i<101;i=i+1) {
			if(i%5==0 & i%7==0) {
				System.out.println("fizzbuzz");
			}
			else if(i%5==0) {
				System.out.println("fizz");
			} 
			else if(i%7==0) {
				System.out.println("buzz");
			} 
			else {
				System.out.println(i);
			}
		}
	}
}

<연습문제1>
달의 중력은 지구 중력의 17%에 불과합니다. 지구에서 몸무게가 100kg인 사람은 달에 가면 17kg밖에 안됩니다. 당신의 몸무게는 달에서 얼마입니까?
(몸무게 N은 실수이고 키보드로부터 입력받습니다)

출력 ex) 지구몸무게 : 100
달 몸무게 : 17kg

  • Scanner는 java폴더 아래 util폴더 아래 선언되어 있는 클래스이다.(자바가상머신을 설치하면 내장되어 있는 클래스)
  • import문을 써야 하는 건, java.lang 폴더가 아닌 폴더는 JVM이 찾을 수가 없어서 반드시 import문으로 물리적인 위치를 나타낸다
  • Scanner 클래스 내부에도 여러 개의 메소드가 정의되어 있다. 어떤 메소드가 있는지는 인스턴스화 한 후에 인스턴스 변수.을 찍고 기다리면
    quick fix 기능 제공되어 확인해볼 수 있다.
  • quick fix 기능을 누가 제공? → 이클립스
    이클립스는 JVM에서 제공하는 API, 즉 document문서를 제공받고 있어서 그 내용을 보여주는 것이다
<예제5-1>
package com.step3;

import java.util.Scanner;
// 변수가 필요한가? - 그렇다면 몇 개가 필요한가요?
public class MoonWeightMain {
	public static void main(String[] args) {
		System.out.println("당신의 몸무게를 입력하세요.");
		Scanner sc = new Scanner(System.in);
		int user = sc.nextInt();
		System.out.println("사용자가 입력한 값은 " +user+"입니다.");
		double moon = 0.0;
		moon = (user*17)/100.0; // 실행문
		System.out.println("달의 몸무게는 " +moon+"입니다.");
	}
}
  • 달뿐만 아니라 화성 등 많아질 수 있으니 재사용성을 위해 메소드를 따로 꺼내보자
<예제5-2>
package com.step3;

import java.util.Scanner;

class MoonWeight {
	double account(int earth) {
		double moon = 0.0; // 지변으로 처리
		moon = (earth*17)/100.0;
		return moon;
	}
}
public class MoonWeightMain {
	public static void main(String[] args) {
		System.out.println("당신의 몸무게를 입력하세요.");
		Scanner sc = new Scanner(System.in);
		int user = sc.nextInt();
		System.out.println("사용자가 입력한 값은 " +user+"입니다.");
		MoonWeight mw = new MoonWeight();
		System.out.println("달의 몸무게는 " + mw.account(user) +"입니다.");
	}
}
  • 메소드를 좀 더 디테일하게 나눠보자 (스캐너를 따로 꺼내서 메소드로)
    → 사용자로부터 입력 받는 값을 별도의 메소드로 선언해보기
<예제5-3>
package com.step3;

import java.util.Scanner;

class MoonWeight {

	int getUser() {
		Scanner sc = new Scanner(System.in);
		int user = sc.nextInt();
		return user;
	}
	double account(int earth) {
		double moon = 0.0; 
		moon = (earth*17)/100.0; 
		return moon;
	}
}
public class MoonWeightMain {

	public static void main(String[] args) {
		System.out.println("당신의 몸무게를 입력하세요.");
		MoonWeight mw = new MoonWeight();
		int user = mw.getUser();
		System.out.println("사용자가 입력한 값은 " + mw.getUser() +"입니다.");
		System.out.println("달의 몸무게는 " + mw.account(mw.getUser()) +"입니다.");
	}
}
  • int getUser(): 리턴타입을 int로 한 이유는?
    *힌트 int user = sc.nextInt();
    → 사용자가 콘솔에 입력한 값을 읽어오는 메소드가 nextInt()인데, 이 넥스트인트 메소드의 소유주가 Scanner이다. nextInt로 읽어오는 값이 int이므로 메소드 설계시 리턴타입은 동일한 int로 결정함.

  • this 이슈: 화면 쪽에 리액트가 활용되고, 타입스크립트도 등장하면서 this가 참조하는 객체가 달라졌다(초보개발자에게는 구분이 어려움)

  • 메소드 호출결과를 굳이 리턴타입으로 받아서 처리하는 방법과, 변수로 받지 않고 메소드 호출을 직접 하는 경우의 차이가 있다?없다?
    → 문제점 지적 - 인스턴스 변수 하나에 대해서 입력받은 지구의 몸무게 값도 하나이어야 하는데, 만일 변수로 치환하지 않고 매번 메소드를 새로 호출하면 입력받는 값이 그 때마다 달라질 수 있어서 이런 상황일 때는 리턴타입으로 받아서 그 변수를 사용하는 것이 맞는 방법(매번 메소드를 호출하는 게 아니라 리턴값을 받고 동일한 값으로 처리되도록)

<예제6-리턴타입>
package com.step3;

import java.util.Random;

public class Return1 {
	void m() {
		System.out.println("리턴타입 자리에 void인 경우 = 반환값을 받을 수 없다");
	}
	int m2() {
		System.out.println("리턴타입 자리에 xxx인 경우 = 반환값을 받을 수 있다");
		return 0;
	}
	String m3() {
		System.out.println("리턴타입 자리에 xxx인 경우 = 반환값을 받을 수 있다");
		return "높여라";
	}
	Random m4() { // 리턴타입에 클래스가 오는 것
		return new Random();
	}
	Random m5() { // 리턴타입에 클래스가 오는 것
		Random r = new Random();
		return r; 
		// return new Random();을 두 줄로 풀어쓴 것과 같음
	}
	public static void main(String[] args) {
		Return1 r1 = new Return1();
		// int i = r1.m(); // 리턴타입 자리에 void이기 때문에 에러
		// System.out.println(r1.m()); // 에러
		int i = r1.m2(); // 0 출력
		System.out.println(r1.m2());
		System.out.println(r1.m3());
		System.out.println(r1.m4()); // 주소번지 출력
		System.out.println(r1.m5()); // m4와 다른 주소번지 출력
		// 타입은 같지만 각각 new로 생성했기 때문에
	}
}
출력: 리턴타입 자리에 xxx인 경우 = 반환값을 받을 수 있다
     리턴타입 자리에 xxx인 경우 = 반환값을 받을 수 있다
     0
     리턴타입 자리에 xxx인 경우 = 반환값을 받을 수 있다
     높여라
     java.util.Random@379619aa
     java.util.Random@cac736f
<예제-리턴타입>
package com.step3;

public class Return2 {
	void m(int i) { // r2.m(-1);에서 호출될 때 파라미터 자리에 -1 있다
		if(i==-1) { // -1==-1 같니? -> 네(true) -> 그럼 리턴
			return; // if문 안에 return을 쓰면 메소드를 탈출하고 나를 호출한 메인메소드로 이동
		}
		System.out.println("요기");
	}
	public static void main(String[] args) {
		Return2 r2 = new Return2();
		r2.m(-1);
		System.out.println("여기");
	}
}
<예제-break>
package com.step3;

public class Break1 {

	public static void main(String[] args) {
		for(int i=2;i<10;i=i+1) {
			// if문 안에 return을 만나면 메소드 탈출하고
			// if문이 반복문 안에 있을 땐 break;을 사용할 수 있다 - for문을 탈출함
			if(i==6) break;
		}
		System.out.println("요기요");
	}

}
<예제>
package com.step3;

public class Return3 {
	String m(int i) {
		String hint = null;
		// 조건에 따라서 return을 사용하게 되므로 못 만날 수도 있다
		// 그래서 반드시 else 추가해서 디폴트라도 넣어줘라
		if(i<0) { // 음수
			return hint = "너 음수래";
		} else if(i>0) {
			hint = "너 양수래";
			return hint; // return hint = "너 음수래";랑 같은 내용임
		} else {
			return "";
		}
		// return hint;
	}
	String m2(int i) {
		String hint = null;
		if(i<0) { // 음수
			return hint = "너 음수래";
		} else if(i>0) {
			hint = "너 양수래";
			return hint; // return hint = "너 음수래";랑 같은 내용임
		} 
		return "";
	}
	public static void main(String[] args) {
	}
}

<연습문제2>
두 개의 정수 중에서 큰 숫자를 반환하는 max메소드를 구현하세요. 두 개의 정수를 입력 받고 큰 숫자를 출력합니다.
ex. 출력) 정수(두 개) : 5 8
최대값 : 8

package com.step3;

import java.util.Scanner;

class MaxPrint {
	int max(int n1, int n2) { // max 메소드 선언 및 구현
		if(n1>n2) {
			// 웹개발에서 html페이지에 처리결과를 출력할 때 사용되기 때문에 기억하기
			// (요청할 땐 파라미터, 응답할 땐 리턴타입)
			// 아래 문장은 반드시 실행되는 건 아니다. 조건에 따라서 실행될 수도 안될 수도 있다.
			return n1;
		} else if(n1<n2) {
			return n2;
		} else {
			return -1; // EOF // -1대신 다른 숫자 써도 됨
		}
	}
}
public class MaxPrintmain {

	public static void main(String[] args) {
		MaxPrint mp = new MaxPrint();
		Scanner sc = new Scanner(System.in);
		int user1 = 0;
		int user2 = 0;
		for(int i=0;i<2;i=i+1) {
			// Scanner sc = new Scanner(System.in); // 여기는 2번 처리해야 하니까 비효율적
			if(i==0) {
				// 아래 코드가 단 한 번만 실행되도록 코드를 수정하기
				user1 = sc.nextInt(); // 이 문장이 두 번 호출되므로 user1 변수에만 값이 두 번 담기고 
				// 결과적으로 덮어쓰기가 되므로 하나의 값만 기억됨
			}
			else if(i==1) { // 두 번째 반복될 때는 아래 코드가 실행됨
				user2 = sc.nextInt();
			}
			System.out.println("user1: "+ user1 +", user2: "+ user2); // user2: 0 왜냐 재정의가 안 되고 있어서(user1만 계속 바뀐다는 것)
			// 아래 낱말 카드 문제점에 대해 설명하시오
			// 서로 다른 두 수를 입력 받아서 크다 작다를 비교해야 하므로
			// 메소드 호출전에 두 수가 먼저 결정되어 있어야 함 - 그래서 for문 밖에서 max메소드를 호출해야 함
		}
		System.out.println(user1 + "," + user2);
		int big = mp.max(user1,user2);
		System.out.println("big => "+big);
	}
}

<랜덤숫자>

<숫자맞추기 게임>
package com.step3;

import java.util.Random;
import java.util.Scanner;

import javax.swing.JOptionPane;

public class RandomGame {
	// 선언부
	// 새로 채번된 숫자를 담는다 - 정답이다
	int dap = -1; // -1은 end of file(찾아도 없다라는 의미로 -1을 쓴다)
	// 사용자가 입력하는 숫자는 절대로 전변으로 하지 않는다- 매번 입력할 때마다 바뀌어야 하니까 (유지되면 안 되니까)
	// 게임을 하는데 필요한 메소드
	// 새게임을 누를 때마다 호출되는 메소드
	// 여기서 채번되는 숫자가 정답이므로 노출하지 않는다 - 그래서 나는 전변으로 선언하였다
	public void newGame() { // 정답을 보여주면 안 되니까 모르는 상태에서 맞추도록 void
		Random r = new Random();
		// 좋은 점은? 리턴타입이 없어도 전변이면 어떠한 메소드에서도 재정의가 가능하다
		dap = r.nextInt(10); // 여기서 정답이 결정. // nextInt는 API
		// 답이 수시로 변경되면 안 된다. 유지되어야 한다. 종료될 때까지
	}
	// 판정을 내려주는 메소드를 선언해 보자. 
	/****************************************
	 * * 판정을 내려주는 메소드 구현하기
	 * @param user - 사용자가 숫자를 맞추기 위해서 입력하는 값을 담는 변수이다. - 입력할 때마다 바뀐다 - 지변
	 * @return - String - 힌트를 반환하는 변수(힌트의 예시: 높여라, 낮춰라, 정답입니다. 축하니다)
	 *****************************************/
	public String account(int user) { // 이 user자리가 매번 화면에 사용자가 입력하고 엔터쳤을 때 결정되는 값
		System.out.println("dap: " + dap + ", user: " + user);
		String hint = null;
		if(dap == user) {
			hint = "정답입니다.";
		} else if(dap > user) {
			hint = "높여라.";
			
		} else if(dap < user) {
			hint = "낮춰라.";
			
		}
		return hint;
	}
	//public void messagePrint(int user) { // user=5 복사됨 - call by value니까
		//System.out.println(account(5)); //24->5를 쥐고 간다->높여라 출력
	//}
	// 메소드 파라미터 자리에 리턴타입이 존재하는 메소드를 호출할 수 있다
	public static void main(String[] args) {
 		RandomGame rg = new RandomGame(); 
		rg.newGame(); // 이 메소드가 호출되어야 0부터 9 사이의 숫자가 채번된다. 그래서 채번된 숫자는 dap에 담김
		// messagePrint 호출할 때 파라미터 자리에 5를 넘겨주고 36번에서 account()호출될 때 지역변수에 복사된 user값
		// 즉 5가 파라미터로 넘어간다.
		// 24번에서도 user값은 5가 된다.
		Scanner sc = new Scanner(System.in); //java.util.Scanner
		for(int i=0;i<5;i++) {
			System.out.println("0~9 사이의 숫자를 입력하세요.(입력하면 엔터치기)");
			int user = sc.nextInt(); // 초기화가 5번 반복된다 - 덮어쓰기가 된다 - 맨 마지막에 덮어씌워진 값만 유지된다
			String hint = rg.account(user); 
			if(hint.equals("정답입니다")) {
				JOptionPane.showMessageDialog(null, "축하합니다.");
				break; // for문 탈출
			}
			//insert here
			else if(hint.equals("높여라.")) {
				System.out.println("더 큰 숫자를 입력하세요.");
			}
			else if(hint.equals("낮춰라.")) {
				System.out.println("더 작은 숫자를 입력하세요.");				
			}			
		}
	}
}

/*
0~9 사이의 임의의 숫자를 채번(랜덤하게 찍기)하고
사용자로부터 숫자를 입력받아서
입력받은 숫자가 더 작으면 힌트를 높여라 라고 출력하고
더 크면 낮춰라 라고 힌트를 주어서
5번까지만 기회를 제공해서 그 숫자를 맞추는 게임을 작성해 보시오

새게임을 선택했을 때는 09 사이에 새로운 숫자를 채번해야 합니다.
채번한 숫자는 dap이라는 변수에 저장해 둡시다.
그리고 dap은 전역변수로 하는 것이 좋겠습니다.
왜냐면 그 게임을 하는 그 사람이 사용하는 동안에는 오직 하나의 객체만 사용하게 될 테니까요.
(힌트문은 입력할 때마다 바뀌어야 하기 때문에 그 값은 지변)

*/
<숫자맞추기 게임>
package com.step3;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

// JFrame을 상속받아서 사용자 정의 클래스를 선언하였다
// ActionListener는 엔터쳤을 때 이벤트 처리를 위해서 선언한 인터페이스이다.
public class RandomGameView extends JFrame  implements ActionListener{
	// FlowLayout 설정해서 중앙-다중문 쓰는 JTextArea배치, 남쪽에는 싱글로우 작성하는 JTextField
	JPanel 		jp_center 	= new JPanel(); 
	JPanel 		jp_east 	= new JPanel(); // 새게임, 정답, 지우기, 종료버튼 배치하기
	JTextArea 	ta_result 	= new JTextArea(10,50);
	JTextField	tf_input	= new JTextField("");
	JButton		jtbnNew		= new JButton("새 게임");
	JButton		jtbnDap		= new JButton("정답");
	JButton		jtbnClear	= new JButton("지우기");
	JButton		jtbnExit	= new JButton("종료");
	Font 		f 			= new Font("Thoma", Font.BOLD, 18);
	
	public void initDisplay(){
		// 엔터를 치는 건 사람인데 엔터를 느끼는 건 JVM이라서 ActionListener라는 인터페이스의 약속된 메소드를 오버라이딩하기
		tf_input.addActionListener(this); // 이벤트 소스와 이벤트 처리를 담당하는 핸들러 클래스 매핑하기
		jp_center.setLayout(new FlowLayout()); // 동서남북중앙버튼이나 체크박스 배치하기
		jp_center.setBackground(Color.yellow);
		jp_center.add("Center",ta_result);
		jp_center.add("South",tf_input);
		jp_east.setBackground(Color.black);
		jp_east.setLayout(new GridLayout(4,1,2,2)); // 동서남북중앙버튼이나 체크박스 배치하기
		
		// jp_east 속지에 새게임 버튼 배치하기
		jp_east.add(jtbnNew);
		jp_east.add(jtbnDap);
		jp_east.add(jtbnClear);
		jp_east.add(jtbnExit);
		this.add("Center",jp_center);
		this.add("East",jp_east); // this는 JFrame을 가리키는 수정자이다. (상속받고 있는 JFrame)
		this.setTitle("숫자맞추기게임");
		this.setSize(600,400);
		this.setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 이 코드가 X버튼 눌렸을 때(종료) 사용된 자원 회수함
	}	
	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		RandomGameView rgv = new RandomGameView();
		rgv.initDisplay();
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		Object obj = e.getSource();
		String command = e.getActionCommand();//이벤트 발동하는 버튼의 라벨
		if("1".equals(command)) {
			System.out.println(command);
			ta_result.append(command);
		}
		else if(obj == tf_input) {
			ta_result.append(tf_input.getText()+"\n");
			tf_input.setText("");
		}
	}
}

<야구숫자게임>
3자리 숫자를 맞추는 게임 구현하기

ex. 정답: 257
329 입력: 0스트라이크1볼
529 입력: 0스트라이크 2볼
259 입력: 2스트라이크 0볼

🤦‍문제를 보고 생각해야할 점

  • 스트라이크를 전변으로 할까 지변으로 할까?
  • 볼 변수 선언
  • 변수의 개수 결정할 수 있다
  • 변수의 타입을 결정할 수 있다
  • 화면을 제공받았을 때도 코드의 재사용성을 누릴 수 있도록 메소드 설계가 되었는가
  • 파라미터의 타입과 리턴타입까지도 결정할 수 있고 활용할 수 있는지?
  • Outline
    : 이클립스-Window-Show View-Outline

0개의 댓글