Browse Source

First working version

master
parent
commit
88047e2eb1
  1. 4
      .gitignore
  2. 31
      README.md
  3. 107
      roll-the-dice.go

4
.gitignore vendored

@ -96,3 +96,7 @@ fabric.properties
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# Result binary
./roll-the-dice

31
README.md

@ -1,3 +1,32 @@
# roll-the-dice
Simple dice roller for D'n'D-like games
Simple dice roller for D'n'D-like games
## What it is?
- golang simple http service
- simulate rolling dices `d2`, `d4`, `d6`, `d8`, `d10`, `d12`, `d20`
- multiple dices roll
- use simple urls to roll dices in one request
- no templates in files
## URLs
### /
Show simple API explanation page.
### /XdY
Roll Y dimencion dice X times.
X and Y - are integers.
URL will be like: /2d8
## Build
Use Go >= 1.6
`go build roll-the-dice`

107
roll-the-dice.go

@ -0,0 +1,107 @@
package main
import (
"bytes"
"fmt"
"log"
"math/rand"
"net/http"
"regexp"
"strconv"
"time"
)
var rxDices = *regexp.MustCompile("(\\d+)d(\\d+)")
type route struct {
pattern *regexp.Regexp
handler http.Handler
}
type RegexpHandler struct {
routes []*route
}
func (h *RegexpHandler) Handler(pattern *regexp.Regexp, handler http.Handler) {
h.routes = append(h.routes, &route{pattern, handler})
}
func (h *RegexpHandler) HandleFunc(pattern *regexp.Regexp, handler func(http.ResponseWriter, *http.Request)) {
h.routes = append(h.routes, &route{pattern, http.HandlerFunc(handler)})
}
func (h *RegexpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
for _, route := range h.routes {
if route.pattern.MatchString(r.URL.Path) {
route.handler.ServeHTTP(w, r)
return
}
}
// no pattern matched; send 404 response
http.NotFound(w, r)
}
func handleDices(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "application/json")
r := rxDices.FindAllStringSubmatch(req.URL.Path, -1)
if len(r) == 0 {
res.Write([]byte("0"))
return
}
valueN := 0
valueD := 0
for i := range r {
v1, err := strconv.ParseInt(r[i][1], 10, 32)
if err != nil {
log.Fatal("Convert string N to int: ", err)
continue
}
valueN = int(v1)
v2, err := strconv.ParseInt(r[i][2], 10, 32)
if err != nil {
log.Fatal("Convert string D to int: ", err)
continue
}
valueD = int(v2)
}
roll := int64(0)
var buffer bytes.Buffer
rand.Seed(time.Now().UnixNano())
for valueN > 0 {
valueN -= 1
d := int64(rand.Intn(valueD + 1))
roll += d
}
buffer.WriteString(strconv.FormatInt(roll, 10))
res.Write(buffer.Bytes())
}
func main() {
handler := &RegexpHandler{}
reg1, _ := regexp.Compile("/\\d+d\\d+")
handler.HandleFunc(reg1, handleDices)
reg2, _ := regexp.Compile("/")
handler.HandleFunc(reg2, func (w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
fmt.Fprintf(w, "<h2>Welcome to RollTheDice service!</h2><p>Call <b>/XdY</b> to to roll <i>X</i> dices with <i>Y</i> dimentions.<br>Output will be raw number.</p>")
})
err := http.ListenAndServe(":4000", handler)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
Loading…
Cancel
Save