<예제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이면 ");
}
}
}
🤦문제를 보고 생각해야할 점
<예제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
<예제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볼
🤦문제를 보고 생각해야할 점