clone

fifteen puzzle games for the terminal, with daily puzzles, weekly ladders and xp, built on bubble tea

feat/elo-difficulty
puzzletea / games / sudokurgb / analysis.go
analysis.go 2.2K
1package sudokurgb23type boardAnalysis struct {4 rowCounts [gridSize][valueCount + 1]int5 colCounts [gridSize][valueCount + 1]int6 rowOverQuota [gridSize][valueCount + 1]bool7 colOverQuota [gridSize][valueCount + 1]bool8 boxConflictCells [gridSize][gridSize]bool9}1011func analyzeGrid(g grid) boardAnalysis {12 var analysis boardAnalysis1314 for y := range gridSize {15 for x := range gridSize {16 value := g[y][x].v17 if value < 1 || value > valueCount {18 continue19 }20 analysis.rowCounts[y][value]++21 analysis.colCounts[x][value]++22 }23 }2425 for i := range gridSize {26 for value := 1; value <= valueCount; value++ {27 analysis.rowOverQuota[i][value] = analysis.rowCounts[i][value] > houseQuota28 analysis.colOverQuota[i][value] = analysis.colCounts[i][value] > houseQuota29 }30 }3132 for boxY := range 3 {33 for boxX := range 3 {34 markBoxConflicts(&analysis, g, boxX, boxY)35 }36 }3738 return analysis39}4041func markBoxConflicts(analysis *boardAnalysis, g grid, boxX, boxY int) {42 type pos struct {43 x int44 y int45 }4647 var seen [valueCount + 1][]pos48 for dy := range 3 {49 for dx := range 3 {50 x, y := boxX*3+dx, boxY*3+dy51 value := g[y][x].v52 if value < 1 || value > valueCount {53 continue54 }55 seen[value] = append(seen[value], pos{x: x, y: y})56 }57 }5859 for value := 1; value <= valueCount; value++ {60 if len(seen[value]) <= houseQuota {61 continue62 }63 for _, cell := range seen[value] {64 analysis.boxConflictCells[cell.y][cell.x] = true65 }66 }67}6869func (a boardAnalysis) hasConflicts() bool {70 for i := range gridSize {71 for value := 1; value <= valueCount; value++ {72 if a.rowOverQuota[i][value] || a.colOverQuota[i][value] {73 return true74 }75 }76 }7778 for y := range gridSize {79 for x := range gridSize {80 if a.boxConflictCells[y][x] {81 return true82 }83 }84 }8586 return false87}8889func (a boardAnalysis) rowCountsString(row int) string {90 return countTripletString(a.rowCounts[row])91}9293func (a boardAnalysis) colCountsString(col int) string {94 return countTripletString(a.colCounts[col])95}9697func countTripletString(counts [valueCount + 1]int) string {98 return digitString(counts[1]) + "/" + digitString(counts[2]) + "/" + digitString(counts[3])99}100101func digitString(v int) string {102 return string(rune('0' + v))103}