truco 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +11 -0
- data/lib/card.rb +111 -0
- data/lib/dealer.rb +34 -0
- data/lib/deck.rb +21 -0
- data/lib/fixnum.rb +7 -0
- data/lib/hand.rb +18 -0
- data/lib/judge.rb +52 -0
- data/lib/loader.rb +22 -0
- data/lib/player.rb +53 -0
- data/lib/truco.rb +178 -0
- metadata +68 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7e1ea4004e96f9ba5e1d5b9df08f35144309e5cc
|
4
|
+
data.tar.gz: d2a2e6fd32a6dab11c998d26a1d0c30a5bb361bb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 41b1b0ad4497f5c3e022d7bb794422f57c8c1d9f292a9cdfff17e3156881cdb557d9615b0832cd3fcdedb185b761d29136382cddf92affda8008fce412db858a
|
7
|
+
data.tar.gz: a2318c00d823e8cc809da449e9448f5f3ac2ee17ed8811f37655a900d6197c96f314f21bbb2914cfde89fe325919bd8c55279fd3a9bb1733b47555fb360f2d86
|
data/README.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Venezuelan Truco in Ruby. #
|
2
|
+
|
3
|
+
This is a small game engine that allows you to play Truco Venezuelan style.
|
4
|
+
|
5
|
+
Take a look at lib/loader for an example on how to initiate the game. Moreover, we have a good test suite that will give you an idea of how to put everything together.
|
6
|
+
|
7
|
+
### TODO: ###
|
8
|
+
|
9
|
+
- Logic for envido, truco, etc. AKA apostar between moves. See /lib/truco.rb and spec/truco.rb
|
10
|
+
|
11
|
+
- validations: When asking a user for input, we must validate he chooses a correct card.
|
data/lib/card.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
class Symbol
|
2
|
+
def to_value
|
3
|
+
return card_values[self] if card_values[self]
|
4
|
+
self.to_s.to_i
|
5
|
+
end
|
6
|
+
|
7
|
+
def card_values
|
8
|
+
{
|
9
|
+
# SUITS
|
10
|
+
:"E" => 100,
|
11
|
+
:"P" => 90,
|
12
|
+
:"O" => 80,
|
13
|
+
:"C" => 70,
|
14
|
+
# VALUES
|
15
|
+
:"3" => 30,
|
16
|
+
:"1" => 50,
|
17
|
+
:"2" => 21,
|
18
|
+
|
19
|
+
# Special Cases
|
20
|
+
:"7E" => 45,
|
21
|
+
:"7O" => 40,
|
22
|
+
:"1C" => 20,
|
23
|
+
:"1O" => 20
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Card
|
29
|
+
|
30
|
+
include Comparable
|
31
|
+
|
32
|
+
VALID_SUITS= [:"E", :"P", :"O", :"C"]
|
33
|
+
|
34
|
+
VALID_VALUES= [:"1", :"2", :"3", :"4", :"5", :"6", :"7",
|
35
|
+
:"10", :"11", :"12"]
|
36
|
+
|
37
|
+
def initialize(suit, value)
|
38
|
+
raise "Invalid Card" unless VALID_SUITS.include?(suit)
|
39
|
+
@suit = suit
|
40
|
+
@value = value
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_accessor :suit, :value
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
self.suit.to_s + " " + self.value.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
def <=>(card)
|
50
|
+
@value = :"7E" if is_7_e?
|
51
|
+
card.value = :"7E" if card.is_7_e?
|
52
|
+
|
53
|
+
|
54
|
+
@value = :"7O" if is_7_o?
|
55
|
+
card.value = :"7O" if card.is_7_o?
|
56
|
+
|
57
|
+
|
58
|
+
@value = :"1C" if is_1_c?
|
59
|
+
card.value = :"1C" if card.is_1_c?
|
60
|
+
|
61
|
+
@value = :"1O" if is_1_o?
|
62
|
+
card.value = :"1O" if card.is_1_o?
|
63
|
+
|
64
|
+
if value == card.value
|
65
|
+
if suit.to_value > card.suit.to_value
|
66
|
+
return 1
|
67
|
+
else
|
68
|
+
return -1
|
69
|
+
end
|
70
|
+
end
|
71
|
+
if value.to_value > card.value.to_value
|
72
|
+
return 1
|
73
|
+
else
|
74
|
+
return -1
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def is_7_e?
|
80
|
+
value == :"7" && suit == :"E"
|
81
|
+
end
|
82
|
+
|
83
|
+
def is_7_o?
|
84
|
+
value == :"7" && suit == :"O"
|
85
|
+
end
|
86
|
+
|
87
|
+
def is_1_c?
|
88
|
+
(value == :"1" && suit == :"C") or (value == :"1C")
|
89
|
+
end
|
90
|
+
|
91
|
+
def is_1_o?
|
92
|
+
(value == :"1" && suit == :"O") or (value == :"1O")
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def self.valid_suits
|
100
|
+
VALID_SUITS
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.valid_values
|
104
|
+
VALID_VALUES
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
class TexasHoldem ; end
|
110
|
+
|
111
|
+
|
data/lib/dealer.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
class Dealer
|
2
|
+
|
3
|
+
attr_accessor :deck, :hand
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@deck = Deck.new
|
7
|
+
@hand = Hand.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def deal_to_player(player)
|
11
|
+
player.cards << @deck.cards.pop
|
12
|
+
end
|
13
|
+
|
14
|
+
def flop
|
15
|
+
3.times{ |n| deal }
|
16
|
+
end
|
17
|
+
|
18
|
+
def initial_truco
|
19
|
+
3.times { |n| player.cards << @deck.cards.pop }
|
20
|
+
end
|
21
|
+
|
22
|
+
def hand
|
23
|
+
@hand
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def deal
|
28
|
+
@hand.cards << @deck.cards.pop
|
29
|
+
end
|
30
|
+
|
31
|
+
alias :river :deal ; alias :turn :deal
|
32
|
+
end
|
33
|
+
|
34
|
+
|
data/lib/deck.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
class Deck
|
2
|
+
|
3
|
+
def initialize
|
4
|
+
@valid_suits = Card.valid_suits
|
5
|
+
@valid_values = Card.valid_values
|
6
|
+
@stack = Array.new
|
7
|
+
|
8
|
+
@valid_suits.each do |suit|
|
9
|
+
@valid_values.each{|value | @stack << Card.new(suit, value)}
|
10
|
+
end
|
11
|
+
|
12
|
+
self.shuffle
|
13
|
+
end
|
14
|
+
|
15
|
+
def shuffle
|
16
|
+
@stack.shuffle!
|
17
|
+
end
|
18
|
+
|
19
|
+
def cards ; @stack ; end
|
20
|
+
|
21
|
+
end
|
data/lib/fixnum.rb
ADDED
data/lib/hand.rb
ADDED
data/lib/judge.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
class Judge
|
2
|
+
# For Truco:
|
3
|
+
# 4,5,6,7P, 7C,10,11,12
|
4
|
+
# 2,3,1
|
5
|
+
# 7O, 7E
|
6
|
+
# 1B, 1E
|
7
|
+
# perica
|
8
|
+
# perico
|
9
|
+
|
10
|
+
# Pintas
|
11
|
+
# C,O,P,E
|
12
|
+
|
13
|
+
attr_reader :cards
|
14
|
+
attr_accessor :vira
|
15
|
+
|
16
|
+
def initialize(cards)
|
17
|
+
@cards = cards
|
18
|
+
end
|
19
|
+
|
20
|
+
def winner
|
21
|
+
return perico if perico
|
22
|
+
return perica if perica
|
23
|
+
cards.sort[-1]
|
24
|
+
end
|
25
|
+
|
26
|
+
def suit_rank
|
27
|
+
[
|
28
|
+
:"E",
|
29
|
+
:"P",
|
30
|
+
:"O",
|
31
|
+
:"C"
|
32
|
+
]
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def perica
|
38
|
+
return nil unless @vira
|
39
|
+
@cards.clone.keep_if do |card|
|
40
|
+
((card.value == :"10") && (card.suit == @vira.suit)) or ((card.value == :"12") && (card.suit == @vira.suit) && (@vira.value == :"10"))
|
41
|
+
|
42
|
+
end[0]
|
43
|
+
end
|
44
|
+
|
45
|
+
def perico
|
46
|
+
return nil unless @vira
|
47
|
+
@cards.clone.keep_if do |card|
|
48
|
+
((card.value == :"11") && card.suit == @vira.suit) or ((card.value == :"12") && (card.suit == @vira.suit) && (@vira.value == :"11"))
|
49
|
+
end[0]
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
data/lib/loader.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require './lib/card'
|
2
|
+
require './lib/dealer'
|
3
|
+
require './lib/fixnum'
|
4
|
+
require './lib/hand'
|
5
|
+
require './lib/judge'
|
6
|
+
require './lib/player'
|
7
|
+
require './lib/truco'
|
8
|
+
require './lib/deck'
|
9
|
+
|
10
|
+
def build_game
|
11
|
+
@player1 = Player.new "Ivan"
|
12
|
+
@player2 = Player.new "Bellatrix"
|
13
|
+
|
14
|
+
@game = Truco.new [@player1, @player2]
|
15
|
+
@game.deal_to_players
|
16
|
+
#@game.to_s
|
17
|
+
@game.play
|
18
|
+
|
19
|
+
puts "EL GANADOR:"
|
20
|
+
puts @game.winner.nickname
|
21
|
+
nil
|
22
|
+
end
|
data/lib/player.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
class Player
|
2
|
+
attr_reader :cards
|
3
|
+
attr_accessor :nickname
|
4
|
+
|
5
|
+
def initialize(nickname=nil)
|
6
|
+
@cards = Array.new
|
7
|
+
@nickname = nickname
|
8
|
+
end
|
9
|
+
|
10
|
+
def cards
|
11
|
+
@cards
|
12
|
+
end
|
13
|
+
|
14
|
+
def play(n)
|
15
|
+
card = posible_moves[n]
|
16
|
+
cards.reject!{ |c| c == card }
|
17
|
+
card
|
18
|
+
end
|
19
|
+
|
20
|
+
def posible_moves
|
21
|
+
h = Hash.new
|
22
|
+
cards.count.times do |n|
|
23
|
+
h[n + 1] = cards[n]
|
24
|
+
end
|
25
|
+
h
|
26
|
+
end
|
27
|
+
|
28
|
+
def display_posible_moves
|
29
|
+
posible_moves.each_pair do |k,v|
|
30
|
+
puts "#{k} | #{v.to_s}"
|
31
|
+
end
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def display_cards
|
36
|
+
cards.each do |card|
|
37
|
+
puts card.suit.to_s + " " + card.value.to_s
|
38
|
+
end
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete_card(card)
|
43
|
+
cards.delete_if { |x| x == card }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Vira < Player
|
48
|
+
|
49
|
+
def card
|
50
|
+
cards[0]
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/lib/truco.rb
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
class Game
|
2
|
+
def initialize
|
3
|
+
@dealer = Dealer.new
|
4
|
+
@players = Array.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def dealer
|
8
|
+
@dealer
|
9
|
+
end
|
10
|
+
|
11
|
+
def players
|
12
|
+
@players
|
13
|
+
end
|
14
|
+
|
15
|
+
def hand
|
16
|
+
@dealer.hand
|
17
|
+
end
|
18
|
+
|
19
|
+
def deal_to_players
|
20
|
+
deal_to_everybody
|
21
|
+
end
|
22
|
+
|
23
|
+
def deal_to_everybody
|
24
|
+
@players.each do |player|
|
25
|
+
@dealer.deal_to_player(player)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
@players.each do |player|
|
31
|
+
puts "#" * 50
|
32
|
+
puts "Player: " + player.object_id.to_s
|
33
|
+
player.display_cards
|
34
|
+
puts "#" * 50
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_accessor :player_turn
|
39
|
+
|
40
|
+
def ask_player_for_card
|
41
|
+
puts "Waiting for turn of #{@player_turn.object_id.to_s}"
|
42
|
+
@player_turn.display_cards
|
43
|
+
card = gets.chomp
|
44
|
+
puts card.inspect
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
class Truco < Game
|
50
|
+
|
51
|
+
attr_reader :first_hand, :second_hand, :third_hand, :dealer, :players, :vira
|
52
|
+
|
53
|
+
def initialize(players)
|
54
|
+
@players = players
|
55
|
+
@dealer = Dealer.new
|
56
|
+
@vira = Vira.new
|
57
|
+
@dealer.deal_to_player(vira)
|
58
|
+
@first_hand = Hash.new
|
59
|
+
@second_hand = Hash.new
|
60
|
+
@third_hand = Hash.new
|
61
|
+
end
|
62
|
+
|
63
|
+
def deal_to_players
|
64
|
+
3.times { players.each { |p| dealer.deal_to_player p } }
|
65
|
+
end
|
66
|
+
|
67
|
+
def play_first_hand(player, card)
|
68
|
+
player.delete_card(card)
|
69
|
+
@first_hand[player] = card
|
70
|
+
end
|
71
|
+
|
72
|
+
def play_second_hand(player, card)
|
73
|
+
player.delete_card(card)
|
74
|
+
@second_hand[player] = card
|
75
|
+
end
|
76
|
+
|
77
|
+
def play_third_hand(player, card)
|
78
|
+
player.delete_card(card)
|
79
|
+
@third_hand[player] = card
|
80
|
+
end
|
81
|
+
|
82
|
+
def first_hand_winner
|
83
|
+
@first_hand_winner ||= winner_of_hand(@first_hand)
|
84
|
+
end
|
85
|
+
|
86
|
+
def second_hand_winner
|
87
|
+
@second_hand_winner ||= winner_of_hand(@second_hand)
|
88
|
+
end
|
89
|
+
|
90
|
+
def third_hand_winner
|
91
|
+
@third_hand_winner ||= winner_of_hand(@third_hand)
|
92
|
+
end
|
93
|
+
|
94
|
+
def winner_of_hand(hand)
|
95
|
+
cards = @players.map{|p| hand[p] }
|
96
|
+
judge = Judge.new(cards)
|
97
|
+
judge.vira = vira.card
|
98
|
+
winning_card = judge.winner
|
99
|
+
(winning_card == hand[@players[0]]) ? @players[0] : @players[1]
|
100
|
+
end
|
101
|
+
|
102
|
+
def winner
|
103
|
+
player_won_first_two_hands? ? first_hand_winner : player_that_won_most_matches
|
104
|
+
end
|
105
|
+
|
106
|
+
# TODO: Logic for: Envido, truco, etc. AKA Apostar.
|
107
|
+
|
108
|
+
def play
|
109
|
+
# playing the first hand
|
110
|
+
players.each { |player| ask_for_user_input(player, "play_first_hand") }
|
111
|
+
self.to_s
|
112
|
+
puts " the winner of the first hand #{first_hand_winner.nickname}"
|
113
|
+
|
114
|
+
#playing the second hand
|
115
|
+
ask_for_user_input(first_hand_winner, "play_second_hand")
|
116
|
+
ask_for_user_input(other_player(first_hand_winner), "play_second_hand")
|
117
|
+
|
118
|
+
self.to_s
|
119
|
+
puts " the winner of the second hand #{second_hand_winner.nickname}"
|
120
|
+
return if player_won_first_two_hands?
|
121
|
+
|
122
|
+
#playing the third hand
|
123
|
+
ask_for_user_input(second_hand_winner, "play_third_hand")
|
124
|
+
ask_for_user_input(other_player(second_hand_winner), "play_third_hand")
|
125
|
+
|
126
|
+
self.to_s
|
127
|
+
end
|
128
|
+
|
129
|
+
def to_s
|
130
|
+
puts "First Hand:"
|
131
|
+
display_hand(@first_hand)
|
132
|
+
puts "Second Hand:"
|
133
|
+
display_hand(@second_hand)
|
134
|
+
puts "Third Hand:"
|
135
|
+
display_hand(@third_hand)
|
136
|
+
end
|
137
|
+
|
138
|
+
def first_turn_for_second_hand
|
139
|
+
first_hand_winner
|
140
|
+
end
|
141
|
+
|
142
|
+
def first_turn_for_third_hand
|
143
|
+
second_hand_winner
|
144
|
+
end
|
145
|
+
|
146
|
+
def other_player(p)
|
147
|
+
players.clone.reject{ |player| player == p}[0]
|
148
|
+
end
|
149
|
+
|
150
|
+
private
|
151
|
+
|
152
|
+
def display_hand(hand)
|
153
|
+
return if hand == {}
|
154
|
+
puts "#" * 20
|
155
|
+
hand.each do |k,v|
|
156
|
+
puts "#{k.nickname}: #{v.to_s}"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def player_that_won_most_matches
|
161
|
+
[ first_hand_winner, second_hand_winner, third_hand_winner].group_by { |d| d }.keys.first
|
162
|
+
end
|
163
|
+
|
164
|
+
def player_won_first_two_hands?
|
165
|
+
first_hand_winner == second_hand_winner
|
166
|
+
end
|
167
|
+
|
168
|
+
def ask_for_user_input(player, method)
|
169
|
+
puts "La vira: #{vira.card.to_s}"
|
170
|
+
puts "What are you going to Play #{player.nickname}?"
|
171
|
+
puts player.display_posible_moves
|
172
|
+
p = gets
|
173
|
+
card = player.play p.to_i
|
174
|
+
self.send(method, player, card)
|
175
|
+
100.times{ puts nil }
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: truco
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ivan Acosta-Rubio
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: A game engine to play truco.
|
28
|
+
email:
|
29
|
+
- ivan@softwarecriollo.net
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- README.md
|
35
|
+
- lib/card.rb
|
36
|
+
- lib/dealer.rb
|
37
|
+
- lib/deck.rb
|
38
|
+
- lib/fixnum.rb
|
39
|
+
- lib/hand.rb
|
40
|
+
- lib/judge.rb
|
41
|
+
- lib/loader.rb
|
42
|
+
- lib/player.rb
|
43
|
+
- lib/truco.rb
|
44
|
+
homepage: http://www.softwarecriollo.com
|
45
|
+
licenses:
|
46
|
+
- MIT
|
47
|
+
metadata: {}
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements: []
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 2.2.0
|
65
|
+
signing_key:
|
66
|
+
specification_version: 4
|
67
|
+
summary: A game engine to play truco.
|
68
|
+
test_files: []
|