takuzu.go
author Mikael Berthe <mikael@lilotux.net>
Sun, 16 Oct 2016 11:52:01 +0200
changeset 9 4b3436c03726
parent 8 955d3add9426
child 10 8dc05ff5dbe2
permissions -rw-r--r--
Switch completely to the new validation "ErrorType" Stay backward-compatible with previous error messages.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
package takuzu
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     2
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
import (
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
	"bytes"
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     5
	"fmt"
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
	"math"
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
	"github.com/pkg/errors"
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    11
// Cell is a single cell of a Takuzu game board
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
type Cell struct {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
	Defined bool
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    14
	Value   int
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    16
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
// Takuzu is a Takuzu game board (Size x Size)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    18
type Takuzu struct {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    19
	Size  int
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
	Board [][]Cell
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    21
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    22
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    23
// New creates a new Takuzu board
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    24
func New(size int) Takuzu {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    25
	t := Takuzu{Size: size}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    26
	t.Board = make([][]Cell, size)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    27
	for l := range t.Board {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
		t.Board[l] = make([]Cell, size)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    29
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    30
	return t
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
// NewFromString creates a new Takuzu board from a string definition
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
func NewFromString(s string) (*Takuzu, error) {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    35
	l := len(s)
2
d41c4f8fe066 Add some checks
Mikael Berthe <mikael@lilotux.net>
parents: 0
diff changeset
    36
	if l < 4 {
d41c4f8fe066 Add some checks
Mikael Berthe <mikael@lilotux.net>
parents: 0
diff changeset
    37
		return nil, errors.New("bad string length")
d41c4f8fe066 Add some checks
Mikael Berthe <mikael@lilotux.net>
parents: 0
diff changeset
    38
	}
d41c4f8fe066 Add some checks
Mikael Berthe <mikael@lilotux.net>
parents: 0
diff changeset
    39
0
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    40
	size := int(math.Sqrt(float64(l)))
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
	if size*size != l {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    42
		return nil, errors.New("bad string length")
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    43
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    44
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    45
	i := 0
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    46
	t := New(size)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    47
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    48
	for line := 0; line < size; line++ {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    49
		for col := 0; col < size; col++ {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    50
			switch s[i] {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
			case '0', 'O':
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
				t.Board[line][col].Defined = true
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
				t.Board[line][col].Value = 0
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    54
			case '1', 'I':
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    55
				t.Board[line][col].Defined = true
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    56
				t.Board[line][col].Value = 1
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
			case '.':
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    58
			default:
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    59
				return nil, errors.New("invalid char in string")
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    60
			}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    61
			i++
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    62
		}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    63
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    64
	return &t, nil
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    65
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    66
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
// ToString converts a takuzu board to its string representation
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
func (b Takuzu) ToString() string {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
	var sbuf bytes.Buffer
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    70
	for line := 0; line < b.Size; line++ {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
		for col := 0; col < b.Size; col++ {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
			if b.Board[line][col].Defined {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
				sbuf.WriteString(fmt.Sprintf("%d", b.Board[line][col].Value))
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
				continue
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    75
			}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    76
			sbuf.WriteByte('.')
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    77
		}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
	return sbuf.String()
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    80
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
6
110d38ae22cd Refactor code; split takuzu.go and create solve.go
Mikael Berthe <mikael@lilotux.net>
parents: 4
diff changeset
    82
// DumpString writes the content of the board as a string
0
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
func (b Takuzu) DumpString() {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    84
	fmt.Println(b.ToString())
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
// Clone returns a copy of the Takuzu board
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
func (b Takuzu) Clone() Takuzu {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
	c := New(b.Size)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
	for line := range b.Board {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
		for col := range b.Board[line] {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
			c.Board[line][col] = b.Board[line][col]
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
		}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
	return c
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    97
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
// Copy copies a Takuzu board to another existing board
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
func Copy(src, dst *Takuzu) error {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   100
	if src.Size != dst.Size {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
		return errors.New("sizes do not match")
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
	for line := range src.Board {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
		for col := range src.Board[line] {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   105
			dst.Board[line][col] = src.Board[line][col]
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
		}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   108
	return nil
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   109
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   110
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   111
// BoardsMatch compares a Takuzu board to another, optionally ignoring
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
// empty cells.  Returns true if the two boards match.
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
func BoardsMatch(t1, t2 *Takuzu, ignoreUndefined bool) (match bool, line, col int) {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
	match = true
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
2
d41c4f8fe066 Add some checks
Mikael Berthe <mikael@lilotux.net>
parents: 0
diff changeset
   116
	if t1 == nil || t2 == nil {
d41c4f8fe066 Add some checks
Mikael Berthe <mikael@lilotux.net>
parents: 0
diff changeset
   117
		line, col = -1, -1
d41c4f8fe066 Add some checks
Mikael Berthe <mikael@lilotux.net>
parents: 0
diff changeset
   118
		match = false
d41c4f8fe066 Add some checks
Mikael Berthe <mikael@lilotux.net>
parents: 0
diff changeset
   119
		return
d41c4f8fe066 Add some checks
Mikael Berthe <mikael@lilotux.net>
parents: 0
diff changeset
   120
	}
d41c4f8fe066 Add some checks
Mikael Berthe <mikael@lilotux.net>
parents: 0
diff changeset
   121
0
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   122
	if t1.Size != t2.Size {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   123
		line, col = -1, -1
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   124
		match = false
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   125
		return
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   126
	}
2
d41c4f8fe066 Add some checks
Mikael Berthe <mikael@lilotux.net>
parents: 0
diff changeset
   127
0
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   128
	for line = range t1.Board {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
		for col = range t1.Board[line] {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
			if !t1.Board[line][col].Defined || !t2.Board[line][col].Defined {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
				// At least one of the cells is empty
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   132
				if ignoreUndefined ||
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
					!(t1.Board[line][col].Defined || t2.Board[line][col].Defined) {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
					// Both cells are empty or we ignore empty cells
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   135
					continue
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   136
				}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   137
				match = false
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   138
				return
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   139
			}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   140
			// Both cells are defined
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   141
			if t1.Board[line][col].Value != t2.Board[line][col].Value {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   142
				match = false
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   143
				return
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   144
			}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   145
		}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   146
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   147
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   148
	line, col = -1, -1
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   149
	return
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   150
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   151
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   152
// Set sets the value of the cell; a value -1 will set the cell as undefined
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   153
func (c *Cell) Set(value int) {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   154
	if value != 0 && value != 1 {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   155
		c.Defined = false
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   156
		return
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   157
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   158
	c.Defined = true
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   159
	c.Value = value
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   160
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   161
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   162
// Set sets the value of a specific cell
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   163
// A value -1 will undefine the cell
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   164
func (b Takuzu) Set(l, c, value int) {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   165
	if value != 0 && value != 1 {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   166
		b.Board[l][c].Defined = false
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   167
		return
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   168
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   169
	b.Board[l][c].Defined = true
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   170
	b.Board[l][c].Value = value
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   171
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   172
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   173
// GetLine returns a slice of cells containing the ith line of the board
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   174
func (b Takuzu) GetLine(i int) []Cell {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   175
	return b.Board[i]
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   176
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   177
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   178
// GetColumn returns a slice of cells containing the ith column of the board
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   179
func (b Takuzu) GetColumn(i int) []Cell {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   180
	c := make([]Cell, b.Size)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   181
	for l := range b.Board {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   182
		c[l] = b.Board[l][i]
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   183
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   184
	return c
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   185
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   186
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   187
// GetLinePointers returns a slice of pointers to the cells of the ith line of the board
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   188
func (b Takuzu) GetLinePointers(i int) []*Cell {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   189
	r := make([]*Cell, b.Size)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   190
	for l := range b.Board[i] {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   191
		r[l] = &b.Board[i][l]
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   192
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   193
	return r
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   194
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   195
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   196
// GetColumnPointers returns a slice of pointers to the cells of the ith column of the board
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   197
func (b Takuzu) GetColumnPointers(i int) []*Cell {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   198
	r := make([]*Cell, b.Size)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   199
	for l := range b.Board {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   200
		r[l] = &b.Board[l][i]
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   201
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   202
	return r
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   203
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   204
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   205
// FillLineColumn add missing 0s or 1s if all 1s or 0s are there.
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   206
// Note: This method can update b.
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   207
func (b Takuzu) FillLineColumn(l, c int) {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   208
	fillRange := func(r []*Cell) {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   209
		size := len(r)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   210
		var notFull bool
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   211
		var n [2]int
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   212
		for x := 0; x < size; x++ {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   213
			if r[x].Defined {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   214
				n[r[x].Value]++
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   215
			} else {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   216
				notFull = true
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   217
			}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   218
		}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   219
		if !notFull {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   220
			return
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   221
		}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   222
		if n[0] == size/2 {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   223
			// Let's fill the 1s
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   224
			for _, x := range r {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   225
				if !x.Defined {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   226
					x.Defined = true
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   227
					x.Value = 1
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   228
				}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   229
			}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   230
		} else if n[1] == size/2 {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   231
			// Let's fill the 0s
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   232
			for _, x := range r {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   233
				if !x.Defined {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   234
					x.Defined = true
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   235
					x.Value = 0
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   236
				}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   237
			}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   238
		}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   239
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   240
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   241
	var cells []*Cell
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   242
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   243
	// Fill line
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   244
	cells = b.GetLinePointers(l)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   245
	fillRange(cells)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   246
	// Fill column
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   247
	cells = b.GetColumnPointers(c)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   248
	fillRange(cells)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   249
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   250
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   251
// DumpBoard displays the Takuzu board
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   252
func (b Takuzu) DumpBoard() {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   253
	fmt.Println()
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   254
	for i := range b.Board {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   255
		dumpRange(b.Board[i])
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   256
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   257
}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   258
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   259
func dumpRange(cells []Cell) {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   260
	for _, c := range cells {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   261
		if !c.Defined {
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   262
			fmt.Printf(". ")
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   263
			continue
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   264
		}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   265
		fmt.Printf("%d ", c.Value)
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   266
	}
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   267
	fmt.Println()
00371339bbcc Import refactored version
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   268
}