유난스런 개발 기록

[JAVA] Day-8 _ Math.random() 난수 생성하기 본문

개념정리/JAVA

[JAVA] Day-8 _ Math.random() 난수 생성하기

yourhwan 2023. 1. 18. 21:59

day-8

 Math.random()


 Math.random() 이란

  • java.lang 패키지에 속한 메소드이다.
  •  0.0 이상 1.0 미만의 실수(double)값을 랜덤하게 나타내어주는 메소드이다.
  • 즉,  0.0 <= 임의의 난수(실수) < 1.0

기본적인 코드의 형태는 아래와 같다.

랜덤한 정수 = (int)(Math.random()*구간범위)+시작값;

 

그렇다면 1 부터 10 까지의 랜덤한 정수를 얻기 위해서는 어떻게 해야할까?

int rand1 = (int)(Math.random()*(10))+1;
		System.out.println("1 부터 10 까지의 랜덤한 정수 => " + rand1);

아래의 코드를 통해 1 부터 10 까지의 정수를 랜덤하게 얻을 수 있다.

프로그램 실행 때마다 매번 랜덤으로 값이 출력 된다.

출력되는 값이 나오는 과정을 표현해보자면 다음과 같다.

			1 부터 10 까지중 랜덤한 정수를 얻어와 본다.
		   
		    랜덤한 정수 = (int)(Math.random()*구간범위)+시작값;
		    
		    Math.random() ==> 0.0 일 때 
		    (int)0.0*(10-1+1)+1 ==> 1
		    
		    Math.random() ==> 0.0872948627250868 일 때
		    (int)0.0872948627250868*(10-1+1)+1 ==> 
		    (int)0.872948627250868 ==> 0   + 1 ==> 1  
		    
		    Math.random() ==> 0.8606970691775878 일 때
		    (int)0.8606970691775878*(10-1+1)+1 ==> 
		    (int)8.72948627250868 ==> 8    + 1 ==> 9
		    	
		    Math.random() ==> 0.21534823746789 일 때
		    (int)0.21534823746789*(10-1+1)+1 ==> 
		    (int)2.1534823746789 ==> 2    + 1 ==> 3
		    
		    Math.random() ==> 0.5672984827210117 일 때
		    (int)0.5672984827210117*(10-1+1)+1 ==> 
		    (int)5.672984827210117 ==> 5    + 1 ==> 6

 

Math.random() 메소드를 통해 임의의 실수를 얻고 여기에 구간범위 값을 곱해준 후 첫시작 값을 더해준다.

그 과정 속에서 시작값을 더해주기 전에 구간범위 까지 계산을 한다면, 소수점 이하의 부분이 나오게 된다.

이때 소수점 이하의 부분은 전부 날려주고 정수 부분만 남겨두고 시작값을 더해주면 랜덤한 정수를 얻을 수 있다.

 

3 에서 부터 7 까지라고 한다면 코드는 다음과 같다.

int rand2 = (int)(Math.random()*(7-3+1))+3;
		System.out.println("3 부터 7 까지의 랜덤한 정수 => " + rand2);

 

이렇게 Math.random() 메소드의 기본적인 구조와 사용법을 알아봤다. 

그렇다면 해당 메소드를 활용하여 만들 수 있는 로또 프로그램과 가위바위보 게임을 만들어보자

 

학원에서 실습을 진행할 때는 아무래도 코드를 따라치다보니 이해가 되면서 빠르게 만들었지만,

막상 집에서 혼자 만들어보니 생각보다 시간이 많이 소요됐다. 여러번 반복해서 만들어보고

코드를 직접 짜보는 연습이 가장 중요하다고 한번 더 느꼈다.

수업에서 들은 내용은 내 것이 아니고, 복습하며 직접 짠 코드가 내 것이 된다!!

로또 프로그램의 코드는 다음과 같다.

 

package my.day08.b.random;

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

public class _3GawibawiboMain {

