블럭체인/rust

rust - 카드 놀이 _ 2

bonschicken 2024. 11. 18. 16:45
728x90

 

위에 그림에서 내재적 구현을 사용하여 두가지 유형의 함수를 정의하는 하는 방법입니다.

 

함수에서는 동일한 구현 블록 내에서 정의할 수 있습니다. 메서드와 연관 함수를 정의 할 수 있습니다.

 

연관함수란? 거의 모든 다른 언어에서 클래스 메서드와 동일합니다.

 

 

 

 

 

첫번째 코드 에서는

메서드의 정의: new 메서드는 Deck 구조체의 새로운 인스턴스를 생성하는 함수입니다. fn new() -> Self의 의미는 이 메서드가 Deck 타입의 인스턴스를 반환한다는 것입니다.

호출 방식: Deck::new();는 구조체 이름을 통해 직접 호출하는 정적 메서드입니다. 이 메서드는 인스턴스가 필요 없기 때문에 self를 매개변수로 받지 않습니다.

용도: 일반적으로 구조체의 생성자 역할을 하며, 초기화가 필요한 필드를 설정하는 데 사용됩니다.



두번째 코드 에서는 

메서드의 정의: shuffle 메서드는 &self를 매개변수로 받습니다. 이는 이 메서드가 Deck 구조체의 인스턴스에 대해 호출된다는 것을 의미합니다.

호출 방식: deck.shuffle();은 deck이라는 Deck 인스턴스의 메서드를 호출하는 방식입니다. 이 경우 deck은 이미 생성된 Deck 인스턴스여야 합니다.

용도: 이 메서드는 인스턴스의 상태를 변경하는 작업을 수행할 수 있으며, 이 메서드가 어떤 상태를 변경하지 않더라도, 인스턴스의 데이터를 읽는 데 사용될 수 있습니다.

 

다음은 함수 리턴할 변수에 표현식에 대해서 이야기 하겠습니다.

 

 

#[derive(Debug)]
struct Deck {
    cards:Vec<String>,
}

impl Deck {
    fn new() -> Self {

        let suits = ["Hearts" , "Spades", "Diamonds"];
        let values = ["Ace","Two","Three"];

        let mut cards = vec![];

        for suit in suits{
            for value in values {
                let card = format!("{} of {} ", value, suit);
                cards.push(card)

            }
        }

        Deck { cards: cards}
        
    }
}

fn main() {
    let deck = Deck::new();

    println!("Heres your deck : {:#?}", deck);
}

 

 

Deck 구문에 리턴이 없어도 정상 출력되는 모습을 볼 수 있습니다.

 

이는 러스트의 문법 중하나 암시적 반환이라고 생각하시면 됩니다.

 

return 구문이 없고 세미콜론이 없으면 해당 구문이 리턴된다고 생각해야 합니다.

 

 

 

 카드 셔플 기능

 

카드 셔플 기능을 추가 할려고 합니다.난수 생성기을 만들어야 하지만 기존에 다른 사람의 코드을 사용 할려고 합니다.

 

다른 프로그래밍 언어에서는 다른 엔지니어의 코드를 가져와 프로젝트에 설치할 때 이를 패키지라고 부르지만 러스트에서 crates 이라고 부릅니다.

 

 

 

 

 

crates.io에서 필요한 crates을 다운 받을 수 있습니다.

 

 

 

 

위에 그림은 외부 crates를 설치하거나 프로젝트 내부에 설치할 때마다 모든 코드를 다른 모듈로 구성한 것입니다.

 

모듈은 네임 스페이스와 비슷하다고 생각할 수 있습니다. 

 

모듈은 서로 다른 함수와 구조, 그리고 우리가 최종적으로 만들 다른 것들을 함계 그룹화하여 프로젝트를 더 잘 정리할 수 있습니다.

 

항상 루트 모듈이라고 불리는 모듈이 하나 이상 있습니다. 그래서 우리 rand crates는 루트 모듈에 있습니다.

 

그리고 그 안에는 몇가지 함수나 구조체 또는 다른 무언가가 들어 있습니다.

 

 

 

 

 

rand crate 안에는 두 가지 다른 것을 사용해야 합니다. 

 

카드 목록을 섞기 위해 프로젝트 내부에서 사용해야 합니다.

 

첫 번째로는 필요한 것은 루트 모듈 내부에 스레드 밑줄 RNG라는 함수 입니다.

 

이것은 난수 생성기를 만드는 함수 입니다.

 

또 다른 필요한 것은 시퀀스의 줄임말인 seq라는 서브모듈의 내부의 함수입니다.

 

이 서브 모듈 안에는 특성이 있습니다. 해당 특성의 이름 슬라이스 랜덤입니다.

 

이 특성은 프로젝트 내부의 모든 벡터에 새로운 셔플 메서드를 자동으로 추가합니다. 따라서 벡터가 있다면 이제 벡터에 셔플을 호출하여 벡터 내부의 요소 시퀀스를 셔플할 수 있습니다.

 

 

 

 

 

외부 상자에 모듈 등을 넣을 수 있는 것처럼, 우리도 개인 프로젝트에 모듈을 추가할 수 있습니다.

 

프로젝트에서도 모듈을 추가하여 코드 기반을 더 잘 구성할 수 있습니다. 

 

예를 들어 여기 프로젝트 내부에는 루트 모듈이 있습니다. 그리고 그 안에는 메인 함수가 있습니다.

 

프로젝트를 더 잘 정리하고 싶다면 게임과 같은 하위 모듈을 만들 수 있습니다. 

 

그리고 그안에 데크 구조체를 만들 수 있습니다.

 

프로젝트 내부에 정의된 서브모듈 내부의 것들을 사용하는 방법과는 조금 다를 것입니다.

 

 

다시 한 번 말하지만, Our project에 있는 함수들을 사용하는 것은 프로젝트 내부에 정의된 것을 사용하는 방법과는 약간 다릅니다.

use rand::{thread_rng, seq::SliceRandom};

#[derive(Debug)]
struct Deck {
    cards:Vec<String>,
}

impl Deck {
    fn new() -> Self {

        let suits = ["Hearts" , "Spades", "Diamonds"];
        let values = ["Ace","Two","Three"];

        let mut cards = vec![];

        for suit in suits{
            for value in values {
                let card = format!("{} of {} ", value, suit);
                cards.push(card)

            }
        }

        Deck { cards: cards}
        
    }
}

fn main() {
    let deck = Deck::new();

    println!("Heres your deck : {:#?}", deck);
}

 

 

위에 코드에서 

"use rand::{thread_rng, seq::SliceRandom};" 구문으로 다른 creats을 사용할 수 있습니다.

 

 

 

use rand::{thread_rng, seq::SliceRandom};

#[derive(Debug)]
struct Deck {
    cards:Vec<String>,
}

impl Deck {
    fn new() -> Self {

        let suits = ["Hearts" , "Spades", "Diamonds"];
        let values = ["Ace","Two","Three"];

        let mut cards = vec![];

        for suit in suits{
            for value in values {
                let card = format!("{} of {} ", value, suit);
                cards.push(card)

            }
        }

        Deck { cards: cards}
        
    }

    fn shuffle(&mut self) {
        let mut rng = thread_rng();
        self.cards.shuffle(&mut rng)

    }
}

fn main() {
    let mut deck = Deck::new();

    deck.shuffle();

    println!("Heres your deck : {:#?}", deck);
}

 

위에 코드로 카드 셔플할 수 있는 코드 작성햇습니다.