greed: refactor and prepare for more complete play
[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   end
18
19   def help(plugin, topic="")
20     "Simple dice game. Rules: https://en.wikipedia.org/wiki/Greed_(dice_game)"
21   end
22
23   SCORING = [
24     [ [1,2,3,4,5,6], 1200 ],
25     [ [2,2,3,3,4,4], 800 ],
26     [ [1]*6, 8000 ],
27     [ [1]*5, 4000 ],
28     [ [1]*4, 2000 ],
29     [ [1]*3, 1000 ],
30     [ [1],    100 ],
31     [ [2]*6, 1600 ],
32     [ [2]*5,  800 ],
33     [ [2]*4,  400 ],
34     [ [2]*3,  200 ],
35     [ [3]*6, 2400 ],
36     [ [3]*5, 1200 ],
37     [ [3]*4,  600 ],
38     [ [3]*3,  300 ],
39     [ [4]*6, 3200 ],
40     [ [4]*5, 1600 ],
41     [ [4]*4,  800 ],
42     [ [4]*3,  400 ],
43     [ [5]*6, 4000 ],
44     [ [5]*5, 2000 ],
45     [ [5]*4, 1000 ],
46     [ [5]*3,  500 ],
47     [ [5],     50 ],
48     [ [6]*6, 4800 ],
49     [ [6]*5, 2400 ],
50     [ [6]*4, 1200 ],
51     [ [6]*3,  600 ],
52   ]
53
54   def diceroll(ndice=6)
55     dice = Array.new
56     ndice.times do
57       dice << rand(6) + 1
58     end
59     dice.sort
60   end
61
62   def scores
63     roll = diceroll
64     score = 0
65     groups = []
66     remain = roll.dup
67     SCORING.each do |dice, dscore|
68       idx = remain.index(dice.first)
69       if idx and remain[idx,dice.size] == dice
70         groups << [dice, dscore]
71         remain -= dice
72         score += dscore
73       end
74     end
75     groups << [remain, 0]
76     [roll, score, groups]
77   end
78
79   def greed(m, params)
80     player = scores
81     mhash = {m.sourcenick => player[1]}
82     @scoreboard.merge! mhash
83     m.reply _("you rolled (%{roll}) for %{pts} points (%{groups})") % {
84       :roll => player[0].join(' '),
85       :pts => player[1],
86       :groups => player[2].map { |d, s| "#{d.join(' ')} => #{s}"}.join(', ')
87     }
88     if params[:single] == "bot"
89       bot = scores
90       m.reply _("I rolled (%{roll}) for %{pts} points (%{groups})") % {
91         :roll => bot[0].join(' '),
92         :pts => bot[1],
93         :groups => bot[2].map { |d, s| "#{d.join(' ')} => #{s}"}.join(', ')
94       }
95       if player[1] < bot[1]
96         m.reply _("I win!")
97       else
98         m.reply _("You win!")
99       end
100     end
101     if @scoreboard.values.size == 2
102       m.reply _("%{who} wins!") % {
103         :who => @scoreboard.values[0] > @scoreboard.values[1] ?
104                 @scoreboard.keys.first : @scoreboard.keys.last
105       }
106       @scoreboard.clear
107     end
108   end
109 end
110
111 plugin = Greed.new
112 plugin.map "greed :single", :action => :greed, :requirements => {:single => /bot/}, :thread => "yes"
113 plugin.map "greed", :action => :greed, :thread => "yes"