171 lines
4.6 KiB
Go
171 lines
4.6 KiB
Go
package api
|
||
|
||
import (
|
||
"errors"
|
||
"github.com/kataras/iris/v12"
|
||
"github.com/sirupsen/logrus"
|
||
"main/database"
|
||
"main/model"
|
||
"main/utils"
|
||
"strings"
|
||
)
|
||
|
||
func getSudokuList(ctx iris.Context) {
|
||
var resSudokuList resSudokuListType
|
||
var startingSudokuList []sudokuListType
|
||
var newSudokuList []model.Sudoku
|
||
db := database.GetInstance().GetMysqlDb()
|
||
if err := db.Where("id not in (?)", db.Table("sudoku_statuses").Distinct("sudoku_id").Where("username = ? and deleted_at is null", "admin")).Find(&newSudokuList).Error; err != nil {
|
||
logrus.Errorln("sql执行失败:", err)
|
||
}
|
||
for _, v := range newSudokuList {
|
||
resSudokuList.New = append(resSudokuList.New, sudokuListType{Sudoku: v.Sudoku, SudokuId: v.ID, Complete: false})
|
||
}
|
||
queryId := db.Table("sudoku_statuses").Select("max(id)").Where("username = ? and deleted_at is null", "admin").Group("sudoku_id")
|
||
if queryId.Error != nil {
|
||
logrus.Errorln("sql执行失败:", queryId.Error)
|
||
}
|
||
queryStatus := db.Table("sudoku_statuses").Where("id in (?)", queryId)
|
||
if queryStatus.Error != nil {
|
||
logrus.Errorln("sql执行失败:", queryStatus.Error)
|
||
}
|
||
if err := db.Model(&model.Sudoku{}).Select("sudokus.sudoku, q.*").Joins("left join (?) q on sudokus.id = q.sudoku_id", queryStatus).Scan(&startingSudokuList).Error; err != nil {
|
||
logrus.Errorln("sql执行失败:", err)
|
||
}
|
||
for _, v := range startingSudokuList {
|
||
if v.Complete {
|
||
resSudokuList.Complete = append(resSudokuList.Complete, v)
|
||
} else {
|
||
resSudokuList.Starting = append(resSudokuList.Starting, v)
|
||
}
|
||
}
|
||
err := ctx.JSON(utils.FormatRes(iris.StatusOK, "", resSudokuList))
|
||
if utils.ErrHandle(ctx, err) {
|
||
return
|
||
}
|
||
}
|
||
|
||
func addSudokuGame(ctx iris.Context) {
|
||
var sudokuParam addSudokuParam
|
||
var dbCheck model.Sudoku
|
||
var sudokuResult [9][9]string
|
||
err := ctx.ReadJSON(&sudokuParam)
|
||
if utils.ErrHandle(ctx, err) {
|
||
return
|
||
}
|
||
if sudokuParam.Result != "" {
|
||
sudokuResult, err = sudokuStringToList(sudokuParam.Result)
|
||
if utils.ErrHandle(ctx, err) {
|
||
return
|
||
}
|
||
}
|
||
db := database.GetInstance().GetMysqlDb()
|
||
if err1 := db.Where("sudoku = ?", sudokuParam.Sudoku).First(&dbCheck).Error; err1 != nil {
|
||
logrus.Errorln("sql执行失败:", err1)
|
||
}
|
||
if !utils.DataIsNil(dbCheck) {
|
||
utils.ErrHandle(ctx, errors.New("棋盘已存在"))
|
||
return
|
||
}
|
||
err, r := utils.CheckSudoku(sudokuParam.Sudoku)
|
||
if utils.ErrHandle(ctx, err) {
|
||
return
|
||
}
|
||
if r.Data.Check || checkSudokuCompleted(sudokuResult) {
|
||
if r.Data.Check {
|
||
if err1 := db.Create(&model.Sudoku{Sudoku: sudokuParam.Sudoku, Username: "admin", Result: r.Data.Result}).Error; err1 != nil {
|
||
logrus.Errorln("sql执行失败:", err1)
|
||
}
|
||
} else {
|
||
if err1 := db.Create(&model.Sudoku{Sudoku: sudokuParam.Sudoku, Username: "admin", Result: sudokuParam.Result}).Error; err1 != nil {
|
||
logrus.Errorln("sql执行失败:", err1)
|
||
}
|
||
}
|
||
err = ctx.JSON(utils.FormatRes(iris.StatusOK, "", "success"))
|
||
if utils.ErrHandle(ctx, err) {
|
||
return
|
||
}
|
||
} else {
|
||
utils.ErrHandle(ctx, errors.New("检测题目无法完成,请上传解题结果"))
|
||
return
|
||
}
|
||
}
|
||
|
||
func sudokuStringToList(sudoku string) ([9][9]string, error) {
|
||
var res [9][9]string
|
||
sudokuRows := strings.Split(sudoku, ";")
|
||
if len(sudokuRows) != 9 {
|
||
return res, errors.New("棋盘格式错误")
|
||
}
|
||
for r, row := range sudokuRows {
|
||
sudokuCols := strings.Split(row, ",")
|
||
if len(sudokuCols) != 9 {
|
||
return res, errors.New("棋盘格式错误")
|
||
}
|
||
for c, col := range sudokuCols {
|
||
if len(col) > 1 || strings.Index("123456789", col) == -1 {
|
||
return res, errors.New("棋盘格式错误")
|
||
}
|
||
res[r][c] = col
|
||
}
|
||
}
|
||
return res, nil
|
||
}
|
||
|
||
func sudokuListToString(sudoku [9][9]string) string {
|
||
var res string
|
||
for r, _ := range sudoku {
|
||
var tmp string
|
||
for c, _ := range sudoku[r] {
|
||
if tmp == "" {
|
||
tmp = sudoku[r][c]
|
||
} else {
|
||
tmp += "," + sudoku[r][c]
|
||
}
|
||
}
|
||
if res == "" {
|
||
res = tmp
|
||
} else {
|
||
res += ";" + tmp
|
||
}
|
||
}
|
||
return res
|
||
}
|
||
|
||
// 检查题目是否已完成
|
||
func checkSudokuCompleted(sudoku [9][9]string) bool {
|
||
for r, _ := range sudoku {
|
||
for c, _ := range sudoku[r] {
|
||
if sudoku[r][c] == "" || !checkNum(r, c, sudoku) {
|
||
return false
|
||
}
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
// 检查题目当前位置是否符合要求
|
||
func checkNum(r int, c int, sudoku [9][9]string) bool {
|
||
if sudoku[r][c] == "" {
|
||
return true
|
||
}
|
||
for i, n := range sudoku[r] {
|
||
if n == sudoku[r][c] && i != c {
|
||
return false
|
||
}
|
||
}
|
||
for i, _ := range sudoku {
|
||
if sudoku[i][c] == sudoku[r][c] && i != r {
|
||
return false
|
||
}
|
||
}
|
||
for row := (r % 3) * 3; row < (r%3)*3+2; row++ {
|
||
for col := (c % 3) * 3; col < (c%3)*3+2; col++ {
|
||
if sudoku[row][col] == sudoku[r][c] && row != r && col != c {
|
||
return false
|
||
}
|
||
}
|
||
}
|
||
return true
|
||
}
|