-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLine.lua
167 lines (140 loc) · 3.87 KB
/
Line.lua
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
module(..., package.seeall);
--[[
A Line is a list of Tile objects, a corresponding list of Clue objects calculated from
the state of those Tiles, and some bookkeeping info about e.g. whether this line has
changed since the last time an effort was made to solve it.
--]]
require "Tile"
require "Clue"
-- create a new list of Clue objects based on the content of a line
function create_clues(line)
local building = false
local tiles = {}
line.clue_list = {}
for i=1, line:getLength() do
-- count up distinct runs of Tiles with a Full state and create a set of clues
-- that corresponds to that set of runs
if line:getState(i) and not building then
-- first Full tile in a sequence
building = true
table.insert(tiles, line:getTile(i))
elseif line:getState(i) and building then
-- we're already building a list of Full tiles and found another, keep adding
table.insert(tiles, line:getTile(i))
elseif building then
-- we're building but we've hit an Empty tile, so let's close this clue out
table.insert(line.clue_list, Clue.new(tiles))
building = false
tiles = {}
end
end
-- need to close out any clue-in-progress at the end of the loop, if the last clue
-- in the line was a Full
if building then
table.insert(line.clue_list, Clue.new(tiles))
end
end
-- check the Known state of constituent tiles and update solved accordingly
function check_solved(line)
for i=1, line.length do
if line.tile_list[i]:getKnown() == false then
line.solved = false
return
end
--[[
-- Experimentally rewriting solved to mean, not "we've found all the fulls", but "we've totally
-- filled the line, fulls and empties".
if line.tile_list[i]:getKnown() == false and line.tile_list[i]:getState() == true then
-- we found an unrevealed Full tile, so this line can't be considered solved
line.solved = false
return
end
--]]
-- if we got out, we must know about every Full tile already, huzzah!
line.solved = true
end
end
function getLength(line)
return line.length
end
function getState(line, i)
return line.tile_list[i]:getState()
end
function getKnown(line, i)
return line.tile_list[i]:getKnown()
end
function getTile(line, i)
return line.tile_list[i]
end
function getClues(line)
return line.clue_list
end
function setState(line, i, s)
line.tile_list[i] = s
end
function is_solved(line)
return line.solved
end
-- return a new Line object with tiles and clues reversed
function reverse(line)
local newtiles = {}
local newclues = {}
for i,v in ipairs(line.tile_list) do
table.insert(newtiles, 1, v)
end
for i,v in ipairs(line.clue_list) do
table.insert(newclues, 1, v)
end
local newline = new(newtiles)
newline:setClues(newclues)
return newline
end
-- return a new Line object that is a subset of the original line's tiles and clues
function subline(line, starttile, endtile, startclue, endclue)
local newtiles = {}
for i=starttile, endtile do
table.insert(newtiles, line:getTile(i))
end
local newclues = {}
for i=startclue, endclue do
table.insert(newclues, line:getClues()[i])
end
local newline = new(newtiles)
newline:setClues(newclues)
return newline
end
-- set the list of clues associated with this line to new list
function setClues(line, c)
line.clue_list = c
end
function setChanged(line, b)
line.changed = b
end
function getChanged(line)
return line.changed
end
-- instantiate a Line object with a list of Tiles
function new(tiles)
local o = {}
o.tile_list = tiles or {}
o.length = table.getn(o.tile_list)
o.solved = false
o.changed = true
o.clue_list = {}
o.getLength = getLength
o.getState = getState
o.getKnown = getKnown
o.getTile = getTile
o.getClues = getClues
o.setState = setState
o.create_clues = create_clues
o.check_solved = check_solved
o.is_solved = is_solved
o.reverse = reverse
o.subline = subline
o.setClues = setClues
o.setChanged = setChanged
o.getChanged = getChanged
create_clues(o)
return o
end