diff --git a/android/gradle.properties b/android/gradle.properties
index 7d3ad5fb1ba80989d0c88e55ec415fdc9f5d25f7..2c9d43c520a06b38808242c86e55863c0653df88 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.46
-app.versionCode=46
+app.versionName=0.0.47
+app.versionCode=47
diff --git a/assets/icons/button_random_pick.png b/assets/icons/button_random_pick.png
new file mode 100644
index 0000000000000000000000000000000000000000..7268257b2f50ae51d9c1944fbb5b40767d0aa8fd
Binary files /dev/null and b/assets/icons/button_random_pick.png differ
diff --git a/fastlane/metadata/android/en-US/changelogs/47.txt b/fastlane/metadata/android/en-US/changelogs/47.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1c74d3d7591f3daed4e26a189ea080bc079e4a83
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/47.txt
@@ -0,0 +1 @@
+Add a "start random game" button
diff --git a/fastlane/metadata/android/fr-FR/changelogs/47.txt b/fastlane/metadata/android/fr-FR/changelogs/47.txt
new file mode 100644
index 0000000000000000000000000000000000000000..050a24808d848efaef8425d929267f06bc6460b2
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/47.txt
@@ -0,0 +1 @@
+Ajout d'un bouton "démarrer un puzzle aléatoire"
diff --git a/icons/build_game_icons.sh b/icons/build_game_icons.sh
index 720bca3a19dfc09cc167c7a1b0b13c106dd6fb35..a4c7b7573d1c165b3b3798d07458921e6aed7ad2 100755
--- a/icons/build_game_icons.sh
+++ b/icons/build_game_icons.sh
@@ -18,6 +18,7 @@ ICON_SIZE=192
 AVAILABLE_GAME_IMAGES="
   button_back
   button_shuffle
+  button_random_pick
   game_win
   placeholder
   tip_hidden
