aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZach Latta <zach@zachlatta.com>2016-03-06 06:54:58 -0500
committerZach Latta <zach@zachlatta.com>2016-03-06 06:54:58 -0500
commitd580c5e704ae395176ac42e8573949941b407cae (patch)
treea43839312160dad11ffac145717234d1881a0767
parentd4d7652ba38745c00f592ad26681d30e6af54177 (diff)
downloadsshtron-d580c5e704ae395176ac42e8573949941b407cae.tar.gz
Implement rudimentary multi-game support
-rw-r--r--game.go76
-rw-r--r--main.go35
2 files changed, 81 insertions, 30 deletions
diff --git a/game.go b/game.go
index 39bd8b5..8054c20 100644
--- a/game.go
+++ b/game.go
@@ -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,
diff --git a/main.go b/main.go
index bc8215b..c3dddb6 100644
--- a/main.go
+++ b/main.go
@@ -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)
}
}
Un proyecto texto-plano.xyz