Check in
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Hamcha 2019-10-10 14:36:44 +02:00
commit b72a1a32ce
Signed by: hamcha
GPG key ID: 44AD3571EB09A39E
8 changed files with 268 additions and 0 deletions

11
.drone.yml Normal file
View file

@ -0,0 +1,11 @@
kind: pipeline
name: default
steps:
- name: test
image: golang:alpine
commands:
- CGO_ENABLED=0 go test -v ./...
volumes:
- name: gopath
path: /go

9
Dockerfile Normal file
View file

@ -0,0 +1,9 @@
# Would love to use scratch but we need those CA certs
FROM golang:alpine
ENV GOPROXY https://modules.fromouter.space
ENV GO111MODULE=on
WORKDIR /app
ENTRYPOINT go run .

1
README.md Normal file
View file

@ -0,0 +1 @@
# Bot for scrabble sylladex

5
go.mod Normal file
View file

@ -0,0 +1,5 @@
module git.fromouter.space/Hamcha/scrabblego
go 1.12
require github.com/bwmarrin/discordgo v0.19.0

6
go.sum Normal file
View file

@ -0,0 +1,6 @@
github.com/bwmarrin/discordgo v0.19.0 h1:kMED/DB0NR1QhRcalb85w0Cu3Ep2OrGAqZH1R5awQiY=
github.com/bwmarrin/discordgo v0.19.0/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 h1:y6ce7gCWtnH+m3dCjzQ1PCuwl28DDIc3VNnvY29DlIA=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=

100
index.html Normal file
View file

@ -0,0 +1,100 @@
<!DOCTYPE html>
<html>
<head>
<title>Scrabble calculator</title>
<meta charset="UTF-8" />
<link
rel="stylesheet"
href="https://unpkg.com/spectre.css/dist/spectre.min.css"
/>
<style>
body {
display: flex;
align-items: center;
justify-content: center;
}
main {
padding: 3em;
}
.number {
width: 3em;
}
p {
padding: 1em 0;
}
</style>
</head>
<body>
<main id="app">
<input type="text" placeholder="Oggetto" v-model="text" />
<input
type="text"
placeholder="Quanti slot hai"
class="number"
v-model="maxslot"
/>
<p>
Risultato: <b>{{ score }}</b> % {{ maxslot }} => <b>{{ slot }}</b>
</p>
</main>
<script type="module">
import Vue from "https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.esm.browser.js";
let points = {
A: 1,
O: 1,
I: 1,
E: 1,
C: 2,
R: 2,
S: 2,
T: 2,
L: 3,
M: 3,
N: 3,
U: 3,
W: 4,
Y: 4,
B: 5,
D: 5,
F: 5,
P: 5,
V: 5,
K: 5,
G: 8,
H: 8,
Z: 8,
J: 8,
X: 8,
Q: 10
};
const app = new Vue({
el: "#app",
data: {
text: "",
maxslot: 10
},
computed: {
score: function() {
const letters = this.text
.toUpperCase()
.trim()
.split("");
return letters.reduce((total, letter) => {
if (letter in points) {
total += points[letter];
}
return total;
}, 0);
},
slot: function() {
return (this.score % this.maxslot) + 1;
}
}
});
</script>
</body>
</html>

118
main.go Normal file
View file

@ -0,0 +1,118 @@
package main
import (
"fmt"
"log"
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"github.com/bwmarrin/discordgo"
)
const TriggerWord = "!syl-"
var points = map[rune]int{
'A': 1, 'O': 1, 'I': 1, 'E': 1,
'C': 2, 'R': 2, 'S': 2, 'T': 2,
'L': 3, 'M': 3, 'N': 3, 'U': 3,
'W': 4, 'Y': 4,
'B': 5, 'D': 5, 'F': 5, 'P': 5, 'V': 5, 'K': 5,
'G': 8, 'H': 8, 'Z': 8, 'J': 8, 'X': 8,
'Q': 10,
}
func scrabbleScore(letters string) int {
letters = strings.ToUpper(letters)
totalScore := 0
for _, glyph := range letters {
letterScore, ok := points[glyph]
if ok {
totalScore += letterScore
}
}
return totalScore
}
func scrabbleToStr(letters string) string {
letters = strings.ToUpper(letters)
arr := []string{}
for _, glyph := range letters {
letterScore, ok := points[glyph]
if ok {
arr = append(arr, fmt.Sprintf("%s=%d", string(glyph), letterScore))
}
}
return strings.Join(arr, " + ")
}
func main() {
token := os.Getenv("TOKEN")
if token == "" {
panic("TOKEN env var is missing")
}
// Create a new Discordgo session
dg, err := discordgo.New(token)
checkErr(err)
dg.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
// Ignore bot commands
if m.Author.Bot {
return
}
if strings.HasPrefix(m.Content, TriggerWord) {
msg := m.Content[len(TriggerWord):]
parts := strings.SplitN(msg, " ", 2)
if len(parts) < 2 {
return
}
maxsize, err := strconv.Atoi(parts[0])
if err != nil {
return
}
score := scrabbleScore(parts[1])
slot := score % maxsize
_, err = s.ChannelMessageSendEmbed(m.ChannelID, &discordgo.MessageEmbed{
Author: &discordgo.MessageEmbedAuthor{
Name: "Scrabble Sylladex",
},
Title: fmt.Sprintf("Risultato: %d", slot+1),
Description: fmt.Sprintf("\"%s\" va nello slot %d (di %d)", parts[1], slot+1, maxsize),
Fields: []*discordgo.MessageEmbedField{
{
Name: "Valore parola",
Value: fmt.Sprintf("%s = %d", scrabbleToStr(parts[1]), score),
}, {
Name: "Posizionamento",
Value: fmt.Sprintf("%d mod %d = %d → %d", score, maxsize, slot, slot+1),
},
},
})
if err != nil {
log.Printf("Error: %s\n", err.Error())
}
}
})
dg.AddHandler(func(s *discordgo.Session, m *discordgo.Ready) {
log.Print("ready")
})
checkErr(dg.Open())
defer dg.Close()
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, syscall.SIGSEGV, syscall.SIGHUP)
<-sc
}
func checkErr(err error) {
if err != nil {
log.Fatalf("FATAL ERROR: %s", err.Error())
os.Exit(1)
}
}

18
main_test.go Normal file
View file

@ -0,0 +1,18 @@
package main
import "testing"
func TestScrabbleScore(t *testing.T) {
testscores := map[string]int{
"spada del potere": 35,
"puppami la fava": 39,
"yogurt alla papaja": 49,
"jack": 16,
"mela": 8,
}
for testword, testscore := range testscores {
if score := scrabbleScore(testword); score != testscore {
t.Errorf("Expected word \"%s\" to have score %d but got %d", testword, testscore, score)
}
}
}