]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/games/roulette.rb
remove whitespace
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / games / roulette.rb
1 define_structure :RouletteHistory, :games, :shots, :deaths, :misses, :wins
2
3 class RoulettePlugin < Plugin
4   Config.register Config::BooleanValue.new('roulette.autospin',
5     :default => true,
6     :desc => "Automatically spins the roulette at the butlast shot")
7   Config.register Config::BooleanValue.new('roulette.kick',
8     :default => false,
9     :desc => "Kicks shot players from the channel")
10   Config.register Config::BooleanValue.new('roulette.twice_in_a_row',
11     :default => false,
12     :desc => "Allow players to go twice in a row")
13
14   def initialize
15     super
16     reset_chambers
17     @players = Array.new
18     @last = ''
19   end
20
21   def help(plugin, topic="")
22     "roulette => play russian roulette - starts a new game if one isn't already running. One round in a six chambered gun. Take turns to say roulette to the bot, until somebody dies. roulette reload => force the gun to reload, roulette stats => show stats from all games, roulette stats <player> => show stats for <player>, roulette clearstats => clear stats (config level auth required), roulette spin => spins the cylinder"
23   end
24
25   def clearstats(m, params)
26     @registry.clear
27     m.okay
28   end
29
30   def roulette(m, params)
31     if m.private?
32       m.reply "you gotta play roulette in channel dude"
33       return
34     end
35
36     playerdata = nil
37     if @registry.has_key?("player " + m.sourcenick)
38       playerdata = @registry["player " + m.sourcenick]
39     else
40       playerdata = RouletteHistory.new(0,0,0,0,0)
41     end
42
43     totals = nil
44     if @registry.has_key?("totals")
45       totals = @registry["totals"]
46     else
47       totals = RouletteHistory.new(0,0,0,0,0)
48     end
49
50     if @last == m.sourcenick and not @bot.config['roulette.twice_in_a_row']
51       m.reply "you can't go twice in a row!"
52       return
53     end
54
55     @last = m.sourcenick
56     unless @players.include?(m.sourcenick)
57       @players << m.sourcenick
58       playerdata.games += 1
59     end
60     playerdata.shots += 1
61     totals.shots += 1
62
63     shot = @chambers.pop
64     if shot
65       m.reply "#{m.sourcenick}: chamber #{6 - @chambers.length} of 6 => *BANG*"
66       playerdata.deaths += 1
67       totals.deaths += 1
68       @players.each {|plyr|
69         next if plyr == m.sourcenick
70         pdata = @registry["player " + plyr]
71         next if pdata == nil
72         pdata.wins += 1
73         totals.wins += 1
74         @registry["player " + plyr] = pdata
75       }
76       @players.clear
77       @last = ''
78       @bot.kick(m.replyto, m.sourcenick, "*BANG*") if @bot.config['roulette.kick']
79     else
80       m.reply "#{m.sourcenick}: chamber #{6 - @chambers.length} of 6 => +click+"
81       playerdata.misses += 1
82       totals.misses += 1
83     end
84
85     @registry["player " + m.sourcenick] = playerdata
86     @registry["totals"] = totals
87
88     if shot || @chambers.empty?
89       reload(m)
90     elsif @chambers.length == 1 and @bot.config['roulette.autospin']
91       spin(m)
92     end
93   end
94
95   def reload(m, params = {})
96     if m.private?
97       m.reply "you gotta play roulette in channel dude"
98       return
99     end
100
101     m.act "reloads"
102     reset_chambers
103     # all players win on a reload
104     # (allows you to play 3-shot matches etc)
105     totals = nil
106     if @registry.has_key?("totals")
107       totals = @registry["totals"]
108     else
109       totals = RouletteHistory.new(0,0,0,0,0)
110     end
111
112     @players.each {|plyr|
113       pdata = @registry["player " + plyr]
114       next if pdata == nil
115       pdata.wins += 1
116       totals.wins += 1
117       @registry["player " + plyr] = pdata
118     }
119
120     totals.games += 1
121     @registry["totals"] = totals
122
123     @players.clear
124     @last = ''
125   end
126
127   def spin(m, params={})
128     # Spinning is just like resetting, except that nobody wins
129     if m.private?
130       m.reply "you gotta play roulette in channel dude"
131       return
132     end
133
134     m.act "spins the cylinder"
135     reset_chambers
136   end
137
138   def reset_chambers
139     @chambers = [false, false, false, false, false, false]
140     @chambers[rand(@chambers.length)] = true
141   end
142
143   def playerstats(m, params)
144     player = params[:player]
145     pstats = @registry["player " + player]
146     if pstats.nil?
147       m.reply "#{player} hasn't played enough games yet"
148     else
149       m.reply "#{player} has played #{pstats.games} games, won #{pstats.wins} and lost #{pstats.deaths}. #{player} pulled the trigger #{pstats.shots} times and found the chamber empty on #{pstats.misses} occasions."
150     end
151   end
152
153   def stats(m, params)
154     if @registry.has_key?("totals")
155       totals = @registry["totals"]
156       total_games = totals.games
157       total_shots = totals.shots
158     else
159       total_games = 0
160       total_shots = 0
161     end
162
163     total_players = 0
164
165     died_most = [nil,0]
166     won_most = [nil,0]
167     h_win_percent = [nil,0]
168     l_win_percent = [nil,0]
169     h_luck_percent = [nil,0]
170     l_luck_percent = [nil,0]
171     @registry.each {|k,v|
172       match = /player (.+)/.match(k)
173       next unless match
174       k = match[1]
175
176       total_players += 1
177
178       win_rate = v.wins.to_f / v.games * 100
179       if h_win_percent[0].nil? || win_rate > h_win_percent[1] && v.games > 2
180         h_win_percent = [[k], win_rate]
181       elsif win_rate == h_win_percent[1] && v.games > 2
182         h_win_percent[0] << k
183       end
184       if l_win_percent[0].nil? || win_rate < l_win_percent[1] && v.games > 2
185         l_win_percent = [[k], win_rate]
186       elsif win_rate == l_win_percent[1] && v.games > 2
187         l_win_percent[0] << k
188       end
189
190       luck = v.misses.to_f / v.shots * 100
191       if h_luck_percent[0].nil? || luck > h_luck_percent[1] && v.games > 2
192         h_luck_percent = [[k], luck]
193       elsif luck == h_luck_percent[1] && v.games > 2
194         h_luck_percent[0] << k
195       end
196       if l_luck_percent[0].nil? || luck < l_luck_percent[1] && v.games > 2
197         l_luck_percent = [[k], luck]
198       elsif luck == l_luck_percent[1] && v.games > 2
199         l_luck_percent[0] << k
200       end
201
202       if died_most[0].nil? || v.deaths > died_most[1]
203         died_most = [[k], v.deaths]
204       elsif v.deaths == died_most[1]
205         died_most[0] << k
206       end
207       if won_most[0].nil? || v.wins > won_most[1]
208         won_most = [[k], v.wins]
209       elsif v.wins == won_most[1]
210         won_most[0] << k
211       end
212     }
213     if total_games < 1
214       m.reply "roulette stats: no games completed yet"
215     else
216       m.reply "roulette stats: #{total_games} games completed, #{total_shots} shots fired at #{total_players} players. Luckiest: #{h_luck_percent[0].join(',')} (#{sprintf '%.1f', h_luck_percent[1]}% clicks). Unluckiest: #{l_luck_percent[0].join(',')} (#{sprintf '%.1f', l_luck_percent[1]}% clicks). Highest survival rate: #{h_win_percent[0].join(',')} (#{sprintf '%.1f', h_win_percent[1]}%). Lowest survival rate: #{l_win_percent[0].join(',')} (#{sprintf '%.1f', l_win_percent[1]}%). Most wins: #{won_most[0].join(',')} (#{won_most[1]}). Most deaths: #{died_most[0].join(',')} (#{died_most[1]})."
217     end
218   end
219 end
220
221 plugin = RoulettePlugin.new
222
223 plugin.default_auth('clearstats', false)
224
225 plugin.map 'roulette reload', :action => 'reload'
226 plugin.map 'roulette spin', :action => 'spin'
227 plugin.map 'roulette stats :player', :action => 'playerstats'
228 plugin.map 'roulette stats', :action => 'stats'
229 plugin.map 'roulette clearstats', :action => 'clearstats'
230 plugin.map 'roulette'
231