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