Ruby Programming Tutorial - Lesson 23 - Creating Deck of Cards :)

in #ruby7 years ago (edited)

deck-cards-18354636.jpg

In this Example we are going to create a Deck of Cards in Ruby

Screenshot from 2018-03-15 00-48-54.png

This can come very handy when creating Card games in Ruby.

The Task

Create a Ruby Program for to Create a Deck of Cards ..

Task looks simple but it isn't very simple.. lets identify Entities :) and then Create Classes accordingly
We all Know that Deck of Cards is consisting Upon 2 Things ..

  • Deck
  • Card

So we can make two seperate Classes for Deck and Cards accordingly..
Lets start by Creating a Class for Cards

First Step is to identify its properties.
every card has a Number/Face which we call Rank, and a Suit
like 2 of Clubs, where 2 is rank and Clubs is Suit..
Similarly king of Diamonds where king is rank and Diamonds is Suit

Properties of Card

  • Rank of Card
  • Suit of Card

I have created a Complete Class below. which you can use for yourself. it is very long . I will try my best to explain,
each part of it.

When we Create an object from this Class,
by writing Card.new(1, "clubs")
It will create a Card object for us..

Notice that it has couple of Methods ..

  • constructor Method
    • Which is used to handle the inputs from user, and create Cards accordingly
  • create_card Method
    • Which is used to return, Created card to main.rb .. or where ever it is called
  • is_valid Method
    • Which validates the card, which it gets from user, this can be handy later on ..
    • a card is valid when its rank is valid, and its suit is valid ..
    • For example 20 of clubs is invalid card, and 2 of Mountains is also invalid Card
  • is_rank_valid and is_suit_valid methods handle these Cases.
class Card
    def initialize(*properties)
        @card_rank     = properties[0]
        @card_suit     = properties[1]

        @number_ranks  = ["2", "3", "4", "5", "6", "7", "8", "9", "10"]
        @face_ranks    = ["ace", "jack", "queen", "king"]

        ## local array for special cases
        @special_case  = ["1", "11", "12", "13"]

        ## If card number is '1' convert it to 'ace'
        ## same for 11, 12, 13 .. jack, queen, king
        for i in 0..@special_case.length 
            if properties[0] == @special_case[i]
                @card_rank = @face_ranks[i]
                break;
            else 
                @card_rank = properties[0]
            end
        end
    end

    def create_card
        _card = [@card_rank, @card_suit]
    end

    def is_valid
        if is_suit_valid && is_rank_valid
            return true
        else 
            return false
        end  
    end

    def is_suit_valid
        _card_suits   = ["hearts", "diamonds", "clubs", "spades"]       
        _contains_flag= false

        _card_suits.each do |suit|
            if @card_suit == suit
                _contains_flag = true
            end
        end

        return _contains_flag
    end

    def is_rank_valid
        _contains_flag = false

        @number_ranks.each do |rnk|
            if @card_rank == rnk
                _contains_flag = true
            end
        end

        @face_ranks.each do |rnk|
            if @card_rank == rnk
                _contains_flag = true
            end
        end

        @special_case.each do |rnk|
            if @card_rank == rnk
                _contains_flag = true
            end
        end

        return _contains_flag
    end
end

Lets Start by Learning about is_valid Method..
This Method is used to validate the card which is send by the user, by Card.new
This method is very simple, it asks 2 Methods to validate suit and rank of the card..
If both the Methods return true, then Card is Valid .. otherwise it is not.

    def is_valid
        ## Calling Methods Directly in conditional statement
        ## It is similar to is_suit_valid() && is_rank_valid() 
        ## Notice that we did not created any object .. and when we call methods inside of Class 
        ## We don't need to Create an object. we can just call them :) 

        if is_suit_valid && is_rank_valid
            return true
        else 
            return false
        end  
    end

Now lets look at is_suit_valid() Method .
This Method uses an Array which contains the suits
and also a boolean variable. which is set to false by default.

we can loop through our suit array to find matching value.. if we do match the value, that means suit is valid and we return true, otherwise value of boolean variable remains false, which we return .. In case user passed an invalid suit like e.g Mountains :p, This Method will return false .. also note that this is case sensitive, so if user passed "Hearts" with an uppercase letter instead of "hearts" it will also be considered an invalid suit :) .. We know that the suit value, which user passed is stored inside of "@card_suit" instance variable.

    def is_suit_valid
        _card_suits   = ["hearts", "diamonds", "clubs", "spades"]       
        _contains_flag= false

        _card_suits.each do |suit|
            if @card_suit == suit
                _contains_flag = true
            end
        end

        return _contains_flag
    end

You need to go through is_valid_rank() Method by yourself .. let me know in Comments if you understood the code.

lets now Take a look at Deck Class

require_relative 'card'

class Deck 
    def initialize
        @Deck = []
        @suits = ["hearts", "diamonds", "clubs", "spades"]

        @suits.each do |suit|
            for i in 1..13
                # Creating a new card, pass it value of "i" and converting it to string, using "to_s" Method
                # which ruby programming language provides us. 
                _myCard    = Card.new(i.to_s, suit)
                # once the card object is created. we can call create_method 
                # to get the card in _temp_card local variable
                _temp_card = _myCard.create_card()
                # After we get the card, we push the card to the DECK :) as simple as that ;)
                @Deck << _temp_card
            end
        end
    end

    def display_deck
        print @Deck
    end
end

Notice that we are not taking any arguments in our initialize Method :) we don't need to take arguments when we
don't need them.. in this case we just need to create a Deck of Cards.
We already have a Card Class which can create Cards for us,

So we start by Empty

@Deck = []

Then using two nested loops. one looping through all four suits
Other looping through 1 ... 13 as each suit contains 13 cards, ace through king
For each suit we create a card, with suit, and a number .. and Push the card into the Deck..

This Method Helps us see the Deck :)

    def display_deck
        print @Deck
    end

Screenshot from 2018-03-15 00-48-54.png

After all the hard Work.. finally we created a main.rb file.
In which we have created a Deck of Cards. and we are Displaying them

Screenshot from 2018-03-15 01-13-19.png

Hopefully now that we have Deck of Cards, we can use this awesome Class and use them to create some beautiful games :)

Sort:  

very good, just wondering, have ever made Hangman game using ruby?

don't even know what is hangman game :)

I follow you :)

information based post. thanks for sharing it....@upvoted @resteemit

Awesome! Just checking out my followers to see what I can find after reaching the milestone and here's what I found! :)

I don't know Ruby, but maybe it's a good way to start.

I resteemed and followed you! :)