root/data/rbot/plugins/games/roulette.rb @ ac39a3b330cbf7c4b65ba907783364b63fb109b3

Revision ac39a3b330cbf7c4b65ba907783364b63fb109b3, 7.0 KB (checked in by Giuseppe Bilotta <giuseppe.bilotta@…>, 3 years ago)

Module\#define_structure method: define a new Struct only if doesn't exist already or if the attribute list changed

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