From 7b7d229f9cfaf56ec137e5c4f7e952320c564c03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr>
Date: Tue, 15 Jun 2021 22:17:56 +0200
Subject: [PATCH] Add generate initial board feature

---
 android/gradle.properties       |  4 +--
 assets/files/templates.json     | 45 +++++++++++++++++++++++++
 lib/screens/home.dart           | 60 ++++++++++++++++++++++++++-------
 lib/utils/random_pick_grid.dart | 41 ++++++++++++++++++++++
 pubspec.yaml                    |  1 +
 5 files changed, 137 insertions(+), 14 deletions(-)
 create mode 100644 assets/files/templates.json
 create mode 100644 lib/utils/random_pick_grid.dart

diff --git a/android/gradle.properties b/android/gradle.properties
index db7a1ee..14eed39 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -1,5 +1,5 @@
 org.gradle.jvmargs=-Xmx1536M
 android.useAndroidX=true
 android.enableJetifier=true
-app.versionName=0.0.3
-app.versionCode=3
+app.versionName=0.0.4
+app.versionCode=4
diff --git a/assets/files/templates.json b/assets/files/templates.json
new file mode 100644
index 0000000..d0312cf
--- /dev/null
+++ b/assets/files/templates.json
@@ -0,0 +1,45 @@
+{
+  "templates": {
+    "2x2": {
+      "easy": [
+        "0000320400210100",
+        "0003034000040000",
+        "0402000000004020",
+        "0002001443002000",
+        "4312020000000020"
+      ],
+      "medium": [
+        "3012200003000000",
+        "0003104030002100",
+        "0410100400000030",
+        "0100000030120000"
+      ],
+      "hard": [
+        "0001000003000034",
+        "1000032000040002",
+        "0420000000100040",
+        "0300010010030240"
+      ]
+    },
+    "3x3": {
+      "easy": [
+        "402370008801000000009086400108020000200060009000090207006450100000000603700032905",
+        "000100035060203000020059041002008304000000000509600700450320010000401070780005000",
+        "000130000070960050596000001000700105380000079704009000800000243040083010000091000",
+        "000300000001006030384200100700083056600000003830610002008005649060400200000002000"
+      ],
+      "medium": [
+        "800050003004902700000340600305100800200030001001008409006093000003807200100060004",
+        "020000370500036029000200605004701006000000000600904100802009000950340007043000050",
+        "005060300091000005206400078000957010000000000080143000510004709900000620002030500",
+        "040006090080000320090570040005307900800090004009804200050089030073000010010700060"
+      ],
+      "hard": [
+        "010900700050000060006207900600700080320804096080006007005602300060000010008003040",
+        "000009850900600402007050001000000093861000724730000000100020600406003009092800000",
+        "064900100000020006107006090000050364030000010576040000090500201700090000005007680",
+        "008007010512000370470051000000705900000010000004306000000560098045000763030900100"
+      ]
+    }
+  }
+}
diff --git a/lib/screens/home.dart b/lib/screens/home.dart
index 62d2155..7d399f9 100644
--- a/lib/screens/home.dart
+++ b/lib/screens/home.dart
@@ -1,8 +1,11 @@
+import 'dart:math';
+
 import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
 
 import '../entities/cell.dart';
 import '../provider/data.dart';
