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

View this thread on: d.buzz | hive.blog | peakd.com | ecency.com
·@bilal-haider·
0.000 HBD
Ruby Programming Tutorial - Lesson 23 - Creating Deck of Cards :)
![deck-cards-18354636.jpg](https://steemitimages.com/DQmPKnH91pkB1mo4DXCQDJg9mVYJ6rDVhoZsvtgxprXqxoH/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](https://steemitimages.com/DQmbohLkzyUWTxMqYwNmkPHme3rbaCrYMAJkh2frQsVZCnF/Screenshot%20from%202018-03-15%2000-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 know that the suit value, which user passed is stored inside of "@card_suit" instance variable. 
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 :) .. 

```
    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](https://steemitimages.com/DQmbohLkzyUWTxMqYwNmkPHme3rbaCrYMAJkh2frQsVZCnF/Screenshot%20from%202018-03-15%2000-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](https://steemitimages.com/DQmRwUGfqt9jHDnNKk22z8pr5uDnndfFG9XAPRxVTzg9Dh6/Screenshot%20from%202018-03-15%2001-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 :)
👍 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,