Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
org.benoitharrault.sudoku
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
android
org.benoitharrault.sudoku
Commits
c3582b1f
Commit
c3582b1f
authored
Jun 24, 2021
by
Benoît Harrault
Browse files
Options
Downloads
Patches
Plain Diff
Allow non square sub-blocks, add 3x2 game mode
parent
54ca2069
No related branches found
No related tags found
1 merge request
!16
Resolve "Allow non square sub-blocks"
Pipeline
#1429
passed
Jun 24, 2021
Stage: update
Stage: build-debug
Changes
23
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
lib/utils/board_utils.dart
+70
-55
70 additions, 55 deletions
lib/utils/board_utils.dart
lib/utils/game_utils.dart
+2
-1
2 additions, 1 deletion
lib/utils/game_utils.dart
lib/utils/random_pick_grid.dart
+4
-6
4 additions, 6 deletions
lib/utils/random_pick_grid.dart
with
76 additions
and
62 deletions
lib/utils/board_utils.dart
+
70
−
55
View file @
c3582b1f
...
@@ -22,30 +22,33 @@ class BoardUtils {
...
@@ -22,30 +22,33 @@ class BoardUtils {
static
Future
<
void
>
pickGrid
(
Data
myProvider
)
async
{
static
Future
<
void
>
pickGrid
(
Data
myProvider
)
async
{
int
size
=
myProvider
.
size
;
String
grid
;
String
grid
;
RandomPickGrid
randomPickGrid
;
RandomPickGrid
randomPickGrid
;
randomPickGrid
=
RandomPickGrid
();
randomPickGrid
=
RandomPickGrid
();
await
randomPickGrid
.
init
(
myProvider
.
level
,
size
);
await
randomPickGrid
.
init
(
myProvider
.
level
,
myProvider
.
size
);
if
(
randomPickGrid
.
grid
!=
null
)
{
if
(
randomPickGrid
.
grid
!=
null
)
{
grid
=
randomPickGrid
.
grid
;
grid
=
randomPickGrid
.
grid
;
}
}
if
(
grid
.
length
==
pow
(
size
,
4
))
{
int
blockSizeHorizontal
=
myProvider
.
blockSizeHorizontal
;
myProvider
.
updateCells
=
BoardUtils
.
createBoardFromTemplate
(
grid
);
int
blockSizeVertical
=
myProvider
.
blockSizeVertical
;
if
(
grid
.
length
==
pow
(
blockSizeHorizontal
*
blockSizeVertical
,
2
))
{
print
(
'Picked grid from template: '
+
grid
);
bool
isSymetric
=
(
blockSizeHorizontal
==
blockSizeVertical
);
myProvider
.
updateCells
=
BoardUtils
.
createBoardFromTemplate
(
grid
,
isSymetric
);
}
}
}
}
static
List
createEmptyBoard
(
int
s
ize
)
{
static
List
createEmptyBoard
(
int
boardS
ize
)
{
int
index
=
0
;
int
index
=
0
;
List
cells
=
[];
List
cells
=
[];
for
(
var
rowIndex
=
0
;
rowIndex
<
pow
(
size
,
2
)
;
rowIndex
++
)
{
for
(
var
rowIndex
=
0
;
rowIndex
<
boardSize
;
rowIndex
++
)
{
List
row
=
[];
List
row
=
[];
for
(
var
colIndex
=
0
;
colIndex
<
pow
(
size
,
2
)
;
colIndex
++
)
{
for
(
var
colIndex
=
0
;
colIndex
<
boardSize
;
colIndex
++
)
{
row
.
add
(
Cell
(
0
,
false
));
row
.
add
(
Cell
(
0
,
false
));
}
}
cells
.
add
(
row
);
cells
.
add
(
row
);
...
@@ -55,44 +58,51 @@ class BoardUtils {
...
@@ -55,44 +58,51 @@ class BoardUtils {
}
}
static
List
createBoardFromTemplate
(
String
grid
)
{
static
List
createBoardFromTemplate
(
String
grid
,
bool
isSymetric
)
{
List
cells
=
[];
List
cells
=
[];
int
size
=
int
.
parse
(
pow
(
grid
.
length
,
1
/
4
)
.
toStringAsFixed
(
0
));
int
boardSize
=
int
.
parse
(
pow
(
grid
.
length
,
1
/
2
)
.
toStringAsFixed
(
0
));
int
sideLength
=
pow
(
size
,
2
);
int
index
=
0
;
int
index
=
0
;
for
(
var
rowIndex
=
0
;
rowIndex
<
sideLength
;
rowIndex
++
)
{
for
(
var
rowIndex
=
0
;
rowIndex
<
boardSize
;
rowIndex
++
)
{
List
row
=
[];
List
row
=
[];
for
(
var
colIndex
=
0
;
colIndex
<
sideLength
;
colIndex
++
)
{
for
(
var
colIndex
=
0
;
colIndex
<
boardSize
;
colIndex
++
)
{
int
value
=
int
.
parse
(
grid
[
index
++
]);
int
value
=
int
.
parse
(
grid
[
index
++
]);
row
.
add
(
Cell
(
value
,
(
value
!=
0
)));
row
.
add
(
Cell
(
value
,
(
value
!=
0
)));
}
}
cells
.
add
(
row
);
cells
.
add
(
row
);
}
}
List
<
String
>
allowedFlip
=
[
''
,
'horizontal'
,
'vertical'
];
List
<
String
>
allowedFlip
=
[
'none'
,
'horizontal'
,
'vertical'
];
List
<
String
>
allowedRotate
=
[
''
,
'left'
,
'right'
];
List
<
String
>
allowedRotate
=
[
'none'
,
'left'
,
'right'
];
// Forbid rotation if blocks are not symetric
if
(
!
isSymetric
)
{
allowedRotate
=
[
'none'
];
}
var
rand
=
new
Random
();
var
rand
=
new
Random
();
String
flip
=
allowedFlip
[
rand
.
nextInt
(
allowedFlip
.
length
)];
String
flip
=
allowedFlip
[
rand
.
nextInt
(
allowedFlip
.
length
)];
String
rotate
=
allowedRotate
[
rand
.
nextInt
(
allowedRotate
.
length
)];
String
rotate
=
allowedRotate
[
rand
.
nextInt
(
allowedRotate
.
length
)];
print
(
'flip board: '
+
flip
);
print
(
'rotate board: '
+
rotate
);
switch
(
flip
)
{
switch
(
flip
)
{
case
'horizontal'
:
{
case
'horizontal'
:
{
List
transformedBoard
=
createEmptyBoard
(
s
ize
);
List
transformedBoard
=
createEmptyBoard
(
boardS
ize
);
for
(
var
rowIndex
=
0
;
rowIndex
<
sideLength
;
rowIndex
++
)
{
for
(
var
rowIndex
=
0
;
rowIndex
<
boardSize
;
rowIndex
++
)
{
for
(
var
colIndex
=
0
;
colIndex
<
sideLength
;
colIndex
++
)
{
for
(
var
colIndex
=
0
;
colIndex
<
boardSize
;
colIndex
++
)
{
transformedBoard
[
rowIndex
][
colIndex
]
.
value
=
cells
[
sideLength
-
rowIndex
-
1
][
colIndex
]
.
value
;
transformedBoard
[
rowIndex
][
colIndex
]
.
value
=
cells
[
boardSize
-
rowIndex
-
1
][
colIndex
]
.
value
;
}
}
}
}
cells
=
transformedBoard
;
cells
=
transformedBoard
;
}
}
break
;
break
;
case
'vertical'
:
{
case
'vertical'
:
{
List
transformedBoard
=
createEmptyBoard
(
s
ize
);
List
transformedBoard
=
createEmptyBoard
(
boardS
ize
);
for
(
var
rowIndex
=
0
;
rowIndex
<
sideLength
;
rowIndex
++
)
{
for
(
var
rowIndex
=
0
;
rowIndex
<
boardSize
;
rowIndex
++
)
{
for
(
var
colIndex
=
0
;
colIndex
<
sideLength
;
colIndex
++
)
{
for
(
var
colIndex
=
0
;
colIndex
<
boardSize
;
colIndex
++
)
{
transformedBoard
[
rowIndex
][
colIndex
]
.
value
=
cells
[
rowIndex
][
sideLength
-
colIndex
-
1
]
.
value
;
transformedBoard
[
rowIndex
][
colIndex
]
.
value
=
cells
[
rowIndex
][
boardSize
-
colIndex
-
1
]
.
value
;
}
}
}
}
cells
=
transformedBoard
;
cells
=
transformedBoard
;
...
@@ -102,20 +112,20 @@ class BoardUtils {
...
@@ -102,20 +112,20 @@ class BoardUtils {
switch
(
rotate
)
{
switch
(
rotate
)
{
case
'left'
:
{
case
'left'
:
{
List
transformedBoard
=
createEmptyBoard
(
s
ize
);
List
transformedBoard
=
createEmptyBoard
(
boardS
ize
);
for
(
var
rowIndex
=
0
;
rowIndex
<
sideLength
;
rowIndex
++
)
{
for
(
var
rowIndex
=
0
;
rowIndex
<
boardSize
;
rowIndex
++
)
{
for
(
var
colIndex
=
0
;
colIndex
<
sideLength
;
colIndex
++
)
{
for
(
var
colIndex
=
0
;
colIndex
<
boardSize
;
colIndex
++
)
{
transformedBoard
[
rowIndex
][
colIndex
]
.
value
=
cells
[
colIndex
][
sideLength
-
rowIndex
-
1
]
.
value
;
transformedBoard
[
rowIndex
][
colIndex
]
.
value
=
cells
[
colIndex
][
boardSize
-
rowIndex
-
1
]
.
value
;
}
}
}
}
cells
=
transformedBoard
;
cells
=
transformedBoard
;
}
}
break
;
break
;
case
'right'
:
{
case
'right'
:
{
List
transformedBoard
=
createEmptyBoard
(
s
ize
);
List
transformedBoard
=
createEmptyBoard
(
boardS
ize
);
for
(
var
rowIndex
=
0
;
rowIndex
<
sideLength
;
rowIndex
++
)
{
for
(
var
rowIndex
=
0
;
rowIndex
<
boardSize
;
rowIndex
++
)
{
for
(
var
colIndex
=
0
;
colIndex
<
sideLength
;
colIndex
++
)
{
for
(
var
colIndex
=
0
;
colIndex
<
boardSize
;
colIndex
++
)
{
transformedBoard
[
rowIndex
][
colIndex
]
.
value
=
cells
[
sideLength
-
colIndex
-
1
][
rowIndex
]
.
value
;
transformedBoard
[
rowIndex
][
colIndex
]
.
value
=
cells
[
boardSize
-
colIndex
-
1
][
rowIndex
]
.
value
;
}
}
}
}
cells
=
transformedBoard
;
cells
=
transformedBoard
;
...
@@ -124,8 +134,8 @@ class BoardUtils {
...
@@ -124,8 +134,8 @@ class BoardUtils {
}
}
// Fix cells fixed states
// Fix cells fixed states
for
(
var
rowIndex
=
0
;
rowIndex
<
sideLength
;
rowIndex
++
)
{
for
(
var
rowIndex
=
0
;
rowIndex
<
boardSize
;
rowIndex
++
)
{
for
(
var
colIndex
=
0
;
colIndex
<
sideLength
;
colIndex
++
)
{
for
(
var
colIndex
=
0
;
colIndex
<
boardSize
;
colIndex
++
)
{
cells
[
rowIndex
][
colIndex
]
.
isFixed
=
(
cells
[
rowIndex
][
colIndex
]
.
value
!=
0
)
?
true
:
false
;
cells
[
rowIndex
][
colIndex
]
.
isFixed
=
(
cells
[
rowIndex
][
colIndex
]
.
value
!=
0
)
?
true
:
false
;
}
}
}
}
...
@@ -138,21 +148,24 @@ class BoardUtils {
...
@@ -138,21 +148,24 @@ class BoardUtils {
static
bool
checkBoardIsSolved
(
Data
myProvider
)
{
static
bool
checkBoardIsSolved
(
Data
myProvider
)
{
List
cells
=
myProvider
.
cells
;
List
cells
=
myProvider
.
cells
;
int
size
=
myProvider
.
size
;
int
sideLength
=
pow
(
size
,
2
);
int
blockSizeHorizontal
=
myProvider
.
blockSizeHorizontal
;
int
blockSizeVertical
=
myProvider
.
blockSizeVertical
;
int
boardSize
=
blockSizeHorizontal
*
blockSizeVertical
;
bool
isSolved
=
true
;
bool
isSolved
=
true
;
// reset conflict states
// reset conflict states
for
(
var
row
=
0
;
row
<
sideLength
;
row
++
)
{
for
(
var
row
=
0
;
row
<
boardSize
;
row
++
)
{
for
(
var
col
=
0
;
col
<
sideLength
;
col
++
)
{
for
(
var
col
=
0
;
col
<
boardSize
;
col
++
)
{
cells
[
row
][
col
]
.
conflictsCount
=
0
;
cells
[
row
][
col
]
.
conflictsCount
=
0
;
}
}
}
}
// check grid is fully completed
// check grid is fully completed
for
(
var
row
=
0
;
row
<
sideLength
;
row
++
)
{
for
(
var
row
=
0
;
row
<
boardSize
;
row
++
)
{
for
(
var
col
=
0
;
col
<
sideLength
;
col
++
)
{
for
(
var
col
=
0
;
col
<
boardSize
;
col
++
)
{
if
(
cells
[
row
][
col
]
.
value
==
0
)
{
if
(
cells
[
row
][
col
]
.
value
==
0
)
{
isSolved
=
false
;
isSolved
=
false
;
}
}
...
@@ -160,9 +173,9 @@ class BoardUtils {
...
@@ -160,9 +173,9 @@ class BoardUtils {
}
}
// check lines does not contains a value twice
// check lines does not contains a value twice
for
(
var
row
=
0
;
row
<
sideLength
;
row
++
)
{
for
(
var
row
=
0
;
row
<
boardSize
;
row
++
)
{
List
values
=
[];
List
values
=
[];
for
(
var
col
=
0
;
col
<
sideLength
;
col
++
)
{
for
(
var
col
=
0
;
col
<
boardSize
;
col
++
)
{
int
value
=
cells
[
row
][
col
]
.
value
;
int
value
=
cells
[
row
][
col
]
.
value
;
if
(
value
!=
0
)
{
if
(
value
!=
0
)
{
values
.
add
(
value
);
values
.
add
(
value
);
...
@@ -172,7 +185,7 @@ class BoardUtils {
...
@@ -172,7 +185,7 @@ class BoardUtils {
if
(
values
.
length
!=
distinctValues
.
length
)
{
if
(
values
.
length
!=
distinctValues
.
length
)
{
print
(
'line '
+
row
.
toString
()
+
' contains duplicates'
);
print
(
'line '
+
row
.
toString
()
+
' contains duplicates'
);
// Add line to cells in conflict
// Add line to cells in conflict
for
(
var
col
=
0
;
col
<
sideLength
;
col
++
)
{
for
(
var
col
=
0
;
col
<
boardSize
;
col
++
)
{
cells
[
row
][
col
]
.
conflictsCount
++
;
cells
[
row
][
col
]
.
conflictsCount
++
;
}
}
isSolved
=
false
;
isSolved
=
false
;
...
@@ -180,9 +193,9 @@ class BoardUtils {
...
@@ -180,9 +193,9 @@ class BoardUtils {
}
}
// check columns does not contains a value twice
// check columns does not contains a value twice
for
(
var
col
=
0
;
col
<
sideLength
;
col
++
)
{
for
(
var
col
=
0
;
col
<
boardSize
;
col
++
)
{
List
values
=
[];
List
values
=
[];
for
(
var
row
=
0
;
row
<
sideLength
;
row
++
)
{
for
(
var
row
=
0
;
row
<
boardSize
;
row
++
)
{
int
value
=
cells
[
row
][
col
]
.
value
;
int
value
=
cells
[
row
][
col
]
.
value
;
if
(
value
!=
0
)
{
if
(
value
!=
0
)
{
values
.
add
(
value
);
values
.
add
(
value
);
...
@@ -192,7 +205,7 @@ class BoardUtils {
...
@@ -192,7 +205,7 @@ class BoardUtils {
if
(
values
.
length
!=
distinctValues
.
length
)
{
if
(
values
.
length
!=
distinctValues
.
length
)
{
print
(
'column '
+
col
.
toString
()
+
' contains duplicates'
);
print
(
'column '
+
col
.
toString
()
+
' contains duplicates'
);
// Add column to cells in conflict
// Add column to cells in conflict
for
(
var
row
=
0
;
row
<
sideLength
;
row
++
)
{
for
(
var
row
=
0
;
row
<
boardSize
;
row
++
)
{
cells
[
row
][
col
]
.
conflictsCount
++
;
cells
[
row
][
col
]
.
conflictsCount
++
;
}
}
isSolved
=
false
;
isSolved
=
false
;
...
@@ -200,14 +213,16 @@ class BoardUtils {
...
@@ -200,14 +213,16 @@ class BoardUtils {
}
}
// check blocks does not contains a value twice
// check blocks does not contains a value twice
for
(
var
blockRow
=
0
;
blockRow
<
size
;
blockRow
++
)
{
int
horizontalBlocksCount
=
blockSizeVertical
;
for
(
var
blockCol
=
0
;
blockCol
<
size
;
blockCol
++
)
{
int
verticalBlocksCount
=
blockSizeHorizontal
;
for
(
var
blockRow
=
0
;
blockRow
<
verticalBlocksCount
;
blockRow
++
)
{
for
(
var
blockCol
=
0
;
blockCol
<
horizontalBlocksCount
;
blockCol
++
)
{
List
values
=
[];
List
values
=
[];
for
(
var
rowInBlock
=
0
;
rowInBlock
<
size
;
rowInBlock
++
)
{
for
(
var
rowInBlock
=
0
;
rowInBlock
<
blockSizeVertical
;
rowInBlock
++
)
{
for
(
var
colInBlock
=
0
;
colInBlock
<
size
;
colInBlock
++
)
{
for
(
var
colInBlock
=
0
;
colInBlock
<
blockSizeHorizontal
;
colInBlock
++
)
{
int
row
=
(
blockRow
*
size
)
+
rowInBlock
;
int
row
=
(
blockRow
*
blockSizeVertical
)
+
rowInBlock
;
int
col
=
(
blockCol
*
size
)
+
colInBlock
;
int
col
=
(
blockCol
*
blockSizeHorizontal
)
+
colInBlock
;
int
value
=
cells
[
row
][
col
]
.
value
;
int
value
=
cells
[
row
][
col
]
.
value
;
if
(
value
!=
0
)
{
if
(
value
!=
0
)
{
values
.
add
(
value
);
values
.
add
(
value
);
...
@@ -219,10 +234,10 @@ class BoardUtils {
...
@@ -219,10 +234,10 @@ class BoardUtils {
if
(
values
.
length
!=
distinctValues
.
length
)
{
if
(
values
.
length
!=
distinctValues
.
length
)
{
print
(
'block ['
+
blockCol
.
toString
()
+
','
+
blockRow
.
toString
()
+
'] contains duplicates'
);
print
(
'block ['
+
blockCol
.
toString
()
+
','
+
blockRow
.
toString
()
+
'] contains duplicates'
);
// Add blocks to cells in conflict
// Add blocks to cells in conflict
for
(
var
rowInBlock
=
0
;
rowInBlock
<
size
;
rowInBlock
++
)
{
for
(
var
rowInBlock
=
0
;
rowInBlock
<
blockSizeVertical
;
rowInBlock
++
)
{
for
(
var
colInBlock
=
0
;
colInBlock
<
size
;
colInBlock
++
)
{
for
(
var
colInBlock
=
0
;
colInBlock
<
blockSizeHorizontal
;
colInBlock
++
)
{
int
row
=
(
blockRow
*
size
)
+
rowInBlock
;
int
row
=
(
blockRow
*
blockSizeVertical
)
+
rowInBlock
;
int
col
=
(
blockCol
*
size
)
+
colInBlock
;
int
col
=
(
blockCol
*
blockSizeHorizontal
)
+
colInBlock
;
cells
[
row
][
col
]
.
conflictsCount
++
;
cells
[
row
][
col
]
.
conflictsCount
++
;
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
lib/utils/game_utils.dart
+
2
−
1
View file @
c3582b1f
...
@@ -8,8 +8,9 @@ class GameUtils {
...
@@ -8,8 +8,9 @@ class GameUtils {
}
}
static
Future
<
void
>
startGame
(
Data
myProvider
)
async
{
static
Future
<
void
>
startGame
(
Data
myProvider
)
async
{
print
(
'Start new game: '
+
myProvider
.
size
);
myProvider
.
updateStateRunning
=
true
;
myProvider
.
updateStateRunning
=
true
;
myProvider
.
updateCells
=
BoardUtils
.
createEmptyBoard
(
myProvider
.
size
);
myProvider
.
updateCells
=
BoardUtils
.
createEmptyBoard
(
myProvider
.
blockSizeHorizontal
*
myProvider
.
blockSizeVertical
);
BoardUtils
.
pickGrid
(
myProvider
);
BoardUtils
.
pickGrid
(
myProvider
);
}
}
}
}
This diff is collapsed.
Click to expand it.
lib/utils/random_pick_grid.dart
+
4
−
6
View file @
c3582b1f
...
@@ -6,27 +6,25 @@ class RandomPickGrid {
...
@@ -6,27 +6,25 @@ class RandomPickGrid {
String
_grid
;
String
_grid
;
init
(
String
difficulty
,
in
t
size
)
async
{
init
(
String
difficulty
,
Str
in
g
size
)
async
{
_grid
=
''
;
_grid
=
''
;
await
gridFromLocalFile
(
difficulty
,
size
);
await
gridFromLocalFile
(
difficulty
,
size
);
}
}
Future
<
void
>
gridFromLocalFile
(
String
difficulty
,
int
size
)
async
{
Future
<
void
>
gridFromLocalFile
(
String
difficulty
,
String
size
)
async
{
String
sizeAsString
=
size
.
toString
()
+
'x'
+
size
.
toString
();
// Get global grids list
// Get global grids list
List
grids
;
List
grids
;
try
{
try
{
String
jsonString
=
await
rootBundle
.
loadString
(
'assets/files/templates.json'
);
String
jsonString
=
await
rootBundle
.
loadString
(
'assets/files/templates.json'
);
final
jsonResponse
=
await
json
.
decode
(
jsonString
);
final
jsonResponse
=
await
json
.
decode
(
jsonString
);
grids
=
jsonResponse
[
'templates'
][
size
AsString
][
difficulty
];
grids
=
jsonResponse
[
'templates'
][
size
][
difficulty
];
}
catch
(
e
)
{
}
catch
(
e
)
{
print
(
"
$e
"
);
print
(
"
$e
"
);
}
}
// Check we have enough grids
// Check we have enough grids
if
(
grids
.
length
<
1
)
{
if
(
grids
.
length
<
1
)
{
print
(
'Not enough grids ['
+
size
AsString
+
', '
+
difficulty
+
'] in templates.'
);
print
(
'Not enough grids ['
+
size
+
', '
+
difficulty
+
'] in templates.'
);
}
}
// Randomize grids list
// Randomize grids list
...
...
This diff is collapsed.
Click to expand it.
Prev
1
2
Next
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
sign in
to comment