# 랜덤(Random)

## 랜덤(Random)

랜덤이란 **예측할 수 없는 상태**를 말한다. 예측할 수 있다면 랜덤이라고 볼 수 없으며, 모든 프로그래밍 언어에서는 랜덤 데이터를 만들 수 있는 방법을 제공한다.

### 실생활에서의 랜덤

실생활에서 마주할 수 있는 대표적인 랜덤의 형태는 다음과 같다. 랜덤을 추첨할 때 중요한 것은 **범위**가 존재한다는 것이며, 해당 범위 내에서만 랜덤으로 값이 정해진다는 것을 유의해야 한다.

* 주사위
* 로또
* 경품추첨

### 자바의 랜덤

자바에서는 대표적으로 다음과 같은 형태의 랜덤 생성 방법을 제공한다.

* Math.random() 명령 사용
* Random 도구 사용

두 가지 외에도 다양한 방법들이 존재하지만, 라이브러리에 대한 사용법을 어느 정도 알아야 하기 때문에 현재 단계에서는 생략한다.

위의 명령이나 도구를 이용하여 랜덤 데이터를 추첨하기 전에 알아야 할 내용은 다음과 같다.

* 추첨은 숫자(정수,실수) 형태이며, 문자열은 생성이 불가하다.
* 기초 프로그래밍에서는 대부분 정수를 추첨하여 사용한다.
* 추첨하고 싶은 값의 범위를 정확하게 알아야 한다.
* 값의 범위는 `a부터 b까지`로 계산하는 것이 아니라 `a부터 n개`로 설정한다.

### Math.random()

`Math`는 프로그램에 내장된 `java.lang` 패키지에 포함된 내용으로 수학과 관련된 명령들을 제공한다. 이 중에서 `Math.random()`은 **0 이상 1 미만의 double 데이터**를 생성하여 반환하는 명령이다.

```java
double a = Math.random();
System.out.println("a = " + a);
```

이를 이용하여 계산을 하면 주사위, 로또 등 원하는 범위의 값을 계산할 수 있다.\
예를 들어 주사위 값을 추첨하고 싶은 경우 다음과 같이 코드를 작성한다.

```java
int dice = (int)(Math.random() * 6) + 1;
System.out.println("dice = " + dice);
```

주사위는 `1부터 6까지`이지만, 위에서 언급한것처럼 프로그래밍에서는 범위를 `a부터 n개`로 설정하기 때문에 `1부터 6개`라고 생각하고 코드를 작성한다.

```java
double a = Math.random();//랜덤추첨(0이상 1미만 double)
double b = a * 6;//6개이므로 범위 확장(0이상 6미만 double)
int c = (int)b;//정수변환(0이상 6미만 int)
int d = c + 1;//범위보정(1이상 7미만 int, 원하는 값)
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("c = " + c);
System.out.println("d = " + d);
```

위의 코드를 압축하여 공식처럼 사용할 수 있다.

```java
int value = (int)(Math.random() * 개수) + 시작값;
```

반드시 알아야 할 내용은 범위 설정 시 시작값과 개수를 파악하여 코드를 써야 한다는 점이다.

### Random

`Random`은 `java.util`이라는 패키지에 있으며, 기본적으로 제공되지 않기 때문에 사용법은 조금 더 복잡하지만 다양한 명령을 제공한다는 특징이 있다. 도구를 생성한 뒤 랜덤 데이터를 만드는 방식으로 코드를 작성한다.

```java
import java.util.Random;

public class RandomExample01{
    public static void main(String[] args){
        //도구 생성
        Random r = new Random();
        
        //주사위 데이터 생성
        int dice = r.nextInt(6) + 1;//1부터 6개
        System.out.println("dice = " + dice);
    }
}
```

각각의 코드에 대해서 살펴보면 다음과 같다.

```java
import java.util.Random;
```

Random은 기본적으로 제공되는 도구가 아니기 때문에 import를 통해서 불러오도록 설정해야 한다.

```java
Random r = new Random();
```

Random 도구를 생성하는 명령이며, 사용할 이름은 r이라고 설정한다. 생성원리는 클래스 부분을 배워야 하므로 나중에 살펴본다.(참고 : [생성자(constructor)](http://www.sysout.co.kr/home/webbook/page/read/1390))

```java
int dice = r.nextInt(6) + 1;
```

생성한 Random 도구에는 여러 명령이 있는데, 그 중에서 nextInt()라는 명령을 사용하면 원하는 범위의 값을 추첨할 수 있다. 괄호 안에는 개수를, 뒤에는 시작값만큼을 더하여 계산하며 공식처럼 표기하면 다음과 같다.

```java
int value = r.nextInt(개수) + 시작값;
```

이외에도 다양한 명령들이 존재한다.

* .nextBoolean() : 무작위 논리(boolean) 생성
* .nextInt() : 무작위 정수(int) 생성
* .nextFloat() : 무작위 실수(float) 생성
* .nextDouble() : 무작위 실수(double) 생성. Math.random()과 동일한 명령

마찬가지로 문자열을 추첨하는 방법은 없으며, 정수 추첨 후 조건 설정등을 통해 구현하는 등의 다른 방법을 사용해야 한다.

{% hint style="info" %}
Java 17에서는 다음 명령이 존재한다.

<mark style="color:blue;">`.nextInt(origin, bound)`</mark>

origin은 랜덤의 최소값을 말하며, bound는 최대값보다 1 큰 숫자를 말한다

따라서 1부터 45사이의 랜덤 int값을 위의 명령으로 추첨하려면 다음과 같이 작성해야 한다.

<mark style="color:blue;">`.nextInt(1, 46)`</mark>
{% endhint %}

### 데모 1 : Math.random()을 이용한 로또번호 추첨

```java
public class RandomExample02 {
    public static void main(String[] args){
        int lotto = (int)(Math.random() * 45) + 1;
        System.out.println("로또번호 = "+lotto);
    }
}
```

### 데모 2 : Random을 이용한 로또번호 추첨

```java
import java.util.Random;
public class RandomExample03{
    public static void main(String[] args){
        Random r = new Random();
        int lotto = r.nextInt(45) + 1;
        System.out.println("로또번호 = "+lotto);
    }
}
```

### 데모 3 : Math.random()을 이용한 가위바위보 추첨

```java
public class RandomExample04 {
    public static void main(String[] args){
        //가위(0), 바위(1), 보(2)
        int choice = (int)(Math.random() * 3);
        if(choice == 0){
            System.out.println("가위");
        }
        else if(choice == 1){
            System.out.println("바위");
        }
        else{
            System.out.println("보");
        }
    }
}
```

가위바위보를 추첨하기 위하여 다음과 같이 값을 정해두었다.

* 가위 : 0
* 바위 : 1
* 보 : 2

이러한 약속이 있다면 조건을 통하여 원하는 형태로 치환하여 사용할 수 있다.
