=begin name: Queen of Diamonds v0.3 author: Dirk Meijer date: April 17th 2006 description: The basis of the app, contains the classes. =end class Game attr_accessor(:window, :hand) def initialize(window=Window.new, hand=Deck.new) window.verify_class(Window) hand.verify_class(Hand, Deck) @window=window @hand=hand end def play @window.show end end class Card @@value_order="2345678910JQKAX" @@suit_order="CDSHJ" @@suits_over_values=false include Comparable attr_reader(:value, :suit) def initialize(value, suit) value.verify_class(Fixnum, Symbol, String) suit.verify_class(Symbol, String) if (2..10).include?(value.to_i) @value=value.to_i elsif value.to_s =~ /^[JQKA]$/i @value=value.to_s.upcase.to_sym else raise "invalid card value" end raise "invalid card suit" if suit.to_s !~ /^[HSDC]$/i @suit=suit.to_s.upcase.to_sym end def to_s outp="" if (2..10).include?(@value.to_i) outp << @value.to_s elsif @value==:J outp << "Jack" elsif @value==:Q outp << "Queen" elsif @value==:K outp << "King" elsif @value==:A outp << "Ace" end outp << " of " if @suit==:H outp << "Hearts" elsif @suit==:S outp << "Spades" elsif @suit==:D outp << "Diamonds" elsif @suit==:C outp << "Clubs" end end def <=>(other) other.verify_class(Card, Joker) compare_suits=(@@suit_order =~ /#{suit.to_s}/)<=>(@@suit_order =~ /#{other.suit.to_s}/) compare_values=(@@value_order =~ /#{value.to_s}/)<=>(@@value_order =~ /#{other.value.to_s}/) case @@suits_over_values when true return compare_suits if compare_suits != 0 compare_values when false return compare_values if compare_values != 0 compare_suits end end def inspect "{Card##{to_s}}" end end class Joker < Card def initialize @suit=:J @value=:X end def to_s "Joker" end end class Hand attr_reader(:cards) def initialize(*cards) @cards=cards.flatten @cards.each do |item| item.verify_class(Card, Joker) end end def +(hand) hand.verify_class(Hand, Deck) Hand.new(@cards+hand.cards) end def -(hand) hand.verify_class(Hand, Deck) Hand.new(@cards-hand.cards) end def each &block @cards.each &block self end def each_with_index &block @cards.each_with_index &block self end def to_a @cards end def <<(*cards) cards.each do |item| item.verify_class(Card, Joker) end @cards << cards @cards.flatten! self end def [](index) @cards[index] end def sort Hand.new(@cards.sort) end def sort! @cards.sort! self end def shuffle Hand.new(@cards.sort_by {rand}) end def shuffle! @cards = @cards.sort_by {rand} self end def stock(amount) raise "not enough cards" if amount > @cards.length new = Hand.new(@cards[0...amount]) @cards -= @cards[0...amount] new end def size @cards.length end def to_s @cards.join("\n") end def inspect "{Hand#size:#{@cards.length}}" end def ==(other) @cards==other.cards end end class Deck < Hand def initialize @cards=[] values=[2,3,4,5,6,7,8,9,10,:J,:Q,:K,:A] suits=[:C,:D,:S,:H] values.each do |v| suits.each do |s| @cards << Card.new(v,s) end end end end class Object def verify_class(*classes) if classes.include?(self.class) return true else if classes.length>2 class_names="#{classes[0..-2].join(', ')} or #{classes[-1]}" else class_names=classes.join(" or ") end raise TypeError.new("can't convert #{self.class} into #{class_names}") end end end