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 }