run multiple games at once

master
Jordan Orelli 6 years ago
parent e629c0b6b6
commit 938348ce26

@ -120,7 +120,7 @@ func BroadcastCommand(sys *System) Command {
msg := strings.Join(args, " ") msg := strings.Join(args, " ")
b := NewBroadcast(sys, msg) b := NewBroadcast(sys, msg)
log_info("player %s send broadcast from system %v: %v\n", c.Name(), sys, msg) log_info("player %s send broadcast from system %v: %v\n", c.Name(), sys, msg)
currentGame.Register(b) c.game.Register(b)
}, },
} }
} }
@ -162,7 +162,7 @@ var playersCommand = Command{
name: "players", name: "players",
help: "lists the connected players", help: "lists the connected players",
handler: func(conn *Connection, args ...string) { handler: func(conn *Connection, args ...string) {
for other, _ := range currentGame.connections { for other, _ := range conn.game.connections {
conn.Printf("%v\n", other.Name()) conn.Printf("%v\n", other.Name())
} }
}, },

@ -12,6 +12,7 @@ import (
type Connection struct { type Connection struct {
*bufio.Reader *bufio.Reader
game *Game
net.Conn net.Conn
ConnectionState ConnectionState
bombs int bombs int
@ -30,8 +31,7 @@ func NewConnection(conn net.Conn) *Connection {
bombs: options.startBombs, bombs: options.startBombs,
money: options.startMoney, money: options.startMoney,
} }
c.SetState(SpawnRandomly()) c.SetState(new(LobbyState))
currentGame.Join(c)
return c return c
} }
@ -45,6 +45,7 @@ func (c *Connection) Login() {
log_error("player failed to connect: %v", err) log_error("player failed to connect: %v", err)
return return
} }
if !ValidName(name) { if !ValidName(name) {
c.Printf("that name is illegal.\n") c.Printf("that name is illegal.\n")
continue continue
@ -66,7 +67,6 @@ func (c *Connection) Login() {
} }
break break
} }
currentGame.Register(c)
} }
func (c *Connection) Dead() bool { func (c *Connection) Dead() bool {
@ -162,7 +162,7 @@ func (c *Connection) Printf(template string, args ...interface{}) (int, error) {
func (c *Connection) Close() error { func (c *Connection) Close() error {
log_info("player disconnecting: %s", c.Name()) log_info("player disconnecting: %s", c.Name())
currentGame.Quit(c) c.game.Quit(c)
if c.Conn != nil { if c.Conn != nil {
return c.Conn.Close() return c.Conn.Close()
} }
@ -226,7 +226,7 @@ func (c *Connection) Deposit(n int) {
} }
func (c *Connection) Win(method string) { func (c *Connection) Win(method string) {
currentGame.Win(c, method) c.game.Win(c, method)
} }
func (c *Connection) Die(frame int64) { func (c *Connection) Die(frame int64) {
@ -260,3 +260,63 @@ func SpawnRandomly() ConnectionState {
} }
return Idle(sys) return Idle(sys)
} }
type LobbyState struct {
NopExit
}
func (st *LobbyState) String() string { return "Lobby" }
func (st *LobbyState) Enter(c *Connection) {
c.Login()
}
func (st *LobbyState) Tick(c *Connection, frame int64) ConnectionState { return st }
func (st *LobbyState) Commands() []Command {
return []Command{newGameCommand, joinGameCommand}
}
func (st *LobbyState) GetCommand(name string) *Command {
switch name {
case "new":
return &newGameCommand
case "join":
return &joinGameCommand
default:
return nil
}
}
var newGameCommand = Command{
name: "new",
help: "starts a new game",
arity: 0,
variadic: false,
handler: func(c *Connection, args ...string) {
c.Printf("Starting a new game...\n")
game := gm.NewGame()
log_info("Created game: %s", game.id)
go game.Run()
c.game = game
c.Printf("Now playing in game: %s\n\n", game.id)
c.Line()
c.game.Join(c)
c.SetState(SpawnRandomly())
},
debug: false,
}
var joinGameCommand = Command{
name: "join",
help: "joins an existing game",
arity: 1,
variadic: false,
handler: func(c *Connection, args ...string) {
id := args[0]
c.game = gm.Get(id)
c.SetState(SpawnRandomly())
c.game.Join(c)
},
debug: false,
}

@ -56,14 +56,6 @@ func NewGame() *Game {
for _, system := range index { for _, system := range index {
game.Register(system) game.Register(system)
} }
if currentGame != nil {
log_info("passing %d connections...", len(currentGame.connections))
for conn, _ := range currentGame.connections {
log_info("moving player %s to new game", conn.Name())
currentGame.Quit(conn)
game.Join(conn)
}
}
return game return game
} }
@ -90,7 +82,9 @@ func (g *Game) Store() error {
} }
func (g *Game) Join(conn *Connection) { func (g *Game) Join(conn *Connection) {
log_info("Player %s has joined game %s", conn.Name(), g.id)
g.connections[conn] = true g.connections[conn] = true
g.Register(conn)
} }
func (g *Game) Quit(conn *Connection) { func (g *Game) Quit(conn *Connection) {

@ -0,0 +1,34 @@
package main
import (
"sync"
)
var gm *GameManager
func init() {
gm = &GameManager{
games: make(map[string]*Game, 32),
}
}
type GameManager struct {
games map[string]*Game
sync.Mutex
}
func (g *GameManager) NewGame() *Game {
g.Lock()
defer g.Unlock()
game := NewGame()
g.games[game.id] = game
return game
}
func (g *GameManager) Get(id string) *Game {
g.Lock()
defer g.Unlock()
return g.games[id]
}

@ -98,7 +98,7 @@ func (i *IdleState) bomb(c *Connection, args ...string) {
c.bombs -= 1 c.bombs -= 1
c.lastBomb = time.Now() c.lastBomb = time.Now()
bomb := NewBomb(c, i.System, target) bomb := NewBomb(c, i.System, target)
currentGame.Register(bomb) c.game.Register(bomb)
} }
func (i *IdleState) mine(c *Connection, args ...string) { func (i *IdleState) mine(c *Connection, args ...string) {
@ -115,7 +115,7 @@ func (i *IdleState) scan(c *Connection, args ...string) {
return return
} }
c.Printf("Scanning the galaxy for signs of life...\n") c.Printf("Scanning the galaxy for signs of life...\n")
currentGame.Register(NewScan(i.System)) c.game.Register(NewScan(i.System))
} }
// "make" is already a keyword // "make" is already a keyword

@ -34,9 +34,8 @@ var options struct {
} }
var ( var (
info_log *log.Logger info_log *log.Logger
error_log *log.Logger error_log *log.Logger
currentGame *Game
) )
func log_error(template string, args ...interface{}) { func log_error(template string, args ...interface{}) {
@ -58,7 +57,6 @@ func bail(status int, template string, args ...interface{}) {
func handleConnection(conn *Connection) { func handleConnection(conn *Connection) {
defer conn.Close() defer conn.Close()
conn.Login()
c := make(chan []string) c := make(chan []string)
go conn.ReadLines(c) go conn.ReadLines(c)
@ -95,14 +93,6 @@ func main() {
} }
log_info("listening on %s", addr) log_info("listening on %s", addr)
go func() {
for {
log_info("starting new game")
currentGame = NewGame()
currentGame.Run()
}
}()
for { for {
conn, err := listener.Accept() conn, err := listener.Accept()
if err != nil { if err != nil {

@ -279,7 +279,7 @@ func indexSystems() map[int]*System {
index[p.id] = &p index[p.id] = &p
nameIndex[p.name] = &p nameIndex[p.name] = &p
p.money = int64(rand.NormFloat64()*options.moneySigma + options.moneyMean) p.money = int64(rand.NormFloat64()*options.moneySigma + options.moneyMean)
log_info("seeded system %v with %v monies", p, p.money) // log_info("seeded system %v with %v monies", p, p.money)
} }
return index return index
} }

Loading…
Cancel
Save