Card Game Data Structure
#1
Card Game Data Structure
Version: 1.0


Introduction
This is mainly a tool for scripters, This small script contains classes that are very useful in making card games (Ex. BlackJack, Poker, etc.). Includes A Deck Class, A Card class, A Hand class, a Sprite class for Cards. Also includes Card graphics.


Screenshots
Look at the script editor after you add this, there's your screenshot


Demo
Pretty much pointless, see my BlackJack demo for an aplication of this.


Script
Yay the families will be overjoyed...
Code:
class Game_Deck
  #--------------------------------------------------------------------------
  # * Constants
  #--------------------------------------------------------------------------
  Suits = %w( spades hearts diamonds clubs )
  Values = 'A','2','3','4','5','6','7','8','9','10','J','Q','K'
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(num_decks = 1)
    # Setup Cards
    @cards = []
    # Setup Deck
    @deck = []
    # Setup Discarded
    @discard = []
    # Setup In Play
    @in_play = []
    # Setup Number of Decks
    @num_decks = num_decks
    # Setup Cards
    setup_cards
    # Shuffle
    shuffle
  end
  #--------------------------------------------------------------------------
  # * Setup Cards
  #--------------------------------------------------------------------------
  def setup_cards
    # Run Through number of decks times
    @num_decks.times do
      # Run Through Each Suit
      Suits.each do |suit|
        # Run Through each value
        Values.each do |number|
          # Setup Card
          card = Game_Card.new(suit, number)
          # Push into cards array
          @deck << card
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Shuffle
  #--------------------------------------------------------------------------
  def shuffle
    # Setup local variable cards
    cards = []
    # Clear Discarded
    @discard.clear
    # Setup Cards to Deck
    @cards = [@deck].flatten!
    # Delete Cards already out
    delete_in_use_cards
    # Run through until cards are empty
    until @cards.empty?
      # Push a Random Card and Delete
      cards << @cards.delete_at(rand(@cards.size))
    end
    # Set Cards to Cards
    @cards = cards
  end
  #--------------------------------------------------------------------------
  # * Draw
  #--------------------------------------------------------------------------
  def draw(number = 1)
    # Return if number is 1
    if number == 1
      # Shuffle if empty?
      shuffle if @cards.empty?
      # Get Card
      card = @cards.shift
      # Add Card to in play
      @in_play << card
      # Return card
      return card
    end
    # Setup Array
    drawn = []
    # Run Through number of times
    number.times do
      # Shuffle if empty?
      shuffle if @cards.empty?
      # Break if cards are still empty (all in play)
      break if @cards.empty?
      # Get Card
      card = @cards.shift
      # Add Card to in play
      @in_play << card
      # Add to Drawn
      drawn << card
    end
    # Return Drawn Cards
    return drawn
  end
  #--------------------------------------------------------------------------
  # * Discard In Play
  #--------------------------------------------------------------------------
  def discard
    # Add all in play cards to discard
    @discard += @in_play
    # Clear in play
    @in_play.clear
  end
  #--------------------------------------------------------------------------
  # * Number
  #--------------------------------------------------------------------------
  def number(*strings)
    # Setup Local Variable
    number = 0
    # Run Through each card
    @cards.each do |card|
      # Run Through Each String Sent to this method
      strings.each do |string|
        # If A Suit
        if Suits.include?(string)
          # Increase By 1 if suits are equal
          number += 1 if card.suit == string
        # If A Value
        elsif Values.include?(string)
          # Increase By 1 if values are equal
          number += 1 if card.value == string
        end
      end
    end
    return number
  end
  #--------------------------------------------------------------------------
  # * Size
  #--------------------------------------------------------------------------
  def size
    return @cards.size
  end
  #--------------------------------------------------------------------------
  # * Delete Cards In Use
  #--------------------------------------------------------------------------
  private
  def delete_in_use_cards
    # Return if empty cards
    return if @in_play.empty?
    # Run Through each in play card and Delete Card from list
    @in_play.each {|card| @cards.delete(card)}
    # Clear In Play
    @in_play.clear
  end
end

class Game_Card
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_reader :number
  attr_reader :suit
  attr_reader :value
  attr_accessor :flipped
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(suit, value, face10 = false, ace11 = false)
    @suit = suit
    @value = value
    @face10 = face10
    @ace11 = ace11
    @flipped = true
    setup_number
  end
  #--------------------------------------------------------------------------
  # * Ace?
  #--------------------------------------------------------------------------
  def ace?
    return @value == 'A'
  end
  #--------------------------------------------------------------------------
  # * King?
  #--------------------------------------------------------------------------
  def king?
    return @value == 'K'
  end
  #--------------------------------------------------------------------------
  # * Queen?
  #--------------------------------------------------------------------------
  def queen?
    return @value == 'Q'
  end
  #--------------------------------------------------------------------------
  # * Jack?
  #--------------------------------------------------------------------------
  def jack?
    return @value == 'J'
  end
  #--------------------------------------------------------------------------
  # * Face?
  #--------------------------------------------------------------------------
  def face?
    return ['J','Q','K'].include?(@value)
  end
  #--------------------------------------------------------------------------
  # * Ten?
  #--------------------------------------------------------------------------
  def ten?
    return @value == '10' || (self.face? and @face10)
  end
  #--------------------------------------------------------------------------
  # * To String (Returns card's value)
  #--------------------------------------------------------------------------
  def to_s
    return self.value
  end
  #--------------------------------------------------------------------------
  # * Setup Number (Private)
  #--------------------------------------------------------------------------
  private
  def setup_number
    case @value
    when 'A'
      @number = @ace11 ? 11 : 1
    when 'J'
      @number = @face10 ? 10 : 11
    when 'Q'
      @number = @face10 ? 10 : 12
    when 'K'
      @number = @face10 ? 10 : 13
    else
      @number = @value.to_i
    end
  end
