-
Notifications
You must be signed in to change notification settings - Fork 10
/
board_utils.go
145 lines (134 loc) · 3.69 KB
/
board_utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package board
import (
"fmt"
"log"
"regexp"
"strings"
"github.com/domino14/macondo/alphabet"
)
type TilesInPlay struct {
OnBoard []alphabet.MachineLetter
Rack1 []alphabet.MachineLetter
Rack2 []alphabet.MachineLetter
}
var boardPlaintextRegex = regexp.MustCompile(`\|(.+)\|`)
var userRackRegex = regexp.MustCompile(`(?U).+\s+([A-Z\?]*)\s+-?[0-9]+`)
func (g *GameBoard) ToDisplayText(alph *alphabet.Alphabet) string {
var str string
n := g.Dim()
row := " "
for i := 0; i < n; i++ {
row = row + fmt.Sprintf("%c", 'A'+i) + " "
}
str = str + row + "\n"
str = str + " " + strings.Repeat("-", n*2) + "\n"
for i := 0; i < n; i++ {
row := fmt.Sprintf("%2d|", i+1)
for j := 0; j < n; j++ {
row = row + g.squares[i][j].DisplayString(alph) + " "
}
row = row + "|"
str = str + row + "\n"
}
str = str + " " + strings.Repeat("-", n*2) + "\n"
return "\n" + str
}
// SetFromPlaintext sets the board from the given plaintext board.
// It returns a list of all played machine letters (tiles) so that the
// caller can reconcile the tile bag appropriately.
func (g *GameBoard) setFromPlaintext(qText string,
alph *alphabet.Alphabet) *TilesInPlay {
g.Clear()
tilesInPlay := &TilesInPlay{}
// Take a Quackle Plaintext Board and turn it into an internal structure.
playedTiles := []alphabet.MachineLetter(nil)
result := boardPlaintextRegex.FindAllStringSubmatch(qText, -1)
if len(result) != 15 {
panic("Wrongly implemented")
}
g.tilesPlayed = 0
var err error
var letter alphabet.MachineLetter
for i := range result {
// result[i][1] has the string
j := -1
for _, ch := range result[i][1] {
j++
if j%2 != 0 {
continue
}
letter, err = alph.Val(ch)
if err != nil {
// Ignore the error; we are passing in a space or another
// board marker.
g.squares[i][j/2].letter = alphabet.EmptySquareMarker
} else {
g.squares[i][j/2].letter = letter
g.tilesPlayed++
playedTiles = append(playedTiles, letter)
}
}
}
userRacks := userRackRegex.FindAllStringSubmatch(qText, -1)
for i := range userRacks {
if i > 1 { // only the first two lines that match
break
}
rack := userRacks[i][1]
rackTiles := []alphabet.MachineLetter{}
for _, ch := range rack {
letter, err = alph.Val(ch)
if err != nil {
panic(err)
}
rackTiles = append(rackTiles, letter)
}
if i == 0 {
tilesInPlay.Rack1 = rackTiles
} else if i == 1 {
tilesInPlay.Rack2 = rackTiles
}
}
tilesInPlay.OnBoard = playedTiles
return tilesInPlay
}
func (b *GameBoard) SetRow(rowNum int, letters string, alph *alphabet.Alphabet) []alphabet.MachineLetter {
// Set the row in board to the passed in letters array.
for idx := 0; idx < b.Dim(); idx++ {
b.SetLetter(int(rowNum), idx, alphabet.EmptySquareMarker)
}
lettersPlayed := []alphabet.MachineLetter{}
for idx, r := range letters {
if r != ' ' {
letter, err := alph.Val(r)
if err != nil {
log.Fatalf(err.Error())
}
b.SetLetter(int(rowNum), idx, letter)
b.tilesPlayed++
lettersPlayed = append(lettersPlayed, letter)
}
}
return lettersPlayed
}
// Equals checks the boards for equality. Two boards are equal if all
// the squares are equal. This includes anchors, letters, and cross-sets.
func (g *GameBoard) Equals(g2 *GameBoard) bool {
if g.Dim() != g2.Dim() {
log.Printf("Dims don't match: %v %v", g.Dim(), g2.Dim())
return false
}
if g.tilesPlayed != g2.tilesPlayed {
log.Printf("Tiles played don't match: %v %v", g.tilesPlayed, g2.tilesPlayed)
return false
}
for row := 0; row < g.Dim(); row++ {
for col := 0; col < g.Dim(); col++ {
if !g.GetSquare(row, col).equals(g2.GetSquare(row, col)) {
log.Printf("> Not equal, row %v col %v", row, col)
return false
}
}
}
return true
}