Решение на Game of Life от Диана Генева

Обратно към всички решения

Към профила на Диана Генева

Резултати

  • 10 точки от тестове
  • 1 отнета точка
  • 9 точки общо
  • 14 успешни тест(а)
  • 0 неуспешни тест(а)

Код

package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strconv"
)
type Cell struct {
X int64 `json:"x"`
Y int64 `json:"y"`
}
type GameOfLife struct {
cells map[[2]int64]struct{}
Generation int
}
func NewGameOflife(cells map[[2]int64]struct{}) *GameOfLife {
return &GameOfLife{cells: cells, Generation: 0}
}
func (g *GameOfLife) addCells(toAdd []Cell) {
for _, cell := range toAdd {
g.cells[[2]int64{cell.X, cell.Y}] = struct{}{}
}
}
func (g *GameOfLife) alive(x, y int64) bool {
cell := [2]int64{x, y}
_, ok := g.cells[cell]
return ok
}
func (g *GameOfLife) reset() {
g.cells = make(map[[2]int64]struct{})
g.Generation = 0
}
func (g *GameOfLife) countNeighbours(x, y int64) int {
neighbour := 0
var ok bool
if _, ok = g.cells[[2]int64{x - 1, y}]; ok {
neighbour += 1
}
if _, ok = g.cells[[2]int64{x, y - 1}]; ok {
neighbour += 1
}
if _, ok = g.cells[[2]int64{x + 1, y}]; ok {
neighbour += 1
}
if _, ok = g.cells[[2]int64{x, y + 1}]; ok {
neighbour += 1
}
if _, ok = g.cells[[2]int64{x + 1, y + 1}]; ok {
neighbour += 1
}
if _, ok = g.cells[[2]int64{x - 1, y - 1}]; ok {
neighbour += 1
}
if _, ok = g.cells[[2]int64{x + 1, y - 1}]; ok {
neighbour += 1
}
if _, ok = g.cells[[2]int64{x - 1, y + 1}]; ok {
neighbour += 1
}
return neighbour
}
func (g *GameOfLife) evolve() {
g.Generation += 1
var ok bool
evolved := make(map[[2]int64]struct{})
neighbour := 0
for cell := range g.cells {
neighbour = 0
if _, ok = g.cells[[2]int64{cell[0] - 1, cell[1]}]; ok {
neighbour += 1
} else {
if g.countNeighbours(cell[0]-1, cell[1]) == 3 {
evolved[[2]int64{cell[0] - 1, cell[1]}] = struct{}{}
}
}
if _, ok = g.cells[[2]int64{cell[0], cell[1] - 1}]; ok {
neighbour += 1
} else {
if g.countNeighbours(cell[0], cell[1]-1) == 3 {
evolved[[2]int64{cell[0], cell[1] - 1}] = struct{}{}
}
}
if _, ok = g.cells[[2]int64{cell[0] + 1, cell[1]}]; ok {
neighbour += 1
} else {
if g.countNeighbours(cell[0]+1, cell[1]) == 3 {
evolved[[2]int64{cell[0] + 1, cell[1]}] = struct{}{}
}
}
if _, ok = g.cells[[2]int64{cell[0], cell[1] + 1}]; ok {
neighbour += 1
} else {
if g.countNeighbours(cell[0], cell[1]+1) == 3 {
evolved[[2]int64{cell[0], cell[1] + 1}] = struct{}{}
}
}
if _, ok = g.cells[[2]int64{cell[0] + 1, cell[1] + 1}]; ok {
neighbour += 1
} else {
if g.countNeighbours(cell[0]+1, cell[1]+1) == 3 {
evolved[[2]int64{cell[0] + 1, cell[1] + 1}] = struct{}{}
}
}
if _, ok = g.cells[[2]int64{cell[0] - 1, cell[1] - 1}]; ok {
neighbour += 1
} else {
if g.countNeighbours(cell[0]-1, cell[1]-1) == 3 {
evolved[[2]int64{cell[0] - 1, cell[1] - 1}] = struct{}{}
}
}
if _, ok = g.cells[[2]int64{cell[0] + 1, cell[1] - 1}]; ok {
neighbour += 1
} else {
if g.countNeighbours(cell[0]+1, cell[1]-1) == 3 {
evolved[[2]int64{cell[0] + 1, cell[1] - 1}] = struct{}{}
}
}
if _, ok = g.cells[[2]int64{cell[0] - 1, cell[1] + 1}]; ok {
neighbour += 1
} else {
if g.countNeighbours(cell[0]-1, cell[1]+1) == 3 {
evolved[[2]int64{cell[0] - 1, cell[1] + 1}] = struct{}{}
}
}
if neighbour == 2 || neighbour == 3 {
evolved[cell] = struct{}{}
}
}
g.cells = evolved
}
func (g *GameOfLife) getLiving() [][2]int64 {
living := make([][2]int64, 0)
for cell := range g.cells {
living = append(living, cell)
}
return living
}
type GameOfLifeHandler struct {
cells *GameOfLife
handler *http.ServeMux
}
func NewGameOfLifeHandler(cells [][2]int64) *GameOfLifeHandler {
game := &GameOfLifeHandler{}
board := make(map[[2]int64]struct{})
for _, cell := range cells {
board[cell] = struct{}{}
}
game.cells = NewGameOflife(board)
game.handler = http.NewServeMux()
game.handler.HandleFunc("/cell/status/", game.getStatus)
game.handler.HandleFunc("/generation/", game.getLiving)
game.handler.HandleFunc("/reset/", game.reset)
game.handler.HandleFunc("/cells/", game.addCells)
game.handler.HandleFunc("/generation/evolve/", game.evolve)
return game
}
func (g *GameOfLifeHandler) addCells(w http.ResponseWriter, req *http.Request) {
if req.Method != "POST" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
body, err := ioutil.ReadAll(req.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "%s Missing a", err)
return
}
newCells := make([]Cell, 0)
err = json.Unmarshal(body, &newCells)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "%s Unmarshal error", err)
return
}
g.cells.addCells(newCells)
w.WriteHeader(http.StatusCreated)
}
func (g *GameOfLifeHandler) evolve(w http.ResponseWriter, req *http.Request) {
if req.Method != "POST" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
g.cells.evolve()
w.WriteHeader(http.StatusNoContent)
}
func (g *GameOfLifeHandler) reset(w http.ResponseWriter, req *http.Request) {
if req.Method != "POST" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
g.cells.reset()
w.WriteHeader(http.StatusNoContent)
}
func (g *GameOfLifeHandler) getLiving(w http.ResponseWriter, req *http.Request) {
if req.Method != "GET" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
cells := g.cells.getLiving()
data, err := json.Marshal(map[string]interface{}{"generation": g.cells.Generation, "living": cells})
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "%s Json error", err)
}
w.Write(data)
}
func (g *GameOfLifeHandler) getStatus(w http.ResponseWriter, req *http.Request) {
if req.Method != "GET" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
req.ParseForm()
x, err := strconv.ParseInt(req.Form.Get("x"), 10, 64)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "%s Missing argument:x", err)
}
y, err := strconv.ParseInt(req.Form.Get("y"), 10, 64)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "%s Missing argument:y", err)
}
alive := g.cells.alive(x, y)
data, err := json.Marshal(map[string]bool{"alive": alive})
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "%s Json error", err)
}
w.Write(data)
}
func (g *GameOfLifeHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
g.handler.ServeHTTP(w, req)
}

