Skip to content

Commit

Permalink
Merge pull request #107 from KazeNoYumeX/feature/add-transmit-intelli…
Browse files Browse the repository at this point in the history
…gence-card

Feat: Added api for transmit intelligence card by #95
  • Loading branch information
linycken013127 committed Jan 22, 2024
2 parents 5c586f3 + 6416fdb commit 146454e
Show file tree
Hide file tree
Showing 9 changed files with 476 additions and 69 deletions.
20 changes: 20 additions & 0 deletions Backend/enums/intelligence_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package enums

const (
SecretTelegram = 1
DIRECT = 2
DOCUMENT = 3
)

func ToString(secretTelegramType int) string {
switch secretTelegramType {
case SecretTelegram:
return "密電"
case DIRECT:
return "直達"
case DOCUMENT:
return "文件"
default:
return ""
}
}
60 changes: 57 additions & 3 deletions Backend/service/delivery/http/v1/player_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package http

import (
"fmt"
"github.com/Game-as-a-Service/The-Message/enums"
"github.com/Game-as-a-Service/The-Message/service/request"
"net/http"
"strconv"

"github.com/Game-as-a-Service/The-Message/service/service"
"github.com/gin-gonic/gin"
"net/http"
"strconv"
)

type PlayerHandler struct {
Expand All @@ -31,6 +31,7 @@ func RegisterPlayerHandler(opts *PlayerHandlerOptions) {
}

opts.Engine.POST("/api/v1/players/:playerId/player-cards", handler.PlayCard)
opts.Engine.POST("/api/v1/player/:playerId/transmit-intelligence", handler.TransmitIntelligence)
}

// PlayCard godoc
Expand Down Expand Up @@ -70,3 +71,56 @@ func (p *PlayerHandler) PlayCard(c *gin.Context) {
"result": true,
})
}

// TransmitIntelligence godoc
// @Summary Transmit intelligence
// @Description Transmit an intelligence card
// @Tags players
// @Accept json
// @Produce json
// @Param playerId path int true "Player ID"
// @Param card_id body request.PlayCardRequest true "Card ID"
// @Param intelligence_type body request.PlayCardRequest true "Intelligence Type"
// @Success 200 {object} request.PlayCardResponse
// @Router /api/v1/player/{playerId}/transmit-intelligence [post]
func (p *PlayerHandler) TransmitIntelligence(c *gin.Context) {
playerId, _ := strconv.Atoi(c.Param("playerId"))
var req request.PlayCardRequest

if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"message": err.Error()})
return
}

intelligenceType := enums.ToString(req.IntelligenceType)

if intelligenceType == "" {
c.JSON(http.StatusBadRequest, gin.H{"message": "Invalid intelligence type"})
return
}

player, err := p.playerService.GetPlayerById(c, playerId)

if err != nil || player == nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": "Player not found"})
return
}

// Check card_id exists in player_cards
exist, err := p.playerService.CheckPlayerCardExist(c, playerId, player.GameId, req.CardID)
if err != nil || !exist {
c.JSON(http.StatusInternalServerError, gin.H{"message": "Card not found"})
return
}

ret, err := p.playerService.TransmitIntelligenceCard(c, playerId, player.GameId, req.CardID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
return
}

c.JSON(http.StatusOK, gin.H{
"result": ret,
"message": enums.ToString(req.IntelligenceType) + " intelligence transmitted",
})
}
59 changes: 41 additions & 18 deletions Backend/service/repository/mysql/player_card_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package mysql

import (
"context"

"errors"
"github.com/Game-as-a-Service/The-Message/service/repository"
"gorm.io/gorm"
)
Expand All @@ -17,10 +17,8 @@ func NewPlayerCardRepository(db *gorm.DB) *PlayerCardRepository {
}
}

