Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
6
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
W
wordbase-hacker
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
0
Merge Requests
0
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Test Cases
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Package Registry
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PurkkaKoodari
wordbase-hacker
Commits
d326e41c
Commit
d326e41c
authored
Sep 09, 2017
by
PurkkaKoodari
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor solver, speed up scoring by 10x
parent
7bba2f63
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
207 additions
and
210 deletions
+207
-210
app/src/main/java/net/pietu1998/wordbasehacker/BoardActivity.java
...main/java/net/pietu1998/wordbasehacker/BoardActivity.java
+5
-85
app/src/main/java/net/pietu1998/wordbasehacker/BoardDrawable.java
...main/java/net/pietu1998/wordbasehacker/BoardDrawable.java
+14
-11
app/src/main/java/net/pietu1998/wordbasehacker/solver/Board.java
.../main/java/net/pietu1998/wordbasehacker/solver/Board.java
+174
-78
app/src/main/java/net/pietu1998/wordbasehacker/solver/Game.java
...c/main/java/net/pietu1998/wordbasehacker/solver/Game.java
+0
-9
app/src/main/java/net/pietu1998/wordbasehacker/solver/Possibility.java
...java/net/pietu1998/wordbasehacker/solver/Possibility.java
+12
-4
app/src/main/java/net/pietu1998/wordbasehacker/solver/Tile.java
...c/main/java/net/pietu1998/wordbasehacker/solver/Tile.java
+2
-23
No files found.
app/src/main/java/net/pietu1998/wordbasehacker/BoardActivity.java
View file @
d326e41c
...
...
@@ -6,7 +6,6 @@ import java.io.File;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
net.pietu1998.wordbasehacker.solver.Board
;
...
...
@@ -98,12 +97,6 @@ public class BoardActivity extends Activity {
this
.
dialog
=
dialog
;
}
private
class
TrieNode
{
private
TrieNode
[]
nodes
=
new
TrieNode
[
1024
];
private
boolean
hasChildren
=
false
;
private
String
content
=
null
;
}
@Override
protected
Integer
doInBackground
(
Void
...
params
)
{
try
{
...
...
@@ -161,64 +154,16 @@ public class BoardActivity extends Activity {
}
}
short
charMap
[]
=
new
short
[
65536
];
short
charIndex
=
0
;
Tile
[][]
tiles
=
new
Tile
[
10
][
13
];
short
[]
tileLetters
=
new
short
[
130
];
for
(
int
x
=
0
;
x
<
10
;
x
++)
{
for
(
int
y
=
0
;
y
<
13
;
y
++)
{
char
letter
=
rows
[
y
].
charAt
(
x
);
int
mapping
=
charMap
[
letter
];
if
(
mapping
==
0
)
mapping
=
charMap
[
letter
]
=
(
short
)
++
charIndex
;
tiles
[
x
][
y
]
=
new
Tile
(
tileStates
[
x
+
10
*
y
],
letter
);
tileLetters
[
x
+
10
*
y
]
=
(
short
)
(
mapping
-
1
);
}
}
game
.
setBoard
(
new
Board
(
tiles
,
words
));
publishProgress
(
R
.
string
.
analyzing_words
);
words
=
game
.
getBoard
().
getWords
();
TrieNode
root
=
new
TrieNode
();
for
(
String
word
:
words
)
{
if
(
game
.
isPlayed
(
word
))
continue
;
TrieNode
node
=
root
;
for
(
int
i
=
0
;
i
<
word
.
length
();
i
++)
{
int
mapping
=
charMap
[
word
.
charAt
(
i
)]
-
1
;
node
.
hasChildren
=
true
;
TrieNode
next
=
node
.
nodes
[
mapping
];
if
(
next
==
null
)
node
=
node
.
nodes
[
mapping
]
=
new
TrieNode
();
else
node
=
next
;
}
node
.
content
=
word
;
}
Board
board
=
new
Board
(
rows
,
tileStates
,
words
,
game
);
publishProgress
(
R
.
string
.
finding_words
);
results
=
new
ArrayList
<>();
long
start
=
System
.
currentTimeMillis
();
for
(
int
iteration
=
0
;
iteration
<
500
;
iteration
++)
{
boolean
positions
[]
=
new
boolean
[
130
];
byte
coords
[]
=
new
byte
[
24
];
for
(
int
y
=
0
,
index
=
0
;
y
<
13
;
y
++)
for
(
int
x
=
0
;
x
<
10
;
x
++,
index
++)
if
((
tileStates
[
index
]
&
Tile
.
PLAYER
)
!=
0
)
findWords
(
tileLetters
,
0
,
x
,
y
,
index
,
coords
,
positions
,
root
);
if
(
iteration
<
499
)
results
.
clear
();
}
long
end
=
System
.
currentTimeMillis
();
Log
.
d
(
"WordbaseHacker"
,
"Finding took "
+
(
end
-
start
)
+
"ms"
);
board
.
findWords
();
publishProgress
(
R
.
string
.
scoring_words
);
start
=
System
.
currentTimeMillis
();
for
(
int
iteration
=
0
;
iteration
<
20
;
iteration
++)
for
(
Possibility
pos
:
results
)
game
.
getBoard
().
score
(
pos
,
game
.
isFlipped
());
end
=
System
.
currentTimeMillis
();
Log
.
d
(
"WordbaseHacker"
,
"Scoring took "
+
(
end
-
start
)
+
"ms"
);
board
.
scoreWords
(
game
.
isFlipped
());
results
=
board
.
getResults
();
return
0
;
}
catch
(
NumberFormatException
|
ParseException
|
SQLiteException
|
IndexOutOfBoundsException
e
)
{
Log
.
e
(
"WordbaseHacker"
,
"Failed to read data."
,
e
);
...
...
@@ -226,31 +171,6 @@ public class BoardActivity extends Activity {
}
}
private
void
findWords
(
short
[]
tiles
,
int
length
,
int
x
,
int
y
,
int
index
,
byte
[]
coords
,
boolean
[]
positions
,
TrieNode
node
)
{
if
(
length
>=
12
||
x
<
0
||
x
>
9
||
y
<
0
||
y
>
12
||
positions
[
index
])
return
;
short
letter
=
tiles
[
index
];
node
=
node
.
nodes
[
letter
];
if
(
node
==
null
)
return
;
coords
[
length
*
2
]
=
(
byte
)
x
;
coords
[
length
*
2
+
1
]
=
(
byte
)
y
;
if
(
node
.
content
!=
null
)
results
.
add
(
new
Possibility
(
Arrays
.
copyOf
(
coords
,
length
*
2
+
2
),
node
.
content
));
if
(!
node
.
hasChildren
)
return
;
positions
[
index
]
=
true
;
findWords
(
tiles
,
length
+
1
,
x
,
y
+
1
,
index
+
10
,
coords
,
positions
,
node
);
findWords
(
tiles
,
length
+
1
,
x
-
1
,
y
+
1
,
index
+
9
,
coords
,
positions
,
node
);
findWords
(
tiles
,
length
+
1
,
x
+
1
,
y
+
1
,
index
+
11
,
coords
,
positions
,
node
);
findWords
(
tiles
,
length
+
1
,
x
-
1
,
y
,
index
-
1
,
coords
,
positions
,
node
);
findWords
(
tiles
,
length
+
1
,
x
+
1
,
y
,
index
+
1
,
coords
,
positions
,
node
);
findWords
(
tiles
,
length
+
1
,
x
,
y
-
1
,
index
-
10
,
coords
,
positions
,
node
);
findWords
(
tiles
,
length
+
1
,
x
-
1
,
y
-
1
,
index
-
11
,
coords
,
positions
,
node
);
findWords
(
tiles
,
length
+
1
,
x
+
1
,
y
-
1
,
index
-
9
,
coords
,
positions
,
node
);
positions
[
index
]
=
false
;
}
@Override
protected
void
onProgressUpdate
(
Integer
...
values
)
{
dialog
.
setMessage
(
getResources
().
getString
(
values
[
0
]));
...
...
app/src/main/java/net/pietu1998/wordbasehacker/BoardDrawable.java
View file @
d326e41c
...
...
@@ -9,6 +9,7 @@ import android.graphics.Paint;
import
android.graphics.PixelFormat
;
import
android.graphics.Typeface
;
import
android.graphics.drawable.Drawable
;
import
android.support.annotation.NonNull
;
public
class
BoardDrawable
extends
Drawable
{
...
...
@@ -33,7 +34,7 @@ public class BoardDrawable extends Drawable {
}
@Override
public
void
draw
(
Canvas
canvas
)
{
public
void
draw
(
@NonNull
Canvas
canvas
)
{
if
(
pos
.
getResult
()
==
null
)
return
;
...
...
@@ -62,23 +63,25 @@ public class BoardDrawable extends Drawable {
path
.
setStrokeCap
(
Paint
.
Cap
.
ROUND
);
path
.
setColor
(
0xFF009900
);
for
(
int
x
=
0
;
x
<
10
;
x
++)
{
for
(
int
y
=
0
;
y
<
13
;
y
++)
{
Tile
t
=
pos
.
getResult
().
getTiles
()[
x
][
y
];
if
(
t
.
isSet
(
Tile
.
SUPER_MINE
))
char
[]
tileLetters
=
pos
.
getTileLetters
();
int
[]
tileStates
=
pos
.
getResult
();
for
(
int
y
=
0
,
index
=
0
;
y
<
13
;
y
++)
{
for
(
int
x
=
0
;
x
<
10
;
x
++,
index
++)
{
int
t
=
tileStates
[
index
];
if
((
t
&
Tile
.
SUPER_MINE
)
!=
0
)
canvas
.
drawRect
(
x
*
80
,
y
*
80
,
x
*
80
+
80
,
y
*
80
+
80
,
purpleBg
);
else
if
(
t
.
isSet
(
Tile
.
MINE
)
)
else
if
(
(
t
&
Tile
.
MINE
)
!=
0
)
canvas
.
drawRect
(
x
*
80
,
y
*
80
,
x
*
80
+
80
,
y
*
80
+
80
,
blackBg
);
else
if
(
t
.
isSet
(
Tile
.
PLAYER
)
)
else
if
(
(
t
&
Tile
.
PLAYER
)
!=
0
)
canvas
.
drawRect
(
x
*
80
,
y
*
80
,
x
*
80
+
80
,
y
*
80
+
80
,
flipped
?
blueBg
:
orangeBg
);
else
if
(
t
.
isSet
(
Tile
.
OPPONENT
)
)
else
if
(
(
t
&
Tile
.
OPPONENT
)
!=
0
)
canvas
.
drawRect
(
x
*
80
,
y
*
80
,
x
*
80
+
80
,
y
*
80
+
80
,
flipped
?
orangeBg
:
blueBg
);
else
canvas
.
drawRect
(
x
*
80
,
y
*
80
,
x
*
80
+
80
,
y
*
80
+
80
,
whiteBg
);
canvas
.
drawText
(
String
.
valueOf
(
t
.
getLetter
()
),
x
*
80
+
40
-
blackText
.
measureText
(
String
.
valueOf
(
t
.
getLetter
()
))
/
2
,
canvas
.
drawText
(
String
.
valueOf
(
t
ileLetters
[
index
]
),
x
*
80
+
40
-
blackText
.
measureText
(
String
.
valueOf
(
t
ileLetters
[
index
]
))
/
2
,
y
*
80
+
40
-
blackText
.
ascent
()
/
2
,
t
.
isSet
(
Tile
.
MINE
|
Tile
.
SUPER_MINE
)
?
whiteText
:
blackText
);
(
t
&
(
Tile
.
MINE
|
Tile
.
SUPER_MINE
))
!=
0
?
whiteText
:
blackText
);
}
}
if
(
pos
.
getCoordinates
().
length
>
2
)
{
...
...
app/src/main/java/net/pietu1998/wordbasehacker/solver/Board.java
View file @
d326e41c
package
net.pietu1998.wordbasehacker.solver
;
import
java.util.HashSet
;
import
java.util.Set
;
import
android.util.Log
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
public
class
Board
{
private
Tile
[][]
tiles
;
private
String
[]
words
;
private
short
[]
charMap
=
new
short
[
65536
];
private
short
charIndex
=
0
;
private
int
[]
tileStates
;
private
char
[]
tileLetters
;
private
short
[]
tileMappedLetters
;
private
TrieNode
root
;
public
Board
(
Tile
[][]
tiles
,
String
[]
words
)
{
this
.
tiles
=
tiles
;
this
.
words
=
words
;
private
List
<
Possibility
>
results
=
new
ArrayList
<>();
public
List
<
Possibility
>
getResults
()
{
return
results
;
}
public
Tile
[][]
getTiles
()
{
return
tiles
;
private
class
TrieNode
{
private
TrieNode
[]
nodes
;
private
boolean
hasChildren
=
false
;
private
String
content
=
null
;
TrieNode
()
{
nodes
=
new
TrieNode
[
charIndex
];
}
}
public
String
[]
getWords
()
{
return
words
;
public
Board
(
String
[]
rows
,
int
[]
tileStates
,
String
[]
words
,
Game
game
)
{
this
.
tileStates
=
tileStates
;
tileLetters
=
new
char
[
130
];
tileMappedLetters
=
new
short
[
130
];
for
(
int
y
=
0
,
index
=
0
;
y
<
13
;
y
++)
{
for
(
int
x
=
0
;
x
<
10
;
x
++,
index
++)
{
char
letter
=
tileLetters
[
index
]
=
rows
[
y
].
charAt
(
x
);
int
mapping
=
charMap
[
letter
];
if
(
mapping
==
0
)
mapping
=
charMap
[
letter
]
=
++
charIndex
;
tileMappedLetters
[
index
]
=
(
short
)
(
mapping
-
1
);
}
}
root
=
new
TrieNode
();
for
(
String
word
:
words
)
{
if
(
game
.
isPlayed
(
word
))
continue
;
Board
.
TrieNode
node
=
root
;
for
(
int
i
=
0
;
i
<
word
.
length
();
i
++)
{
int
mapping
=
charMap
[
word
.
charAt
(
i
)]
-
1
;
node
.
hasChildren
=
true
;
Board
.
TrieNode
next
=
node
.
nodes
[
mapping
];
if
(
next
==
null
)
node
=
node
.
nodes
[
mapping
]
=
new
Board
.
TrieNode
();
else
node
=
next
;
}
node
.
content
=
word
;
}
}
public
void
findWords
()
{
long
start
=
System
.
currentTimeMillis
();
for
(
int
iteration
=
0
;
iteration
<
500
;
iteration
++)
{
boolean
positions
[]
=
new
boolean
[
130
];
byte
coords
[]
=
new
byte
[
24
];
for
(
int
y
=
0
,
index
=
0
;
y
<
13
;
y
++)
for
(
int
x
=
0
;
x
<
10
;
x
++,
index
++)
if
((
tileStates
[
index
]
&
Tile
.
PLAYER
)
!=
0
)
findWordsRecursive
(
tileMappedLetters
,
0
,
x
,
y
,
index
,
coords
,
positions
,
root
,
results
);
if
(
iteration
<
499
)
results
.
clear
();
}
long
end
=
System
.
currentTimeMillis
();
Log
.
d
(
"WordbaseHacker"
,
"Finding took "
+
(
end
-
start
)
+
"ms"
);
}
public
void
score
(
Possibility
pos
,
boolean
flipped
)
{
Tile
[][]
newTiles
=
new
Tile
[
10
][
13
];
int
oldMines
=
0
,
oldPlayer
=
0
,
oldOpponent
=
0
,
oldDistP
=
0
,
oldDistO
=
0
;
for
(
int
x
=
0
;
x
<
10
;
x
++)
{
for
(
int
y
=
0
;
y
<
13
;
y
++)
{
newTiles
[
x
][
y
]
=
tiles
[
x
][
y
];
if
(
newTiles
[
x
][
y
].
isSet
(
Tile
.
PLAYER
))
{
private
void
findWordsRecursive
(
short
[]
tiles
,
int
length
,
int
x
,
int
y
,
int
index
,
byte
[]
coords
,
boolean
[]
positions
,
TrieNode
node
,
List
<
Possibility
>
results
)
{
if
(
length
>=
12
||
x
<
0
||
x
>
9
||
y
<
0
||
y
>
12
||
positions
[
index
])
return
;
short
letter
=
tiles
[
index
];
node
=
node
.
nodes
[
letter
];
if
(
node
==
null
)
return
;
coords
[
length
*
2
]
=
(
byte
)
x
;
coords
[
length
*
2
+
1
]
=
(
byte
)
y
;
if
(
node
.
content
!=
null
)
results
.
add
(
new
Possibility
(
Arrays
.
copyOf
(
coords
,
length
*
2
+
2
),
node
.
content
));
if
(!
node
.
hasChildren
)
return
;
positions
[
index
]
=
true
;
findWordsRecursive
(
tiles
,
length
+
1
,
x
,
y
+
1
,
index
+
10
,
coords
,
positions
,
node
,
results
);
findWordsRecursive
(
tiles
,
length
+
1
,
x
-
1
,
y
+
1
,
index
+
9
,
coords
,
positions
,
node
,
results
);
findWordsRecursive
(
tiles
,
length
+
1
,
x
+
1
,
y
+
1
,
index
+
11
,
coords
,
positions
,
node
,
results
);
findWordsRecursive
(
tiles
,
length
+
1
,
x
-
1
,
y
,
index
-
1
,
coords
,
positions
,
node
,
results
);
findWordsRecursive
(
tiles
,
length
+
1
,
x
+
1
,
y
,
index
+
1
,
coords
,
positions
,
node
,
results
);
findWordsRecursive
(
tiles
,
length
+
1
,
x
,
y
-
1
,
index
-
10
,
coords
,
positions
,
node
,
results
);
findWordsRecursive
(
tiles
,
length
+
1
,
x
-
1
,
y
-
1
,
index
-
11
,
coords
,
positions
,
node
,
results
);
findWordsRecursive
(
tiles
,
length
+
1
,
x
+
1
,
y
-
1
,
index
-
9
,
coords
,
positions
,
node
,
results
);
positions
[
index
]
=
false
;
}
public
void
scoreWords
(
boolean
flipped
)
{
long
start
=
System
.
currentTimeMillis
();
for
(
int
iteration
=
0
;
iteration
<
100
;
iteration
++)
for
(
Possibility
pos
:
results
)
{
scoreWord
(
pos
,
flipped
);
pos
.
setTileLetters
(
tileLetters
);
}
long
end
=
System
.
currentTimeMillis
();
Log
.
d
(
"WordbaseHacker"
,
"Scoring took "
+
(
end
-
start
)
+
"ms"
);
}
private
void
scoreWord
(
Possibility
pos
,
boolean
flipped
)
{
int
[]
newStates
=
new
int
[
130
];
int
oldMines
=
0
,
oldPlayer
=
0
,
oldOpponent
=
0
,
oldDistPlayer
=
0
,
oldDistOpponent
=
0
;
for
(
int
y
=
0
,
index
=
0
;
y
<
13
;
y
++)
{
for
(
int
x
=
0
;
x
<
10
;
x
++,
index
++)
{
int
state
=
newStates
[
index
]
=
tileStates
[
index
];
if
((
state
&
Tile
.
PLAYER
)
!=
0
)
{
oldPlayer
++;
oldDistP
=
max
(
oldDistP
,
flipped
?
12
-
y
:
y
);
}
else
if
(
newTiles
[
x
][
y
].
isSet
(
Tile
.
OPPONENT
)
)
{
oldDistP
layer
=
Math
.
max
(
oldDistPlayer
,
flipped
?
12
-
y
:
y
);
}
else
if
(
(
state
&
Tile
.
OPPONENT
)
!=
0
)
{
oldOpponent
++;
oldDistO
=
max
(
oldDistO
,
flipped
?
y
:
12
-
y
);
}
else
if
(
newTiles
[
x
][
y
].
isSet
(
Tile
.
MINE
|
Tile
.
SUPER_MINE
)
)
{
oldDistO
pponent
=
Math
.
max
(
oldDistOpponent
,
flipped
?
y
:
12
-
y
);
}
else
if
(
(
state
&
(
Tile
.
MINE
|
Tile
.
SUPER_MINE
))
!=
0
)
{
oldMines
++;
}
}
}
byte
[]
coords
=
pos
.
getCoordinates
();
for
(
int
i
=
0
;
i
<
coords
.
length
;
i
+=
2
)
takeTile
(
newTiles
,
coords
[
i
],
coords
[
i
+
1
]);
Set
<
Coordinate
>
connected
=
new
HashSet
<
Coordinate
>();
for
(
int
x
=
0
;
x
<
10
;
x
++)
{
addConnected
(
newTiles
,
x
,
flipped
?
0
:
12
,
connected
,
flipped
);
}
for
(
int
x
=
0
;
x
<
10
;
x
++)
{
for
(
int
y
=
0
;
y
<
13
;
y
++)
{
if
(
newTiles
[
x
][
y
].
isSet
(
Tile
.
OPPONENT
)
&&
!
connected
.
contains
(
new
Coordinate
(
x
,
y
)))
newTiles
[
x
][
y
]
=
newTiles
[
x
][
y
].
modify
(
0
,
Tile
.
OPPONENT
);
}
for
(
int
i
=
0
;
i
<
coords
.
length
;
i
+=
2
)
{
byte
x
=
coords
[
i
];
byte
y
=
coords
[
i
+
1
];
takeTile
(
newStates
,
x
,
y
,
x
+
10
*
y
);
}
int
newMines
=
0
,
newPlayer
=
0
,
newOpponent
=
0
,
newDistP
=
0
,
newDistO
=
0
;
for
(
int
x
=
0
;
x
<
10
;
x
++)
{
for
(
int
y
=
0
;
y
<
13
;
y
++)
{
if
(
newTiles
[
x
][
y
].
isSet
(
Tile
.
PLAYER
))
{
boolean
[]
connected
=
new
boolean
[
130
];
int
baseY
=
flipped
?
0
:
12
;
int
offset
=
10
*
baseY
;
for
(
int
x
=
0
;
x
<
10
;
x
++)
addConnected
(
newStates
,
x
,
baseY
,
x
+
offset
,
connected
);
for
(
int
index
=
0
;
index
<
130
;
index
++)
if
(!
connected
[
index
])
newStates
[
index
]
&=
~
Tile
.
OPPONENT
;
int
newMines
=
0
,
newPlayer
=
0
,
newOpponent
=
0
,
newDistPlayer
=
0
,
newDistOpponent
=
0
;
for
(
int
y
=
0
,
index
=
0
;
y
<
13
;
y
++)
{
for
(
int
x
=
0
;
x
<
10
;
x
++,
index
++)
{
int
state
=
newStates
[
index
];
if
((
state
&
Tile
.
PLAYER
)
!=
0
)
{
newPlayer
++;
newDistP
=
max
(
newDistP
,
flipped
?
12
-
y
:
y
);
}
else
if
(
newTiles
[
x
][
y
].
isSet
(
Tile
.
OPPONENT
)
)
{
newDistP
layer
=
Math
.
max
(
newDistPlayer
,
flipped
?
12
-
y
:
y
);
}
else
if
(
(
state
&
Tile
.
OPPONENT
)
!=
0
)
{
newOpponent
++;
newDistO
=
max
(
newDistO
,
flipped
?
y
:
12
-
y
);
}
else
if
(
newTiles
[
x
][
y
].
isSet
(
Tile
.
MINE
|
Tile
.
SUPER_MINE
)
)
{
newDistO
pponent
=
Math
.
max
(
newDistOpponent
,
flipped
?
y
:
12
-
y
);
}
else
if
(
(
state
&
(
Tile
.
MINE
|
Tile
.
SUPER_MINE
))
!=
0
)
{
newMines
++;
}
}
}
pos
.
setScore
(
new
Score
(
pos
.
getCoordinates
().
length
/
2
,
oldMines
-
newMines
,
newPlayer
-
oldPlayer
,
oldOpponent
-
newOpponent
,
newDistP
-
oldDistP
,
oldDistO
-
newDistO
,
newDistP
==
12
));
pos
.
setResult
(
new
Board
(
newTiles
,
words
));
}
private
static
int
max
(
int
a
,
int
b
)
{
return
a
>
b
?
a
:
b
;
pos
.
setScore
(
new
Score
(
pos
.
getCoordinates
().
length
/
2
,
oldMines
-
newMines
,
newPlayer
-
oldPlayer
,
oldOpponent
-
newOpponent
,
newDistPlayer
-
oldDistPlayer
,
oldDistOpponent
-
newDistOpponent
,
newDistPlayer
==
12
));
pos
.
setResult
(
newStates
);
}
private
void
addConnected
(
Tile
[][]
tiles
,
int
x
,
int
y
,
Set
<
Coordinate
>
positions
,
boolean
flipped
)
{
if
(
x
<
0
||
x
>
9
||
y
<
0
||
y
>
12
||
positions
.
contains
(
new
Coordinate
(
x
,
y
))
||
!
tiles
[
x
][
y
].
isSet
(
Tile
.
OPPONENT
))
private
void
takeTile
(
int
[]
tiles
,
int
x
,
int
y
,
int
index
)
{
if
(
x
<
0
||
x
>
9
||
y
<
0
||
y
>
12
)
return
;
positions
.
add
(
new
Coordinate
(
x
,
y
));
addConnected
(
tiles
,
x
,
y
+
1
,
positions
,
flipped
);
addConnected
(
tiles
,
x
-
1
,
y
+
1
,
positions
,
flipped
);
addConnected
(
tiles
,
x
+
1
,
y
+
1
,
positions
,
flipped
);
addConnected
(
tiles
,
x
-
1
,
y
,
positions
,
flipped
);
addConnected
(
tiles
,
x
+
1
,
y
,
positions
,
flipped
);
addConnected
(
tiles
,
x
,
y
-
1
,
positions
,
flipped
);
addConnected
(
tiles
,
x
-
1
,
y
-
1
,
positions
,
flipped
);
addConnected
(
tiles
,
x
+
1
,
y
-
1
,
positions
,
flipped
);
int
state
=
tiles
[
index
];
if
(
state
!=
(
state
&=
~
Tile
.
SUPER_MINE
))
{
takeTile
(
tiles
,
x
-
1
,
y
-
1
,
index
-
11
);
takeTile
(
tiles
,
x
+
1
,
y
-
1
,
index
-
9
);
takeTile
(
tiles
,
x
-
1
,
y
+
1
,
index
+
9
);
takeTile
(
tiles
,
x
+
1
,
y
+
1
,
index
+
11
);
takeTile
(
tiles
,
x
,
y
-
1
,
index
-
10
);
takeTile
(
tiles
,
x
-
1
,
y
,
index
-
1
);
takeTile
(
tiles
,
x
+
1
,
y
,
index
+
1
);
takeTile
(
tiles
,
x
,
y
+
1
,
index
+
10
);
}
else
if
(
state
!=
(
state
&=
~
Tile
.
MINE
))
{
takeTile
(
tiles
,
x
,
y
-
1
,
index
-
10
);
takeTile
(
tiles
,
x
-
1
,
y
,
index
-
1
);
takeTile
(
tiles
,
x
+
1
,
y
,
index
+
1
);
takeTile
(
tiles
,
x
,
y
+
1
,
index
+
10
);
}
tiles
[
index
]
=
(
state
&
~
Tile
.
OPPONENT
)
|
Tile
.
PLAYER
;
}
private
static
void
takeTile
(
Tile
[][]
tiles
,
int
x
,
int
y
)
{
if
(
x
<
0
||
x
>
9
||
y
<
0
||
y
>
12
)
private
void
addConnected
(
int
[]
tiles
,
int
x
,
int
y
,
int
index
,
boolean
[]
positions
)
{
if
(
x
<
0
||
x
>
9
||
y
<
0
||
y
>
12
||
positions
[
index
]
||
(
tiles
[
index
]
&
Tile
.
OPPONENT
)
==
0
)
return
;
if
(
tiles
[
x
][
y
].
isSet
(
Tile
.
MINE
|
Tile
.
SUPER_MINE
))
{
if
(
tiles
[
x
][
y
].
isSet
(
Tile
.
SUPER_MINE
))
{
tiles
[
x
][
y
]
=
tiles
[
x
][
y
].
modify
(
0
,
Tile
.
SUPER_MINE
);
takeTile
(
tiles
,
x
-
1
,
y
-
1
);
takeTile
(
tiles
,
x
-
1
,
y
+
1
);
takeTile
(
tiles
,
x
+
1
,
y
-
1
);
takeTile
(
tiles
,
x
+
1
,
y
+
1
);
}
tiles
[
x
][
y
]
=
tiles
[
x
][
y
].
modify
(
0
,
Tile
.
MINE
);
takeTile
(
tiles
,
x
,
y
-
1
);
takeTile
(
tiles
,
x
-
1
,
y
);
takeTile
(
tiles
,
x
+
1
,
y
);
takeTile
(
tiles
,
x
,
y
+
1
);
}
tiles
[
x
][
y
]
=
tiles
[
x
][
y
].
modify
(
Tile
.
PLAYER
,
Tile
.
OPPONENT
);
positions
[
index
]
=
true
;
addConnected
(
tiles
,
x
-
1
,
y
-
1
,
index
-
11
,
positions
);
addConnected
(
tiles
,
x
,
y
-
1
,
index
-
10
,
positions
);
addConnected
(
tiles
,
x
+
1
,
y
-
1
,
index
-
9
,
positions
);
addConnected
(
tiles
,
x
-
1
,
y
,
index
-
1
,
positions
);
addConnected
(
tiles
,
x
+
1
,
y
,
index
+
1
,
positions
);
addConnected
(
tiles
,
x
-
1
,
y
+
1
,
index
+
9
,
positions
);
addConnected
(
tiles
,
x
,
y
+
1
,
index
+
10
,
positions
);
addConnected
(
tiles
,
x
+
1
,
y
+
1
,
index
+
11
,
positions
);
}
}
app/src/main/java/net/pietu1998/wordbasehacker/solver/Game.java
View file @
d326e41c
...
...
@@ -10,7 +10,6 @@ public class Game implements Parcelable {
private
int
id
,
boardId
,
opponentId
;
private
String
layout
,
opponent
=
null
;
private
Board
board
=
null
;
private
Set
<
String
>
played
;
private
boolean
flipped
;
...
...
@@ -31,14 +30,6 @@ public class Game implements Parcelable {
this
.
opponent
=
opponent
;
}
public
Board
getBoard
()
{
return
board
;
}
public
void
setBoard
(
Board
board
)
{
this
.
board
=
board
;
}
public
int
getId
()
{
return
id
;
}
...
...
app/src/main/java/net/pietu1998/wordbasehacker/solver/Possibility.java
View file @
d326e41c
...
...
@@ -9,7 +9,8 @@ public class Possibility {
@NonNull
private
String
word
;
private
Score
score
;
private
Board
result
;
private
int
[]
result
;
private
char
[]
tileLetters
;
public
Possibility
(
@NonNull
byte
[]
coordinates
,
@NonNull
String
word
)
{
this
.
coordinates
=
coordinates
;
...
...
@@ -24,15 +25,22 @@ public class Possibility {
this
.
score
=
score
;
}
@NonNull
public
Board
getResult
()
{
public
int
[]
getResult
()
{
return
result
;
}
public
void
setResult
(
Board
result
)
{
public
void
setResult
(
int
[]
result
)
{
this
.
result
=
result
;
}
public
char
[]
getTileLetters
()
{
return
tileLetters
;
}
public
void
setTileLetters
(
char
[]
tileLetters
)
{
this
.
tileLetters
=
tileLetters
;
}
@NonNull
public
byte
[]
getCoordinates
()
{
return
coordinates
;
...
...
app/src/main/java/net/pietu1998/wordbasehacker/solver/Tile.java
View file @
d326e41c
package
net.pietu1998.wordbasehacker.solver
;
public
class
Tile
{
public
final
class
Tile
{
public
static
final
int
PLAYER
=
1
;
public
static
final
int
OPPONENT
=
2
;
...
...
@@ -8,27 +8,6 @@ public class Tile {
public
static
final
int
BASE
=
8
;
public
static
final
int
SUPER_MINE
=
16
;
private
int
flags
;
private
char
letter
;