	public static void main(String[] args) {
		
		Random rnd = new Random();
		
		Scanner sc = new Scanner(System.in);
		
		String str_menuno = "";
		
		int win=0, draw=0, lose=0;	// 전적을 담아줄 변수 선언
		do {
	        System.out.println("\n============= 메 뉴 =============\n"
	        		          +"1.가위\t2.바위\t3.보\t4.게임종료\n"
	        		          +"=================================");
	        
	        System.out.print(">> 선택하세요 => ");
	        
	        str_menuno = sc.nextLine(); // 사용자가 입력
	        
	        // 1~3 까지중 랜덤한 숫자 한개 만들기
	        int rndnum = rnd.nextInt(3-1+1) + 1;
	        
	        // 정수를 문자열로 변환하기 => String.ValueOf(); 메소드를 사용
	        String str_rndnum = String.valueOf(rndnum);   
	        //  1=>"1"  2=>"2"  3=>"3"
	        // 사용자가 입력 한 값은 nextLine()으로 받았기 때문에 문자열이다. 때문에 난수를 생성한 것은 int, 즉 정수기 때문에 문자열로 형변환을 해줘야한다.
	        String str_pc_gbb = "";
	        if("1".equals(str_rndnum))       str_pc_gbb = "가위";
	        else if("2".equals(str_rndnum))  str_pc_gbb = "바위";
	        else                             str_pc_gbb = "보";
	        
	        boolean status = true;
	        String str_user_gbb = "";
	        switch (str_menuno) {
				case "1": // 가위
					str_user_gbb = "가위";
					break;

				case "2": // 바위
					str_user_gbb = "바위";
					break;	
					
				case "3": // 보
					str_user_gbb = "보";
					break;	
					
				case "4": // 게임종료
					status = false;
					break;					
	
				default:
					System.out.println(">> [경고] 메뉴에 존재하지 않는 것입니다. \n");
					status = false;
					break;
			}// end of switch(str_menuno)-----------------
	        
	        if(status) {
	        	
	        	String str_result = "";
	        	// 사용자가 이긴경우
	        	if( "1".equals(str_menuno) && "3".equals(str_rndnum) ||
	        		"2".equals(str_menuno) && "1".equals(str_rndnum) ||
	        		"3".equals(str_menuno) && "2".equals(str_rndnum) ) {
	        	str_result = "이겼습니다.^^!!\n";
	        	win++;
	        	}
	        	// 사용자가 진경우
	        	else if( "1".equals(str_menuno) && "2".equals(str_rndnum) ||
		        		"2".equals(str_menuno) && "3".equals(str_rndnum) ||
		        		"3".equals(str_menuno) && "1".equals(str_rndnum) ) {
	        	str_result = "졌습니다.ㅜㅜ\n";
	        	lose++;
	        	}
	        	// 사용자와 PC가 비긴경우
	        	else {
	        	str_result = "비겼습니다.\n";
	        	draw++;
	        	}
	        	System.out.println("\n=== 게임결과 ===\n"
	        				     + "사용자 : "+str_user_gbb+"\n"
	        		             + "컴퓨터 : "+str_pc_gbb+"\n"
	        		             + "사용자님이 "+str_result+"\n"
	        					 + "사용자 전적 : \n"
	        		             + win+"승"+draw+"무"+lose+"패");
	        }
	        
		} while( !("4".equals(str_menuno)) );
        
		sc.close();
		System.out.println("\n>> 프로그램 종료 <<");

	}// end of main()-------------------------------------

}

 

가장 헷갈렸던 부분은 if문에서 .equals()를 사용했는데 ==과 차이가 무엇인지 개념이 확실하게 자리잡지 못했었다.

.equal()의 경우 문자열의 리터럴 값을 비교한다고 한다. 한마디로 객체 간의 값을 비교하는 것이다.

==의 경우는 주소값을 비교한다.

생각해보니 책으로 공부할 때 참조변수 부분을 공부할 때, 참조변수 선언 시 메모리에 퍼올려지는 과정을 살펴보는 부분에서

==를 통해 서로 다른 주소값을 갖게 된다는 것을 실습으로 확인했었다.

잠깐 헤멘 부분이지만 다시 한번 확실하게 짚고 넘어갈 수 있어서 좋았다!

 

저번 수업시간에 배웠던 do~while문을 통해 내부의 조건문과 반복문이 특정 조건에 맞는다면

사용자가 반복적으로 게임을 진행할 수 있도록 만들었다. 

추가로 boolean을 통해 내부 조건문의 값이 true면 프로그램을 이어서 진행하고

false일 경우 break를 통해 다시 처음부터 알맞은 값을 넣을 수 있게 유도했다...!

코드를 이해하고 만드는 거 보다 글로 설명하려니 더 어려운듯하다...

 

스터디원들과 더 많이 소통하고 대화하며 설명하는 연습도 해봐야겠다.