Add bot to play against.
This commit is contained in:
@@ -62,6 +62,9 @@ type room struct {
|
||||
game *game.Game
|
||||
conns map[*client]struct{}
|
||||
debug bool // mirrors Server.debug, for broadcastLocked
|
||||
// botArmed is set while a delayed bot move is scheduled, so only one
|
||||
// timer exists per room at a time.
|
||||
botArmed bool
|
||||
}
|
||||
|
||||
// getRoom returns the room for a game ID, loading it from the store if it
|
||||
@@ -78,6 +81,11 @@ func (s *Server) getRoom(gameID string) (*room, error) {
|
||||
}
|
||||
r := &room{game: g, conns: make(map[*client]struct{}), debug: s.debug}
|
||||
s.rooms[gameID] = r
|
||||
// If the game was persisted mid-bot-turn (e.g. across a server restart),
|
||||
// get the bot moving again.
|
||||
r.mu.Lock()
|
||||
s.scheduleBotsLocked(r)
|
||||
r.mu.Unlock()
|
||||
return r, nil
|
||||
}
|
||||
|
||||
@@ -116,24 +124,45 @@ type joinResponse struct {
|
||||
func (s *Server) handleCreate(w http.ResponseWriter, req *http.Request) {
|
||||
var body struct {
|
||||
Name string `json:"name"`
|
||||
// Bot, when set, fills the other seat with a computer player:
|
||||
// "easy" | "medium" | "hard".
|
||||
Bot string `json:"bot"`
|
||||
}
|
||||
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
|
||||
httpError(w, http.StatusBadRequest, "invalid JSON body")
|
||||
return
|
||||
}
|
||||
var bot struct {
|
||||
level float64
|
||||
name string
|
||||
}
|
||||
if body.Bot != "" {
|
||||
var ok bool
|
||||
bot, ok = botDifficulty[body.Bot]
|
||||
if !ok {
|
||||
httpError(w, http.StatusBadRequest, "unknown bot difficulty")
|
||||
return
|
||||
}
|
||||
}
|
||||
g := game.New()
|
||||
p, err := g.AddPlayer(strings.TrimSpace(body.Name))
|
||||
if err != nil {
|
||||
httpError(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
if body.Bot != "" {
|
||||
if _, err := g.AddBot(bot.name, bot.level); err != nil {
|
||||
httpError(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
r := &room{game: g, conns: make(map[*client]struct{}), debug: s.debug}
|
||||
s.mu.Lock()
|
||||
s.rooms[g.ID] = r
|
||||
s.mu.Unlock()
|
||||
|
||||
r.mu.Lock()
|
||||
s.persist(r)
|
||||
s.commitLocked(r)
|
||||
r.mu.Unlock()
|
||||
writeJSON(w, joinResponse{GameID: g.ID, Code: g.Code, PlayerID: p.ID, Token: p.Token})
|
||||
}
|
||||
@@ -163,9 +192,8 @@ func (s *Server) handleJoin(w http.ResponseWriter, req *http.Request) {
|
||||
httpError(w, http.StatusConflict, err.Error())
|
||||
return
|
||||
}
|
||||
s.persist(r)
|
||||
resp := joinResponse{GameID: r.game.ID, Code: r.game.Code, PlayerID: p.ID, Token: p.Token}
|
||||
r.broadcastLocked()
|
||||
s.commitLocked(r)
|
||||
r.mu.Unlock()
|
||||
writeJSON(w, resp)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user