end

class Game_CardHand
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    # Setup Cards
    @cards = []
  end
  #--------------------------------------------------------------------------
  # * Each (Runs Through Each Card in Hand)
  #--------------------------------------------------------------------------
  def each
    @cards.each {|card| yield(card)}
  end
  #--------------------------------------------------------------------------
  # * Cards
  #--------------------------------------------------------------------------
  def cards
    return @cards.size
  end
  #--------------------------------------------------------------------------
  # * Draw
  #--------------------------------------------------------------------------
  def draw(*cards)
    @cards.push(*cards)
  end
  #--------------------------------------------------------------------------
  # * Discard
  #--------------------------------------------------------------------------
  def discard
    @cards.clear
  end
  #--------------------------------------------------------------------------
  # * To String (ex. A234K)
  #--------------------------------------------------------------------------
  def to_s
    string = ''
    @cards.each {|card| string += card.to_s}
    return string
  end
end

module RPG
module Cache
  #--------------------------------------------------------------------------
  # * Card
  #--------------------------------------------------------------------------
  def self.card(suit, number)
    style = $game_system.card_style
    self.load_bitmap("Graphics/Cards/#{style}/", "#{suit}_#{number}")
  end
  #--------------------------------------------------------------------------
  # * Card Back
  #--------------------------------------------------------------------------
  def self.card_back(style)
    self.load_bitmap("Graphics/Cards/Backs/", style)
  end
end
end

class Sprite_Card < Sprite
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(card, flipped = true)
    super(nil)
    # Setup Suit and Value
    @suit, @value = card.suit, card.value
    # Setup Flipped Flag
    @flipped = flipped
    # Setup Bitmap
    if @flipped
      # Get Flipped Card
      self.bitmap = RPG::Cache.card(@suit, @value)
    else
      # Get Card Back
      self.bitmap = RPG::Cache.card_back($game_system.card_back_style)
    end
  end
  #--------------------------------------------------------------------------
  # * Flipped
  #--------------------------------------------------------------------------
  def flipped=(bool)
    # Set Flipped Flag
    @flipped = bool
    # Setup Bitmap
    if @flipped
      # Get Flipped Card
      self.bitmap = RPG::Cache.card(@suit, @value)
    else
      # Get Card Back
      self.bitmap = RPG::Cache.card_back($game_system.card_back_style)
    end
  end
end

class Game_System
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :card_style
  attr_accessor :card_back_style
  #--------------------------------------------------------------------------
  # * Initialize
  #--------------------------------------------------------------------------
  alias card_setup_initialize initialize
  def initialize
    # The Usual
    card_setup_initialize
    # Setup Card Style
    @card_style = 'Normal'
    # Setup Card Back Style
    @card_back_style = 'DragonKid'
  end
end


Instructions
The best way to ensure compatibility is to make classes that inherit from these classes like I did in my BlackJack minigame, I tried to include useful methods in these classes and I will give an explanation of what each of them do here

Name: Game_Deck
Description: The Deck class. Holds in play, discarded, and cards not played yet, automatically shuffles if there are no cards left, also handles multiple decks.
Methods:
  • initialize(number of decks) (private)
    - Creates a new Game_Deck object automatically called from the new method, the parameter number of decks is the number of decks of cards to use (The Default is 1)
  • setup_cards
    - Creates all of the Cards, one for each suit and value
  • shuffle
    - Shuffles the Deck
  • draw(number of cards)
    - Draws number of cards from the deck automatically shuffles if the deck is empty during this process, the parameter number of cards is the number of cards to draw (The default is 1). If only one card is drawn this method will return that card, else it will return an array.
    - Note: will return as many cards as it can if drawing more than one card (All cards could be in play making it unable to shuffle)
  • discard
    - Discards All In Play Cards
  • number(variable amount of strings)
    - Tells how many of cards of suit or value are remaining in the deck. The strings have to match with the constants which is explained further down
  • size
    - Tells how many cards are remaining in the deck
  • delete_in_use_cards (private)
    - Deletes all in play cards from deck, used when reshuffling