Лог от изпълнението

PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.005s
PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.005s
PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.006s
PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.007s
PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.007s
PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.006s
PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.006s
PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.008s
PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.006s
PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.008s
PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.009s
PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.009s
PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.011s
PASS
ok  	_/tmp/d20160126-5892-14v7f9v	0.063s

История (1 версия и 1 коментар)

Диана обнови решението на 26.01.2016 14:40 (преди над 2 години)

+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "strconv"
+)
+
+type Cell struct {
+ X int64 `json:"x"`
+ Y int64 `json:"y"`
+}
+type GameOfLife struct {
+ cells map[[2]int64]struct{}
+ Generation int
+}
+
+func NewGameOflife(cells map[[2]int64]struct{}) *GameOfLife {
+ return &GameOfLife{cells: cells, Generation: 0}
+}
+
+func (g *GameOfLife) addCells(toAdd []Cell) {
+ for _, cell := range toAdd {
+ g.cells[[2]int64{cell.X, cell.Y}] = struct{}{}
+ }
+}
+
+func (g *GameOfLife) alive(x, y int64) bool {
+ cell := [2]int64{x, y}
+ _, ok := g.cells[cell]
+ return ok
+}
+
+func (g *GameOfLife) reset() {
+ g.cells = make(map[[2]int64]struct{})
+ g.Generation = 0
+}
+
+func (g *GameOfLife) countNeighbours(x, y int64) int {
+ neighbour := 0
+ var ok bool
+ if _, ok = g.cells[[2]int64{x - 1, y}]; ok {
+ neighbour += 1
+ }
+
+ if _, ok = g.cells[[2]int64{x, y - 1}]; ok {
+ neighbour += 1
+ }
+
+ if _, ok = g.cells[[2]int64{x + 1, y}]; ok {
+ neighbour += 1
+ }
+
+ if _, ok = g.cells[[2]int64{x, y + 1}]; ok {
+ neighbour += 1
+ }
+
+ if _, ok = g.cells[[2]int64{x + 1, y + 1}]; ok {
+ neighbour += 1
+ }
+
+ if _, ok = g.cells[[2]int64{x - 1, y - 1}]; ok {
+ neighbour += 1
+ }
+
+ if _, ok = g.cells[[2]int64{x + 1, y - 1}]; ok {
+ neighbour += 1
+ }
+
+ if _, ok = g.cells[[2]int64{x - 1, y + 1}]; ok {
+ neighbour += 1
+ }
+ return neighbour
+}
+
+func (g *GameOfLife) evolve() {
+ g.Generation += 1
+ var ok bool
+ evolved := make(map[[2]int64]struct{})
+ neighbour := 0
+ for cell := range g.cells {
+ neighbour = 0
+ if _, ok = g.cells[[2]int64{cell[0] - 1, cell[1]}]; ok {
+ neighbour += 1
+ } else {
+ if g.countNeighbours(cell[0]-1, cell[1]) == 3 {
+ evolved[[2]int64{cell[0] - 1, cell[1]}] = struct{}{}
+ }
+ }
+
+ if _, ok = g.cells[[2]int64{cell[0], cell[1] - 1}]; ok {
+ neighbour += 1
+ } else {
+ if g.countNeighbours(cell[0], cell[1]-1) == 3 {
+ evolved[[2]int64{cell[0], cell[1] - 1}] = struct{}{}
+ }
+ }
+
+ if _, ok = g.cells[[2]int64{cell[0] + 1, cell[1]}]; ok {
+ neighbour += 1
+ } else {
+ if g.countNeighbours(cell[0]+1, cell[1]) == 3 {
+ evolved[[2]int64{cell[0] + 1, cell[1]}] = struct{}{}
+ }
+ }
+
+ if _, ok = g.cells[[2]int64{cell[0], cell[1] + 1}]; ok {
+ neighbour += 1
+ } else {
+ if g.countNeighbours(cell[0], cell[1]+1) == 3 {
+ evolved[[2]int64{cell[0], cell[1] + 1}] = struct{}{}
+ }
+ }
+
+ if _, ok = g.cells[[2]int64{cell[0] + 1, cell[1] + 1}]; ok {
+ neighbour += 1
+ } else {
+ if g.countNeighbours(cell[0]+1, cell[1]+1) == 3 {
+ evolved[[2]int64{cell[0] + 1, cell[1] + 1}] = struct{}{}
+ }
+ }
+
+ if _, ok = g.cells[[2]int64{cell[0] - 1, cell[1] - 1}]; ok {
+ neighbour += 1
+ } else {
+ if g.countNeighbours(cell[0]-1, cell[1]-1) == 3 {
+ evolved[[2]int64{cell[0] - 1, cell[1] - 1}] = struct{}{}
+ }
+ }
+
+ if _, ok = g.cells[[2]int64{cell[0] + 1, cell[1] - 1}]; ok {
+ neighbour += 1
+ } else {
+ if g.countNeighbours(cell[0]+1, cell[1]-1) == 3 {
+ evolved[[2]int64{cell[0] + 1, cell[1] - 1}] = struct{}{}
+ }
+ }
+
+ if _, ok = g.cells[[2]int64{cell[0] - 1, cell[1] + 1}]; ok {
+ neighbour += 1
+ } else {
+ if g.countNeighbours(cell[0]-1, cell[1]+1) == 3 {
+ evolved[[2]int64{cell[0] - 1, cell[1] + 1}] = struct{}{}
+ }
+ }
+
+ if neighbour == 2 || neighbour == 3 {
+ evolved[cell] = struct{}{}
+ }
+
+ }
+ g.cells = evolved
+}
+
+func (g *GameOfLife) getLiving() [][2]int64 {
+ living := make([][2]int64, 0)
+ for cell := range g.cells {
+ living = append(living, cell)
+ }
+ return living
+}
+
+type GameOfLifeHandler struct {
+ cells *GameOfLife
+ handler *http.ServeMux
+}
+
+func NewGameOfLifeHandler(cells [][2]int64) *GameOfLifeHandler {
+ game := &GameOfLifeHandler{}
+ board := make(map[[2]int64]struct{})
+ for _, cell := range cells {
+ board[cell] = struct{}{}
+ }
+ game.cells = NewGameOflife(board)
+ game.handler = http.NewServeMux()
+
+ game.handler.HandleFunc("/cell/status/", game.getStatus)
+ game.handler.HandleFunc("/generation/", game.getLiving)
+ game.handler.HandleFunc("/reset/", game.reset)
+ game.handler.HandleFunc("/cells/", game.addCells)
+ game.handler.HandleFunc("/generation/evolve/", game.evolve)
+
+ return game
+}
+
+func (g *GameOfLifeHandler) addCells(w http.ResponseWriter, req *http.Request) {
+ if req.Method != "POST" {
+ w.WriteHeader(http.StatusMethodNotAllowed)
+ return
+ }
+ body, err := ioutil.ReadAll(req.Body)
+ if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
+ fmt.Fprintf(w, "%s Missing a", err)
+ return
+ }
+
+ newCells := make([]Cell, 0)
+ err = json.Unmarshal(body, &newCells)
+
+ if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
+ fmt.Fprintf(w, "%s Unmarshal error", err)
+ return
+ }
+
+ g.cells.addCells(newCells)
+ w.WriteHeader(http.StatusCreated)
+}
+
+func (g *GameOfLifeHandler) evolve(w http.ResponseWriter, req *http.Request) {
+ if req.Method != "POST" {
+ w.WriteHeader(http.StatusMethodNotAllowed)
+ return
+ }
+
+ g.cells.evolve()
+ w.WriteHeader(http.StatusNoContent)
+}
+
+func (g *GameOfLifeHandler) reset(w http.ResponseWriter, req *http.Request) {
+ if req.Method != "POST" {
+ w.WriteHeader(http.StatusMethodNotAllowed)
+ return
+ }
+ g.cells.reset()
+ w.WriteHeader(http.StatusNoContent)
+}
+
+func (g *GameOfLifeHandler) getLiving(w http.ResponseWriter, req *http.Request) {
+ if req.Method != "GET" {
+ w.WriteHeader(http.StatusMethodNotAllowed)
+ return
+ }
+ cells := g.cells.getLiving()
+
+ data, err := json.Marshal(map[string]interface{}{"generation": g.cells.Generation, "living": cells})
+ if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
+ fmt.Fprintf(w, "%s Json error", err)
+ }
+ w.Write(data)
+}
+
+func (g *GameOfLifeHandler) getStatus(w http.ResponseWriter, req *http.Request) {
+ if req.Method != "GET" {
+ w.WriteHeader(http.StatusMethodNotAllowed)
+ return
+ }
+ req.ParseForm()
+ x, err := strconv.ParseInt(req.Form.Get("x"), 10, 64)
+ if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
+ fmt.Fprintf(w, "%s Missing argument:x", err)
+ }
+ y, err := strconv.ParseInt(req.Form.Get("y"), 10, 64)
+ if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
+ fmt.Fprintf(w, "%s Missing argument:y", err)
+ }
+ alive := g.cells.alive(x, y)
+ data, err := json.Marshal(map[string]bool{"alive": alive})
+ if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
+ fmt.Fprintf(w, "%s Json error", err)
+ }
+ w.Write(data)
+}
+
+func (g *GameOfLifeHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+ g.handler.ServeHTTP(w, req)
+}