|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
1 |
# |
| |
2 |
# :title: Truco Game Plugin for rbot |
| |
3 |
# |
| |
4 |
# Author:: Marcos Piccinini <nofxx> |
| |
5 |
# Copyright:: (C) 2008 Marcos Piccinini |
|
ae6d5031
»
|
nofxx |
2008-08-01 |
working on... |
6 |
# License:: GPL v2 |
|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
7 |
# |
|
ae6d5031
»
|
nofxx |
2008-08-01 |
working on... |
8 |
# Adaptation of: |
| |
9 |
# Uno Game Plugin for rbot |
| |
10 |
# Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com> |
| |
11 |
# Copyright:: (C) 2008 Giuseppe Bilotta |
|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
12 |
# License:: GPL v2 |
| |
13 |
# |
|
ae6d5031
»
|
nofxx |
2008-08-01 |
working on... |
14 |
# |
|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
15 |
# Truco: You start with 3 cards. The values are as shown in the table. |
| |
16 |
# The one who wins two hands, wins a point. |
| |
17 |
# |
| |
18 |
# If the first one drawns, the next one must decide (the most valuable card wins) |
| |
19 |
# |
| |
20 |
# You can play with 2 or 4 ppl. |
| |
21 |
# |
|
ae6d5031
»
|
nofxx |
2008-08-01 |
working on... |
22 |
# |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
23 |
# # # # # # # # # # # # # # |
| |
24 |
# |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
25 |
# TrucoGame |
| |
26 |
# |
| |
27 |
class TrucoGame |
| |
28 |
NAIPES = %w{Ouro Copas Espada Paus} |
| |
29 |
#Values already in the weight order |
| |
30 |
SPECIALS = %w{Zap SeteCopas Espadilha SeteOuro} |
| |
31 |
VALUES = %w{3 2 A K J Q 7 6 5 4} |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
32 |
ORDER = SPECIALS.concat(VALUES) |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
33 |
|
| |
34 |
# cards in stock |
| |
35 |
attr_reader :stock |
| |
36 |
# current discard |
| |
37 |
attr_reader :discard |
| |
38 |
# previous discard, in case of challenge |
| |
39 |
attr_reader :last_discard |
| |
40 |
# channel the game is played in |
| |
41 |
attr_reader :channel |
| |
42 |
# list of players |
| |
43 |
attr :players |
| |
44 |
# game start time |
| |
45 |
attr :start_time |
| |
46 |
# the IRC user that created the game |
| |
47 |
attr_accessor :manager |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
48 |
# who call the last truco! |
| |
49 |
attr_accessor :called_truco |
| |
50 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
51 |
def TrucoGame.color_map(clr) |
| |
52 |
case clr |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
53 |
when 'Ouro' then :red |
| |
54 |
when 'Copas' then :white |
| |
55 |
when 'Espada' then :black |
| |
56 |
when 'Paus' then :white |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
57 |
end |
| |
58 |
end |
|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
59 |
|
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
60 |
def TrucoGame.irc_naipe_bg(clr) |
| |
61 |
cor = case clr |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
62 |
when 'Ouro' then :white |
| |
63 |
when 'Copas' then :red |
| |
64 |
when 'Espada' then :white |
| |
65 |
when 'Paus' then :black |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
66 |
end |
| |
67 |
Irc.color(cor, TrucoGame.color_map(clr)) |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
68 |
end |
|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
69 |
|
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
70 |
def TrucoGame.irc_naipe_fg(clr) |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
71 |
Irc.color(TrucoGame.color_map(clr)) |
| |
72 |
end |
| |
73 |
|
| |
74 |
def TrucoGame.colorify(str, fg=false) |
| |
75 |
ret = Bold.dup |
| |
76 |
str.length.times do |i| |
| |
77 |
ret << (fg ? |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
78 |
TrucoGame.irc_naipe_fg(NAIPES[i%4]) : |
| |
79 |
TrucoGame.irc_naipe_bg(NAIPES[i%4]) ) +str[i,1] |
|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
80 |
end |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
81 |
ret << NormalText |
|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
82 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
83 |
|
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
84 |
def TrucoGame.simbolizar(na) |
| |
85 |
case na |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
86 |
when 'Copas' then "♥ " |
| |
87 |
when 'Ouro' then "♦ " |
| |
88 |
when 'Paus' then "♣ " |
| |
89 |
when 'Espada' then "♠ " |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
90 |
end |
| |
91 |
end |
| |
92 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
93 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
94 |
# |
| |
95 |
# |
| |
96 |
# |
| |
97 |
# |
| |
98 |
# INIT |
| |
99 |
# |
|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
100 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
101 |
TRUCO = TrucoGame.colorify('TRUCO!', true) |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
102 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
103 |
def initialize(plugin, channel, manager) |
| |
104 |
@channel = channel |
| |
105 |
@plugin = plugin |
| |
106 |
@bot = plugin.bot |
| |
107 |
@players = [] |
| |
108 |
@dropouts = [] |
| |
109 |
@value = nil |
| |
110 |
@naipe = nil |
| |
111 |
make_base_stock |
| |
112 |
@stock = [] |
| |
113 |
make_stock |
|
c873e484
»
|
nofxx |
2008-08-02 |
cleanup |
114 |
@hands = [] |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
115 |
@round_value = 1 |
|
c873e484
»
|
nofxx |
2008-08-02 |
cleanup |
116 |
@rounds = [] |
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
117 |
@turns = 0 |
|
ae6d5031
»
|
nofxx |
2008-08-01 |
working on... |
118 |
@called_truco = nil |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
119 |
@accept_truco = false |
|
ae6d5031
»
|
nofxx |
2008-08-01 |
working on... |
120 |
@top_card = nil |
|
c873e484
»
|
nofxx |
2008-08-02 |
cleanup |
121 |
@top_card_owner = nil |
|
ae6d5031
»
|
nofxx |
2008-08-01 |
working on... |
122 |
@score = [] |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
123 |
@start_time = nil |
| |
124 |
@join_timer = nil |
| |
125 |
@must_play = nil |
| |
126 |
@manager = manager |
| |
127 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
128 |
|
| |
129 |
|
| |
130 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
131 |
# |
| |
132 |
# |
| |
133 |
# |
| |
134 |
# |
| |
135 |
# CARD |
|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
136 |
# |
| |
137 |
class Card |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
138 |
attr_reader :naipe |
| |
139 |
attr_reader :value |
| |
140 |
attr_reader :shortform |
| |
141 |
attr_reader :to_s |
| |
142 |
attr_reader :score |
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
143 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
144 |
def initialize(c)#naipe, value) |
| |
145 |
naipe = c[0] |
| |
146 |
value = c[1] |
| |
147 |
# raise unless NAIPES.include? naipe || SPECIAL.include? naipe |
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
148 |
|
| |
149 |
raise unless ORDER.include? value |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
150 |
@naipe = naipe.dup |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
151 |
@value = value.dup |
|
c873e484
»
|
nofxx |
2008-08-02 |
cleanup |
152 |
@shortform = (@naipe[0,1]+@value.to_s[0,1]).downcase |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
153 |
|
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
154 |
@to_s = TrucoGame.irc_naipe_bg(@naipe) + |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
155 |
Bold + ["|", @value, TrucoGame.simbolizar(@naipe), @naipe, '|'].join(' ') + NormalText |
|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
156 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
157 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
158 |
def <=>(other) |
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
159 |
return ORDER.index(other.value) <=> ORDER.index(self.value) |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
160 |
end |
| |
161 |
include Comparable |
|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
162 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
163 |
|
| |
164 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
165 |
# |
| |
166 |
# |
| |
167 |
# |
| |
168 |
# |
| |
169 |
# PLAYER |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
170 |
# |
|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
171 |
class Player |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
172 |
attr_accessor :cards |
| |
173 |
attr_accessor :user |
|
ae6d5031
»
|
nofxx |
2008-08-01 |
working on... |
174 |
attr_accessor :score |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
175 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
176 |
def initialize(user) |
| |
177 |
@user = user |
| |
178 |
@cards = [] |
|
ae6d5031
»
|
nofxx |
2008-08-01 |
working on... |
179 |
@score = 0 |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
180 |
end |
| |
181 |
def has_card?(short) |
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
182 |
has = nil |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
183 |
@cards.each { |c| |
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
184 |
has = c if c.shortform == short |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
185 |
} |
| |
186 |
if has.empty? |
| |
187 |
return false |
| |
188 |
else |
| |
189 |
return has |
| |
190 |
end |
| |
191 |
end |
| |
192 |
def to_s |
| |
193 |
Bold + @user.to_s + Bold |
| |
194 |
end |
|
ae6d5031
»
|
nofxx |
2008-08-01 |
working on... |
195 |
def score(score = 1) |
| |
196 |
@score += score |
| |
197 |
end |
| |
198 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
199 |
|
|
ae6d5031
»
|
nofxx |
2008-08-01 |
working on... |
200 |
class Team |
| |
201 |
def initialize(players) |
| |
202 |
@players = players |
| |
203 |
end |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
204 |
end |
| |
205 |
|
| |
206 |
def get_player(user) |
| |
207 |
case user |
| |
208 |
when User |
| |
209 |
@players.each do |p| |
| |
210 |
return p if p.user == user |
| |
211 |
end |
| |
212 |
when String |
| |
213 |
@players.each do |p| |
| |
214 |
return p if p.user.irc_downcase == user.irc_downcase(channel.casemap) |
| |
215 |
end |
| |
216 |
else |
| |
217 |
get_player(user.to_s) |
| |
218 |
end |
| |
219 |
return nil |
| |
220 |
end |
| |
221 |
|
|
c873e484
»
|
nofxx |
2008-08-02 |
cleanup |
222 |
def current_player |
| |
223 |
get_player(@players[0]) |
| |
224 |
end |
| |
225 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
226 |
def announce(msg, opts={}) |
| |
227 |
@bot.say channel, msg, opts |
| |
228 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
229 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
230 |
def notify(player, msg, opts={}) |
| |
231 |
@bot.notice player.user, msg, opts |
| |
232 |
end |
| |
233 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
234 |
|
| |
235 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
236 |
# |
| |
237 |
# |
| |
238 |
# |
| |
239 |
# |
| |
240 |
# STOCK |
| |
241 |
# |
| |
242 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
243 |
def make_base_stock |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
244 |
|
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
245 |
base = NAIPES.inject([]) do |list, naip| |
| |
246 |
VALUES.each { |v| list << [naip, v] } |
| |
247 |
list |
| |
248 |
end |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
249 |
# # |
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
250 |
# SPECIAL CARDS |
| |
251 |
#TODO:refactor |
| |
252 |
zap = %w{Paus 4} |
| |
253 |
setecopas = %w{Copas 7} |
| |
254 |
espadilha = %w{Espada A} |
| |
255 |
seteouro = %w{Ouro 7} |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
256 |
|
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
257 |
#especiais = [zap, setecopas, espadilha, seteouro] |
| |
258 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
259 |
base[base.index(zap)] = ['Paus','Zap'] |
| |
260 |
base[base.index(espadilha)] = ['Espada','SeteCopas'] |
| |
261 |
base[base.index(setecopas)] = ['Copas','Espadilha'] |
| |
262 |
base[base.index(seteouro)] = ['Ouro','SeteOuro'] |
| |
263 |
|
| |
264 |
#especiais = [ , ] |
| |
265 |
#final = especiais.concat(base) |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
266 |
# @base_stock = especiais.concat(@base_stock) |
| |
267 |
# # # |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
268 |
# ORDER |
| |
269 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
270 |
# list.concat(CARDS) |
| |
271 |
# list |
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
272 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
273 |
@base_stock = base.inject([]) do |ll, f| |
| |
274 |
ll << Card.new(f) |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
275 |
end |
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
276 |
# @base_stock = NAIPES.inject([]) do |list, naip| |
| |
277 |
# VALUES.each do |v| |
| |
278 |
# list << Card.new(naip, v) |
| |
279 |
# #list << Card.new(naip, v) unless v == 0 |
| |
280 |
# end |
| |
281 |
# list |
| |
282 |
# end |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
283 |
|
| |
284 |
end |
| |
285 |
|
| |
286 |
def make_stock |
| |
287 |
@stock.replace @base_stock |
| |
288 |
# remove the cards in the players hand |
| |
289 |
@players.each { |p| p.cards.each { |c| @stock.delete_one c } } |
| |
290 |
# remove current top discarded card if present |
| |
291 |
if @discard |
| |
292 |
@stock.delete_one(discard) |
| |
293 |
end |
| |
294 |
@stock.shuffle! |
| |
295 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
296 |
|
| |
297 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
298 |
# |
| |
299 |
# |
| |
300 |
# |
| |
301 |
# |
| |
302 |
# START GAME |
| |
303 |
# |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
304 |
|
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
305 |
def start_game#(num_players) |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
306 |
debug "TRUCO----------------START---------------> game" |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
307 |
@players.shuffle! |
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
308 |
if @players.length == 3 |
| |
309 |
announce _("%{p} you are out!!") % { |
| |
310 |
:p => @players.last |
| |
311 |
} |
| |
312 |
drop_player(@players.last) |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
313 |
|
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
314 |
end |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
315 |
show_order |
|
c873e484
»
|
nofxx |
2008-08-02 |
cleanup |
316 |
announce _("%{p} começa o jogo!! mão %{n}") % { |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
317 |
:p => @players.first, |
|
c873e484
»
|
nofxx |
2008-08-02 |
cleanup |
318 |
:n => @hands.length |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
319 |
} |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
320 |
#card = @stock.shift |
| |
321 |
#@picker = 0 |
| |
322 |
##@special = false |
| |
323 |
#set_discard(card) |
| |
324 |
#show_discard |
| |
325 |
#if @special |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
326 |
# do_special |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
327 |
#end |
| |
328 |
#next_turn |
| |
329 |
show_turn |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
330 |
@start_time = Time.now |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
331 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
332 |
end |
| |
333 |
|
| |
334 |
def elapsed_time |
| |
335 |
if @start_time |
| |
336 |
Utils.secs_to_string(Time.now-@start_time) |
| |
337 |
else |
| |
338 |
_("no time") |
| |
339 |
end |
| |
340 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
341 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
342 |
def set_discard(card) |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
343 |
@discard = card |
| |
344 |
@value = card.value.dup rescue card.value |
| |
345 |
@must_play = nil |
| |
346 |
end |
| |
347 |
|
| |
348 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
349 |
# |
| |
350 |
# |
| |
351 |
# |
| |
352 |
# |
| |
353 |
# TABLE |
| |
354 |
# |
| |
355 |
|
| |
356 |
def clean_table |
| |
357 |
|
| |
358 |
@turns = 0 |
| |
359 |
@top_card = nil |
| |
360 |
@top_card_owner = nil |
| |
361 |
end |
| |
362 |
|
| |
363 |
def next_turn(kind = nil,opts={}) |
| |
364 |
|
| |
365 |
case kind |
| |
366 |
when nil |
| |
367 |
@players << @players.shift |
| |
368 |
|
| |
369 |
when :hand |
| |
370 |
announce _("%{p} ganhou essa mão com %{card}.") % { |
| |
371 |
:p => @top_card_owner, |
| |
372 |
:card => @top_card |
| |
373 |
} |
| |
374 |
@hands << @top_card_owner#, @top_card] |
| |
375 |
@players += @players.shift(@players.index(@top_card_owner)) |
| |
376 |
clean_table |
| |
377 |
|
| |
378 |
when :round |
| |
379 |
|
| |
380 |
if @top_card_owner.score > 15 |
| |
381 |
announce _("%{p} ganhou essa partida!!!!.") % { |
| |
382 |
:p => @top_card_owner, |
| |
383 |
:s => @top_card_owner.score |
| |
384 |
} |
| |
385 |
end_game |
| |
386 |
end |
| |
387 |
@players.each { |p| deal(p, 3) } |
| |
388 |
@top_card_owner.score(@round_value) |
| |
389 |
@round_value = 1 |
| |
390 |
@rounds << @hands |
| |
391 |
@hands = [] |
| |
392 |
@players << @players.shift |
| |
393 |
announce _("%{p} ganhou essa rodada e tem agora %{s} pontos.") % { |
| |
394 |
:p => @top_card_owner, |
| |
395 |
:s => @top_card_owner.score |
| |
396 |
} |
| |
397 |
clean_table |
| |
398 |
end |
| |
399 |
|
| |
400 |
show_turn |
| |
401 |
end |
| |
402 |
|
| |
403 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
404 |
# |
| |
405 |
# |
| |
406 |
# |
| |
407 |
# |
| |
408 |
# PLAY |
| |
409 |
# |
| |
410 |
|
| |
411 |
def can_play(card) |
| |
412 |
true |
| |
413 |
end |
| |
414 |
|
| |
415 |
def get_card(source, card) |
| |
416 |
p = get_player(source) |
| |
417 |
return nil unless p |
| |
418 |
unless card =~ /1|2|3/ |
| |
419 |
shorts = card.gsub(/\s+/,'').match(/^(?:([ceop]\+?\S){1,2}|([zap])|([copas])?)$/).to_a |
| |
420 |
debug shorts.inspect |
| |
421 |
if shorts.empty? |
| |
422 |
announce _("what cards were that again?") |
| |
423 |
return |
| |
424 |
end |
| |
425 |
full = shorts[0] |
| |
426 |
short = shorts[1] || shorts[2] || shorts[3] |
| |
427 |
|
| |
428 |
debug [full, short].inspect #, jolly, jcolor, toplay].inspect |
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
429 |
# r7r7 -> r7r7, r7, nil, nil |
| |
430 |
# r7 -> r7, r7, nil, nil |
| |
431 |
# w -> w, nil, w, nil |
| |
432 |
# wg -> wg, nil, w, g |
| |
433 |
|
| |
434 |
|
| |
435 |
card = p.has_card?(short) |
| |
436 |
else |
| |
437 |
# new = > 1 | 2 | 3 |
| |
438 |
card = p.cards[card.to_i - 1] |
| |
439 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
440 |
|
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
441 |
if card |
| |
442 |
return card |
| |
443 |
else |
| |
444 |
return nil |
| |
445 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
446 |
end |
| |
447 |
|
| |
448 |
def play_card(source, cards=nil, cover=false) |
| |
449 |
if @called_truco |
| |
450 |
unless @accept_truco |
| |
451 |
|
| |
452 |
announce _("Voce deve aceitar ou nao o truco! Valor da rodada: %{v}") % { |
| |
453 |
:v => @round_value |
| |
454 |
} |
| |
455 |
return |
| |
456 |
end |
| |
457 |
end |
| |
458 |
return unless cards |
| |
459 |
|
| |
460 |
debug "Playing card #{cards}" |
| |
461 |
p = get_player(source) |
| |
462 |
puts cards.inspect |
| |
463 |
debug cards |
| |
464 |
if cards = get_card(source, cards) |
| |
465 |
set_discard(p.cards.delete_one(cards)) |
| |
466 |
|
| |
467 |
unless cover |
| |
468 |
|
| |
469 |
|
| |
470 |
if @top_card.nil? |
| |
471 |
|
| |
472 |
@top_card = @discard |
| |
473 |
@top_card_owner = p |
| |
474 |
announce _("%{p} começa a mão com %{card}") % { |
| |
475 |
:p => p, |
| |
476 |
:card => @discard |
| |
477 |
} |
| |
478 |
|
| |
479 |
elsif @discard > @top_card |
| |
480 |
@top_card = @discard |
| |
481 |
@top_card_owner = p |
| |
482 |
announce _("%{p} chegou matando com %{card}!") % { |
| |
483 |
:p => p, |
| |
484 |
:card => @discard |
| |
485 |
} |
| |
486 |
|
| |
487 |
elsif @top_card == @discard |
| |
488 |
# TODO: call draw |
| |
489 |
announce _("%{p} jogou %{card}..e empata a mão, a maior ganha agora!") % { |
| |
490 |
:p => p, |
| |
491 |
:card => @discard |
| |
492 |
} |
| |
493 |
|
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
494 |
else |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
495 |
announce _("%{p} não deu conta com esse %{card}, a maior carta é %{t}") % { |
| |
496 |
:p => p, |
| |
497 |
:card => @discard, |
| |
498 |
:t => @top_card |
| |
499 |
} |
| |
500 |
|
| |
501 |
end |
| |
502 |
end |
| |
503 |
@turns += 1 |
| |
504 |
|
| |
505 |
if @turns == @players.count |
| |
506 |
if @hands.length == 2 || @hands[0] == @top_card_owner |
| |
507 |
next_turn(:round) |
| |
508 |
else |
| |
509 |
next_turn(:hand) |
| |
510 |
end |
| |
511 |
else |
| |
512 |
next_turn |
| |
513 |
end |
| |
514 |
else |
| |
515 |
announce _("você não tem essa carta...") |
| |
516 |
end |
| |
517 |
end |
| |
518 |
|
| |
519 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
520 |
# |
| |
521 |
# |
| |
522 |
# |
| |
523 |
# |
| |
524 |
# TRUCO |
| |
525 |
# |
| |
526 |
|
| |
527 |
def pass(source, ok) |
| |
528 |
if @called_truco |
| |
529 |
p = get_player(source) |
| |
530 |
|
| |
531 |
if @called_truco == p |
| |
532 |
announce _("Seu oponente deve fazer isso...") |
| |
533 |
else |
| |
534 |
if ok |
| |
535 |
announce _("%{p} aceitou truco...") % { :p => p } |
| |
536 |
@accept_truco = true |
| |
537 |
# value_increase |
| |
538 |
else |
| |
539 |
announce _("%{p} fugiu da parada...") % { :p => p } |
| |
540 |
@accept_truco = false |
| |
541 |
next_turn(:round) |
| |
542 |
end |
| |
543 |
end |
| |
544 |
end |
| |
545 |
end |
| |
546 |
|
| |
547 |
def value_increase |
| |
548 |
@round_value == 1 ? @round_value = 3 : @round_value *= 2 |
| |
549 |
announce _("Essa rodada foi pra %{v}" % { :v => @round_value} ) |
| |
550 |
# @called_truco = nil |
| |
551 |
end |
| |
552 |
|
| |
553 |
def truco!(source) |
| |
554 |
p = get_player(source) |
| |
555 |
if @called_truco |
| |
556 |
|
| |
557 |
if @called_truco == p |
| |
558 |
announce _("%{p}, você acabou de pedir truco, ô animal!" % { :p => p }) |
| |
559 |
return |
| |
560 |
end |
| |
561 |
announce _("%{p} Pediu: DOOOOOOOOBRO LADRÃO!!!"% { :p => p }) |
| |
562 |
value_increase |
| |
563 |
@accept_truco = false |
| |
564 |
@called_truco = p |
| |
565 |
else |
| |
566 |
announce _("%{p} Pediu: TRUUUUUUUUUUUCO LADRÃO!!!"% { :p => p }) |
| |
567 |
value_increase |
| |
568 |
@accept_truco = false |
| |
569 |
@called_truco = p |
| |
570 |
end |
| |
571 |
|
| |
572 |
end |
| |
573 |
|
| |
574 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
575 |
# |
| |
576 |
# |
| |
577 |
# |
| |
578 |
# |
| |
579 |
# SHOW STUFF |
| |
580 |
# |
| |
581 |
|
| |
582 |
def show_time |
| |
583 |
if @start_time |
| |
584 |
announce _("This %{truco} game has been going on for %{time}") % { |
| |
585 |
:truco => TRUCO, |
| |
586 |
:time => elapsed_time |
| |
587 |
} |
| |
588 |
else |
| |
589 |
announce _("The game hasn't started yet") |
| |
590 |
end |
| |
591 |
end |
| |
592 |
|
| |
593 |
def show_order |
| |
594 |
announce _("%{truco} jogando: %{players}") % { |
| |
595 |
:truco => TRUCO, :players => players.join(' ') |
| |
596 |
} |
| |
597 |
end |
| |
598 |
|
| |
599 |
def show_turn(opts={}) |
| |
600 |
cards = true |
| |
601 |
cards = opts[:cards] if opts.key?(:cards) |
| |
602 |
player = @players.first |
| |
603 |
announce _("é a vez de %{player}") % { :player => player } |
| |
604 |
show_user_cards(player) if cards |
| |
605 |
end |
| |
606 |
|
| |
607 |
def has_turn?(source) |
| |
608 |
@start_time && (@players.first.user == source) |
| |
609 |
end |
| |
610 |
|
| |
611 |
def is_next?(source) |
| |
612 |
@start_time && (@players[1].user == source) |
| |
613 |
end |
| |
614 |
|
| |
615 |
def show_discard |
| |
616 |
announce _("Current discard: %{card} %{c}") % { :card => @discard, |
| |
617 |
:c => (SPECIALS === @discard) ? TrucoGame.irc_naipe_bg(@naipe) + " #{@naipe} " : nil |
| |
618 |
} |
| |
619 |
show_picker |
| |
620 |
end |
| |
621 |
|
| |
622 |
def show_user_cards(player) |
| |
623 |
p = Player === player ? player : get_player(player) |
| |
624 |
return unless p |
| |
625 |
notify p, _('Your cards: %{cards}') % { |
| |
626 |
:cards => p.cards.join(' ') |
| |
627 |
} |
| |
628 |
end |
| |
629 |
|
| |
630 |
def show_all_cards(u=nil) |
| |
631 |
show_user_cards(u) if u |
| |
632 |
end |
| |
633 |
|
| |
634 |
def deal(player, num=1) |
| |
635 |
picked = [] |
| |
636 |
num.times do |
| |
637 |
picked << @stock.delete_one |
| |
638 |
end |
| |
639 |
picked.sort! |
| |
640 |
#notify player, _("Você recebeu %{picked}") % { :picked => picked.join(' ') } |
| |
641 |
player.cards += picked |
| |
642 |
player.cards.sort! |
| |
643 |
end |
| |
644 |
|
| |
645 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
646 |
# |
| |
647 |
# |
| |
648 |
# |
| |
649 |
# |
| |
650 |
# PLAYER MANAGEMENT |
| |
651 |
# |
| |
652 |
|
| |
653 |
def add_player(user) |
| |
654 |
if p = get_player(user) |
| |
655 |
announce _("you're already in the game, %{p}") % { |
| |
656 |
:p => p |
| |
657 |
} |
| |
658 |
return |
| |
659 |
end |
| |
660 |
@dropouts.each do |dp| |
| |
661 |
if dp.user == user |
| |
662 |
announce _("you dropped from the game, %{p}, you can't get back in") % { |
| |
663 |
:p => dp |
| |
664 |
} |
| |
665 |
return |
| |
666 |
end |
| |
667 |
end |
| |
668 |
|
| |
669 |
if @players.length > 4 |
| |
670 |
announce _("maximo de 4 jogaores, %{p}") % { |
| |
671 |
:p => user |
| |
672 |
} |
| |
673 |
return |
| |
674 |
end |
| |
675 |
|
| |
676 |
if @start_time |
| |
677 |
announce _("Jogo já começou...espere o próximo #{user}") |
| |
678 |
return |
| |
679 |
end |
| |
680 |
|
| |
681 |
p = Player.new(user) |
| |
682 |
@players << p |
| |
683 |
announce _("%{p} entrou no jogo %{truco}") % { |
| |
684 |
:p => p, :truco => TRUCO |
| |
685 |
} |
| |
686 |
|
| |
687 |
cards = 3 |
| |
688 |
deal(p, cards) |
| |
689 |
return if @start_time |
| |
690 |
if @join_timer |
| |
691 |
@bot.timer.reschedule(@join_timer, 4) # 10s |
| |
692 |
elsif @players.length > 1 |
| |
693 |
announce _("game will start in 5 seconds") # 20s |
| |
694 |
@join_timer = @bot.timer.add_once(5) { |
|
a0167159
»
|
nofxx |
2008-08-02 |
ugly code but working |
695 |
start_game |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
696 |
} |
| |
697 |
end |
| |
698 |
end |
| |
699 |
|
| |
700 |
def drop_player(nick) |
| |
701 |
# A nick is passed because the original player might have left |
| |
702 |
# the channel or IRC |
| |
703 |
unless p = get_player(nick) |
| |
704 |
announce _("%{p} isn't playing %{truco}") % { |
| |
705 |
:p => p, :truco => TRUCO |
| |
706 |
} |
| |
707 |
return |
| |
708 |
end |
| |
709 |
announce _("%{p} gives up this game of %{truco}") % { |
| |
710 |
:p => p, :truco => TRUCO |
| |
711 |
} |
| |
712 |
# case @players.length |
| |
713 |
# when 2 |
| |
714 |
if p == @players.first |
| |
715 |
next_turn |
| |
716 |
end |
| |
717 |
end_game |
| |
718 |
# return |
| |
719 |
# when 1 |
| |
720 |
# end_game(true) |
| |
721 |
return |
| |
722 |
# end |
| |
723 |
# debug @stock.length |
| |
724 |
# while p.cards.length > 0 |
| |
725 |
# @stock.insert(rand(@stock.length), p.cards.shift) |
|
c873e484
»
|
nofxx |
2008-08-02 |
cleanup |
726 |
# end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
727 |
# debug @stock.length |
| |
728 |
@dropouts << @players.delete_one(p) |
| |
729 |
end |
| |
730 |
|
| |
731 |
def replace_player(old, new) |
| |
732 |
# The new user |
| |
733 |
user = channel.get_user(new) |
| |
734 |
if p = get_player(user) |
| |
735 |
announce _("%{p} is already playing %{truco} here") % { |
| |
736 |
:p => p, :truco => TRUCO |
| |
737 |
} |
| |
738 |
return |
| |
739 |
end |
| |
740 |
# We scan the player list of the player with the old nick, instead |
| |
741 |
# of using get_player, in case of IRC drops etc |
| |
742 |
@players.each do |p| |
| |
743 |
if p.user.nick == old |
| |
744 |
p.user = user |
| |
745 |
announce _("%{p} takes %{b}%{old}%{b}'s place at %{truco}") % { |
| |
746 |
:p => p, :b => Bold, :old => old, :truco => TRUCO |
| |
747 |
} |
| |
748 |
return |
| |
749 |
end |
| |
750 |
end |
| |
751 |
announce _("%{b}%{old}%{b} isn't playing %{truco} here") % { |
| |
752 |
:truco => TRUCO, :b => Bold, :old => old |
| |
753 |
} |
| |
754 |
end |
| |
755 |
|
| |
756 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
757 |
# |
| |
758 |
# |
| |
759 |
# |
| |
760 |
# |
| |
761 |
# END GAME |
| |
762 |
# |
| |
763 |
|
| |
764 |
def end_game(halted = false) |
| |
765 |
runtime = @start_time ? Time.now - @start_time : 0 |
| |
766 |
if halted |
| |
767 |
if @start_time |
| |
768 |
announce _("%{truco} game halted after %{time}") % { |
| |
769 |
:time => elapsed_time, |
| |
770 |
:truco => TRUCO |
| |
771 |
} |
| |
772 |
else |
| |
773 |
announce _("%{truco} game halted before it could start") % { |
| |
774 |
:truco => TRUCO |
| |
775 |
} |
| |
776 |
end |
| |
777 |
else |
| |
778 |
announce _("%{truco} game finished after %{time}! The winner is %{p}") % { |
| |
779 |
:time => elapsed_time, |
| |
780 |
:truco => TRUCO, :p => @players.first |
| |
781 |
} |
| |
782 |
end |
| |
783 |
|
| |
784 |
score = @players.inject(0) do |sum, p| |
| |
785 |
#if p.cards.length > 0 |
| |
786 |
# announce _("%{p} still had %{cards}") % { |
| |
787 |
# :p => p, :cards => p.cards.join(' ') |
| |
788 |
# } |
| |
789 |
sum += p.score #.inject(0) do |cs, c| |
| |
790 |
# cs += c.score |
| |
791 |
# end |
|
c873e484
»
|
nofxx |
2008-08-02 |
cleanup |
792 |
# end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
793 |
sum |
| |
794 |
end |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
795 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
796 |
closure = { :dropouts => @dropouts, :players => @players, :runtime => runtime } |
| |
797 |
if not halted |
| |
798 |
announce _("%{p} wins with %{b}%{score}%{b} points!") % { |
| |
799 |
:p => @players.first, :score => score, :b => Bold |
| |
800 |
} |
| |
801 |
closure.merge!(:winner => @players.first, :score => score, |
| |
802 |
:opponents => @players.length - 1) |
| |
803 |
end |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
804 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
805 |
@plugin.do_end_game(@channel, closure) |
| |
806 |
end |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
807 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
808 |
end |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
809 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
810 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
811 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
812 |
# |
| |
813 |
# |
| |
814 |
# |
| |
815 |
# |
| |
816 |
# TRUCO |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
817 |
# |
| |
818 |
# A won game: store score and number of opponents, so we can calculate |
| |
819 |
# an average score per opponent (requested by Squiddhartha) |
| |
820 |
define_structure :TrucoGameWon, :score, :opponents |
| |
821 |
# For each player we store the number of games played, the number of |
| |
822 |
# games forfeited, and an trucoGameWon for each won game |
| |
823 |
define_structure :TrucoPlayerStats, :played, :forfeits, :won |
| |
824 |
class TrucoPlugin < Plugin |
| |
825 |
attr :games |
| |
826 |
def initialize |
| |
827 |
super |
| |
828 |
@games = {} |
|
afc1a717
»
|
nofxx |
2008-07-31 |
roulette e comecando truco |
829 |
end |
| |
830 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
831 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
832 |
# |
| |
833 |
# |
| |
834 |
# |
| |
835 |
# |
| |
836 |
# HELP |
| |
837 |
# |
| |
838 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
839 |
def help(plugin, topic="") |
| |
840 |
case topic |
| |
841 |
when 'commands' |
| |
842 |
[ |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
843 |
_("'tru' para entrar"), |
| |
844 |
_("'pl <carta>' pra jogar <carta>: ex.: 'pl 7o' pra jogar 7 de Ouro, ou 'pl zap' pra jogar o Zap!"), |
| |
845 |
_("'pa' pra descartar no monte"), |
| |
846 |
_("'ca' pra mostrar suas cartas"), |
| |
847 |
_("'cd' pra mostrar o descarte atual"), |
| |
848 |
_("'od' mostra a ordem de jogo"), |
| |
849 |
_("'ti' mostra o tempo de jogo"), |
| |
850 |
_("'tu' mostra de quem é a vez") |
| |
851 |
].join("; ") |
| |
852 |
when 'rules' |
| |
853 |
_("play all your cards, one at a time, by matching either the color or the value of the currently discarded card. ") + |
| |
854 |
_("cards with special effects: Skip (next player skips a turn), Reverse (reverses the playing order), +2 (next player has to take 2 cards). ") + |
| |
855 |
_("Wilds can be played on any card, and you must specify the color for the next card. ") + |
| |
856 |
_("Wild +4 also forces the next player to take 4 cards, but it can only be played if you can't play a color card. ") + |
| |
857 |
_("you can play another +2 or +4 card on a +2 card, and a +4 on a +4, forcing the first player who can't play one to pick the cumulative sum of all cards. ") + |
| |
858 |
_("you can also play a Reverse on a +2 or +4, bouncing the effect back to the previous player (that now comes next). ") |
| |
859 |
when /scor(?:e|ing)/, /points?/ |
| |
860 |
[ |
| |
861 |
_("The points won with a game of %{truco} are totalled from the cards remaining in the hands of the other players."), |
| |
862 |
_("Each normal (not special) card is worth its face value (from 0 to 9 points)."), |
| |
863 |
_("Each colored special card (+2, Reverse, Skip) is worth 20 points."), |
| |
864 |
_("Each Wild and Wild +4 is worth 50 points.") |
| |
865 |
].join(" ") % { :truco => TrucoGame::TRUCO } |
| |
866 |
when /cards?/ |
| |
867 |
[ |
| |
868 |
_("Existem 56 cards em um baralho de %{truco}."), |
| |
869 |
_("É retirado do baralho as cartas 8, 9, 10, a ordem de valores fica: 3 2 A K J Q 7 6 5 4."), |
| |
870 |
_("Existem também as quatro cartas especiais, Zap (4 ♣), Sete Copas ( 7 ♥), Espadilha (A ♠), Sete Ouro ( 7 ♦)"), |
| |
871 |
_("Elas matam qualquer carta normal, na ordem que estão colocadas acima.") |
| |
872 |
].join(" ") % { :truco => TrucoGame::TRUCO } |
| |
873 |
when 'admin' |
| |
874 |
_("The game manager (the user that started the game) can execute the following commands to manage it: ") + |
| |
875 |
[ |
| |
876 |
_("'truco drop <user>' to drop a user from the game (any user can drop itself using 'truco drop')"), |
| |
877 |
_("'truco replace <old> [with] <new>' to replace a player with someone else (useful in case of disconnects)"), |
| |
878 |
_("'truco transfer [to] <nick>' to transfer game ownership to someone else"), |
| |
879 |
_("'truco end' to end the game before its natural completion") |
| |
880 |
].join("; ") |
| |
881 |
else |
| |
882 |
_("%{truco} game. !truco to start a game. see 'help truco rules' for the rules, 'help truco admin' for admin commands. In-game commands: %{cmds}.") % { |
| |
883 |
:truco => TrucoGame::TRUCO, |
| |
884 |
:cmds => help(plugin, 'commands') |
| |
885 |
} |
| |
886 |
end |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
887 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
888 |
|
| |
889 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
890 |
# |
| |
891 |
# |
| |
892 |
# |
| |
893 |
# |
| |
894 |
# COMMANDS |
| |
895 |
# |
| |
896 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
897 |
def message(m) |
| |
898 |
return unless @games.key?(m.channel) |
| |
899 |
return unless m.plugin # skip messages such as: <someuser> botname, |
| |
900 |
g = @games[m.channel] |
| |
901 |
case m.plugin.intern |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
902 |
when :tru # join game |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
903 |
return if m.params |
| |
904 |
g.add_player(m.source) |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
905 |
when :truco!, :seis!, :doze! |
|
ae6d5031
»
|
nofxx |
2008-08-01 |
working on... |
906 |
return if m.params or not g.start_time |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
907 |
if g.has_turn?(m.source) || g.is_next?(m.source) |
| |
908 |
g.truco!(m.source) |
|
ae6d5031
»
|
nofxx |
2008-08-01 |
working on... |
909 |
else |
| |
910 |
m.reply _("Acha bonito atrapalhar o jogo? Nao eh tua vez!") |
| |
911 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
912 |
when :pc # play covered |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
913 |
return if m.params or not g.start_time |
| |
914 |
if g.has_turn?(m.source) |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
915 |
g.play_card(m.source, m.params.downcase, true) |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
916 |
else |
| |
917 |
m.reply _("It's not your turn") |
| |
918 |
end |
| |
919 |
when :pl # play card |
| |
920 |
if g.has_turn?(m.source) |
| |
921 |
g.play_card(m.source, m.params.downcase) |
| |
922 |
else |
| |
923 |
m.reply _("It's not your turn") |
| |
924 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
925 |
when :ok # accept truco |
| |
926 |
if g.called_truco |
| |
927 |
if g.has_turn?(m.source) || g.is_next?(m.source) |
| |
928 |
g.pass(m.source, true) |
| |
929 |
else |
| |
930 |
m.reply _("It's not your turn") |
| |
931 |
end |
| |
932 |
else |
| |
933 |
m.reply _("Ninguem pediu truco...") |
| |
934 |
end |
| |
935 |
when :no # deny truco |
| |
936 |
if g.called_truco |
| |
937 |
if g.has_turn?(m.source) || g.is_next?(m.source) |
| |
938 |
g.pass(m.source, false) |
| |
939 |
else |
| |
940 |
m.reply _("It's not your turn") |
| |
941 |
end |
| |
942 |
else |
| |
943 |
m.reply _("Ninguem pediu truco...") |
| |
944 |
end |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
945 |
when :ca # show current cards |
| |
946 |
return if m.params |
| |
947 |
g.show_all_cards(m.source) |
| |
948 |
when :cd # show current discard |
| |
949 |
return if m.params or not g.start_time |
| |
950 |
g.show_discard |
| |
951 |
when :od # show playing order |
| |
952 |
return if m.params |
| |
953 |
g.show_order |
| |
954 |
when :ti # show play time |
| |
955 |
return if m.params |
| |
956 |
g.show_time |
| |
957 |
when :tu # show whose turn is it |
| |
958 |
return if m.params |
| |
959 |
if g.has_turn?(m.source) |
| |
960 |
m.nickreply _("it's your turn, sleepyhead") |
| |
961 |
else |
| |
962 |
g.show_turn(:cards => false) |
| |
963 |
end |
| |
964 |
end |
| |
965 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
966 |
|
| |
967 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
968 |
# |
| |
969 |
# |
| |
970 |
# |
| |
971 |
# |
| |
972 |
# GAME MANAGEMENT |
| |
973 |
# |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
974 |
|
| |
975 |
def create_game(m, p) |
| |
976 |
if @games.key?(m.channel) |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
977 |
m.reply _("Já existe um %{truco} rodando aqui, quem começou foi %{who}. diga 'tru' pra entrar") % { |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
978 |
:who => @games[m.channel].manager, |
| |
979 |
:truco => TrucoGame::TRUCO |
| |
980 |
} |
| |
981 |
return |
| |
982 |
end |
| |
983 |
@games[m.channel] = TrucoGame.new(self, m.channel, m.source) |
| |
984 |
@bot.auth.irc_to_botuser(m.source).set_temp_permission('truco::manage', true, m.channel) |
|
73f71d32
»
|
nofxx |
2008-08-01 |
looking better |
985 |
m.reply _("Ok, criado jogo de ♥ ♦ %{truco} ♠ ♣ no canal %{channel}, diga 'tru' pra entrar") % { |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
986 |
:truco => TrucoGame::TRUCO, |
| |
987 |
:channel => m.channel |
| |
988 |
} |
| |
989 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
990 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
991 |
def transfer_ownership(m, p) |
| |
992 |
unless @games.key?(m.channel) |
| |
993 |
m.reply _("There is no %{truco} game running here") % { :truco => TrucoGame::TRUCO } |
| |
994 |
return |
| |
995 |
end |
| |
996 |
g = @games[m.channel] |
| |
997 |
old = g.manager |
| |
998 |
new = m.channel.get_user(p[:nick]) |
| |
999 |
if new |
| |
1000 |
g.manager = new |
| |
1001 |
@bot.auth.irc_to_botuser(old).reset_temp_permission('truco::manage', m.channel) |
| |
1002 |
@bot.auth.irc_to_botuser(new).set_temp_permission('truco::manage', true, m.channel) |
| |
1003 |
m.reply _("%{truco} game ownership transferred from %{old} to %{nick}") % { |
| |
1004 |
:truco => TrucoGame::TRUCO, :old => old, :nick => p[:nick] |
| |
1005 |
} |
| |
1006 |
else |
| |
1007 |
m.reply _("who is this %{nick} you want me to transfer game ownership to?") % p |
| |
1008 |
end |
| |
1009 |
end |
| |
1010 |
|
| |
1011 |
def end_game(m, p) |
| |
1012 |
unless @games.key?(m.channel) |
| |
1013 |
m.reply _("There is no %{truco} game running here") % { :truco => TrucoGame::TRUCO } |
| |
1014 |
return |
| |
1015 |
end |
| |
1016 |
@games[m.channel].end_game(true) |
| |
1017 |
end |
| |
1018 |
|
| |
1019 |
def cleanup |
| |
1020 |
@games.each { |k, g| g.end_game(true) } |
| |
1021 |
super |
| |
1022 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
1023 |
|
| |
1024 |
|
| |
1025 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
1026 |
# |
| |
1027 |
# |
| |
1028 |
# |
| |
1029 |
# |
| |
1030 |
# CHANNEL |
| |
1031 |
# |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
1032 |
|
| |
1033 |
def chan_reg(channel) |
| |
1034 |
@registry.sub_registry(channel.downcase) |
| |
1035 |
end |
| |
1036 |
|
| |
1037 |
def chan_stats(channel) |
| |
1038 |
stats = chan_reg(channel).sub_registry('stats') |
| |
1039 |
class << stats |
| |
1040 |
def store(val) |
| |
1041 |
val.to_i |
| |
1042 |
end |
| |
1043 |
def restore(val) |
| |
1044 |
val.to_i |
| |
1045 |
end |
| |
1046 |
end |
| |
1047 |
stats.set_default(0) |
| |
1048 |
return stats |
| |
1049 |
end |
| |
1050 |
|
| |
1051 |
def chan_pstats(channel) |
| |
1052 |
pstats = chan_reg(channel).sub_registry('players') |
| |
1053 |
pstats.set_default(TrucoPlayerStats.new(0,0,[])) |
| |
1054 |
return pstats |
| |
1055 |
end |
| |
1056 |
|
| |
1057 |
def do_end_game(channel, closure) |
| |
1058 |
reg = chan_reg(channel) |
| |
1059 |
stats = chan_stats(channel) |
| |
1060 |
stats['played'] += 1 |
| |
1061 |
stats['played_runtime'] += closure[:runtime] |
| |
1062 |
if closure[:winner] |
| |
1063 |
stats['finished'] += 1 |
| |
1064 |
stats['finished_runtime'] += closure[:runtime] |
| |
1065 |
|
| |
1066 |
pstats = chan_pstats(channel) |
| |
1067 |
|
| |
1068 |
closure[:players].each do |pl| |
| |
1069 |
k = pl.user.downcase |
| |
1070 |
pls = pstats[k] |
| |
1071 |
pls.played += 1 |
| |
1072 |
pstats[k] = pls |
| |
1073 |
end |
| |
1074 |
|
| |
1075 |
closure[:dropouts].each do |pl| |
| |
1076 |
k = pl.user.downcase |
| |
1077 |
pls = pstats[k] |
| |
1078 |
pls.played += 1 |
| |
1079 |
pls.forfeits += 1 |
| |
1080 |
pstats[k] = pls |
| |
1081 |
end |
| |
1082 |
|
| |
1083 |
winner = closure[:winner] |
| |
1084 |
won = TrucoGameWon.new(closure[:score], closure[:opponents]) |
| |
1085 |
k = winner.user.downcase |
| |
1086 |
pls = pstats[k] # already marked played +1 above |
| |
1087 |
pls.won << won |
| |
1088 |
pstats[k] = pls |
| |
1089 |
end |
| |
1090 |
|
| |
1091 |
@bot.auth.irc_to_botuser(@games[channel].manager).reset_temp_permission('truco::manage', channel) |
| |
1092 |
@games.delete(channel) |
| |
1093 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
1094 |
|
| |
1095 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
1096 |
# |
| |
1097 |
# |
| |
1098 |
# |
| |
1099 |
# |
| |
1100 |
# STATS |
| |
1101 |
# |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
1102 |
|
| |
1103 |
def do_chanstats(m, p) |
| |
1104 |
stats = chan_stats(m.channel) |
| |
1105 |
np = stats['played'] |
| |
1106 |
nf = stats['finished'] |
| |
1107 |
if np > 0 |
| |
1108 |
str = _("%{nf} %{truco} games completed over %{np} games played. ") % { |
| |
1109 |
:np => np, :truco => TrucoGame::TRUCO, :nf => nf |
| |
1110 |
} |
| |
1111 |
cgt = stats['finished_runtime'] |
| |
1112 |
tgt = stats['played_runtime'] |
| |
1113 |
str << _("%{cgt} game time for completed games") % { |
| |
1114 |
:cgt => Utils.secs_to_string(cgt) |
| |
1115 |
} |
| |
1116 |
if np > nf |
| |
1117 |
str << _(" on %{tgt} total game time. ") % { |
| |
1118 |
:tgt => Utils.secs_to_string(tgt) |
| |
1119 |
} |
| |
1120 |
else |
| |
1121 |
str << ". " |
| |
1122 |
end |
| |
1123 |
str << _("%{avg} average game time for completed games") % { |
| |
1124 |
:avg => Utils.secs_to_string(cgt/nf) |
| |
1125 |
} |
| |
1126 |
str << _(", %{tavg} for all games") % { |
| |
1127 |
:tavg => Utils.secs_to_string(tgt/np) |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
1128 |
} if np > nf |
| |
1129 |
m.reply str |
| |
1130 |
else |
| |
1131 |
m.reply _("nobody has played %{truco} on %{chan} yet") % { |
| |
1132 |
:truco => TrucoGame::TRUCO, :chan => m.channel |
| |
1133 |
} |
| |
1134 |
end |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
1135 |
end |
| |
1136 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
1137 |
def do_pstats(m, p) |
| |
1138 |
dnick = p[:nick] || m.source # display-nick, don't later case |
| |
1139 |
nick = dnick.downcase |
| |
1140 |
ps = chan_pstats(m.channel)[nick] |
| |
1141 |
if ps.played == 0 |
| |
1142 |
m.reply _("%{nick} never played %{truco} here") % { |
| |
1143 |
:truco => TrucoGame::TRUCO, :nick => dnick |
| |
1144 |
} |
| |
1145 |
return |
| |
1146 |
end |
| |
1147 |
np = ps.played |
| |
1148 |
nf = ps.forfeits |
| |
1149 |
nw = ps.won.length |
| |
1150 |
score = ps.won.inject(0) { |sum, w| sum += w.score } |
| |
1151 |
str = _("%{nick} played %{np} %{truco} games here, ") % { |
| |
1152 |
:nick => dnick, :np => np, :truco => TrucoGame::TRUCO |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
1153 |
} |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
1154 |
str << _("forfeited %{nf} games, ") % { :nf => nf } if nf > 0 |
| |
1155 |
str << _("won %{nw} games") % { :nw => nw} |
| |
1156 |
if nw > 0 |
| |
1157 |
str << _(" with %{score} total points") % { :score => score } |
| |
1158 |
avg = ps.won.inject(0) { |sum, w| sum += w.score/w.opponents }/nw |
| |
1159 |
str << _(" and an average of %{avg} points per opponent") % { :avg => avg } |
| |
1160 |
end |
| |
1161 |
m.reply str |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
1162 |
end |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
1163 |
|
| |
1164 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
1165 |
# |
| |
1166 |
# |
| |
1167 |
# |
| |
1168 |
# |
| |
1169 |
# PLAYER MANAGEMENT |
| |
1170 |
# |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
1171 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
1172 |
def replace_player(m, p) |
| |
1173 |
unless @games.key?(m.channel) |
| |
1174 |
m.reply _("There is no %{truco} game running here") % { :truco => TrucoGame::TRUCO } |
| |
1175 |
return |
| |
1176 |
end |
| |
1177 |
@games[m.channel].replace_player(p[:old], p[:new]) |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
1178 |
end |
| |
1179 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
1180 |
def drop_player(m, p) |
| |
1181 |
unless @games.key?(m.channel) |
| |
1182 |
m.reply _("There is no %{truco} game running here") % { :truco => TrucoGame::TRUCO } |
| |
1183 |
return |
| |
1184 |
end |
| |
1185 |
@games[m.channel].drop_player(p[:nick] || m.source.nick) |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
1186 |
end |
| |
1187 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
1188 |
def print_stock(m, p) |
| |
1189 |
unless @games.key?(m.channel) |
| |
1190 |
m.reply _("There is no %{truco} game running here") % { :truco => TrucoGame::TRUCO } |
| |
1191 |
return |
| |
1192 |
end |
| |
1193 |
stock = @games[m.channel].stock |
| |
1194 |
m.reply(_("%{num} cards in stock: %{stock}") % { |
| |
1195 |
:num => stock.length, |
| |
1196 |
:stock => stock.join(' ') |
| |
1197 |
}, :split_at => /#{NormalText}\s*/) |
| |
1198 |
end |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
1199 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
1200 |
def do_top(m, p) |
| |
1201 |
pstats = chan_pstats(m.channel) |
| |
1202 |
scores = [] |
| |
1203 |
wins = [] |
| |
1204 |
pstats.each do |k, v| |
| |
1205 |
wins << [v.won.length, k] |
| |
1206 |
scores << [v.won.inject(0) { |s, w| s+=w.score }, k] |
| |
1207 |
end |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
1208 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
1209 |
if n = p[:scorenum] |
| |
1210 |
msg = _("%{truco} %{num} highest scores: ") % { |
| |
1211 |
:truco => TrucoGame::TRUCO, :num => p[:scorenum] |
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
1212 |
} |
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
1213 |
scores.sort! { |a1, a2| -(a1.first <=> a2.first) } |
| |
1214 |
scores = scores[0, n.to_i].compact |
| |
1215 |
i = 0 |
| |
1216 |
if scores.length <= 5 |
| |
1217 |
list = "\n" + scores.map { |a| |
| |
1218 |
i+=1 |
| |
1219 |
_("%{i}. %{b}%{nick}%{b} with %{b}%{score}%{b} points") % { |
| |
1220 |
:i => i, :b => Bold, :nick => a.last, :score => a.first |
| |
1221 |
} |
| |
1222 |
}.join("\n") |
| |
1223 |
else |
| |
1224 |
list = scores.map { |a| |
| |
1225 |
i+=1 |
| |
1226 |
_("%{i}. %{nick} ( %{score} )") % { |
| |
1227 |
:i => i, :nick => a.last, :score => a.first |
| |
1228 |
} |
| |
1229 |
}.join(" | ") |
| |
1230 |
end |
| |
1231 |
elsif n = p[:winnum] |
| |
1232 |
msg = _("%{truco} %{num} most wins: ") % { |
| |
1233 |
:truco => TrucoGame::TRUCO, :num => p[:winnum] |
| |
1234 |
} |
| |
1235 |
wins.sort! { |a1, a2| -(a1.first <=> a2.first) } |
| |
1236 |
wins = wins[0, n.to_i].compact |
| |
1237 |
i = 0 |
| |
1238 |
if wins.length <= 5 |
| |
1239 |
list = "\n" + wins.map { |a| |
| |
1240 |
i+=1 |
| |
1241 |
_("%{i}. %{b}%{nick}%{b} with %{b}%{score}%{b} wins") % { |
| |
1242 |
:i => i, :b => Bold, :nick => a.last, :score => a.first |
| |
1243 |
} |
| |
1244 |
}.join("\n") |
| |
1245 |
else |
| |
1246 |
list = wins.map { |a| |
| |
1247 |
i+=1 |
| |
1248 |
_("%{i}. %{nick} ( %{score} )") % { |
| |
1249 |
:i => i, :nick => a.last, :score => a.first |
| |
1250 |
} |
| |
1251 |
}.join(" | ") |
| |
1252 |
end |
| |
1253 |
else |
| |
1254 |
msg = _("uh, what kind of score list did you want, again?") |
| |
1255 |
list = _(" I can only show the top scores (with top) and the most wins (with topwin)") |
| |
1256 |
end |
| |
1257 |
m.reply msg + list, :max_lines => (msg+list).count("\n")+1 |
| |
1258 |
end |
| |
1259 |
|
| |
1260 |
|
| |
1261 |
end |
| |
1262 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
1263 |
|
|
966b40ef
»
|
nofxx |
2008-08-02 |
all but 4 players |
1264 |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
| |
1265 |
# |
| |
1266 |
# |
| |
1267 |
# |
| |
1268 |
# |
| |
1269 |
# TRUCO < RBOT |
| |
1270 |
# |
| |
1271 |
|
|
8cd708ee
»
|
nofxx |
2008-08-01 |
truco plugin using uno base |
1272 |
tp = TrucoPlugin.new |
| |
1273 |
|
| |
1274 |
tp.map 'truco', :private => false, :action => :create_game |
| |
1275 |
tp.map 'truco end', :private => false, :action => :end_game, :auth_path => 'manage' |
| |
1276 |
tp.map 'truco drop', :private => false, :action => :drop_player, :auth_path => 'manage::drop::self!' |
| |
1277 |
tp.map 'truco giveup', :private => false, :action => :drop_player, :auth_path => 'manage::drop::self!' |
| |
1278 |
tp.map 'truco drop :nick', :private => false, :action => :drop_player, :auth_path => 'manage::drop::other!' |
| |
1279 |
tp.map 'truco replace :old [with] :new', :private => false, :action => :replace_player, :auth_path => 'manage' |
| |
1280 |
tp.map 'truco transfer [game [ownership]] [to] :nick', :private => false, :action => :transfer_ownership, :auth_path => 'manage' |
| |
1281 |
tp.map 'truco stock', :private => false, :action => :print_stock |
| |
1282 |
tp.map 'truco chanstats', :private => false, :action => :do_chanstats |
| |
1283 |
tp.map 'truco stats [:nick]', :private => false, :action => :do_pstats |
| |
1284 |
tp.map 'truco top :scorenum', :private => false, :action => :do_top, :defaults => { :scorenum => 5 } |
| |
1285 |
tp.map 'truco topwin :winnum', :private => false, :action => :do_top, :defaults => { :winnum => 5 } |
| |
1286 |
|
| |
1287 |
tp.default_auth('stock', false) |
| |
1288 |
tp.default_auth('manage', false) |
| |
1289 |
tp.default_auth('manage::drop::self', true) |