initial go implementation

This commit is contained in:
Stephen McQuay 2013-06-16 00:00:25 -07:00
parent 3c0128b9b9
commit d777a978ab
3 changed files with 152 additions and 0 deletions

39
game.go Normal file
View File

@ -0,0 +1,39 @@
package main
type game struct {
players map[*player]bool
broadcast chan *player
register chan *player
unregister chan *player
}
var g = game{
broadcast: make(chan *player),
register: make(chan *player),
unregister: make(chan *player),
players: make(map[*player]bool),
}
func (g *game) run() {
for {
select {
case c := <-g.register:
g.players[c] = true
case c := <-g.unregister:
delete(g.players, c)
close(c.send)
case p := <-g.broadcast:
for c := range g.players {
if p != c {
select {
case c.send <- p:
default:
delete(g.players, c)
close(c.send)
go c.ws.Close()
}
}
}
}
}
}

30
main.go Normal file
View File

@ -0,0 +1,30 @@
package main
import (
"code.google.com/p/go.net/websocket"
"flag"
"fmt"
"log"
"net/http"
)
var addr = flag.String("addr", ":8666", "http service address")
var static_files = flag.String("static", "./static", "location of static files")
func main() {
flag.Parse()
http.Handle("/", http.FileServer(http.Dir(
fmt.Sprintf("%s/html", *static_files))))
http.Handle("/static/", http.StripPrefix("/static/",
http.FileServer(http.Dir(*static_files))))
http.Handle("/ws/game/", websocket.Handler(addPlayer))
go g.run()
err := http.ListenAndServe(*addr, nil)
if err != nil {
log.Fatal("unable to start server")
}
}

83
player.go Normal file
View File

@ -0,0 +1,83 @@
package main
import (
"code.google.com/p/go.net/websocket"
"encoding/json"
"fmt"
"log"
"math"
)
type Position struct {
X, Y int
}
type player struct {
Position Position `json:"position"`
Name string `json:"name"`
ws *websocket.Conn
send chan *player
}
func (p *player) validMove(next Position) (r bool) {
r = true
if math.Abs(float64(p.Position.X - next.X)) > 1 {
r = false
}
if math.Abs(float64(p.Position.Y - next.Y)) > 1 {
r = false
}
return
}
func (p *player) sender() {
for pinfo := range p.send {
err := websocket.JSON.Send(p.ws, pinfo)
if err != nil {
break
}
}
p.ws.Close()
}
func (p *player) recv() {
for {
var msg string
err := websocket.Message.Receive(p.ws, &msg)
if err != nil {
break
}
// XXX: the danger!
var pos Position
err = json.Unmarshal([]byte(msg), &pos)
if err != nil {
break
}
if !p.validMove(pos) {
break
}
p.Position = pos
g.broadcast <- p
}
p.ws.Close()
}
func addPlayer(ws *websocket.Conn) {
var name string
err := websocket.Message.Receive(ws, &name)
if err != nil {
log.Fatal("trouble parsing username")
}
p := &player{
Name: name,
send: make(chan *player, 256),
ws: ws,
}
g.register <- p
defer func() {
g.unregister <- p
}()
go p.sender()
p.recv()
fmt.Printf("%v has been disconnect from this game\n", p)
}