지난글에 이어서 랜덤 정수를 만들어보겠습니다.
2022.09.30 - [Rust] - [2 - 1] Rust 간단한 숫자 맞추기 게임
[2 - 1] Rust 간단한 숫자 맞추기 게임
Rust의 구체적인 내용을 배우기 전에 몸풀기로 간단한 숫자 맞추기 게임을 만들어보고 시작하겠습니다. 이 게임은 콘솔로 숫자를 입력받고 입력받은 숫자가 맞춰야 될 숫자에 비해서 큰지 작은
supern0va.tistory.com
랜덤 정수 생성하기
Rust 크레이트(Crate)를 사용하여 외부 라이브러리 가져오기
Rust 크레이트(Crate)를 사용하여 외부 라이브러리 가져오기
러스트에서도 외부 라이브러리를 사용할 수 있습니다. 우선 러스트에서 pakage는 크레이트(Crate) 라고 부릅니다. 컴파일 해서 실행 가능한 것은 binary crate이고 아래서 살펴볼 rand와 같은 다른 프로
supern0va.tistory.com
지난 글에서 rand crate를 가져오는 방법에 대해서 알아보았는데요. 그 방법대로 진행해보겠습니다.
crate는 Rust에서 pakage를 부르는 말입니다.
Cargo.toml 파일을 열어 [dependencies] 아래에 다음 코드를 추가해줍니다.
[dependencies]
rand = "0.8.5"
그리고 cargo build를 실행하여 rand를 가져옵니다.
이제 rand를 사용해봅시다.
use rand::Rng;
use std::io;
fn main() {
println!("==== 숫자 맞추기 게임! ====");
let secret_number = rand::thread_rng().gen_range(1..=100);
println!("숫자를 입력해주세요.");
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("입력받지 못했습니다.");
println!("당신의 예측: {}정답: {}", guess, secret_number);
}
우선 첫번째 줄에 use rand::Rng를 추가했습니다. Rng는 랜덤 숫자를 만들어내기 위한 메서드를 모아놓은 trait입니다.
그리고 gen_range메서드는 범위 내의 숫자를 랜덤으로 뽑아서 돌려줍니다. 인자로 1..=100을 넣었는데 start..=end는 start부터 end까지의 범위를 나타냅니다. 따라서 1부터 100사이의 숫자 중에서 랜덤하게 뽑아 secret_number 변수에 값이 들어갑니다.
cargo run으로 실행해봅시다.
여기서 줄바꿈이 일어나는 이유는 read_line을 했을 때 개행문자도 같이 저장되었기 때문입니다.
숫자를 비교하기
다음 코드를 작성해봅시다.
use rand::Rng;
use std::cmp::Ordering;
use std::io;
fn main() {
println!("==== 숫자 맞추기 게임! ====");
let secret_number = rand::thread_rng().gen_range(1..=100);
println!("숫자를 입력해주세요.");
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("입력받지 못했습니다.");
println!("당신의 예측: {}정답: {}", guess, secret_number);
match guess.cmp(&secret_number) {
Ordering::Less => println!("업!"),
Ordering::Greater => println!("다운!"),
Ordering::Equal => println!("정답!"),
}
}
현재 guess는 String이고 secret_number는 i32입니다. 그러므로 바로 비교를 할 수 없기 때문에 geuss를 i32로 변환해야 합니다.
변환하지 않고 비교하면 컴파일러가 에러를 냅니다.
코드를 다음과 같이 수정해줍니다.
use rand::Rng;
use std::cmp::Ordering;
use std::io;
fn main() {
println!("==== 숫자 맞추기 게임! ====");
let secret_number = rand::thread_rng().gen_range(1..=100);
println!("숫자를 입력해주세요.");
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("입력받지 못했습니다.");
let guess: u32 = guess.trim().parse().expect("숫자가 아닙니다.");
println!("당신의 예측: {}\n정답: {}", guess, secret_number);
match guess.cmp(&secret_number) {
Ordering::Less => println!("업!"),
Ordering::Greater => println!("다운!"),
Ordering::Equal => println!("정답!"),
}
}
추가된 코드를 살펴보죠.
let guess: u32 = guess.trim().parse().expect("숫자가 아닙니다.");
여기서 trim은 앞뒤 공백과 개행문자를 제거해줍니다. parse는 문자열을 숫자형으로 변환해줍니다. 만약 숫자가 입력되지 않을 경우를 위해 expect를 사용해 에러를 처리해줍니다.
guess에서 개행문자가 사라졌기 때문에 println!도 수정해줍니다.
guess.cmp(&secret_number)는 guess와 secret_number를 비교해 Ordering::Less, Ordering::Greater또는 Ordering::Equal을 반환합니다. 그리고 match안에서는 매칭이 되면 => 연산자 뒤에 코드를 작성하여 해당 조건에 맞는 코드를 실행시킬 수 있습니다.
실행해봅시다.
잘 동작하네요. 이제 반복문을 사용해서 여러번 맞출 수 있게 만들어봅시다.
반복문
loop 키워드는 범위 안의 코드를 무한루프로 실행합니다.
use rand::Rng;
use std::cmp::Ordering;
use std::io;
fn main() {
println!("==== 숫자 맞추기 게임! ====");
let secret_number = rand::thread_rng().gen_range(1..=100);
loop {
println!("숫자를 입력해주세요.");
// --snip--
match guess.cmp(&secret_number) {
Ordering::Less => println!("업!"),
Ordering::Greater => println!("다운!"),
Ordering::Equal => println!("정답!"),
}
}
}
실행시켜보면
위와 같이 무한루프로 동작합니다. 숫자가 아니라 문자를 입력하면 에러를 발생시키고 중단됩니다.
정답일 경우 종료하려면 Ordering::Equal 조건에 break를 추가합니다.
match guess.cmp(&secret_number) {
Ordering::Less => println!("업!"),
Ordering::Greater => println!("다운!"),
Ordering::Equal => {
println!("정답!");
break;
}
}
그리고 잘못된 문자를 받았을 경우에 오류를 발생시키지 않고 다시 입력받도록 코드를 작성해줍니다.
// --snip--
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
println!("당신의 예측: {}\n정답: {}", guess, secret_number);
// --snip--
횟수 제한 설정하기
마지막으로 7번 안에 맞추면 성공 아니면 실패하도록 만들어보겠습니다.
우선 현재 몇번째 예측인지 확인할 guess_number변수를 만듭니다.
let mut guess_number = 0;
그리고 비교가 끝난 뒤에 guess_number에 1을 더해주고 이 값이 7인지 확인을 합니다.
match guess.cmp(&secret_number) {
Ordering::Less => println!("업!"),
Ordering::Greater => println!("다운!"),
Ordering::Equal => {
println!("정답!");
break;
}
}
guess_number += 1;
println!(" ({}번 남았습니다.)\n", 7 - guess_number);
if guess_number == 7 {
println!("실패!");
println!("정답은 {}입니다!\n", secret_number);
break;
}
그리고 보기 좋게 약간의 수정을 해줍니다. 다음은 전체 코드입니다.
use rand::Rng;
use std::cmp::Ordering;
use std::io;
fn main() {
println!("==== 숫자 맞추기 게임! ====");
let secret_number = rand::thread_rng().gen_range(1..=100);
let mut guess_number = 0;
loop {
println!("숫자를 입력해주세요!");
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("입력받지 못했습니다.");
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
match guess.cmp(&secret_number) {
Ordering::Less => print!("업!"),
Ordering::Greater => print!("다운!"),
Ordering::Equal => {
print!("정답!");
break;
}
}
guess_number += 1;
println!(" ({}번 남았습니다.)\n", 7 - guess_number);
if guess_number == 7 {
println!("실패!");
println!("정답은 {}입니다!\n", secret_number);
break;
}
}
}
실행시켜봅시다.
잘 동작하네요!
'Rust' 카테고리의 다른 글
Rust 데이터 타입(Data Types) (0) | 2022.10.11 |
---|---|
Rust 변수의 가변성(mutable)과 상수(const) (1) | 2022.10.07 |
Rust 크레이트(Crate)를 사용하여 외부 라이브러리 가져오기 (0) | 2022.10.04 |
[2 - 1] Rust 간단한 숫자 맞추기 게임 (1) | 2022.09.30 |
[1] Rust (러스트) Getting Started! (0) | 2022.09.29 |