Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • android/org.benoitharrault.sudoku
1 result
Select Git revision
Show changes
Commits on Source (4)
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
app.versionName=0.0.38 app.versionName=0.0.40
app.versionCode=38 app.versionCode=40
Improve tip on grid if cell with wrong value, compute solved grid on new game
Save/retrieve game settings
Amélioration du coup de pouce en cas de cellule avec une valeur fausse, calcul de la grille résolue au début de la partie
Sauvegarde et recharge des paramètres de jeu
...@@ -91,12 +91,16 @@ class Cell { ...@@ -91,12 +91,16 @@ class Cell {
Color backgroundColor = Colors.grey[200]; Color backgroundColor = Colors.grey[200];
List cells = myProvider.cells;
int blockSizeHorizontal = myProvider.blockSizeHorizontal;
int blockSizeVertical = myProvider.blockSizeVertical;
if ( if (
myProvider.showConflicts myProvider.showConflicts
&& myProvider.currentCellCol != null && myProvider.currentCellCol != null
&& myProvider.currentCellRow != null && myProvider.currentCellRow != null
) { ) {
if (!BoardUtils.isValueAllowed(myProvider, myProvider.currentCellCol, myProvider.currentCellRow, this.value)) { if (!BoardUtils.isValueAllowed(cells, blockSizeHorizontal, blockSizeVertical, myProvider.currentCellCol, myProvider.currentCellRow, this.value)) {
backgroundColor = Colors.pink[100]; backgroundColor = Colors.pink[100];
} }
} }
......
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Data extends ChangeNotifier { class Data extends ChangeNotifier {
...@@ -12,9 +13,12 @@ class Data extends ChangeNotifier { ...@@ -12,9 +13,12 @@ class Data extends ChangeNotifier {
List get availableSkins => _availableSkins; List get availableSkins => _availableSkins;
// Application default configuration // Application default configuration
String _level = 'medium'; String _level = null;
String _size = '3x3'; String _levelDefault = 'medium';
String _skin = 'default'; String _size = null;
String _sizeDefault = '3x3';
String _skin = null;
String _skinDefault = 'default';
bool _showConflicts = false; bool _showConflicts = false;
// Game data // Game data
...@@ -22,6 +26,7 @@ class Data extends ChangeNotifier { ...@@ -22,6 +26,7 @@ class Data extends ChangeNotifier {
int _blockSizeVertical = null; int _blockSizeVertical = null;
int _blockSizeHorizontal = null; int _blockSizeHorizontal = null;
List _cells = []; List _cells = [];
List _cellsSolved = [];
int _currentCellCol = null; int _currentCellCol = null;
int _currentCellRow = null; int _currentCellRow = null;
int _currentCellValue = null; int _currentCellValue = null;
...@@ -77,7 +82,7 @@ class Data extends ChangeNotifier { ...@@ -77,7 +82,7 @@ class Data extends ChangeNotifier {
} }
} }
setParameterValue(String parameterCode, String parameterValue) { setParameterValue(String parameterCode, String parameterValue) async {
switch(parameterCode) { switch(parameterCode) {
case 'difficulty': { updateLevel = parameterValue; } case 'difficulty': { updateLevel = parameterValue; }
break; break;
...@@ -86,6 +91,15 @@ class Data extends ChangeNotifier { ...@@ -86,6 +91,15 @@ class Data extends ChangeNotifier {
case 'skin': { updateSkin = parameterValue; } case 'skin': { updateSkin = parameterValue; }
break; break;
} }
final prefs = await SharedPreferences.getInstance();
prefs.setString(parameterCode, parameterValue);
}
void initParametersValues() async {
final prefs = await SharedPreferences.getInstance();
setParameterValue('difficulty', prefs.getString('difficulty') ?? _levelDefault);
setParameterValue('size', prefs.getString('size') ?? _sizeDefault);
setParameterValue('skin', prefs.getString('skin') ?? _skinDefault);
} }
List get cells => _cells; List get cells => _cells;
...@@ -94,6 +108,11 @@ class Data extends ChangeNotifier { ...@@ -94,6 +108,11 @@ class Data extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
List get cellsSolved => _cellsSolved;
set updateCellsSolved(List cells) {
_cellsSolved = cells;
}
int get currentCellCol => _currentCellCol; int get currentCellCol => _currentCellCol;
set updateCurrentCellCol(int currentCellCol) { set updateCurrentCellCol(int currentCellCol) {
_currentCellCol = currentCellCol; _currentCellCol = currentCellCol;
......
...@@ -7,9 +7,22 @@ import '../layout/parameters.dart'; ...@@ -7,9 +7,22 @@ import '../layout/parameters.dart';
import '../provider/data.dart'; import '../provider/data.dart';
import '../utils/game_utils.dart'; import '../utils/game_utils.dart';
class Home extends StatelessWidget { class Home extends StatefulWidget {
static const String id = 'home'; static const String id = 'home';
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
void initState() {
super.initState();
Data myProvider = Provider.of<Data>(context, listen: false);
myProvider.initParametersValues();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Data myProvider = Provider.of<Data>(context); Data myProvider = Provider.of<Data>(context);
......
...@@ -6,16 +6,18 @@ import '../provider/data.dart'; ...@@ -6,16 +6,18 @@ import '../provider/data.dart';
class BoardUtils { class BoardUtils {
static printGrid(List cells) { static printGrid(List cells, List solvedCells) {
String stringValues = '0123456789ABCDEFG'; String stringValues = '0123456789ABCDEFG';
print(''); print('');
print('-------'); print('-------');
for (var rowIndex = 0; rowIndex < cells.length; rowIndex++) { for (var rowIndex = 0; rowIndex < cells.length; rowIndex++) {
String row = ''; String row = '';
String rowSolved = '';
for (var colIndex = 0; colIndex < cells[rowIndex].length; colIndex++) { for (var colIndex = 0; colIndex < cells[rowIndex].length; colIndex++) {
row += stringValues[cells[rowIndex][colIndex].value]; row += stringValues[cells[rowIndex][colIndex].value];
rowSolved += stringValues[solvedCells[rowIndex][colIndex].value];
} }
print(row); print(row + ' | ' + rowSolved);
} }
print('-------'); print('-------');
print(''); print('');
...@@ -40,13 +42,14 @@ class BoardUtils { ...@@ -40,13 +42,14 @@ class BoardUtils {
print('Picked grid from template: ' + grid); print('Picked grid from template: ' + grid);
bool isSymetric = (blockSizeHorizontal == blockSizeVertical); bool isSymetric = (blockSizeHorizontal == blockSizeVertical);
myProvider.updateCells = BoardUtils.createBoardFromTemplate(grid, isSymetric); myProvider.updateCells = BoardUtils.createBoardFromTemplate(grid, isSymetric);
myProvider.updateCellsSolved = BoardUtils.getSolvedGrid(myProvider);
myProvider.selectCell(null, null); myProvider.selectCell(null, null);
printGrid(myProvider.cells, myProvider.cellsSolved);
} }
} }
static List createEmptyBoard(int boardSize) { static List createEmptyBoard(int boardSize) {
int index = 0;
List cells = []; List cells = [];
for (var rowIndex = 0; rowIndex < boardSize; rowIndex++) { for (var rowIndex = 0; rowIndex < boardSize; rowIndex++) {
List row = []; List row = [];
...@@ -59,6 +62,18 @@ class BoardUtils { ...@@ -59,6 +62,18 @@ class BoardUtils {
return cells; return cells;
} }
static List copyBoard(List cells) {
List copiedGrid = [];
for (var rowIndex = 0; rowIndex < cells.length; rowIndex++) {
List row = [];
for (var colIndex = 0; colIndex < cells[rowIndex].length; colIndex++) {
row.add(Cell(cells[rowIndex][colIndex].value, false));
}
copiedGrid.add(row);
}
return copiedGrid;
}
static List createBoardFromTemplate(String grid, bool isSymetric) { static List createBoardFromTemplate(String grid, bool isSymetric) {
List cells = []; List cells = [];
...@@ -145,12 +160,9 @@ class BoardUtils { ...@@ -145,12 +160,9 @@ class BoardUtils {
} }
} }
printGrid(cells);
return cells; return cells;
} }
static bool checkBoardIsSolved(Data myProvider) { static bool checkBoardIsSolved(Data myProvider) {
List cells = myProvider.cells; List cells = myProvider.cells;
...@@ -178,16 +190,11 @@ class BoardUtils { ...@@ -178,16 +190,11 @@ class BoardUtils {
return true; return true;
} }
static bool isValueAllowed(Data myProvider, int candidateCol, int candidateRow, int candidateValue) { static bool isValueAllowed(List cells, int blockSizeHorizontal, int blockSizeVertical, int candidateCol, int candidateRow, int candidateValue) {
if (candidateValue == 0) { if (candidateValue == 0) {
return true; return true;
} }
List cells = myProvider.cells;
int blockSizeHorizontal = myProvider.blockSizeHorizontal;
int blockSizeVertical = myProvider.blockSizeVertical;
int boardSize = blockSizeHorizontal * blockSizeVertical; int boardSize = blockSizeHorizontal * blockSizeVertical;
// check lines does not contains a value twice // check lines does not contains a value twice
...@@ -257,7 +264,6 @@ class BoardUtils { ...@@ -257,7 +264,6 @@ class BoardUtils {
return true; return true;
} }
static void computeConflictsInBoard(Data myProvider) { static void computeConflictsInBoard(Data myProvider) {
List cells = myProvider.cells; List cells = myProvider.cells;
...@@ -345,4 +351,82 @@ class BoardUtils { ...@@ -345,4 +351,82 @@ class BoardUtils {
} }
} }
static List getCellsWithWrongValue(List cells, List cellsSolved, int blockSizeHorizontal, int blockSizeVertical) {
List cellsWithWrongValue = [];
int boardSize = blockSizeHorizontal * blockSizeVertical;
for (var row = 0; row < boardSize; row++) {
for (var col = 0; col < boardSize; col++) {
if (cells[row][col].value != 0 && cells[row][col].value != cellsSolved[row][col].value) {
cellsWithWrongValue.add([col, row]);
}
}
}
return cellsWithWrongValue;
}
static List getConflictingCells(List cells, int blockSizeHorizontal, int blockSizeVertical) {
List conflictingCells = [];
int boardSize = blockSizeHorizontal * blockSizeVertical;
for (var row = 0; row < boardSize; row++) {
for (var col = 0; col < boardSize; col++) {
if (!cells[row][col].isFixed && cells[row][col].value != 0) {
if (cells[row][col].conflictsCount != 0 && !BoardUtils.isValueAllowed(cells, blockSizeHorizontal, blockSizeVertical, col, row, cells[row][col].value)) {
conflictingCells.add([col, row]);
}
}
}
}
return conflictingCells;
}
static List getCellsWithUniqueAvailableValue(List cells, int blockSizeHorizontal, int blockSizeVertical) {
List candidateCells = [];
int boardSize = blockSizeHorizontal * blockSizeVertical;
for (var row = 0; row < boardSize; row++) {
for (var col = 0; col < boardSize; col++) {
if (cells[row][col].value == 0) {
int allowedValuesCount = 0;
int candidateValue = 0;
for (var value = 1; value <= boardSize; value++) {
if (BoardUtils.isValueAllowed(cells, blockSizeHorizontal, blockSizeVertical, col, row, value)) {
candidateValue = value;
allowedValuesCount++;
}
}
if (allowedValuesCount == 1) {
candidateCells.add([col, row, candidateValue]);
}
}
}
}
return candidateCells;
}
static List getSolvedGrid(Data myProvider) {
List cells = copyBoard(myProvider.cells);
int blockSizeHorizontal = myProvider.blockSizeHorizontal;
int blockSizeVertical = myProvider.blockSizeVertical;
do {
List cellsWithUniqueAvailableValue = BoardUtils.getCellsWithUniqueAvailableValue(cells, blockSizeHorizontal, blockSizeVertical);
if (cellsWithUniqueAvailableValue.length == 0) {
break;
}
for (var i = 0; i < cellsWithUniqueAvailableValue.length; i++) {
int col = cellsWithUniqueAvailableValue[i][0];
int row = cellsWithUniqueAvailableValue[i][1];
int value = cellsWithUniqueAvailableValue[i][2];
cells[row][col].value = value;
}
} while (true);
return cells;
}
} }
...@@ -29,42 +29,25 @@ class GameUtils { ...@@ -29,42 +29,25 @@ class GameUtils {
static void helpSelectCell(Data myProvider) { static void helpSelectCell(Data myProvider) {
List cells = myProvider.cells; List cells = myProvider.cells;
int boardSize = myProvider.blockSizeHorizontal * myProvider.blockSizeVertical; int blockSizeHorizontal = myProvider.blockSizeHorizontal;
int blockSizeVertical = myProvider.blockSizeVertical;
// pick one of conflicting cells, if found // pick one of wrong value cells, if found
List conflictingCells = []; List wrongValueCells = BoardUtils.getCellsWithWrongValue(cells, myProvider.cellsSolved, blockSizeHorizontal, blockSizeVertical);
for (var row = 0; row < boardSize; row++) { if (wrongValueCells.length != 0) {
for (var col = 0; col < boardSize; col++) { GameUtils.pickRandomFromList(myProvider, wrongValueCells);
if (!cells[row][col].isFixed && cells[row][col].value != 0) { return;
if (cells[row][col].conflictsCount != 0 && !BoardUtils.isValueAllowed(myProvider, col, row, cells[row][col].value)) {
conflictingCells.add([col, row]);
}
}
}
} }
// pick one of conflicting cells, if found
List conflictingCells = BoardUtils.getCellsWithUniqueAvailableValue(cells, blockSizeHorizontal, blockSizeVertical);
if (conflictingCells.length != 0) { if (conflictingCells.length != 0) {
GameUtils.pickRandomFromList(myProvider, conflictingCells); GameUtils.pickRandomFromList(myProvider, conflictingCells);
return; return;
} }
// pick one form cells with unique non-conflicting candidate value // pick one form cells with unique non-conflicting candidate value
List candidateCells = []; List candidateCells = BoardUtils.getCellsWithUniqueAvailableValue(cells, blockSizeHorizontal, blockSizeVertical);
for (var row = 0; row < boardSize; row++) {
for (var col = 0; col < boardSize; col++) {
if (cells[row][col].value == 0) {
int allowedValuesCount = 0;
for (var value = 1; value <= boardSize; value++) {
if (BoardUtils.isValueAllowed(myProvider, col, row, value)) {
allowedValuesCount++;
}
}
if (allowedValuesCount == 1) {
candidateCells.add([col, row]);
}
}
}
}
if (candidateCells.length != 0) { if (candidateCells.length != 0) {
GameUtils.pickRandomFromList(myProvider, candidateCells); GameUtils.pickRandomFromList(myProvider, candidateCells);
return; return;
...@@ -80,14 +63,19 @@ class GameUtils { ...@@ -80,14 +63,19 @@ class GameUtils {
} }
static void helpFillCell(Data myProvider) { static void helpFillCell(Data myProvider) {
int boardSize = myProvider.blockSizeHorizontal * myProvider.blockSizeVertical; List cells = myProvider.cells;
int blockSizeHorizontal = myProvider.blockSizeHorizontal;
int blockSizeVertical = myProvider.blockSizeVertical;
int boardSize = blockSizeHorizontal * blockSizeVertical;
// Will clean cell if no eligible value found
int eligibleValue = 0; int eligibleValue = 0;
// ensure there is only one eligible value for this cell // ensure there is only one eligible value for this cell
int allowedValuesCount = 0; int allowedValuesCount = 0;
for (var value = 1; value <= boardSize; value++) { for (var value = 1; value <= boardSize; value++) {
if (BoardUtils.isValueAllowed(myProvider, myProvider.currentCellCol, myProvider.currentCellRow, value)) { if (BoardUtils.isValueAllowed(cells, blockSizeHorizontal, blockSizeVertical, myProvider.currentCellCol, myProvider.currentCellRow, value)) {
allowedValuesCount++; allowedValuesCount++;
eligibleValue = value; eligibleValue = value;
} }
...@@ -97,4 +85,5 @@ class GameUtils { ...@@ -97,4 +85,5 @@ class GameUtils {
myProvider.selectCell(null, null); myProvider.selectCell(null, null);
BoardUtils.computeConflictsInBoard(myProvider); BoardUtils.computeConflictsInBoard(myProvider);
} }
} }
...@@ -35,7 +35,7 @@ packages: ...@@ -35,7 +35,7 @@ packages:
name: charcode name: charcode
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.3.1"
clock: clock:
dependency: transitive dependency: transitive
description: description:
...@@ -57,6 +57,20 @@ packages: ...@@ -57,6 +57,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.2"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
...@@ -67,6 +81,18 @@ packages: ...@@ -67,6 +81,18 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
...@@ -80,7 +106,7 @@ packages: ...@@ -80,7 +106,7 @@ packages:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.4.0" version: "1.7.0"
nested: nested:
dependency: transitive dependency: transitive
description: description:
...@@ -95,6 +121,48 @@ packages: ...@@ -95,6 +121,48 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0" version: "1.8.0"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
platform:
dependency: transitive
description:
name: platform
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.3"
provider: provider:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -102,6 +170,48 @@ packages: ...@@ -102,6 +170,48 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.0.0" version: "5.0.0"
shared_preferences:
dependency: "direct main"
description:
name: shared_preferences
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
shared_preferences_macos:
dependency: transitive
description:
name: shared_preferences_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
...@@ -148,7 +258,7 @@ packages: ...@@ -148,7 +258,7 @@ packages:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.0" version: "0.4.1"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
...@@ -163,6 +273,20 @@ packages: ...@@ -163,6 +273,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.1.0"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.5"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
sdks: sdks:
dart: ">=2.12.0 <3.0.0" dart: ">=2.13.0 <3.0.0"
flutter: ">=1.16.0" flutter: ">=2.0.0"
...@@ -11,6 +11,7 @@ dependencies: ...@@ -11,6 +11,7 @@ dependencies:
sdk: flutter sdk: flutter
provider: ^5.0.0 provider: ^5.0.0
badges: ^2.0.1 badges: ^2.0.1
shared_preferences: ^2.0.6
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
......