172 lines
4.4 KiB
Go
172 lines
4.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"time"
|
|
)
|
|
|
|
var F = [][]int{
|
|
{1, -1, 1, 0, 1, 1, 2, 1}, {0, 1, 1, -1, 1, 0, 2, 0},
|
|
{1, 0, 1, 1, 1, 2, 2, 1}, {1, 0, 1, 1, 2, -1, 2, 0},
|
|
{1, -2, 1, -1, 1, 0, 2, -1}, {0, 1, 1, 1, 1, 2, 2, 1},
|
|
{1, -1, 1, 0, 1, 1, 2, -1}, {1, -1, 1, 0, 2, 0, 2, 1},
|
|
}
|
|
|
|
var I = [][]int{{0, 1, 0, 2, 0, 3, 0, 4}, {1, 0, 2, 0, 3, 0, 4, 0}}
|
|
|
|
var L = [][]int{
|
|
{1, 0, 1, 1, 1, 2, 1, 3}, {1, 0, 2, 0, 3, -1, 3, 0},
|
|
{0, 1, 0, 2, 0, 3, 1, 3}, {0, 1, 1, 0, 2, 0, 3, 0}, {0, 1, 1, 1, 2, 1, 3, 1},
|
|
{0, 1, 0, 2, 0, 3, 1, 0}, {1, 0, 2, 0, 3, 0, 3, 1}, {1, -3, 1, -2, 1, -1, 1, 0},
|
|
}
|
|
|
|
var N = [][]int{
|
|
{0, 1, 1, -2, 1, -1, 1, 0}, {1, 0, 1, 1, 2, 1, 3, 1},
|
|
{0, 1, 0, 2, 1, -1, 1, 0}, {1, 0, 2, 0, 2, 1, 3, 1}, {0, 1, 1, 1, 1, 2, 1, 3},
|
|
{1, 0, 2, -1, 2, 0, 3, -1}, {0, 1, 0, 2, 1, 2, 1, 3}, {1, -1, 1, 0, 2, -1, 3, -1},
|
|
}
|
|
|
|
var P = [][]int{
|
|
{0, 1, 1, 0, 1, 1, 2, 1}, {0, 1, 0, 2, 1, 0, 1, 1},
|
|
{1, 0, 1, 1, 2, 0, 2, 1}, {0, 1, 1, -1, 1, 0, 1, 1}, {0, 1, 1, 0, 1, 1, 1, 2},
|
|
{1, -1, 1, 0, 2, -1, 2, 0}, {0, 1, 0, 2, 1, 1, 1, 2}, {0, 1, 1, 0, 1, 1, 2, 0},
|
|
}
|
|
|
|
var T = [][]int{
|
|
{0, 1, 0, 2, 1, 1, 2, 1}, {1, -2, 1, -1, 1, 0, 2, 0},
|
|
{1, 0, 2, -1, 2, 0, 2, 1}, {1, 0, 1, 1, 1, 2, 2, 0},
|
|
}
|
|
|
|
var U = [][]int{
|
|
{0, 1, 0, 2, 1, 0, 1, 2}, {0, 1, 1, 1, 2, 0, 2, 1},
|
|
{0, 2, 1, 0, 1, 1, 1, 2}, {0, 1, 1, 0, 2, 0, 2, 1},
|
|
}
|
|
|
|
var V = [][]int{
|
|
{1, 0, 2, 0, 2, 1, 2, 2}, {0, 1, 0, 2, 1, 0, 2, 0},
|
|
{1, 0, 2, -2, 2, -1, 2, 0}, {0, 1, 0, 2, 1, 2, 2, 2},
|
|
}
|
|
|
|
var W = [][]int{
|
|
{1, 0, 1, 1, 2, 1, 2, 2}, {1, -1, 1, 0, 2, -2, 2, -1},
|
|
{0, 1, 1, 1, 1, 2, 2, 2}, {0, 1, 1, -1, 1, 0, 2, -1},
|
|
}
|
|
|
|
var X = [][]int{{1, -1, 1, 0, 1, 1, 2, 0}}
|
|
|
|
var Y = [][]int{
|
|
{1, -2, 1, -1, 1, 0, 1, 1}, {1, -1, 1, 0, 2, 0, 3, 0},
|
|
{0, 1, 0, 2, 0, 3, 1, 1}, {1, 0, 2, 0, 2, 1, 3, 0}, {0, 1, 0, 2, 0, 3, 1, 2},
|
|
{1, 0, 1, 1, 2, 0, 3, 0}, {1, -1, 1, 0, 1, 1, 1, 2}, {1, 0, 2, -1, 2, 0, 3, 0},
|
|
}
|
|
|
|
var Z = [][]int{
|
|
{0, 1, 1, 0, 2, -1, 2, 0}, {1, 0, 1, 1, 1, 2, 2, 2},
|
|
{0, 1, 1, 1, 2, 1, 2, 2}, {1, -2, 1, -1, 1, 0, 2, -2},
|
|
}
|
|
|
|
var shapes = [][][]int{F, I, L, N, P, T, U, V, W, X, Y, Z}
|
|
|
|
var symbols = []byte("FILNPTUVWXYZ-")
|
|
|
|
const (
|
|
nRows = 8
|
|
nCols = 8
|
|
blank = 12
|
|
)
|
|
|
|
var grid [nRows][nCols]int
|
|
var placed [12]bool
|
|
|
|
func tryPlaceOrientation(o []int, r, c, shapeIndex int) bool {
|
|
for i := 0; i < len(o); i += 2 {
|
|
x := c + o[i+1]
|
|
y := r + o[i]
|
|
if x < 0 || x >= nCols || y < 0 || y >= nRows || grid[y][x] != -1 {
|
|
return false
|
|
}
|
|
}
|
|
grid[r][c] = shapeIndex
|
|
for i := 0; i < len(o); i += 2 {
|
|
grid[r+o[i]][c+o[i+1]] = shapeIndex
|
|
}
|
|
return true
|
|
}
|
|
|
|
func removeOrientation(o []int, r, c int) {
|
|
grid[r][c] = -1
|
|
for i := 0; i < len(o); i += 2 {
|
|
grid[r+o[i]][c+o[i+1]] = -1
|
|
}
|
|
}
|
|
|
|
func solve(pos, numPlaced int) bool {
|
|
if numPlaced == len(shapes) {
|
|
return true
|
|
}
|
|
row := pos / nCols
|
|
col := pos % nCols
|
|
if grid[row][col] != -1 {
|
|
return solve(pos+1, numPlaced)
|
|
}
|
|
|
|
for i := range shapes {
|
|
if !placed[i] {
|
|
for _, orientation := range shapes[i] {
|
|
if !tryPlaceOrientation(orientation, row, col, i) {
|
|
continue
|
|
}
|
|
placed[i] = true
|
|
if solve(pos+1, numPlaced+1) {
|
|
return true
|
|
}
|
|
removeOrientation(orientation, row, col)
|
|
placed[i] = false
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func shuffleShapes() {
|
|
rand.Shuffle(len(shapes), func(i, j int) {
|
|
shapes[i], shapes[j] = shapes[j], shapes[i]
|
|
symbols[i], symbols[j] = symbols[j], symbols[i]
|
|
})
|
|
}
|
|
|
|
func printResult() {
|
|
for _, r := range grid {
|
|
for _, i := range r {
|
|
fmt.Printf("%c ", symbols[i])
|
|
}
|
|
fmt.Println()
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
rand.Seed(time.Now().UnixNano())
|
|
shuffleShapes()
|
|
for r := 0; r < nRows; r++ {
|
|
for i := range grid[r] {
|
|
grid[r][i] = -1
|
|
}
|
|
}
|
|
for i := 0; i < 4; i++ {
|
|
var randRow, randCol int
|
|
for {
|
|
randRow = rand.Intn(nRows)
|
|
randCol = rand.Intn(nCols)
|
|
if grid[randRow][randCol] != blank {
|
|
break
|
|
}
|
|
}
|
|
grid[randRow][randCol] = blank
|
|
}
|
|
if solve(0, 0) {
|
|
printResult()
|
|
} else {
|
|
fmt.Println("No solution")
|
|
}
|
|
}
|