Constants:
  • Suits
    -The suits used, by default there are clubs, hearts, diamonds, and spades.
    - Note: remember create a class that inherits from this one and then change the constant in that class if for any reason you want to change it (note you will have to rename/add graphics if if you do)
  • Values
    - The values used, by default A-K (Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, and K). No Jokers.
    - see note for Suits.

Properties:
  • None

Name: Game_Card
Description: The Card class. Represents a card. It is created and used within the Game_Deck class.
Methods:
  • initialize(suit, value, face cards are 10, aces are 11) (private)
    - Creates a new Game_Card object automatically called from the new method, the parameter suit tells the suit of the card, value is the value of the card, face cards are 10 flag telling if face cards (J,Q,K) are worth 10 else their worth is 11,12,and 13 repectively, aces are 11 flag telling if aces are worth 11 instead of 1
  • ace?
    - returns true if the card is an ace
  • jack?
    - returns true if the card is a jack
  • queen?
    - returns true if the card is a queen
  • king?
    - returns true if the card is a jack
  • face?
    - returns true if the card is a face card
  • ten?
    - returns true if the card is worth 10
  • to_s
    - returns a String Representation of this object (The Cards Value)
  • setup_number (private)
    - Sets up the cards worth.

Constants:
  • None

Properties:
  • number (readable)
  • The Cards Worth. (1-13)
  • suit (readable)
  • The Cards Suit.
  • value (readable)
  • The Cards Value. (A-K)
  • flipped (accessible)
  • The Flipped Flag It is set to true in the initialize method.


Name: Game_CardHand
Description: A Class for a Player's Hand, Holds Game_Card objects.
Methods:
  • initialize (private)
    - Creates a new Game_CardHand object automatically called from the new method. Nothing fancy here.
  • each
  • Runs through all cards in hand
  • cards
  • Returns the number of card in hand
  • draw(variable amount Game_Card)
    - Adds Cards to Hand
  • discard
  • Discards (Clears) All cards from Hand
  • to_s
  • returns the string representation of this object, that is the values of all cards in hand

Constants:
  • None

Properties:
  • None

Name: Sprite_Card
Description: A Sprite Class for Displaying Cards.
Methods:
  • initialize(card, flipped flag) (private)
    - Creates a new Sprite_Card object automatically called from the new method. The Parameter card is a Game_Card Object, and the flipped flag tells if the card is displayed face up or face down (The Default is true - face up)
  • flipped=(boolean)
    - Sets the flipped flag, either send true or false to this method

Constants:
  • None[/list[

    Properties:
    • None


    FAQ
    Note: Permission granted by Trickster to post:
    Quote:And if you post what you have now of my stuff then you don't have the latest versions. I'm too lazy/busy to post stuff.
    As this is his material, it is deletable upon his request. Due to his current absense, no support is available. Please do not PM or eMail him for support.


    Compatibility
    Should be compatible with anything as long as you follow my note in the instructions section


    Credits and Thanks
    EiB for providing me with the graphics (see attachment)
    Tana - DragonKid

    If I'm missing anything PM me and tell


    Terms and Conditions
    Hey, I posted this publicly. You can use it. What do you expect? But if you do use it, I do expect you to spell my name correctly in your game. And yes you can use it in commercial games too.
Reply }


Messages In This Thread
Card Game Data Structure - by Trickster - 03-01-2008, 05:13 AM
Card Game Data Structure - by explocion200 - 12-08-2009, 11:31 PM
Card Game Data Structure - by Trickster - 12-09-2009, 12:30 AM
Card Game Data Structure - by explocion200 - 12-09-2009, 12:46 AM
Card Game Data Structure - by Ramiro - 12-09-2009, 01:58 AM
Card Game Data Structure - by Trickster - 12-09-2009, 06:38 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
   Name Game Switch & Variable XP kyonides 0 1,092 06-27-2023, 09:17 PM
Last Post: kyonides
   Saving Temporary Actors' Data kyonides 1 4,893 09-07-2018, 06:40 AM
Last Post: kyonides
   LILY'S MEGA DATA! DerVVulfman 1 6,886 08-28-2017, 08:07 PM
Last Post: EricandTheCheat
Photo  Map Tileset Changer during the game Narzew 1 6,415 05-06-2013, 09:18 PM
Last Post: Narzew
   DerVVulfman's Game Data Sneak DerVVulfman 1 7,455 04-03-2013, 08:42 PM
Last Post: Taylor
   Mr.Mo ABS Game Log Window JayRay 0 5,367 10-30-2012, 06:54 AM
Last Post: JayRay
   Limit Breaker - breaks game limits Narzew 1 6,391 10-09-2012, 10:35 AM
Last Post: MetalRenard
   1 Save Slot / AutoLoad Saved Game kyonides 1 6,733 07-09-2010, 08:38 AM
Last Post: Kread-EX
   Game Over Replacer + Enhancer [Exclusive] PK8 0 7,938 07-03-2009, 10:31 AM
Last Post: PK8
   Universal Data Back-Up Kain Nobel 2 7,107 04-19-2009, 12:33 PM
Last Post: Kain Nobel



Users browsing this thread: 1 Guest(s)