Skip to content

Commit

Permalink
move tests, fix join solver
Browse files Browse the repository at this point in the history
  • Loading branch information
deanveloper committed Sep 12, 2021
1 parent 6818279 commit 7b06b8d
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 261 deletions.
8 changes: 8 additions & 0 deletions solve/test/crown_test.go → solve/crown_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@ package solve_test

import (
"testing"

"github.com/deanveloper/gridspech-go/solve"
)

func testSolveCrownsAbstract(t *testing.T, level string, expectedSolutionsStrings []string, maxColors int) {
t.Helper()

testSolveAbstract(t, level, expectedSolutionsStrings, maxColors, solve.GridSolver.SolveCrowns)
}

func TestSolveCrowns_basic1(t *testing.T) {
const lvl = `
0 0 0k
Expand Down
15 changes: 1 addition & 14 deletions solve/test/dot_test.go → solve/dot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,7 @@ import (
func testSolveDotsAbstract(t *testing.T, level string, maxColors int, expectedSolutionStrings []string) {
t.Helper()

solver := solve.NewGridSolver(gs.MakeGridFromString(level, 2))

var expectedSolutions []gs.TileSet
var actualSolutions []gs.TileSet

for _, solutionString := range expectedSolutionStrings {
expectedSolutions = append(expectedSolutions, tileSetFromString(solver.Grid, solutionString))
}

for solution := range solver.SolveDots() {
actualSolutions = append(actualSolutions, solution)
}

testUnorderedTilesetSliceEq(t, expectedSolutions, actualSolutions)
testSolveAbstract(t, level, expectedSolutionStrings, maxColors, solve.GridSolver.SolveDots)
}

func TestDots_levelBasic1(t *testing.T) {
Expand Down
File renamed without changes.
66 changes: 0 additions & 66 deletions solve/goals.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,72 +71,6 @@ func (g GridSolver) solveGoals(ch chan<- gs.TileSet) {
}
}

func mergeSolutionsSlices(sols1, sols2 []gs.TileSet) []gs.TileSet {
var result []gs.TileSet
for _, sol1 := range sols1 {
nextSolution:
for _, sol2 := range sols2 {

// do not merge if they have any tiles with unmatched colors
for _, t1 := range sol1.Slice() {
for _, t2 := range sol2.Slice() {
if t1.Coord == t2.Coord && t1.Data.Color != t2.Data.Color {
continue nextSolution
}
}
}

var merged gs.TileSet
merged.Merge(sol1)
merged.Merge(sol2)
result = append(result, merged)
}
}
return result
}

func removeIfInvalid(g GridSolver, tilesToValidate []gs.TileCoord, in []gs.TileSet) []gs.TileSet {
var validSolutions []gs.TileSet

base := g.Grid
for _, solution := range in {
newBase := base.Clone()
newBase.ApplyTileSet(solution)

allValid := true
for _, coord := range tilesToValidate {
if !newBase.ValidTile(coord) {
allValid = false
break
}
}
if allValid {
validSolutions = append(validSolutions, solution)
}
}

return validSolutions
}

func removeIfNonUnique(in []gs.TileSet) []gs.TileSet {
var filtered []gs.TileSet

for _, solution := range in {
unique := true
for _, seen := range filtered {
if solution.Eq(seen) {
unique = false
break
}
}
if unique {
filtered = append(filtered, solution)
}
}

return filtered
}

func allTilePairingSets(tiles []gs.TileCoord) [][][2]gs.TileCoord {

pairingSets := AllPairingSets(len(tiles))
Expand Down
87 changes: 87 additions & 0 deletions solve/helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package solve_test

import (
"strings"
"testing"

gs "github.com/deanveloper/gridspech-go"
"github.com/deanveloper/gridspech-go/solve"
)

func testSolveAbstract(t *testing.T, level string, expectedSolutionsStrings []string, maxColors int, f func(solve.GridSolver) <-chan gs.TileSet) {
t.Helper()

solver := solve.NewGridSolver(gs.MakeGridFromString(level, maxColors))

var expectedSolutions []gs.TileSet
var actualSolutions []gs.TileSet

for _, solutionString := range expectedSolutionsStrings {
expectedSolutions = append(expectedSolutions, tileSetFromString(solver.Grid, solutionString))
}

solutionsCh := f(solver)
for solution := range solutionsCh {
actualSolutions = append(actualSolutions, solution)
}

testUnorderedTilesetSliceEq(t, expectedSolutions, actualSolutions)
}

func tileSetFromString(grid gs.Grid, str string) gs.TileSet {
lines := strings.Split(strings.Trim(str, "{}"), "|")
var ts gs.TileSet
for i, line := range lines {
y := len(lines) - i - 1
x := -1
for {
index := strings.IndexAny(line[x+1:], "012345")
if index < 0 {
break
}
x = x + 1 + index
tileWithColor := *grid.TileAt(x, y)
tileWithColor.Data.Color = gs.TileColor(line[x] - '0')
ts.Add(tileWithColor)
}
}
return ts
}

func commaSeparatedSlice(slice []gs.TileSet) string {
var asStr []string
for _, v := range slice {
asStr = append(asStr, v.String())
}
return strings.Join(asStr, ",")
}

func testUnorderedTilesetSliceEq(t *testing.T, expected, actual []gs.TileSet) {
t.Helper()

for i1 := range expected {
var found bool
for i2 := range actual {
if expected[i1].Eq(actual[i2]) {
found = true
break
}
}
if !found {
t.Errorf("expected to find tileset %v", expected[i1])
}
}

for i1 := range actual {
var found bool
for i2 := range expected {
if actual[i1].Eq(expected[i2]) {
found = true
break
}
}
if !found {
t.Errorf("incorrect solution %v", actual[i1])
}
}
}
10 changes: 7 additions & 3 deletions solve/join.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package solve

import gs "github.com/deanveloper/gridspech-go"
import (
gs "github.com/deanveloper/gridspech-go"
)

// SolveJoins returns a channel of solutions for all of the Join tiles.
func (g GridSolver) SolveJoins() <-chan gs.TileSet {
Expand All @@ -10,7 +12,7 @@ func (g GridSolver) SolveJoins() <-chan gs.TileSet {

tilesToSolutions := make([]<-chan gs.TileSet, len(joinTiles))
for i, tile := range joinTiles {
tilesToSolutions[i] = g.SolveCrown(tile.Coord)
tilesToSolutions[i] = g.SolveJoin(tile)
}

// now merge them all together
Expand All @@ -19,14 +21,16 @@ func (g GridSolver) SolveJoins() <-chan gs.TileSet {
tilesToSolutions[i] = mergedIter
}

return nil
return tilesToSolutions[len(tilesToSolutions)-1]
}

// SolveJoin returns a channel of solutions for an individual join tile.
func (g GridSolver) SolveJoin(join gs.Tile) <-chan gs.TileSet {
joinIter := make(chan gs.TileSet)

go func() {
defer close(joinIter)

var joinNum int
switch join.Data.Type {
case gs.TypeJoin1:
Expand Down
26 changes: 26 additions & 0 deletions solve/join_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package solve_test

import (
"testing"

"github.com/deanveloper/gridspech-go/solve"
)

func testSolveJoinsAbstract(t *testing.T, level string, expectedSolutionsStrings []string, maxColors int) {
t.Helper()

testSolveAbstract(t, level, expectedSolutionsStrings, maxColors, solve.GridSolver.SolveJoins)
}

func TestSolveJoins_basic(t *testing.T) {
const level = `
0j1 0 0 0j1
`
solutions := []string{
"0000",
"1111",
"2222",
}

testSolveJoinsAbstract(t, level, solutions, 3)
}
64 changes: 0 additions & 64 deletions solve/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,67 +88,3 @@ func (g GridSolver) dfsDirectPaths(color gs.TileColor, prev, end gs.Tile, path g
g.dfsDirectPaths(color, next, end, nextPath, ch)
}
}

func decorateSetBorder(g GridSolver, shapeColor gs.TileColor, tileSet gs.TileSet) <-chan gs.TileSet {
iter := make(chan gs.TileSet)
go func() {
defer close(iter)

var unknownNeighbors []gs.Tile
for tile := range tileSet.Iter() {
neighboringUnknowns := g.Grid.NeighborSetWith(tile.Coord, func(o gs.Tile) bool {
return g.UnknownTiles.Has(o.Coord) &&
!tileSet.ToTileCoordSet().Has(o.Coord)
})
unknownNeighbors = append(unknownNeighbors, neighboringUnknowns.Slice()...)
}

for permutation := range Permutation(g.Grid.MaxColors-1, len(unknownNeighbors)) {
var setWithDecoration gs.TileSet
setWithDecoration.Merge(tileSet)
for i, unknown := range unknownNeighbors {
color := permutation[i]
if color >= int(shapeColor) {
color++
}
unknown.Data.Color = gs.TileColor(color)
setWithDecoration.Add(unknown)
}
iter <- setWithDecoration
}
}()
return iter
}

func decorateSetIterBorders(g GridSolver, shapeColor gs.TileColor, tileSets <-chan gs.TileSet) <-chan gs.TileSet {
iter := make(chan gs.TileSet)
go func() {
defer close(iter)
for tileSet := range tileSets {

var unknownNeighbors []gs.Tile
for tile := range tileSet.Iter() {
neighboringUnknowns := g.Grid.NeighborSetWith(tile.Coord, func(o gs.Tile) bool {
return g.UnknownTiles.Has(o.Coord) &&
!tileSet.ToTileCoordSet().Has(o.Coord)
})
unknownNeighbors = append(unknownNeighbors, neighboringUnknowns.Slice()...)
}

for permutation := range Permutation(g.Grid.MaxColors-1, len(unknownNeighbors)) {
var setWithDecoration gs.TileSet
setWithDecoration.Merge(tileSet)
for i, unknown := range unknownNeighbors {
color := permutation[i]
if color >= int(shapeColor) {
color++
}
unknown.Data.Color = gs.TileColor(color)
setWithDecoration.Add(unknown)
}
iter <- setWithDecoration
}
}
}()
return iter
}
Loading

0 comments on commit 7b06b8d

Please sign in to comment.