|
|
@ -4,8 +4,10 @@ import (
|
|
|
|
"bytes"
|
|
|
|
"bytes"
|
|
|
|
"encoding/base64"
|
|
|
|
"encoding/base64"
|
|
|
|
"encoding/json"
|
|
|
|
"encoding/json"
|
|
|
|
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"fmt"
|
|
|
|
"image/png"
|
|
|
|
"image/png"
|
|
|
|
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
|
|
|
"log"
|
|
|
|
"math/rand"
|
|
|
|
"math/rand"
|
|
|
|
"net/http"
|
|
|
|
"net/http"
|
|
|
@ -15,7 +17,6 @@ import (
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
type WebGameParams struct {
|
|
|
|
type WebGameParams struct {
|
|
|
|
Random bool
|
|
|
|
|
|
|
|
Height int
|
|
|
|
Height int
|
|
|
|
Width int
|
|
|
|
Width int
|
|
|
|
Xmul int
|
|
|
|
Xmul int
|
|
|
@ -23,8 +24,8 @@ type WebGameParams struct {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type WebGameState struct {
|
|
|
|
type WebGameState struct {
|
|
|
|
State *GameState `json:"state"`
|
|
|
|
State *GameState `json:"s"`
|
|
|
|
Img string `json:"img"`
|
|
|
|
Img string `json:"i"`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var jQueryMinJs = []byte("")
|
|
|
|
var jQueryMinJs = []byte("")
|
|
|
@ -46,10 +47,6 @@ func NewWebGameParams(q url.Values) *WebGameParams {
|
|
|
|
Ymul: 10,
|
|
|
|
Ymul: 10,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if len(q.Get("random")) > 0 {
|
|
|
|
|
|
|
|
params.Random = true
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
h := q.Get("h")
|
|
|
|
h := q.Get("h")
|
|
|
|
if len(h) > 0 {
|
|
|
|
if len(h) > 0 {
|
|
|
|
if i, err := strconv.Atoi(h); err == nil {
|
|
|
|
if i, err := strconv.Atoi(h); err == nil {
|
|
|
@ -132,73 +129,91 @@ func HandleWebGameStatic(w http.ResponseWriter, req *http.Request) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func HandleWebGameState(w http.ResponseWriter, req *http.Request) {
|
|
|
|
func HandleWebGameState(w http.ResponseWriter, req *http.Request) {
|
|
|
|
if req.Method != "GET" {
|
|
|
|
switch req.Method {
|
|
|
|
|
|
|
|
case "GET":
|
|
|
|
|
|
|
|
handleWebGameStateGET(w, req)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
case "POST":
|
|
|
|
|
|
|
|
handleWebGameStatePOST(w, req)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
default:
|
|
|
|
handle405(req.Method, req.RequestURI, w)
|
|
|
|
handle405(req.Method, req.RequestURI, w)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func handleWebGameStateGET(w http.ResponseWriter, req *http.Request) {
|
|
|
|
q := req.URL.Query()
|
|
|
|
q := req.URL.Query()
|
|
|
|
params := NewWebGameParams(q)
|
|
|
|
params := NewWebGameParams(q)
|
|
|
|
|
|
|
|
|
|
|
|
if params.Random {
|
|
|
|
game := NewGameOfLife(params.Height, params.Width)
|
|
|
|
game := NewGameOfLife(params.Height, params.Width)
|
|
|
|
err := game.ImportRandomState()
|
|
|
|
err := game.ImportRandomState()
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
handle500(err, w)
|
|
|
|
handle500(err, w)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sendWebGameStateJSONPayload(w, http.StatusOK, game, params)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
img, err := game.Image(params.Xmul, params.Ymul)
|
|
|
|
func handleWebGameStatePOST(w http.ResponseWriter, req *http.Request) {
|
|
|
|
|
|
|
|
q := req.URL.Query()
|
|
|
|
|
|
|
|
params := NewWebGameParams(q)
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
defer func() {
|
|
|
|
handle500(err, w)
|
|
|
|
r := recover()
|
|
|
|
return
|
|
|
|
if r != nil {
|
|
|
|
|
|
|
|
handle500(errors.New(fmt.Sprintf("OH NOES! %v", r)), w)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
body, err := ioutil.ReadAll(req.Body)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
handle500(err, w)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
log.Println("Serving random state image.")
|
|
|
|
webGameState := &WebGameState{}
|
|
|
|
|
|
|
|
err = json.Unmarshal(body, webGameState)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
handle500(err, w)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var pngBuf bytes.Buffer
|
|
|
|
height, width := webGameState.State.Height(), webGameState.State.Width()
|
|
|
|
err = png.Encode(&pngBuf, img)
|
|
|
|
game := NewGameOfLife(height, width)
|
|
|
|
if err != nil {
|
|
|
|
game.ImportState(webGameState.State)
|
|
|
|
handle500(err, w)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
imgB64 := base64.StdEncoding.EncodeToString(pngBuf.Bytes())
|
|
|
|
game.EvaluateGeneration()
|
|
|
|
webGameState := &WebGameState{State: game.State, Img: imgB64}
|
|
|
|
|
|
|
|
wgsJson, err := json.Marshal(webGameState)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
sendWebGameStateJSONPayload(w, http.StatusCreated, game, params)
|
|
|
|
handle500(err, w)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
|
func sendWebGameStateJSONPayload(w http.ResponseWriter, status int, game *GameOfLife, params *WebGameParams) {
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
img, err := game.Image(params.Xmul, params.Ymul)
|
|
|
|
w.Write(wgsJson)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
handle500(err, w)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rawState := q.Get("s")
|
|
|
|
log.Println("Serving state image.")
|
|
|
|
if len(rawState) < 1 {
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "text/plain")
|
|
|
|
var pngBuf bytes.Buffer
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
err = png.Encode(&pngBuf, img)
|
|
|
|
w.Write([]byte("Missing query param \"s\".\n"))
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
handle500(err, w)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//state := &GameState{}
|
|
|
|
imgB64 := base64.StdEncoding.EncodeToString(pngBuf.Bytes())
|
|
|
|
//err := json.Unmarshal([]byte(rawState), state)
|
|
|
|
webGameState := &WebGameState{State: game.State, Img: imgB64}
|
|
|
|
//if err != nil {
|
|
|
|
wgsJson, err := json.Marshal(webGameState)
|
|
|
|
//w.Header().Set("Content-Type", "text/plain")
|
|
|
|
|
|
|
|
//w.WriteHeader(http.StatusBadRequest)
|
|
|
|
if err != nil {
|
|
|
|
//w.Write([]byte(fmt.Sprintf("Invalid query param \"s\": %v\n", err)))
|
|
|
|
handle500(err, w)
|
|
|
|
//return
|
|
|
|
}
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
w.WriteHeader(status)
|
|
|
|
w.Write([]byte(`{"state":null,"img":""}`))
|
|
|
|
w.Write(wgsJson)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func RunWebGame(address string, height, width, sleepMs int, mutate bool) (int, error) {
|
|
|
|
func RunWebGame(address string, height, width, sleepMs int, mutate bool) (int, error) {
|
|
|
|