diff options
author | Zach Latta <zach@zachlatta.com> | 2016-03-06 06:54:58 -0500 |
---|---|---|
committer | Zach Latta <zach@zachlatta.com> | 2016-03-06 06:54:58 -0500 |
commit | d580c5e704ae395176ac42e8573949941b407cae (patch) | |
tree | a43839312160dad11ffac145717234d1881a0767 | |
parent | d4d7652ba38745c00f592ad26681d30e6af54177 (diff) | |
download | sshtron-d580c5e704ae395176ac42e8573949941b407cae.tar.gz |
Implement rudimentary multi-game support
-rw-r--r-- | game.go | 76 | ||||
-rw-r--r-- | main.go | 35 |
2 files changed, 81 insertions, 30 deletions
@@ -1,6 +1,7 @@ package main import ( + "bufio" "fmt" "github.com/dustinkirkland/golang-petname" "github.com/fatih/color" @@ -285,6 +286,79 @@ type Tile struct { Type TileType } +const ( + gameWidth = 78 + gameHeight = 22 +) + +type GameManager struct { + Games map[string]*Game + HandleChannel chan ssh.Channel +} + +func NewGameManager() *GameManager { + return &GameManager{ + Games: map[string]*Game{}, + HandleChannel: make(chan ssh.Channel), + } +} + +// getGameWithAvailability returns a reference to a game with available spots for +// players. If one does not exist, nil is returned. +func (gm *GameManager) getGameWithAvailability() *Game { + var g *Game + + for _, game := range gm.Games { + spots := game.AvailableColors() + if len(spots) > 0 { + g = game + break + } + } + + return g +} + +func (gm *GameManager) Run() { + for { + select { + case c := <-gm.HandleChannel: + g := gm.getGameWithAvailability() + if g == nil { + g = NewGame(gameWidth, gameHeight) + gm.Games[g.Name] = g + + go g.Run() + } + + session := NewSession(c, g.WorldWidth(), g.WorldHeight(), + g.AvailableColors()[0]) + g.AddSession(session) + + go func() { + reader := bufio.NewReader(c) + for { + r, _, err := reader.ReadRune() + if err != nil { + fmt.Println(err) + break + } + + switch r { + case keyUp: + session.Player.HandleUp() + case keyLeft: + session.Player.HandleLeft() + case keyDown: + session.Player.HandleDown() + case keyRight: + session.Player.HandleRight() + } + } + }() + } + } +} type Game struct { Name string @@ -389,7 +463,7 @@ func (g *Game) worldString(s *Session) string { // Draw the player's score scoreStr := fmt.Sprintf( - " Score: %d : Your High Score: %d : Global High Score: %d ", + " Score: %d : Your High Score: %d : Game High Score: %d ", s.Player.Score(), s.HighScore, g.HighScore, @@ -1,7 +1,6 @@ package main import ( - "bufio" "fmt" "golang.org/x/crypto/ssh" "io/ioutil" @@ -15,7 +14,7 @@ const ( keyRight = 'd' ) -func handler(conn net.Conn, game *Game, config *ssh.ServerConfig) { +func handler(conn net.Conn, gm *GameManager, config *ssh.ServerConfig) { // Before use, a handshake must be performed on the incoming // net.Conn. _, chans, reqs, err := ssh.NewServerConn(conn, config) @@ -59,29 +58,7 @@ func handler(conn net.Conn, game *Game, config *ssh.ServerConfig) { fmt.Println("Received new connection") - session := NewSession(channel, game.WorldWidth(), game.WorldHeight(), - game.AvailableColors()[0]) - game.AddSession(session) - - reader := bufio.NewReader(channel) - for { - r, _, err := reader.ReadRune() - if err != nil { - fmt.Println(err) - break - } - - switch r { - case keyUp: - session.Player.HandleUp() - case keyLeft: - session.Player.HandleLeft() - case keyDown: - session.Player.HandleDown() - case keyRight: - session.Player.HandleRight() - } - } + gm.HandleChannel <- channel } } @@ -103,9 +80,9 @@ func main() { config.AddHostKey(private) - // Create the game itself - game := NewGame(78, 22) - go game.Run() + // Create the GameManager + gm := NewGameManager() + go gm.Run() // Once a ServerConfig has been configured, connections can be // accepted. @@ -119,6 +96,6 @@ func main() { panic("failed to accept incoming connection") } - go handler(nConn, game, config) + go handler(nConn, gm, config) } } |