greed: prevent players from going twice in a row
[rbot] / data / rbot / plugins / games / greed.rb
1 #-- vim:sw=2:et
2 #++
3 #
4 # :title: Greed dice game plugin for rbot
5 #
6 # Author:: Okasu <oka.sux@gmail.com>
7 #
8 # Distributed under the same license as rbot itself
9 #
10
11
12 class Greed < Plugin
13
14   def initialize
15     super
16     @scoreboard = {}
17     @players = []
18   end
19
20   def help(plugin, topic="")
21     "Simple dice game. Rules: https://en.wikipedia.org/wiki/Greed_(dice_game)"
22   end
23
24   SCORING = [
25     [ [1,2,3,4,5,6], 1200 ],
26     [ [2,2,3,3,4,4], 800 ],
27     [ [1]*6, 8000 ],
28     [ [1]*5, 4000 ],
29     [ [1]*4, 2000 ],
30     [ [1]*3, 1000 ],
31     [ [1],    100 ],
32     [ [2]*6, 1600 ],
33     [ [2]*5,  800 ],
34     [ [2]*4,  400 ],
35     [ [2]*3,  200 ],
36     [ [3]*6, 2400 ],
37     [ [3]*5, 1200 ],
38     [ [3]*4,  600 ],
39     [ [3]*3,  300 ],
40     [ [4]*6, 3200 ],
41     [ [4]*5, 1600 ],
42     [ [4]*4,  800 ],
43     [ [4]*3,  400 ],
44     [ [5]*6, 4000 ],
45     [ [5]*5, 2000 ],
46     [ [5]*4, 1000 ],
47     [ [5]*3,  500 ],
48     [ [5],     50 ],
49     [ [6]*6, 4800 ],
50     [ [6]*5, 2400 ],
51     [ [6]*4, 1200 ],
52     [ [6]*3,  600 ],
53   ]
54
55   def diceroll(ndice=6)
56     dice = Array.new
57     ndice.times do
58       dice << rand(6) + 1
59     end
60     dice.sort
61   end
62
63   def scores
64     roll = diceroll
65     score = 0
66     groups = []
67     remain = roll.dup
68     SCORING.each do |dice, dscore|
69       idx = remain.index(dice.first)
70       if idx and remain[idx,dice.size] == dice
71         groups << [dice, dscore]
72         remain -= dice
73         score += dscore
74       end
75     end
76     groups << [remain, 0]
77     [roll, score, groups]
78   end
79
80   def greed(m, params)
81     player = scores
82     mhash = {m.sourcenick => player[1]}
83     @players.push mhash.to_a[0][0]
84     if @players[-1] == @players[-2]
85       m.reply _("Oh you, %{who}! You can't go twice in a row!") % {:who => @players[-1]}
86       return
87     end
88     @scoreboard.merge! mhash
89     m.reply _("you rolled (%{roll}) for %{pts} points (%{groups})") % {
90       :roll => player[0].join(' '),
91       :pts => player[1],
92       :groups => player[2].map { |d, s| "#{d.join(' ')} => #{s}"}.join(', ')
93     }
94     if params[:single] == "bot"
95       bot = scores
96       m.reply _("I rolled (%{roll}) for %{pts} points (%{groups})") % {
97         :roll => bot[0].join(' '),
98         :pts => bot[1],
99         :groups => bot[2].map { |d, s| "#{d.join(' ')} => #{s}"}.join(', ')
100       }
101       if player[1] < bot[1]
102         m.reply _("I win!")
103       else
104         m.reply _("You win!")
105       end
106       @players.clear
107       return
108     end
109     if @scoreboard.values.size == 2
110       m.reply _("%{who} wins!") % {
111         :who => @scoreboard.values[0] > @scoreboard.values[1] ?
112                 @scoreboard.keys.first : @scoreboard.keys.last
113       }
114       @scoreboard.clear
115       @players.clear
116     end
117   end
118 end
119
120 plugin = Greed.new
121 plugin.map "greed :single", :action => :greed, :requirements => {:single => /bot/}, :thread => "yes"
122 plugin.map "greed", :action => :greed, :thread => "yes"