Files
web_ylsa/api_iris/service/api/backgammon.go
2025-07-11 16:54:11 +08:00

314 lines
8.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package api
import (
"errors"
"github.com/kataras/iris/v12"
"github.com/sirupsen/logrus"
"main/database"
"main/model"
"main/utils"
"strconv"
"strings"
)
// 初始化新棋盘
var cols = 15
func getRooms(ctx iris.Context) {
db := database.GetInstance().GetMysqlDb()
var rooms []typeRoomStatus
if err := db.Model(&model.BackgammonRoom{}).Distinct("room_id").Order("room_id").Scan(&rooms).Error; err != nil {
logrus.Errorln("sql执行失败", err)
}
for k, v := range rooms {
roomStatus, err := getRoomStatus(v.RoomId)
if utils.ErrHandle(ctx, err) {
return
}
rooms[k].Player = roomStatus.Player
}
err := ctx.JSON(utils.FormatRes(iris.StatusOK, "", rooms))
if utils.ErrHandle(ctx, err) {
return
}
}
// 删除房间
func delRoom(ctx iris.Context) {
username := utils.GetLoginUser(ctx)
if utils.DataIsNil(username) {
return
}
id, err := strconv.Atoi(ctx.Params().Get("id"))
if utils.ErrHandle(ctx, err) {
return
}
roomStatus, err := getRoomStatus(id)
if utils.ErrHandle(ctx, err) {
return
}
db := database.GetInstance().GetMysqlDb()
if roomStatus.Player == username.Username {
if err1 := db.Where("room_id = ?", id).Delete(&model.BackgammonRoom{}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
} else if strings.Split(roomStatus.Player, ",")[0] == username.Username {
if err1 := db.Create(&model.BackgammonRoom{
RoomId: roomStatus.RoomId,
Player: strings.Split(roomStatus.Player, ",")[1],
Winner: "",
Current: strings.Split(roomStatus.Player, ",")[1],
PawnStatus: initPawns(),
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
} else if strings.Split(roomStatus.Player, ",")[1] == username.Username {
if err1 := db.Create(&model.BackgammonRoom{
RoomId: roomStatus.RoomId,
Player: strings.Split(roomStatus.Player, ",")[0],
Winner: "",
Current: strings.Split(roomStatus.Player, ",")[0],
PawnStatus: initPawns(),
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
}
err = ctx.JSON(utils.FormatRes(iris.StatusOK, "", "success"))
if utils.ErrHandle(ctx, err) {
return
}
}
func initPawns() string {
var newPawns string
for i := 0; i < cols; i++ {
tmp := "0" + strings.Repeat(",0", cols-1)
if i == 0 {
newPawns = tmp
continue
}
newPawns += ";" + tmp
}
return newPawns
}
// 新建房间
func addRoom(ctx iris.Context) {
username := utils.GetLoginUser(ctx)
if utils.DataIsNil(username) {
return
}
var currentStatus model.BackgammonRoom
db := database.GetInstance().GetMysqlDb()
if err := db.Order("room_id desc").First(&currentStatus).Error; err != nil {
logrus.Errorln("sql执行失败", err)
}
newPawns := initPawns()
if err := db.Create(&model.BackgammonRoom{
RoomId: currentStatus.RoomId + 1,
Player: username.Username,
Current: username.Username,
Winner: "",
PawnStatus: newPawns,
}).Error; err != nil {
logrus.Errorln("sql执行失败", err)
}
err := ctx.JSON(utils.FormatRes(iris.StatusOK, "", currentStatus.RoomId+1))
if utils.ErrHandle(ctx, err) {
return
}
}
func joinRoom(ctx iris.Context) {
username := utils.GetLoginUser(ctx)
if utils.DataIsNil(username) {
return
}
id, err := strconv.Atoi(ctx.Params().Get("id"))
if utils.ErrHandle(ctx, err) {
return
}
roomStatus, err := getRoomStatus(id)
if utils.ErrHandle(ctx, err) {
return
}
if utils.CheckListItem(strings.Split(roomStatus.Player, ","), username.Username) {
ctx.StatusCode(iris.StatusBadRequest)
ctx.SetErr(errors.New("无法重复加入房间"))
return
}
if !utils.CheckListItem(strings.Split(roomStatus.Player, ","), username.Username) && len(strings.Split(roomStatus.Player, ",")) > 2 {
ctx.StatusCode(iris.StatusBadRequest)
ctx.SetErr(errors.New("房间人数已满"))
return
}
roomStatus.Player = roomStatus.Player + "," + username.Username
db := database.GetInstance().GetMysqlDb()
if err1 := db.Model(&model.BackgammonRoom{}).Where("id = ?", roomStatus.ID).Updates(&roomStatus).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
err = ctx.JSON(utils.FormatRes(iris.StatusOK, "", "success"))
if utils.ErrHandle(ctx, err) {
return
}
}
func getRoomStatus(roomId int) (model.BackgammonRoom, error) {
var status model.BackgammonRoom
db := database.GetInstance().GetMysqlDb()
if err := db.Where("room_id = ?", roomId).Order("id desc").First(&status).Error; err != nil {
logrus.Errorln("sql执行失败", err)
}
if utils.DataIsNil(status) {
return model.BackgammonRoom{}, errors.New("房间号不存在")
}
return status, nil
}
// 获取房间棋盘状态
func getStatus(ctx iris.Context) {
id, err := strconv.Atoi(ctx.Params().Get("id"))
if utils.ErrHandle(ctx, err) {
return
}
roomStatus, err := getRoomStatus(id)
if utils.ErrHandle(ctx, err) {
return
}
err = ctx.JSON(utils.FormatRes(iris.StatusOK, "", roomStatus))
if utils.ErrHandle(ctx, err) {
return
}
}
// 新增棋子
func addPawn(ctx iris.Context) {
username := utils.GetLoginUser(ctx)
if utils.DataIsNil(username) {
return
}
id, err := strconv.Atoi(ctx.Params().Get("id"))
if utils.ErrHandle(ctx, err) {
return
}
roomStatus, err := getRoomStatus(id)
if utils.ErrHandle(ctx, err) {
return
}
var tmpT string
if roomStatus.Winner != "" {
ctx.StatusCode(iris.StatusBadRequest)
ctx.SetErr(errors.New("对局已结束"))
return
}
if len(strings.Split(roomStatus.Player, ",")) != 2 {
ctx.StatusCode(iris.StatusBadRequest)
ctx.SetErr(errors.New("当前房间,玩家人数不足"))
return
}
if roomStatus.Current != username.Username {
ctx.StatusCode(iris.StatusBadRequest)
ctx.SetErr(errors.New("现在不是你的回合"))
return
}
if strings.Split(roomStatus.Player, ",")[0] == username.Username {
tmpT = "1"
} else if strings.Split(roomStatus.Player, ",")[1] == username.Username {
tmpT = "-1"
} else {
ctx.StatusCode(iris.StatusBadRequest)
ctx.SetErr(errors.New("非玩家,无法进行游戏"))
return
}
place := strings.Split(ctx.URLParam("place"), ",")
var newPawn []int
for _, i := range place {
tmp, _ := strconv.Atoi(i)
newPawn = append(newPawn, tmp)
}
var pawnStatus [][]string
for _, i := range strings.Split(roomStatus.PawnStatus, ";") {
var tmp []string
for _, j := range strings.Split(i, ",") {
tmp = append(tmp, j)
}
pawnStatus = append(pawnStatus, tmp)
}
if pawnStatus[newPawn[0]][newPawn[1]] != "0" {
ctx.StatusCode(iris.StatusBadRequest)
ctx.SetErr(errors.New("该位置已有棋子"))
return
}
winner := getWinner(pawnStatus, tmpT, [2]int{newPawn[0], newPawn[1]})
if winner {
roomStatus.Winner = username.Username
}
pawnStatus[newPawn[0]][newPawn[1]] = tmpT
var tmp []string
for _, i := range pawnStatus {
tmp = append(tmp, strings.Join(i, ","))
}
roomStatus.PawnStatus = strings.Join(tmp, ";")
roomStatus.Current = strings.Replace(strings.Replace(roomStatus.Player, username.Username, "", 1), ",", "", 1)
db := database.GetInstance().GetMysqlDb()
if err1 := db.Create(&model.BackgammonRoom{
RoomId: roomStatus.RoomId,
Player: roomStatus.Player,
Winner: roomStatus.Winner,
Current: roomStatus.Current,
PawnStatus: roomStatus.PawnStatus,
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
err = ctx.JSON(utils.FormatRes(iris.StatusOK, "", roomStatus))
if utils.ErrHandle(ctx, err) {
return
}
}
// 判断当前是否存在winner
func getWinner(pawns [][]string, t string, pawn [2]int) bool {
pawnAround := [8][2]int{{pawn[0] - 1, pawn[1] - 1}, {pawn[0], pawn[1] - 1}, {pawn[0] + 1, pawn[1] - 1}, {pawn[0] - 1, pawn[1]},
{pawn[0] + 1, pawn[1]}, {pawn[0] - 1, pawn[1] + 1}, {pawn[0], pawn[1] + 1}, {pawn[0] + 1, pawn[1] + 1}}
around := [8]int{0, 0, 0, 0, 0, 0, 0, 0}
for i, p := range pawnAround {
if p[0] >= 0 && p[1] >= 0 && p[0] < cols && p[1] < cols && pawns[p[0]][p[1]] == t {
current := [2]int{p[0], p[1]}
for j := 0; j < 3; j++ {
switch i {
case 0:
current[0]--
current[1]--
case 1:
current[1]--
case 2:
current[0]++
current[1]--
case 3:
current[0]--
case 4:
current[0]++
case 5:
current[0]--
current[1]++
case 6:
current[1]++
case 7:
current[0]++
current[1]++
}
//fmt.Println(current)
if current[0] < 0 || current[0] > cols-1 || current[1] < 0 || current[1] > cols-1 || pawns[current[0]][current[1]] != t {
around[i] = j + 1
break
}
around[i] = j + 2
}
}
}
if around[0]+around[7] >= 4 || around[1]+around[6] >= 4 || around[2]+around[5] >= 4 || around[3]+around[4] >= 4 {
return true
}
return false
}