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

171 lines
4.6 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"
"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
}