+import '../utils/random_pick_grid.dart';
 
 class Home extends StatelessWidget {
   static const String id = 'home';
@@ -17,21 +20,54 @@ class Home extends StatelessWidget {
   Future<void> startGame(Data myProvider) async {
     myProvider.updateStateRunning = true;
     myProvider.updateCells = createEmptyBoard(myProvider.size);
+    pickGrid(myProvider);
+  }
+
+  Future<void> pickGrid(Data myProvider) async {
+    int size = myProvider.size;
+
+    String grid;
+    RandomPickGrid randomPickGrid;
+
+    randomPickGrid = RandomPickGrid();
+    await randomPickGrid.init(myProvider.level, size);
+
+    if (randomPickGrid.grid != null) {
+      grid = randomPickGrid.grid;
+    }
+
+    if (grid.length == pow(size, 4)) {
+      List cells = createBoardFromTemplate(grid);
+      myProvider.updateCells = cells;
+    }
+  }
+
+  List createBoardFromTemplate(String grid) {
+    List cells = [];
+    int size = int.parse(pow(grid.length, 1/4).toStringAsFixed(0));
+
+    int index = 0;
+    for (var rowIndex = 0; rowIndex < pow(size, 2); rowIndex++) {
+      List row = [];
+      for (var colIndex = 0; colIndex < pow(size, 2); colIndex++) {
+        int value = int.parse(grid[index++]);
+        row.add(Cell(value, colIndex, rowIndex));
+      }
+      cells.add(row);
+    }
+
+    // TODO: shuffle/flip/rotate grid
+    
+    return cells;
   }
 
   List createEmptyBoard(int size) {
     int index = 0;
     List cells = [];
-    for (var rowIndex = 0; rowIndex < (size * size); rowIndex++) {
+    for (var rowIndex = 0; rowIndex < pow(size, 2); rowIndex++) {
       List row = [];
-      for (var colIndex = 0; colIndex < (size * size); colIndex++) {
-        row.add(
-          Cell(
-            (index++ % ((size * size) + 1)), // for debug purpose only :')
-            colIndex,
-            rowIndex
-          )
-        );
+      for (var colIndex = 0; colIndex < pow(size, 2); colIndex++) {
+        row.add(Cell(0, colIndex, rowIndex));
       }
       cells.add(row);
     }
@@ -160,9 +196,9 @@ class Home extends StatelessWidget {
       child: Table(
         defaultColumnWidth: IntrinsicColumnWidth(),
         children: [
-          for (var row = 0; row < (size * size); row++)
+          for (var row = 0; row < pow(size, 2); row++)
             TableRow(children: [
-              for (var col = 0; col < (size * size); col++)
+              for (var col = 0; col < pow(size, 2); col++)
                 Column(children: [
                   cells[row][col].widget(myProvider)
                 ]),
@@ -189,7 +225,7 @@ class Home extends StatelessWidget {
         children: [
           TableRow(
             children: [
-              for (var value = 0; value < ((size * size) + 1); value++)
+              for (var value = 0; value < (pow(size, 2) + 1); value++)
                 Column(
                   children: [
                     Cell(
diff --git a/lib/utils/random_pick_grid.dart b/lib/utils/random_pick_grid.dart
new file mode 100644
index 0000000..aa08feb
--- /dev/null
+++ b/lib/utils/random_pick_grid.dart
@@ -0,0 +1,41 @@
+import 'dart:async';
+import 'dart:convert';
+import 'package:flutter/services.dart';
+
+class RandomPickGrid {
+  RandomPickGrid();
+
+  String _grid;
+
+  init(String difficulty, int size) async {
+    _grid = '';
+    await gridFromLocalFile(difficulty, size);
+  }
+
+  Future<void> gridFromLocalFile(String difficulty, int size) async {
+    String sizeAsString = size.toString() + 'x' + size.toString();
+
+    // Get global grids list
+    List grids;
+    try {
+      String jsonString = await rootBundle.loadString('assets/files/templates.json');
+      final jsonResponse = await json.decode(jsonString);
+      grids = jsonResponse['templates'][sizeAsString][difficulty];
+    } catch (e) {
+      print("$e");
+    }
+
+    // Check we have enough grids
+    if (grids.length < 1) {
+      print('Not enough grids [' + sizeAsString + ', ' + difficulty + '] in templates.');
+    }
+
+    // Randomize grids list
+    grids.shuffle();
+
+    // Pick first grids from shuffled list
+    _grid = grids.take(1).toList()[0];
+  }
+
+  String get grid => _grid;
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index bbdc442..00a80e8 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -18,5 +18,6 @@ dev_dependencies:
 flutter:
   uses-material-design: true
   assets:
+    - assets/files/
     - assets/icons/
     - assets/skins/
-- 
GitLab