Skip to content

Commit

Permalink
Implement new game clears board, and join game loads board in client
Browse files Browse the repository at this point in the history
  • Loading branch information
armsnyder committed Oct 18, 2020
1 parent 62c988c commit f824dde
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 21 deletions.
5 changes: 0 additions & 5 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,9 @@ linters:
linters-settings:
goimports:
local-prefixes: github.com/armsnyder/othelgo
unparam:
check-exported: true
unused:
check-exported: true

issues:
exclude-rules:
- path: _test\.go
linters:
- scopelint
- unused
5 changes: 4 additions & 1 deletion pkg/client/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ func Run() error {
}

currentScene = nextScene
currentScene.Setup(changeScene, c.WriteJSON, sceneContext)

if err := currentScene.Setup(changeScene, c.WriteJSON, sceneContext); err != nil {
return err
}

return drawAndFlush(currentScene)
}
Expand Down
24 changes: 15 additions & 9 deletions pkg/client/scenes/game.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package scenes

import (
"fmt"

"github.com/nsf/termbox-go"

"github.com/armsnyder/othelgo/pkg/messages"
Expand All @@ -16,18 +14,26 @@ type Game struct {
board messages.Board
}

func (g *Game) Setup(changeScene ChangeScene, sendMessage SendMessage, setupContext SceneContext) {
g.scene.Setup(changeScene, sendMessage, setupContext)
func (g *Game) Setup(changeScene ChangeScene, sendMessage SendMessage, setupContext SceneContext) error {
if err := g.scene.Setup(changeScene, sendMessage, setupContext); err != nil {
return err
}

g.player = setupContext["player"].(int)

var message interface{}
if g.player == 1 {
message = messages.NewNewGameMessage()
} else {
message = messages.NewJoinGameMessage()
}

return sendMessage(message)
}

func (g *Game) OnMessage(message messages.AnyMessage) error {
switch m := message.Message.(type) {
case *messages.UpdateBoardMessage:
if m, ok := message.Message.(*messages.UpdateBoardMessage); ok {
g.board = m.Board

default:
return fmt.Errorf("unhandled message type %T", m)
}

return nil
Expand Down
5 changes: 3 additions & 2 deletions pkg/client/scenes/scene.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
// Scene is responsible for the logic and view of a particular page of the application.
// It can handle websocket messages and terminal events.
type Scene interface {
Setup(changeScene ChangeScene, sendMessage SendMessage, sceneContext SceneContext)
Setup(changeScene ChangeScene, sendMessage SendMessage, sceneContext SceneContext) error
OnMessage(message messages.AnyMessage) error
OnTerminalEvent(event termbox.Event) error
Draw()
Expand All @@ -29,10 +29,11 @@ type scene struct {
SceneContext
}

func (b *scene) Setup(changeScene ChangeScene, sendMessage SendMessage, sceneContext SceneContext) {
func (b *scene) Setup(changeScene ChangeScene, sendMessage SendMessage, sceneContext SceneContext) error {
b.ChangeScene = changeScene
b.SendMessage = sendMessage
b.SceneContext = sceneContext
return nil
}

func (b *scene) OnMessage(_ messages.AnyMessage) error {
Expand Down
16 changes: 16 additions & 0 deletions pkg/messages/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ import (
const (
PlaceDiskAction = "placeDisk"
UpdateBoardAction = "updateBoard"
NewGameAction = "newGame"
JoinGameAction = "joinGame"
)

var actionToMessage = map[string]interface{}{
PlaceDiskAction: PlaceDiskMessage{},
UpdateBoardAction: UpdateBoardMessage{},
NewGameAction: NewGameMessage{},
JoinGameAction: JoinGameMessage{},
}

const BoardSize = 8
Expand Down Expand Up @@ -52,6 +56,18 @@ func NewUpdateBoardMessage(board Board) UpdateBoardMessage {
}
}

type NewGameMessage BaseMessage

func NewNewGameMessage() NewGameMessage {
return NewGameMessage{Action: NewGameAction}
}

type JoinGameMessage BaseMessage

func NewJoinGameMessage() JoinGameMessage {
return JoinGameMessage{Action: JoinGameAction}
}

type AnyMessage struct {
Message interface{}
}
Expand Down
28 changes: 24 additions & 4 deletions pkg/server/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ func handleMessage(ctx context.Context, req events.APIGatewayWebsocketProxyReque
switch message.Action {
case messages.PlaceDiskAction:
return handlePlaceDisk(ctx, req)
case messages.NewGameAction:
return handleNewGame(ctx, req)
case messages.JoinGameAction:
return handleJoinGame(ctx, req)
default:
return fmt.Errorf("unrecognized message action %q", message.Action)
}
Expand All @@ -61,12 +65,28 @@ func handlePlaceDisk(ctx context.Context, req events.APIGatewayWebsocketProxyReq

board[message.X][message.Y] = message.Player

err = saveBoard(ctx, board)
if err != nil {
if err := saveBoard(ctx, board); err != nil {
return err
}

return broadcastMessage(ctx, req.RequestContext, messages.NewUpdateBoardMessage(board))
}

func handleNewGame(ctx context.Context, req events.APIGatewayWebsocketProxyRequest) error {
var board messages.Board

if err := saveBoard(ctx, board); err != nil {
return err
}

boardMessage := messages.NewUpdateBoardMessage(board)
return broadcastMessage(ctx, req.RequestContext, messages.NewUpdateBoardMessage(board))
}

func handleJoinGame(ctx context.Context, req events.APIGatewayWebsocketProxyRequest) error {
board, err := loadBoard(ctx)
if err != nil {
return err
}

return broadcastMessage(ctx, req.RequestContext, boardMessage)
return reply(ctx, req.RequestContext, messages.NewUpdateBoardMessage(board))
}
11 changes: 11 additions & 0 deletions pkg/server/management_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ func broadcastMessage(ctx context.Context, reqCtx events.APIGatewayWebsocketProx
return group.Wait()
}

func reply(ctx context.Context, reqCtx events.APIGatewayWebsocketProxyRequestContext, message interface{}) error {
data, err := json.Marshal(message)
if err != nil {
return err
}

client := newManagementAPIClient(reqCtx)

return sendMessage(ctx, client, reqCtx.ConnectionID, data)()
}

func newManagementAPIClient(reqCtx events.APIGatewayWebsocketProxyRequestContext) *apigatewaymanagementapi.ApiGatewayManagementApi {
endpoint := fmt.Sprintf("https://%s/%s/", reqCtx.DomainName, reqCtx.Stage)
return apigatewaymanagementapi.New(session.Must(session.NewSession(aws.NewConfig().WithEndpoint(endpoint))))
Expand Down

0 comments on commit f824dde

Please sign in to comment.