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