func (p PlayerCardRepository) GetPlayerCardById(ctx context.Context, id int) (*repository.PlayerCard, error) {
card := new(repository.PlayerCard)

result := p.db.First(&card, "id = ?", id)
func (p PlayerCardRepository) CreatePlayerCard(ctx context.Context, card *repository.PlayerCard) (*repository.PlayerCard, error) {
result := p.db.Create(&card)

if result.Error != nil {
return nil, result.Error
Expand All @@ -29,38 +27,51 @@ func (p PlayerCardRepository) GetPlayerCardById(ctx context.Context, id int) (*r
return card, nil
}

func (p PlayerCardRepository) GetPlayerCardsByGameId(ctx context.Context, id int) ([]*repository.PlayerCard, error) {
var cards []*repository.PlayerCard
func (p PlayerCardRepository) DeletePlayerCard(ctx context.Context, id int) error {
card := new(repository.PlayerCard)

result := p.db.Find(&cards, "game_id = ?", id)
result := p.db.Delete(&card, "id = ?", id)

if result.Error != nil {
return nil, result.Error
return result.Error
}

return cards, nil
return nil
}

func (p PlayerCardRepository) CreatePlayerCard(ctx context.Context, card *repository.PlayerCard) (*repository.PlayerCard, error) {
result := p.db.Create(&card)
func (p PlayerCardRepository) DeletePlayerCardByPlayerIdAndCardId(ctx context.Context, playerId int, gameId int, cardId int) (bool, error) {
card := new(repository.PlayerCard)

result := p.db.Delete(&card, "player_id = ? AND game_id = ? AND card_id = ?", playerId, gameId, cardId)
if result.Error != nil {
return nil, result.Error
return false, result.Error
}

return card, nil
return true, nil
}

func (p PlayerCardRepository) DeletePlayerCard(ctx context.Context, id int) error {
func (p *PlayerCardRepository) ExistPlayerCardByPlayerIdAndCardId(ctx context.Context, playerId int, gameId int, cardId int) (bool, error) {
var card repository.PlayerCard
result := p.db.First(&card, "player_id = ? AND game_id = ? AND card_id = ?", playerId, gameId, cardId)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return false, nil
}
return false, result.Error
}
return true, nil
}

func (p PlayerCardRepository) GetPlayerCardById(ctx context.Context, id int) (*repository.PlayerCard, error) {
card := new(repository.PlayerCard)

result := p.db.Delete(&card, "id = ?", id)
result := p.db.First(&card, "id = ?", id)

if result.Error != nil {
return result.Error
return nil, result.Error
}

return nil
return card, nil
}

func (p *PlayerCardRepository) GetPlayerCards(ctx context.Context, playerCard *repository.PlayerCard) (*[]repository.PlayerCard, error) {
Expand All @@ -72,3 +83,15 @@ func (p *PlayerCardRepository) GetPlayerCards(ctx context.Context, playerCard *r

return playerCards, nil
}

func (p PlayerCardRepository) GetPlayerCardsByGameId(ctx context.Context, id int) ([]*repository.PlayerCard, error) {
var cards []*repository.PlayerCard

result := p.db.Find(&cards, "game_id = ?", id)

if result.Error != nil {
return nil, result.Error
}

return cards, nil
}
5 changes: 3 additions & 2 deletions Backend/service/repository/player_card_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ package repository

import (
"context"
"time"

"gorm.io/gorm"
"time"
)

type PlayerCard struct {
Expand All @@ -26,5 +25,7 @@ type PlayerCardRepository interface {
GetPlayerCardsByGameId(ctx context.Context, id int) ([]*PlayerCard, error)
CreatePlayerCard(ctx context.Context, card *PlayerCard) (*PlayerCard, error)
DeletePlayerCard(ctx context.Context, id int) error
DeletePlayerCardByPlayerIdAndCardId(ctx context.Context, playerId int, gameId int, cardId int) (bool, error)
ExistPlayerCardByPlayerIdAndCardId(ctx context.Context, playerId int, gameId int, cardId int) (bool, error)
GetPlayerCards(ctx context.Context, playerCard *PlayerCard) (*[]PlayerCard, error)
}
3 changes: 2 additions & 1 deletion Backend/service/request/game_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ type PlayCardResponse struct {
}

type PlayCardRequest struct {
CardID int `json:"card_id"`
CardID int `json:"card_id"`
IntelligenceType int `json:"intelligence_type"`
}
2 changes: 1 addition & 1 deletion Backend/service/service/game_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func (g *GameService) NextPlayer(c *gin.Context, player *repository.Player) (*re
return player.Game, nil
}

func (g *GameService) UpdateStatus(c *gin.Context, game *repository.Game, stage string) {
func (g *GameService) UpdateStatus(c context.Context, game *repository.Game, stage string) {
game.Status = stage
err := g.GameRepo.UpdateGame(c, game)
if err != nil {
Expand Down
90 changes: 69 additions & 21 deletions Backend/service/service/player_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,32 @@ func (p *PlayerService) ShuffleIdentityCards(cards []string) []string {
return shuffledCards
}

func (p *PlayerService) CanPlayCard(c context.Context, player *repository.Player) (bool, error) {
if player.Game.Status == enums.GameEnd {
return false, errors.New("遊戲已結束")
}

if player.Status == enums.PlayerStatusDead {
return false, errors.New("你已死亡")
}

if player.Game.CurrentPlayerId != player.Id {
return false, errors.New("尚未輪到你出牌")
}

return true, nil
}

func (p *PlayerService) CheckPlayerCardExist(c context.Context, playerId int, gameId int, cardId int) (bool, error) {
exist, err := p.PlayerCardRepo.ExistPlayerCardByPlayerIdAndCardId(c, playerId, gameId, cardId)

if err != nil {
return false, err
}

return exist, nil
}

func (p *PlayerService) CreatePlayer(c context.Context, player *repository.Player) (*repository.Player, error) {
player, err := p.PlayerRepo.CreatePlayer(c, player)
if err != nil {
Expand All @@ -78,6 +104,22 @@ func (p *PlayerService) CreatePlayer(c context.Context, player *repository.Playe
return player, nil
}

func (p *PlayerService) CreatePlayerCard(c context.Context, card *repository.PlayerCard) error {
_, err := p.PlayerCardRepo.CreatePlayerCard(c, card)
if err != nil {
return err
}
return nil
}

func (p *PlayerService) GetPlayerById(c context.Context, id int) (*repository.Player, error) {
player, err := p.PlayerRepo.GetPlayer(c, id)
if err != nil {
return nil, err
}
return player, nil
}

func (p *PlayerService) GetPlayersByGameId(c context.Context, id int) ([]*repository.Player, error) {
players, err := p.PlayerRepo.GetPlayersByGameId(c, id)
if err != nil {
Expand All @@ -86,12 +128,13 @@ func (p *PlayerService) GetPlayersByGameId(c context.Context, id int) ([]*reposi
return players, nil
}

func (p *PlayerService) CreatePlayerCard(c context.Context, card *repository.PlayerCard) error {
_, err := p.PlayerCardRepo.CreatePlayerCard(c, card)
if err != nil {
return err
func (p *PlayerService) GetHandCardId(player *repository.Player, cardId int) (*repository.PlayerCard, error) {
for _, card := range player.PlayerCards {
if card.CardId == cardId && card.Type == "hand" {
return &card, nil
}
}
return nil
return nil, errors.New("找不到手牌")
}

func (p *PlayerService) PlayCard(c *gin.Context, playerId int, cardId int) (*repository.Game, *repository.Card, error) {
Expand All @@ -100,7 +143,7 @@ func (p *PlayerService) PlayCard(c *gin.Context, playerId int, cardId int) (*rep
return nil, nil, err
}

result, err := p.CanPlayCard(c, player, cardId)
result, err := p.CanPlayCard(c, player)
if !result || err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -128,27 +171,32 @@ func (p *PlayerService) PlayCard(c *gin.Context, playerId int, cardId int) (*rep
return game, &handCard.Card, nil
}

func (p *PlayerService) CanPlayCard(c *gin.Context, player *repository.Player, cardId int) (bool, error) {
if player.Game.Status == enums.GameEnd {
return false, errors.New("遊戲已結束")
func (p *PlayerService) TransmitIntelligenceCard(c *gin.Context, playerId int, gameId int, cardId int) (bool, error) {
player, err := p.PlayerRepo.GetPlayerWithGamePlayersAndPlayerCardsCard(c, playerId)
if err != nil {
return false, err
}

if player.Status == enums.PlayerStatusDead {
return false, errors.New("你已死亡")
result, err := p.CanPlayCard(c, player)
if !result || err != nil {
return false, err
}

if player.Game.CurrentPlayerId != player.Id {
return false, errors.New("尚未輪到你出牌")
game, err := p.GameServ.NextPlayer(c, player)
if err != nil {
return false, err
}

return true, nil
}
ret, err := p.PlayerCardRepo.DeletePlayerCardByPlayerIdAndCardId(c, playerId, gameId, cardId)

func (p *PlayerService) GetHandCardId(player *repository.Player, cardId int) (*repository.PlayerCard, error) {
for _, card := range player.PlayerCards {
if card.CardId == cardId && card.Type == "hand" {
return &card, nil
}
if err != nil {
return false, err
}
return nil, errors.New("找不到手牌")

err = p.GameRepo.UpdateGame(c, game)
if err != nil {
return false, err
}

return ret, nil
}
Loading

0 comments on commit 146454e

Please sign in to comment.