1
2 class Card
3 include Comparable
4 attr_accessor :suit, :value
5
6 @@values = Hash.new { |hash, key| key.to_s }
7 @@values.merge!(11 => 'jack', 12 => 'queen', 13 => 'king', 14 => 'ace')
8
9 def initialize(suit, value)
10 @suit = suit
11 @value = value
12 end
13
14 def to_s
15 "#{@@values[@value]} of #{@suit}s"
16 end
17
18 def <=> (other)
19 @value <=> other.value
20 end
21 end
22
23 class GroupOfCards < Array
24 def shuffle!
25 replace(sort_by { rand })
26 end
27
28 def to_s
29 join(", ")
30 end
31 end
32
33 class Deck < GroupOfCards
34 def initialize
35 [:spade, :diamond, :club, :heart].each do |suit|
36 (2..14).each do |value|
37 push(Card.new(suit, value))
38 end
39 end
40 end
41 end
42
43 class Player
44 attr_accessor :name, :table
45
46 def initialize(name)
47 @name = name
48 @hand = GroupOfCards.new
49 @pile = GroupOfCards.new
50 @table = GroupOfCards.new
51 end
52
53 def play_card
54 if @hand.empty?
55 @hand, @pile = @pile, @hand
56 @hand.shuffle!
57 end
58 @table << @hand.pop
59 end
60
61 def add_card(card)
62 @pile << card
63 end
64
65 def cards
66 @hand + @pile
67 end
68
69 def showing
70 @table.last
71 end
72
73 def card_count
74 @hand.size + @pile.size + @table.size
75 end
76
77 def has_cards?
78 card_count > 0
79 end
80
81 def status
82 "#{@name}(#{card_count}) plays #{showing}"
83 end
84
85 def to_s
86 name
87 end
88 end
89
90 class GameOfWar
91 def initialize(player_count=2)
92 deck = Deck.new
93 deck.shuffle!
94 @players = Array.new(player_count) { |i| Player.new("Player #{i+1}") }
95
96 deck.shuffle!
97 until deck.empty?
98 player = @players.shift
99 player.add_card(deck.pop)
100 @players.push(player)
101 end
102 end
103
104 def play_round(players)
105 spoils_of_war = []
106
107
108 players.each do |p|
109 p.play_card
110 puts p.status
111 end
112
113
114 winners = players.sort_by { |p| p.showing }
115 high_card = winners.last.showing
116
117 winners = winners.select { |p| p.showing == high_card }
118
119
120 if winners.size > 1
121 puts "WAR: #{winners.join(", ")}"
122
123 winners.each { |p| p.play_card }
124 winner = play_round(winners)
125 else
126 winner = winners.first
127 puts "Winner: #{winner}"
128 end
129
130 players.each { |p| spoils_of_war += p.table; p.table = [] }
131 spoils_of_war.each { |c| winner.add_card(c) }
132 winner
133 end
134
135 def play
136 round = 1
137 until @players.size == 1
138 puts "\nAt Round #{round}"
139 play_round(@players)
140 round += 1
141
142
143 loosers = @players.select { |p| p.card_count == 0 }
144 loosers.each { |p| puts "#{p} lost"}
145 @players -= loosers
146 end
147
148 puts "\n#{@players.first.name} Won!!!"
149 end
150
151 def to_s
152 @players.join("\n")
153 end
154 end
155
156 if __FILE__ == $0
157 g = GameOfWar.new 3
158 g.play
159 end