session skeleton up

This commit is contained in:
stryan 2022-03-07 14:47:21 -05:00
parent e09c1c64e9
commit 06e2175021
3 changed files with 167 additions and 9 deletions

83
api.go
View File

@ -53,6 +53,7 @@ func (a *API) GetGame(res http.ResponseWriter, req *http.Request) {
respondWithError(res, http.StatusBadRequest, "No such game")
return
}
//TODO filter based off player info
respondWithJSON(res, http.StatusOK, gameResp{s.simulator})
return
}
@ -83,3 +84,85 @@ func (a *API) GetGameStatus(res http.ResponseWriter, req *http.Request) {
}
respondWithJSON(res, http.StatusOK, gameStatusResp{s.simulator.State, s.moveNum})
}
//PostMove attempts to make a game move
func (a *API) PostMove(res http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
id, err := strconv.Atoi(vars["id"])
if err != nil {
respondWithError(res, http.StatusBadRequest, "Invalid game ID")
return
}
var gr gameMovePostReq
decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&gr); err != nil {
respondWithError(res, http.StatusBadRequest, "Invalid resquest payload")
return
}
defer req.Body.Close()
if gr.PlayerID != "red" && gr.PlayerID != "blue" {
respondWithError(res, http.StatusBadRequest, "Bad player ID")
return
}
var p *Player
s, isset := a.games[id]
if !isset {
respondWithError(res, http.StatusBadRequest, "No such game")
return
}
if gr.PlayerID == "red" {
p = s.redPlayer
} else {
p = s.bluePlayer
}
parsed, err := s.tryMove(p, gr.Move)
if err != nil {
respondWithJSON(res, http.StatusOK, gameMovePostRes{false, false, parsed.String(), err})
}
}
//GetMove returns the move made at turn X
func (a *API) GetMove(res http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
id, err := strconv.Atoi(vars["id"])
if err != nil {
respondWithError(res, http.StatusBadRequest, "Invalid game ID")
return
}
move, err := strconv.Atoi(vars["move_number"])
if err != nil {
respondWithError(res, http.StatusBadRequest, "Invalid move number")
return
}
var gr gameMoveReq
decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&gr); err != nil {
respondWithError(res, http.StatusBadRequest, "Invalid resquest payload")
return
}
defer req.Body.Close()
if gr.PlayerID != "red" && gr.PlayerID != "blue" {
respondWithError(res, http.StatusBadRequest, "Bad player ID")
return
}
var p *Player
s, isset := a.games[id]
if !isset {
respondWithError(res, http.StatusBadRequest, "No such game")
return
}
if gr.PlayerID == "red" {
p = s.redPlayer
} else {
p = s.bluePlayer
}
moveRes, err := s.getMove(p, move)
if err != nil {
respondWithError(res, http.StatusBadRequest, "No such move")
return
}
respondWithJSON(res, http.StatusOK, gameMoveRes{moveRes})
}

View File

@ -25,3 +25,23 @@ type gameStatusResp struct {
GameStatus freego.GameState `json:"game_status"`
Move int `json:"move"`
}
type gameMovePostReq struct {
PlayerID string `json:"player_id"`
Move string `json:"move"`
}
type gameMovePostRes struct {
Valid bool `json:"valid"`
Result bool `json:"result"`
Parsed string `json:"parsed"`
Error error `json:"error"`
}
type gameMoveReq struct {
PlayerID string `json:"player_id"`
}
type gameMoveRes struct {
Move string `json:"move"`
}

View File

@ -1,21 +1,76 @@
package main
import "git.saintnet.tech/stryan/freego"
import (
"errors"
"fmt"
"git.saintnet.tech/stryan/freego"
)
//Session represents an active game
type Session struct {
simulator *freego.Game
redReady bool
blueReady bool
moveNum int
simulator *freego.Game
redPlayer *Player
bluePlayer *Player
moveNum int
moveList []freego.ParsedCommand
}
//Player is a player in a match
type Player struct {
Ready bool
Team freego.Colour
}
//ID returns player ID
func (p *Player) ID() int {
panic("not implemented") // TODO: Implement
}
//Colour returns player team
func (p *Player) Colour() freego.Colour {
return p.Team
}
//NewSession creates a new game session
func NewSession() *Session {
return &Session{
simulator: freego.NewGame(),
redReady: false,
blueReady: false,
moveNum: 0,
simulator: freego.NewGame(),
redPlayer: &Player{false, freego.Red},
bluePlayer: &Player{false, freego.Blue},
moveNum: 0,
moveList: []freego.ParsedCommand{},
}
}
func (s *Session) tryMove(player *Player, move string) (*freego.ParsedCommand, error) {
raw, err := freego.NewRawCommand(move)
if err != nil {
return nil, err
}
p, err := s.simulator.Parse(player, raw)
if err != nil {
return nil, err
}
return p, nil
}
func (s *Session) mutate(p *freego.ParsedCommand) error {
success, err := s.simulator.Mutate(p)
if err != nil {
return err
}
if !success {
return errors.New("invalid move")
}
s.moveList[s.moveNum] = *p
s.moveNum++
return nil
}
func (s *Session) getMove(p *Player, num int) (string, error) {
if num < 0 || num > s.moveNum {
return "", errors.New("invalid move number")
}
return fmt.Sprintf("%v %v", num, s.moveList[num].String()), nil
}