1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
local man = peripheral.find"manipulator"
assert(man and man.hasModule"plethora:chat","no chat thing")
local M = peripheral.find"monitor"
assert(M,"no monitor")
M.setTextScale(0.5)
M.clear()
local Mw,Mh = M.getSize()
local scorewidth=10
local lbw = 4+16+scorewidth
local wLog = window.create(M,1,12,Mw,Mh-12)
wLog.setBackgroundColor(colors.blue)
wLog.clear()
wLog.write("LOG")
local wLb = window.create(M,Mw-lbw+1,1,lbw,11)
-- wLb.setBackgroundColor(colors.red)
-- wLb.clear()
-- wLb.write("LB")
-- utils
local function p(thing,...)
local o=term.redirect(thing)
print(...)
term.redirect(o)
end
local function pad_r(s,width)
return string.rep(" ",width-#tostring(s))..s
end
local function pad_c(s,width)
local space = width-#tostring(s)
local hspace = math.floor(space/2)
return string.rep(" ",hspace)..s
end
local function round(n)
-- to nearest int
local f = math.floor(n)
if n>=f+0.5 then return math.ceil(n) else return f end
end
local function round_dp(n,dp)
local exp = 10^dp
return round(n*exp)/exp
end
local function sci(x)
local b = math.floor(math.log10(x))
local a = round_dp(x/10^b,2)
return a.."e"..b
end
local function maybe_sci(x)
if #tostring(x) >= scorewidth then return sci(x) else return x end
end
local function isnan(x)
return x ~= x
end
-- drawing
-- lb
local function draw_lb(W,scores)
local w,h = W.getSize()
W.setBackgroundColor(colors.gray)
W.clear()
-- header
W.setTextColor(colors.lime)
W.setCursorPos(1,1)
W.write(pad_c("==[[ LEADERBOARD ]]==",lbw))
-- line numbers
W.setTextColor(colors.yellow)
for line=1,10 do
W.setCursorPos(1,line+1)
W.write(pad_r(line,2)..".")
end
-- actual scores
local thescores = {}
for name,score in pairs(scores) do
table.insert(thescores,{name=name,score=score})
end
table.sort(thescores,function(a,b) return a.score > b.score end)
for i=1,10 do
if not thescores[i] then break end
local name,score = thescores[i].name, thescores[i].score
-- name
W.setTextColor(colors.white)
W.setCursorPos(5,i+1)
W.write(name)
-- score
W.setTextColor(colors.red)
W.setCursorPos(w-scorewidth+1,i+1)
W.write(pad_r(maybe_sci(score),scorewidth))
end
end
-- scoring
local function score(msg)
local s = 0
for num in msg:gmatch"%-?%d+" do s=s+num end
return s
end
local userscores = setmetatable({
aaa=10,
bbb=100,
ccc=12345,
ddd=234287,
thethethethe=69420,
harold=111222,
},{__index=function()return 0 end})
while true do
draw_lb(wLb,userscores)
local _,user,msg = os.pullEvent"chat_message"
local s = score(msg)
userscores[user] = userscores[user] + s
if isnan(userscores[user]) then userscores[user] = 0 end
p(M,string.format("(%d) <%s> %s",s,user,msg))
end
|