예제 #1
0
func (f *Fixtures) runGameFixtures() {
	var (
		numGames            int     = 16
		nextMoveProbability float64 = 0.8
	)

	usersService := f.Users.(*users.UsersService)
	users := usersService.GetAll()

	for gameId := 1; gameId <= numGames; gameId++ {
		shuffle := rand.Perm(len(users))
		white := users[shuffle[0]]
		black := users[shuffle[1]]

		log.Info("Creating game between %s and %s", white.Name, black.Name)

		whiteId := white.Uuid
		blackId := black.Uuid

		if rand.Intn(2) == 0 {
			f.Events.Receive(
				events.NewGameCreateEvent(game.Id(gameId), whiteId, ""),
			)
			time.Sleep(100 * time.Millisecond)
		} else {
			f.Events.Receive(
				events.NewGameCreateEvent(game.Id(gameId), "", blackId),
			)
			time.Sleep(100 * time.Millisecond)
		}

		f.Events.Receive(
			events.NewGameStartEvent(game.Id(gameId), whiteId, blackId),
		)
		time.Sleep(100 * time.Millisecond)

		for turnNumber := 1; ; turnNumber++ {
			if rand.Float64() > nextMoveProbability {
				break
			}

			validMoves, _ := f.Queries.ValidMoves(game.Id(gameId))
			if len(validMoves) == 0 {
				break
			}

			log.Info("Turn %d", turnNumber)

			log.Debug("got valid moves: %v", validMoves)
			randomMoveRecord := validMoves[rand.Intn(len(validMoves))]

			f.Events.Receive(
				events.NewMoveEvent(game.Id(gameId), game.TurnNumber(turnNumber), randomMoveRecord.Move),
			)
			time.Sleep(100 * time.Millisecond)
		}

		log.Info("Done")
	}
}
예제 #2
0
func (api *ChessApi) GetGameInfo(res rest.ResponseWriter, req *rest.Request) {
	u := getUser(req)

	id := req.PathParam("id")
	intId, err := strconv.Atoi(id)
	gameId := game.Id(intId)
	if err != nil {
		log.Debug("Recieved an invalid gameid, it was not an int: %s", id)
		rest.NotFound(res, req)
		return
	}

	gameInfo, found := api.Queries.GameInformation(gameId)
	if !found {
		log.Debug("Recieved an invalid gameid, it was not an int: %s", id)
		rest.NotFound(res, req)
		return
	}

	type Response struct {
		GameInfo        queries.GameInformation `json:",inline"`
		UserColor       game.Color              `json:",omitempty"`
		UserActive      bool
		DrawOfferToUser bool
	}

	response := new(Response)
	response.GameInfo = gameInfo

	if u.Uuid == gameInfo.White.Uuid {
		response.UserColor = game.White
		response.UserActive = gameInfo.ActiveColor == game.White

		if gameInfo.OutstandingDrawOffer && gameInfo.DrawOfferer == game.Black {
			response.DrawOfferToUser = true
		}
	} else if u.Uuid == gameInfo.Black.Uuid {
		response.UserColor = game.Black
		response.UserActive = gameInfo.ActiveColor == game.Black

		if gameInfo.OutstandingDrawOffer && gameInfo.DrawOfferer == game.White {
			response.DrawOfferToUser = true
		}
	}

	res.WriteJson(response)
}
예제 #3
0
func (api *ChessApi) GetGameValidMoves(res rest.ResponseWriter, req *rest.Request) {
	id := req.PathParam("id")
	intId, err := strconv.Atoi(id)
	gameId := game.Id(intId)
	if err != nil {
		log.Debug("Recieved an invalid gameid, it was not an int: %s", id)
		rest.NotFound(res, req)
	}

	validMoves, found := api.Queries.ValidMoves(gameId)
	if !found {
		rest.NotFound(res, req)
		return
	}

	res.WriteJson(validMoves)
}
예제 #4
0
func (api *ChessApi) PostConcede(res rest.ResponseWriter, req *rest.Request) {
	user := getUser(req)

	intId, err := strconv.Atoi(req.PathParam("id"))
	gameId := game.Id(intId)
	if err != nil {
		rest.NotFound(res, req)
	}

	ok, msg := api.Commands.ExecCommand(
		commands.Concede, user.Uuid, map[string]interface{}{
			"gameId": gameId,
		},
	)

	if ok {
		res.WriteHeader(http.StatusAccepted)
		res.WriteJson("ok")
	} else {
		res.WriteHeader(http.StatusBadRequest)
		res.WriteJson(map[string]string{"error": msg})
	}
}
예제 #5
0
func (api *ChessApi) PostDrawOfferResponse(res rest.ResponseWriter, req *rest.Request) {
	user := getUser(req)

	intId, err := strconv.Atoi(req.PathParam("id"))
	gameId := game.Id(intId)
	if err != nil {
		rest.NotFound(res, req)
	}

	type responseBody struct {
		Accept bool `json:"Accept"`
	}

	body := new(responseBody)
	err = req.DecodeJsonPayload(body)
	if err != nil {
		res.WriteHeader(http.StatusBadRequest)
		res.WriteJson(map[string]string{"error": "Accept must be a boolean."})
		return
	}

	ok, msg := api.Commands.ExecCommand(
		commands.DrawOfferRespond, user.Uuid, map[string]interface{}{
			"gameId": gameId,
			"accept": body.Accept,
		},
	)

	if ok {
		res.WriteHeader(http.StatusAccepted)
		res.WriteJson("ok")
	} else {
		res.WriteHeader(http.StatusBadRequest)
		res.WriteJson(map[string]string{"error": msg})
	}
}
예제 #6
0
func (api *ChessApi) PostMove(res rest.ResponseWriter, req *rest.Request) {
	user := getUser(req)

	intId, err := strconv.Atoi(req.PathParam("id"))
	gameId := game.Id(intId)
	if err != nil {
		rest.NotFound(res, req)
	}

	type moveBody struct {
		Move game.AlgebraicMove `json:"Move"`
	}

	body := new(moveBody)
	err = req.DecodeJsonPayload(body)
	if err != nil || body.Move == "" {
		res.WriteHeader(http.StatusBadRequest)
		res.WriteJson(map[string]string{"error": "Move must be a move"})
		return
	}

	ok, msg := api.Commands.ExecCommand(
		commands.Move, user.Uuid, map[string]interface{}{
			"move":   body.Move,
			"gameId": gameId,
		},
	)

	if ok {
		res.WriteHeader(http.StatusAccepted)
		res.WriteJson("ok")
	} else {
		res.WriteHeader(http.StatusBadRequest)
		res.WriteJson(map[string]string{"error": msg})
	}
}
예제 #7
0
func (s *EventsService) startGameIdGenerator() {
	var nextGameId int

	rows, _ := s.db.Table(Event{}.TableName()).
		Select("IFNULL(MAX(game_id), 0) + 1 AS `next_game_id`").
		Rows()
	rows.Next()
	rows.Scan(&nextGameId)
	rows.Close()

	go func(initial int) {
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, syscall.SIGTERM)

		for next := initial; ; next++ {
			select {
			case <-c:
				break
			case s.gameIdChan <- game.Id(next):
				s.log.Debug("Incremented next game ID")
			}
		}
	}(nextGameId)
}