diff --git a/icons/button_random_pick.svg b/icons/button_random_pick.svg
new file mode 100644
index 0000000000000000000000000000000000000000..a3e39b9a0a130e233863f3d9ccbb4afeb093706e
--- /dev/null
+++ b/icons/button_random_pick.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 93.665 93.676" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m83.437 0.38264h-73.092c-5.6481 0-9.9672 4.3191-9.9672 9.9672v73.092c0 5.6481 4.3191 9.9672 9.9672 9.9672h73.092c5.6481 0 9.9672-4.3191 9.9672-9.9672v-73.092c0-5.6481-4.3191-9.9672-9.9672-9.9672z" fill="#0d6586" stroke-width="3.3224"/><g transform="matrix(.13283 0 0 .13283 .34007 9.6436)" fill="#fff" fill-rule="evenodd" stroke="#fff" stroke-width="6.049"><path d="m351.68 33.758c1.3438 0.17188 2.6562 0.58984 3.8516 1.2266l206.85 107.8c3.5938 1.9062 5.9805 5.9062 5.9492 9.9766v3.3242c0.25781 1.3477 0.23438 2.6758 0 4.0234v232.4c0 8.0234-3.5977 10.309-8.0508 12.949-67.969 39.805-136.01 79.484-204.05 119.18-4.6602 2.3828-9.293 1.8555-11.898 0.34766-68.398-39.75-136.66-79.73-204.93-119.7-6.5664-3.8711-7.6523-7.6172-7.875-12.426v-233.8c-0.0508-0.60547-0.043-1.1445 0-1.75v-4.5508c4e-3 -4.1055 2.4648-8.1133 6.125-9.9766l207.38-107.8c1.668-0.85156 3.5508-1.2773 5.4258-1.2266 0.40625-0.02344 0.81641-0.02344 1.2266 0zm-1.3984 23.801-189.35 98.352 189.18 110.25 188.82-110.25zm-196.35 119.7v210.88c61.762 35.758 123.37 71.781 184.98 107.8v-210.18c-8.5195-5.043-138.17-81.852-184.98-108.5zm333.2 74.727c-8.7695-0.42969-17.48 3.7969-22.227 11.898-0.0469 0.0742-0.12891 0.10156-0.17578 0.17578-0.0312 0.0547-0.14453 0.12109-0.17578 0.17578-6.9219 11.734-2.9922 26.805 8.3984 33.949l4e-3 -4e-3c0.17578 0.0625 0.34766 0.12109 0.52734 0.17578 11.566 6.625 26.992 2.9727 33.949-8.75v-0.17578c6.6836-11.523 3.2266-26.727-8.5742-33.773-0.0664-0.0391-0.10937-0.13281-0.17578-0.17578-0.0625-0.0391-0.11328-0.14062-0.17578-0.17578-3.5195-2.1172-7.4688-3.1328-11.375-3.3242zm-35.875 59.852c-8.7852-0.25781-17.441 4.0156-22.227 12.074v-4e-3c-0.0586 0.0586-0.11719 0.11328-0.17188 0.17188-6.6836 11.523-3.2266 26.727 8.5742 33.773 0.0664 0.0547 0.10938 0.13281 0.17578 0.17188 0.0625 0.0547 0.11328 0.14062 0.17578 0.17187 11.418 6.8672 26.918 3.1367 33.773-8.5742 0.0312-0.0547-0.0312-0.125 0-0.17188 0.043-0.0781 0.13281-0.0937 0.17578-0.17188 6.9219-11.734 2.9883-26.805-8.3984-33.949h-4e-3c-0.11328-0.0586-0.23047-0.11719-0.34766-0.17188-3.6133-2.0703-7.7305-3.207-11.727-3.3242zm-35.523 60.023c-8.7344-0.25391-17.422 3.9375-22.227 11.898-0.0195 0.0547 0.0195 0.14063 0 0.17188h-0.17578c-7.0586 11.672-2.9102 26.855 8.3984 33.949h4e-3v0.17578c11.703 7.0977 27.117 3.0078 34.125-8.3984v-4e-3c0.0586-0.0547 0.11719-0.11328 0.17188-0.17188 6.9766-11.75 3.1328-27-8.2266-34.125h4e-3c-0.17578-0.0625-0.34766-0.12109-0.52734-0.17578-3.6133-2.0703-7.5547-3.207-11.551-3.3242z"/><path d="m277.98 350.68c19.855 0 36.293 16.441 36.293 36.559 0 19.992-16.316 36.566-36.293 36.566-20.098 0-36.293-16.691-36.293-36.566 0-20.004 16.312-36.559 36.293-36.559z"/><path d="m209.89 259.82c19.98 0 36.293 16.559 36.293 36.559 0 19.875-16.195 36.566-36.293 36.566-19.977 0-36.293-16.574-36.293-36.566 0-20.117 16.438-36.559 36.293-36.559z"/><path d="m346.94 117.8c15.668 0 30 3.6641 41.234 10.379 11.234 6.7148 20.152 17.469 20.152 30.812 0 13.301-8.9531 23.957-20.176 30.633-11.223 6.6758-25.543 10.344-41.211 10.344s-29.992-3.668-41.215-10.344-20.176-17.332-20.176-30.633c0-13.344 8.9258-24.094 20.16-30.812 11.234-6.7148 25.566-10.379 41.234-10.379z"/></g></svg>
diff --git a/lib/provider/data.dart b/lib/provider/data.dart
index 5deb9c48c7b0f066f9e79550b0d15f22bf176835..d11f57f5c3def7881eb4be52c5b5bc74bd5a94be 100644
--- a/lib/provider/data.dart
+++ b/lib/provider/data.dart
@@ -9,6 +9,7 @@ class Data extends ChangeNotifier {
   List _availableImages = [];
   String _selectedImage = '';
   List<MovingTile> _tiles = [];
+  double _tileImageSize = 1.0;
 
   // application state
   bool _isShufflingBoard = false;
@@ -60,6 +61,11 @@ class Data extends ChangeNotifier {
     notifyListeners();
   }
 
+  double get tileImageSize => _tileImageSize;
+  void updateTileImageSize(double tileImageSize) {
+    _tileImageSize = tileImageSize;
+  }
+
   void swapTiles(List<int> tile1, List<int> tile2) {
     int indexTile1 = _tiles.indexWhere(
         (tile) => ((tile.currentCol == tile1[0]) && (tile.currentRow == tile1[1])));
diff --git a/lib/screens/home.dart b/lib/screens/home.dart
index 3db611e9f1f3e81050cbe7fa53c1e73675c05f31..f2047d497b067074f5dc28edbb95a835a8abea14 100644
--- a/lib/screens/home.dart
+++ b/lib/screens/home.dart
@@ -24,10 +24,8 @@ class Home extends StatelessWidget {
     }
   }
 
-  Future<void> selectImage(Data myProvider, String imageCode, double tileImageSize) async {
-    myProvider.updateIsShufflingBoard(true);
-    myProvider.updateSelectedImage(imageCode);
-    GameUtils.startGame(myProvider, tileImageSize);
+  Future<void> selectImage(Data myProvider, String imageCode) async {
+    GameUtils.startGame(myProvider, imageCode);
   }
 
   void shuffleAvailableImages(Data myProvider) {
@@ -36,7 +34,7 @@ class Home extends StatelessWidget {
     myProvider.updateAvailableImages(images);
   }
 
-  Container _buildImageSelectorItem(Data myProvider, String image, double tileImageSize) {
+  Container _buildImageSelectorItem(Data myProvider, String image) {
     return Container(
       child: TextButton(
         style: TextButton.styleFrom(
@@ -56,13 +54,13 @@ class Home extends StatelessWidget {
           ),
         ),
         onPressed: () {
-          selectImage(myProvider, image, tileImageSize);
+          selectImage(myProvider, image);
         },
       ),
     );
   }
 
-  Container _buildImageSelector(Data myProvider, double tileImageSize) {
+  Container _buildImageSelector(Data myProvider) {
     if (myProvider.availableImages.length == 0) {
       getImagesList(myProvider);
     }
@@ -84,8 +82,7 @@ class Home extends StatelessWidget {
                       Column(
                         children: [
                           if (imgIndex + colIndex < images.length)
-                            _buildImageSelectorItem(
-                                myProvider, images[imgIndex + colIndex], tileImageSize)
+                            _buildImageSelectorItem(myProvider, images[imgIndex + colIndex])
                         ],
                       ),
                   ],
@@ -133,14 +130,15 @@ class Home extends StatelessWidget {
 
     var content;
 
-    double _tileImageSize = (MediaQuery.of(context).size.width - 70) / _myProvider.tilesCount;
+    _myProvider.updateTileImageSize(
+        (MediaQuery.of(context).size.width - 70) / _myProvider.tilesCount);
 
     if (_myProvider.isShufflingBoard) {
       content = Game.buildShufflingIndicatorWidget();
       precacheImage(new AssetImage('assets/icons/game_win.png'), context);
     } else {
       if (_myProvider.selectedImage == '') {
-        content = _buildImageSelector(_myProvider, _tileImageSize);
+        content = _buildImageSelector(_myProvider);
       } else {
         content = Game.buildGameWidget(_myProvider);
       }
@@ -166,6 +164,22 @@ class Home extends StatelessWidget {
         ),
         onPressed: () => shuffleAvailableImages(_myProvider),
       ),
+      TextButton(
+        child: Container(
+          decoration: BoxDecoration(
+            borderRadius: BorderRadius.circular(4),
+            border: Border.all(
+              color: themePrimaryColor,
+              width: 4,
+            ),
+          ),
+          child: Image(
+            image: AssetImage('assets/icons/button_random_pick.png'),
+            fit: BoxFit.fill,
+          ),
+        ),
+        onPressed: () => GameUtils.startRandomGame(_myProvider),
+      ),
     ];
 
     List<Widget> gameActions = [
diff --git a/lib/utils/game_utils.dart b/lib/utils/game_utils.dart
index c22242a4712c7616c373b99915c680cba9b2b5ea..d3df124e283a1c485e38d8d27f2bb1bb7c94a58c 100644
--- a/lib/utils/game_utils.dart
+++ b/lib/utils/game_utils.dart
@@ -14,12 +14,26 @@ class GameUtils {
     return 'assets/images/' + imageCode + '.png';
   }
 
-  static startGame(Data myProvider, double tileImageSize) {
+  static startGame(Data myProvider, String imageCode) {
+    myProvider.updateIsShufflingBoard(true);
+    myProvider.updateSelectedImage(imageCode);
+
     new Timer(new Duration(seconds: 1), () {
-      GameUtils.splitImageInTiles(myProvider, tileImageSize);
+      GameUtils.splitImageInTiles(myProvider);
     });
   }
 
+  static startRandomGame(Data myProvider) {
+    List sizes = [3, 4, 5];
+    sizes.shuffle();
+    myProvider.updateTilesCount(sizes[0]);
+
+    List images = myProvider.availableImages;
+    images.shuffle();
+
+    startGame(myProvider, images[0]);
+  }
+
   static Future<void> resetGame(Data myProvider) async {
     myProvider.resetSelectedImage();
     myProvider.updateIsTipImageDisplayed(false);
@@ -58,7 +72,7 @@ class GameUtils {
     return tiles;
   }
 
-  static Future<void> splitImageInTiles(Data myProvider, double tileImageSize) async {
+  static Future<void> splitImageInTiles(Data myProvider) async {
     String imageAsset = getImageAssetName(myProvider.selectedImage);
     Uint8List imageData = (await rootBundle.load(imageAsset)).buffer.asUint8List();
 
@@ -81,7 +95,7 @@ class GameUtils {
 
         tiles.add(MovingTile(
           Image.memory(tileData),
-          tileImageSize,
+          myProvider.tileImageSize,
           j,
           i,
           j,