diff --git a/android/gradle.properties b/android/gradle.properties
index 81949dfd2077495aaea8a6bc81ad9c75442f9ebb..957c40bc42f3a742d2266dc3a403ad014458ba3f 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.14
-app.versionCode=14
+app.versionName=0.0.15
+app.versionCode=15
diff --git a/assets/files/templates.json b/assets/files/templates.json
index cd7ae73e952b2c251ac4e5addee7204f2c0ac351..4f5a298250b19ff5af470f6d42eedb3ed9ec1f57 100644
--- a/assets/files/templates.json
+++ b/assets/files/templates.json
@@ -38,6 +38,44 @@
         "0410200010000200"
       ]
     },
+    "3x2": {
+      "easy": [
+        "000142214003050361006500503006000405",
+        "420000000000241030356410602040014603",
+        "540010030050120405003162360521210643",
+        "014300023160005423342516406230230005",
+        "200061004530000206006015045120302050",
+        "651400230600460201020004500103000006",
+        "010602206051160305523004640013001000",
+        "500004042060010032024650460320003046",
+        "060123102500340050605341006005450610",
+        "560034004002000041105263600400050306"
+      ],
+      "medium": [
+        "005000600400300005200004020000010060",
+        "000060020051306040000005000000040020",
+        "023010100060500300030100000602005001",
+        "000306500002400000230000600030010640",
+        "000030006405030650002300000000160020",
+        "050100460000030020120603045000000305",
+        "063010410003000460645000030000100000",
+        "000000205004100000023010060001530040",
+        "620304000000500063400010003100040036",
+        "000120510600300000050301060010005000"
+      ],
+      "hard": [
+        "015000000400200000000014000000156300",
+        "003160000050006004300015040200231000",
+        "060000002000000002000300004010100650",
+        "002501500400605200000060000000020600",
+        "030100002600000420021000053000000030",
+        "103204205100006005000003500000600002",
+        "000200060300500002012004000003040100",
+        "052400000001000050005006040032020000",
+        "200160060023000600000002050430004000",
+        "400000060000010400006002000205050046"
+      ]
+    },
     "3x3": {
       "easy": [
         "004210007090083010000500200007050831910600740400000000006100000801007450050300000",
diff --git a/assets/icons/size_2.png b/assets/icons/size_2.png
deleted file mode 100644
index ad699660fc4d991fb370035ed828b50d0722452c..0000000000000000000000000000000000000000
Binary files a/assets/icons/size_2.png and /dev/null differ
diff --git a/assets/icons/size_2x2.png b/assets/icons/size_2x2.png
new file mode 100644
index 0000000000000000000000000000000000000000..90a48baea5a702764515bfa638fcc2e154fbc0e1
Binary files /dev/null and b/assets/icons/size_2x2.png differ
diff --git a/assets/icons/size_3.png b/assets/icons/size_3.png
deleted file mode 100644
index 0d20bb1e00f264f617ca1154d3488e946d13f936..0000000000000000000000000000000000000000
Binary files a/assets/icons/size_3.png and /dev/null differ
diff --git a/assets/icons/size_3x2.png b/assets/icons/size_3x2.png
new file mode 100644
index 0000000000000000000000000000000000000000..6c427f089bc80e4e0433d583289330e8f6b700b4
Binary files /dev/null and b/assets/icons/size_3x2.png differ
diff --git a/assets/icons/size_3x3.png b/assets/icons/size_3x3.png
new file mode 100644
index 0000000000000000000000000000000000000000..7b4c28cb3295725e9a98d9d449ebaf7dbcbb60ae
Binary files /dev/null and b/assets/icons/size_3x3.png differ
diff --git a/generator/batch.sh b/generator/batch.sh
index db347183e0300a15b2ef6d13a6e74bc31ad2a93e..3a08b054e36c2d9cc1837272b0e6527536ed7fed 100755
--- a/generator/batch.sh
+++ b/generator/batch.sh
@@ -2,16 +2,16 @@
 
 CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
 
-ALLOWED_SIZE_VALUES="2 3"
+ALLOWED_BLOCK_SIZE_VALUES="2x2 3x2 3x3"
 ALLOWED_DIFFICULTY_VALUES="easy medium hard"
 GRIDS_COUNT=10
 
-for SIZE in ${ALLOWED_SIZE_VALUES}; do
-  echo "Size: ${SIZE}x${SIZE}"
+for BLOCK_SIZE in ${ALLOWED_BLOCK_SIZE_VALUES}; do
+  echo "Block size: ${BLOCK_SIZE}"
   for DIFFICULTY in ${ALLOWED_DIFFICULTY_VALUES}; do
     echo "Difficulty: ${DIFFICULTY}"
     for i in $(seq ${GRIDS_COUNT}); do
-      python ${CURRENT_DIR}/generate.py ${SIZE} ${DIFFICULTY} | tail -n 1
+      python ${CURRENT_DIR}/generate.py ${BLOCK_SIZE} ${DIFFICULTY} | tail -n 1
     done
   done
 done
diff --git a/generator/generate.py b/generator/generate.py
index 62772326bce89f6af22d2c815882a14b0cb9daff..4551ab825e26383622d530942e4f7d9970ee2ee6 100644
--- a/generator/generate.py
+++ b/generator/generate.py
@@ -1,20 +1,28 @@
+#!/usr/bin/python
+# -*- coding: iso-8859-15 -*-
+
 import sys
+import math
 from random import randint, shuffle
 
 if (len(sys.argv) != 3):
-  print('Usage: generate.py size difficulty')
-  print('size: [2|3]')
+  print('Usage: generate.py block-size difficulty')
+  print('block-size: [2x2|3x2|3x3]')
   print('difficulty: [easy|medium|hard]')
   exit()
 
-size, difficulty = sys.argv[1], sys.argv[2]
-
-size = int(size)
+blocksize, difficulty = sys.argv[1], sys.argv[2]
 
-if not size in [2, 3]:
+if not blocksize in ['2x2', '3x2', '3x3']:
   print('wrong size given')
   exit()
 
+splitted_blocksize = blocksize.split('x')
+size_horizontal = int(splitted_blocksize[0])
+size_vertical = int(splitted_blocksize[1])
+
+boardSize = size_horizontal * size_vertical
+
 if not difficulty in ['easy', 'medium', 'hard']:
   print('wrong difficulty given')
   exit()
@@ -30,13 +38,22 @@ if difficulty == 'hard':
 
 # draw grid (array style)
 def drawGrid(grid):
-  for row in range(len(grid)):
-    for col in range(len(grid[row])):
+  gridVerticalSize = len(grid)
+  gridHorizontalSize = len(grid[0])
+  horizontalLineLength = ((size_horizontal + 1) * size_vertical) + 1
+
+  for row in range(gridHorizontalSize):
+    if ((row % size_vertical) == 0):
+      sys.stdout.write(('═' * horizontalLineLength) + '\n')
+    for col in range(gridVerticalSize):
+      if ((col % size_horizontal) == 0):
+        sys.stdout.write('║')
       if grid[row][col] != 0:
         sys.stdout.write(str(grid[row][col]))
       else:
         sys.stdout.write(' ')
-    sys.stdout.write('\n')
+    sys.stdout.write('║\n')
+  sys.stdout.write(('═' * horizontalLineLength) + '\n')
   sys.stdout.write('\n')
 
 # draw grid (inline style)
@@ -47,12 +64,12 @@ def drawGridInline(grid):
   sys.stdout.write('\n')
 
 #initialise empty grid
-def generateEmptyGrid(size):
+def generateEmptyGrid(boardSize):
   emptyGrid = []
-  for i in range(size * size):
+  for row in range(boardSize):
     emptyGrid.append([])
-    for j in range(size * size):
-      emptyGrid[i].append(0)
+    for col in range(boardSize):
+      emptyGrid[row].append(0)
   return emptyGrid
 
 #A check if the grid is full
@@ -97,9 +114,9 @@ def solveGrid(grid):
 
           if not foundInColumn:
             # Get sub-square
-            blockColFrom = size * int(col / size)
-            blockRowFrom = size * int(row / size)
-            square = [grid[i][blockColFrom:blockColFrom + size] for i in range(blockRowFrom, blockRowFrom + size)]
+            blockColFrom = size_horizontal * int(col / size_horizontal)
+            blockRowFrom = size_vertical * int(row / size_vertical)
+            square = [grid[i][blockColFrom:blockColFrom + size_horizontal] for i in range(blockRowFrom, blockRowFrom + size_vertical)]
 
             #Check that this value has not already be used on this sub square
             if not any(value in squareLine for squareLine in square):
@@ -115,16 +132,16 @@ def solveGrid(grid):
 
 #A backtracking/recursive function to check all possible combinations of numbers until a solution is found
 def fillGrid(grid):
-  gridSize = len(grid)
+  boardSize = len(grid)
   cellsCount = len(grid) * len(grid[0])
-  numberList = [(value + 1) for value in range(gridSize)]
+  numberList = [(value + 1) for value in range(boardSize)]
 
   global solutionsCount
 
   #Find next empty cell
   for i in range(0, cellsCount):
-    row = i // gridSize
-    col = i % gridSize
+    row = i // boardSize
+    col = i % boardSize
     if grid[row][col] == 0:
       shuffle(numberList)
       for value in numberList:
@@ -132,15 +149,15 @@ def fillGrid(grid):
         if not(value in grid[row]):
           #Check that this value has not already be used on this column
           foundInColumn = False
-          for r in range(0, gridSize):
+          for r in range(0, boardSize):
             if (value == grid[r][col]):
               foundInColumn = True
 
           if not foundInColumn:
             # Get sub-square
-            blockColFrom = size * int(col / size)
-            blockRowFrom = size * int(row / size)
-            square = [grid[i][blockColFrom:blockColFrom + size] for i in range(blockRowFrom, blockRowFrom + size)]
+            blockColFrom = size_horizontal * int(col / size_horizontal)
+            blockRowFrom = size_vertical * int(row / size_vertical)
+            square = [grid[i][blockColFrom:blockColFrom + size_horizontal] for i in range(blockRowFrom, blockRowFrom + size_vertical)]
 
             #Check that this value has not already be used on this sub square
             if not any(value in squareLine for squareLine in square):
@@ -155,7 +172,6 @@ def fillGrid(grid):
 
 solutionsCount = 1
 def computeResolvableGrid(grid, wantedAttempts):
-  gridSize = size * size
   global solutionsCount
 
   # A higher number of attempts will end up removing more numbers from the grid
@@ -165,11 +181,11 @@ def computeResolvableGrid(grid, wantedAttempts):
   attempts = wantedAttempts
   while attempts > 0:
     # Select a random cell that is not already empty
-    row = randint(0, gridSize - 1)
-    col = randint(0, gridSize - 1)
+    row = randint(0, boardSize - 1)
+    col = randint(0, boardSize - 1)
     while grid[row][col] == 0:
-      row = randint(0, gridSize - 1)
-      col = randint(0, gridSize - 1)
+      row = randint(0, boardSize - 1)
+      col = randint(0, boardSize - 1)
 
     # Remove value in this random cell
     savedCellValue = grid[row][col]
@@ -183,7 +199,7 @@ def computeResolvableGrid(grid, wantedAttempts):
       grid[row][col] = savedCellValue
       attempts -= 1
 
-grid = generateEmptyGrid(size)
+grid = generateEmptyGrid(boardSize)
 
 sys.stdout.write('Solved grid:\n')
 fillGrid(grid)
diff --git a/icons/build_game_icons.sh b/icons/build_game_icons.sh
index 41dc2c480389c423c99a3fa1c11bcf90942ae6e6..819a80ef7b04b9076e35013f8f1d8ebdc3a803c7 100755
--- a/icons/build_game_icons.sh
+++ b/icons/build_game_icons.sh
@@ -60,8 +60,9 @@ build_icon ${CURRENT_DIR}/button_start.svg ${BASE_DIR}/assets/icons/button_start
 build_icon ${CURRENT_DIR}/difficulty_easy.svg ${BASE_DIR}/assets/icons/difficulty_easy.png
 build_icon ${CURRENT_DIR}/difficulty_medium.svg ${BASE_DIR}/assets/icons/difficulty_medium.png
 build_icon ${CURRENT_DIR}/difficulty_hard.svg ${BASE_DIR}/assets/icons/difficulty_hard.png
-build_icon ${CURRENT_DIR}/size_2.svg ${BASE_DIR}/assets/icons/size_2.png
-build_icon ${CURRENT_DIR}/size_3.svg ${BASE_DIR}/assets/icons/size_3.png
+build_icon ${CURRENT_DIR}/size_2x2.svg ${BASE_DIR}/assets/icons/size_2x2.png
+build_icon ${CURRENT_DIR}/size_3x2.svg ${BASE_DIR}/assets/icons/size_3x2.png
+build_icon ${CURRENT_DIR}/size_3x3.svg ${BASE_DIR}/assets/icons/size_3x3.png
 build_icon ${CURRENT_DIR}/skins/empty.svg ${BASE_DIR}/assets/skins/empty.png
 
 # Skins
diff --git a/icons/size_2.svg b/icons/size_2.svg
deleted file mode 100644
index a5a617280c8a965cc1bcde3914fe90af012bde07..0000000000000000000000000000000000000000
--- a/icons/size_2.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100" ry="2" fill="#6afffe"/><path d="m8.016 8.1944v83.701h83.701v-83.701zm60.683 60.683h-14.648v-14.648h14.648zm0 4.185v14.648h-14.648v-14.648zm4.185 0h14.648v14.648h-14.648zm0-4.185v-14.648h14.648v14.648zm0-23.018v-14.648h14.648v14.648zm-4.185 0h-14.648v-14.648h14.648zm-23.018 0h-14.648v-14.648h14.648zm0 8.3701v14.648h-14.648v-14.648zm0 18.833v14.648h-14.648v-14.648zm41.85-46.035h-14.648v-14.648h14.648zm-18.833-14.648v14.648h-14.648v-14.648zm-23.018 14.648h-14.648v-14.648h14.648zm-33.48-14.648h14.648v14.648h-14.648zm0 18.833h14.648v14.648h-14.648zm0 23.018h14.648v14.648h-14.648zm0 18.833h14.648v14.648h-14.648z" stroke-width="2.0925"/></svg>
diff --git a/icons/size_2x2.svg b/icons/size_2x2.svg
new file mode 100644
index 0000000000000000000000000000000000000000..bb4ec587b62f3bce3a016b04d67592ac7761c387
--- /dev/null
+++ b/icons/size_2x2.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 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100" ry="0" fill="none" stroke="#000"/><path d="m-0.16372-0.23334v100.4h100.4v-100.4zm72.788 72.788h-17.569v-17.569h17.569zm0 5.0198v17.569h-17.569v-17.569zm5.0198 0h17.569v17.569h-17.569zm0-5.0198v-17.569h17.569v17.569zm0-27.61v-17.569h17.569v17.569zm-5.0198 0h-17.569v-17.569h17.569zm-27.61 0h-17.569v-17.569h17.569zm0 10.04v17.569h-17.569v-17.569zm0 22.59v17.569h-17.569v-17.569zm50.198-55.217h-17.569v-17.569h17.569zm-22.59-17.569v17.569h-17.569v-17.569zm-27.61 17.569h-17.569v-17.569h17.569zm-40.158-17.569h17.569v17.569h-17.569zm0 22.59h17.569v17.569h-17.569zm0 27.61h17.569v17.569h-17.569zm0 22.59h17.569v17.569h-17.569z" stroke-width="2.5098"/><g transform="matrix(1.2347 0 0 1.2347 -11.926 -14.48)" fill="#00c700" stroke="#003e00" stroke-width="1.6198" aria-label="2x2"><path d="m35.254 91.326h-23.867q0.41016-3.5352 2.4805-6.6406 2.0898-3.125 7.8125-7.3633 3.4961-2.5977 4.4727-3.9453 0.97656-1.3477 0.97656-2.5586 0-1.3086-0.97656-2.2266-0.95703-0.9375-2.4219-0.9375-1.5234 0-2.5 0.95703-0.95703 0.95703-1.2891 3.3789l-7.9688-0.64453q0.46875-3.3594 1.7188-5.2344 1.25-1.8945 3.5156-2.8906 2.2852-1.0156 6.3086-1.0156 4.1992 0 6.5234 0.95703 2.3438 0.95703 3.6719 2.9492 1.3477 1.9727 1.3477 4.4336 0 2.6172-1.543 5-1.5234 2.3828-5.5664 5.2344-2.4023 1.6602-3.2227 2.3242-0.80078 0.66406-1.8945 1.7383h12.422z"/><path d="m37.617 70.584h9.4336l3.3008 5.7812 3.8281-5.7812h8.7695l-7.0703 9.8828 7.5781 10.859h-9.2773l-3.8281-6.6797-4.5117 6.6797h-8.6133l7.5391-10.859z"/><path d="m88.613 91.326h-23.867q0.41016-3.5352 2.4805-6.6406 2.0898-3.125 7.8125-7.3633 3.4961-2.5977 4.4727-3.9453 0.97656-1.3477 0.97656-2.5586 0-1.3086-0.97656-2.2266-0.95703-0.9375-2.4219-0.9375-1.5234 0-2.5 0.95703-0.95703 0.95703-1.2891 3.3789l-7.9688-0.64453q0.46875-3.3594 1.7188-5.2344 1.25-1.8945 3.5156-2.8906 2.2852-1.0156 6.3086-1.0156 4.1992 0 6.5234 0.95703 2.3438 0.95703 3.6719 2.9492 1.3477 1.9727 1.3477 4.4336 0 2.6172-1.543 5-1.5234 2.3828-5.5664 5.2344-2.4023 1.6602-3.2227 2.3242-0.80078 0.66406-1.8945 1.7383h12.422z"/></g></svg>
diff --git a/icons/size_3.svg b/icons/size_3.svg
deleted file mode 100644
index 1b7e5169f19dcfca54677aabc548317f3eda9c34..0000000000000000000000000000000000000000
--- a/icons/size_3.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100" ry="2" fill="#6afffe"/><path d="m65.824 4.0024h-62v90h90v-90zm9 79v-8h8v8zm8 2v7h-8v-7zm-38-2v-8h8v8zm8 2v7h-8v-7zm-38-2v-8h8v8zm8 2v7h-8v-7zm0-70v8h-8v-8zm-8-2v-7h8v7zm38 2v8h-8v-8zm-8-2v-7h8v7zm0 30v-7h8v7zm8 2v8h-8v-8zm-10-2h-7v-7h7zm0 2v8h-7v-8zm0 10v7h-7v-7zm2 0h8v7h-8zm10 0h7v7h-7zm0-2v-8h7v8zm0-10v-7h7v7zm0-11v-7h7v7zm-2 0h-8v-7h8zm-10 0h-7v-7h7zm-11 0h-7v-7h7zm0 4v7h-7v-7zm0 9v8h-7v-8zm0 10v7h-7v-7zm0 11v7h-7v-7zm4 0h7v7h-7zm9 0h8v7h-8zm10 0h7v7h-7zm11 0h7v7h-7zm0-4v-7h7v7zm0-9v-8h7v8zm0-10v-7h7v7zm0-11v-7h7v7zm0-9v-8h7v8zm-4 0h-7v-8h7zm-19 0h-7v-8h7zm-11 0h-7v-8h7zm-9 2v7h-8v-7zm0 11v7h-8v-7zm0 9v8h-8v-8zm0 10v7h-8v-7zm0 11v7h-8v-7zm2 9h7v8h-7zm11 0h7v8h-7zm19 0h7v8h-7zm11 0h7v8h-7zm9-2v-7h8v7zm0-11v-7h8v7zm0-9v-8h8v8zm0-10v-7h8v7zm0-11v-7h8v7zm0-9v-8h8v8zm0-10v-7h8v7zm-2-7v7h-7v-7zm-11 7h-7v-7h7zm-19-7v7h-7v-7zm-11 7h-7v-7h7zm-26-7h7v7h-7zm0 9h7v8h-7zm0 10h7v7h-7zm0 11h7v7h-7zm0 9h7v8h-7zm0 10h7v7h-7zm0 11h7v7h-7zm0 9h7v8h-7zm0 10h7v7h-7zm19 7v-7h7v7zm11-7h7v7h-7zm19 7v-7h7v7zm11-7h7v7h-7zm26 7h-7v-7h7zm0-9h-7v-8h7zm0-10h-7v-7h7zm0-11h-7v-7h7zm0-9h-7v-8h7zm0-10h-7v-7h7zm0-11h-7v-7h7zm0-9h-7v-8h7zm-7-10v-7h7v7z"/></svg>
diff --git a/icons/size_3x2.svg b/icons/size_3x2.svg
new file mode 100644
index 0000000000000000000000000000000000000000..355de344b5d278b1f42113bf830ede66c977458a
--- /dev/null
+++ b/icons/size_3x2.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 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100" ry="0" fill="none" stroke="#000"/><path d="m0.14969-0.42875v100.8h99.863v-100.8zm69.716 82.666v-10.835h11.314v10.835zm11.314 4.0477v10.835h-11.314v-10.835zm-62.197-4.0477v-10.835h11.314v10.835zm11.314 4.0477v10.835h-11.314v-10.835zm39.569-72.627v-10.835h11.314v10.835zm11.314 4.0477v10.835h-11.314v-10.835zm-15.342-4.0477h-11.314v-10.835h11.314zm0 4.0477v10.835h-11.314v-10.835zm0 19.407v10.835h-11.314v-10.835zm4.0278 0h11.314v10.835h-11.314zm15.342 0h11.314v10.835h-11.314zm0-8.5725v-10.835h11.314v10.835zm0-14.882v-10.835h11.314v10.835zm-39.569-10.835v10.835h-11.314v-10.835zm0 14.882v10.835h-11.314v-10.835zm0 19.407v10.835h-11.314v-10.835zm0 14.882v10.835h-11.314v-10.835zm8.8853 0h11.314v10.835h-11.314zm15.342 0h11.314v10.835h-11.314zm15.343 0h11.314v10.835h-11.314zm-54.91-49.172v10.835h-11.314v-10.835zm0 14.882v10.835h-11.314v-10.835zm0 19.407v10.835h-11.314v-10.835zm0 14.882v10.835h-11.314v-10.835zm4.0278 19.407h11.314v10.835h-11.314zm20.2 0h11.314v10.835h-11.314zm30.684 0h11.314v10.835h-11.314zm-81.567-68.58h11.314v10.835h-11.314zm0 14.882h11.314v10.835h-11.314zm0 19.407h11.314v10.835h-11.314zm0 14.882h11.314v10.835h-11.314zm0 19.407h11.314v10.835h-11.314zm0 14.882h11.314v10.835h-11.314zm30.684 10.835v-10.835h11.314v10.835zm20.2-10.835h11.314v10.835h-11.314zm30.684 10.835v-10.835h11.314v10.835z" stroke-width="1.6844"/><g transform="matrix(1.2405 0 0 1.2405 -12.136 -19.028)" fill="#ff8d05" stroke="#4c2a00" stroke-width="1.6123" aria-label="3x2"><path d="m19.512 73.271-7.5195-1.3477q0.9375-3.5938 3.5938-5.5078 2.6758-1.9141 7.5586-1.9141 5.6055 0 8.1055 2.0898t2.5 5.2539q0 1.8555-1.0156 3.3594t-3.0664 2.6367q1.6602 0.41016 2.5391 0.95703 1.4258 0.87891 2.207 2.3242 0.80078 1.4258 0.80078 3.418 0 2.5-1.3086 4.8047-1.3086 2.2852-3.7695 3.5352-2.4609 1.2305-6.4648 1.2305-3.9062 0-6.1719-0.91797-2.2461-0.91797-3.7109-2.6758-1.4453-1.7773-2.2266-4.4531l7.9492-1.0547q0.46875 2.4023 1.4453 3.3398 0.99609 0.91797 2.5195 0.91797 1.6016 0 2.6562-1.1719 1.0742-1.1719 1.0742-3.125 0-1.9922-1.0352-3.0859-1.0156-1.0938-2.7734-1.0938-0.9375 0-2.5781 0.46875l0.41016-5.6836q0.66406 0.09766 1.0352 0.09766 1.5625 0 2.5977-0.99609 1.0547-0.99609 1.0547-2.3633 0-1.3086-0.78125-2.0898t-2.1484-0.78125q-1.4062 0-2.2852 0.85938-0.87891 0.83984-1.1914 2.9688z"/><path d="m37.441 72.88h9.4336l3.3008 5.7812 3.8281-5.7812h8.7695l-7.0703 9.8828 7.5781 10.859h-9.2773l-3.8281-6.6797-4.5117 6.6797h-8.6133l7.5391-10.859z"/><path d="m88.438 93.622h-23.867q0.41016-3.5352 2.4805-6.6406 2.0898-3.125 7.8125-7.3633 3.4961-2.5977 4.4727-3.9453 0.97656-1.3477 0.97656-2.5586 0-1.3086-0.97656-2.2266-0.95703-0.9375-2.4219-0.9375-1.5234 0-2.5 0.95703-0.95703 0.95703-1.2891 3.3789l-7.9688-0.64453q0.46875-3.3594 1.7188-5.2344 1.25-1.8945 3.5156-2.8906 2.2852-1.0156 6.3086-1.0156 4.1992 0 6.5234 0.95703 2.3438 0.95703 3.6719 2.9492 1.3477 1.9727 1.3477 4.4336 0 2.6172-1.543 5-1.5234 2.3828-5.5664 5.2344-2.4023 1.6602-3.2227 2.3242-0.80078 0.66406-1.8945 1.7383h12.422z"/></g></svg>
diff --git a/icons/size_3x3.svg b/icons/size_3x3.svg
new file mode 100644
index 0000000000000000000000000000000000000000..3037d3530398f70a28a4acdd7c134b8f6e9c18a9
--- /dev/null
+++ b/icons/size_3x3.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 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100" ry="0" fill="none" stroke="#000"/><path d="m68.799-0.020495h-69.133v100.35h100.35v-100.35zm10.035 88.089v-8.9204h8.9204v8.9204zm8.9204 2.2301v7.8053h-8.9204v-7.8053zm-42.372-2.2301v-8.9204h8.9204v8.9204zm8.9204 2.2301v7.8053h-8.9204v-7.8053zm-42.372-2.2301v-8.9204h8.9204v8.9204zm8.9204 2.2301v7.8053h-8.9204v-7.8053zm0-78.053v8.9204h-8.9204v-8.9204zm-8.9204-2.2301v-7.8053h8.9204v7.8053zm42.372 2.2301v8.9204h-8.9204v-8.9204zm-8.9204-2.2301v-7.8053h8.9204v7.8053zm0 33.452v-7.8053h8.9204v7.8053zm8.9204 2.2301v8.9204h-8.9204v-8.9204zm-11.151-2.2301h-7.8053v-7.8053h7.8053zm0 2.2301v8.9204h-7.8053v-8.9204zm0 11.151v7.8053h-7.8053v-7.8053zm2.2301 0h8.9204v7.8053h-8.9204zm11.151 0h7.8053v7.8053h-7.8053zm0-2.2301v-8.9204h7.8053v8.9204zm0-11.151v-7.8053h7.8053v7.8053zm0-12.266v-7.8053h7.8053v7.8053zm-2.2301 0h-8.9204v-7.8053h8.9204zm-11.151 0h-7.8053v-7.8053h7.8053zm-12.266 0h-7.8053v-7.8053h7.8053zm0 4.4603v7.8053h-7.8053v-7.8053zm0 10.035v8.9204h-7.8053v-8.9204zm0 11.151v7.8053h-7.8053v-7.8053zm0 12.266v7.8053h-7.8053v-7.8053zm4.4603 0h7.8053v7.8053h-7.8053zm10.035 0h8.9204v7.8053h-8.9204zm11.151 0h7.8053v7.8053h-7.8053zm12.266 0h7.8053v7.8053h-7.8053zm0-4.4603v-7.8053h7.8053v7.8053zm0-10.035v-8.9204h7.8053v8.9204zm0-11.151v-7.8053h7.8053v7.8053zm0-12.266v-7.8053h7.8053v7.8053zm0-10.035v-8.9204h7.8053v8.9204zm-4.4603 0h-7.8053v-8.9204h7.8053zm-21.186 0h-7.8053v-8.9204h7.8053zm-12.266 0h-7.8053v-8.9204h7.8053zm-10.035 2.2301v7.8053h-8.9204v-7.8053zm0 12.266v7.8053h-8.9204v-7.8053zm0 10.035v8.9204h-8.9204v-8.9204zm0 11.151v7.8053h-8.9204v-7.8053zm0 12.266v7.8053h-8.9204v-7.8053zm2.2301 10.035h7.8053v8.9204h-7.8053zm12.266 0h7.8053v8.9204h-7.8053zm21.186 0h7.8053v8.9204h-7.8053zm12.266 0h7.8053v8.9204h-7.8053zm10.035-2.2301v-7.8053h8.9204v7.8053zm0-12.266v-7.8053h8.9204v7.8053zm0-10.035v-8.9204h8.9204v8.9204zm0-11.151v-7.8053h8.9204v7.8053zm0-12.266v-7.8053h8.9204v7.8053zm0-10.035v-8.9204h8.9204v8.9204zm0-11.151v-7.8053h8.9204v7.8053zm-2.2301-7.8053v7.8053h-7.8053v-7.8053zm-12.266 7.8053h-7.8053v-7.8053h7.8053zm-21.186-7.8053v7.8053h-7.8053v-7.8053zm-12.266 7.8053h-7.8053v-7.8053h7.8053zm-28.991-7.8053h7.8053v7.8053h-7.8053zm0 10.035h7.8053v8.9204h-7.8053zm0 11.151h7.8053v7.8053h-7.8053zm0 12.266h7.8053v7.8053h-7.8053zm0 10.035h7.8053v8.9204h-7.8053zm0 11.151h7.8053v7.8053h-7.8053zm0 12.266h7.8053v7.8053h-7.8053zm0 10.035h7.8053v8.9204h-7.8053zm0 11.151h7.8053v7.8053h-7.8053zm21.186 7.8053v-7.8053h7.8053v7.8053zm12.266-7.8053h7.8053v7.8053h-7.8053zm21.186 7.8053v-7.8053h7.8053v7.8053zm12.266-7.8053h7.8053v7.8053h-7.8053zm28.991 7.8053h-7.8053v-7.8053h7.8053zm0-10.035h-7.8053v-8.9204h7.8053zm0-11.151h-7.8053v-7.8053h7.8053zm0-12.266h-7.8053v-7.8053h7.8053zm0-10.035h-7.8053v-8.9204h7.8053zm0-11.151h-7.8053v-7.8053h7.8053zm0-12.266h-7.8053v-7.8053h7.8053zm0-10.035h-7.8053v-8.9204h7.8053zm-7.8053-11.151v-7.8053h7.8053v7.8053z" stroke-width="1.1151"/><g transform="matrix(1.2388 0 0 1.2388 -11.249 -16.591)" fill="#f00" stroke="#500000" stroke-width="1.6145" aria-label="3x3"><path d="m19.443 72.913-7.5195-1.3477q0.9375-3.5938 3.5938-5.5078 2.6758-1.9141 7.5586-1.9141 5.6055 0 8.1055 2.0898t2.5 5.2539q0 1.8555-1.0156 3.3594t-3.0664 2.6367q1.6602 0.41016 2.5391 0.95703 1.4258 0.87891 2.207 2.3242 0.80078 1.4258 0.80078 3.418 0 2.5-1.3086 4.8047-1.3086 2.2852-3.7695 3.5352-2.4609 1.2305-6.4648 1.2305-3.9062 0-6.1719-0.91797-2.2461-0.91797-3.7109-2.6758-1.4453-1.7773-2.2266-4.4531l7.9492-1.0547q0.46875 2.4023 1.4453 3.3398 0.99609 0.91797 2.5195 0.91797 1.6016 0 2.6562-1.1719 1.0742-1.1719 1.0742-3.125 0-1.9922-1.0352-3.0859-1.0156-1.0938-2.7734-1.0938-0.9375 0-2.5781 0.46875l0.41016-5.6836q0.66406 0.09766 1.0352 0.09766 1.5625 0 2.5977-0.99609 1.0547-0.99609 1.0547-2.3633 0-1.3086-0.78125-2.0898t-2.1484-0.78125q-1.4062 0-2.2852 0.85938-0.87891 0.83984-1.1914 2.9688z"/><path d="m37.373 72.522h9.4336l3.3008 5.7812 3.8281-5.7812h8.7695l-7.0703 9.8828 7.5781 10.859h-9.2773l-3.8281-6.6797-4.5117 6.6797h-8.6133l7.5391-10.859z"/><path d="m72.803 72.913-7.5195-1.3477q0.9375-3.5938 3.5938-5.5078 2.6758-1.9141 7.5586-1.9141 5.6055 0 8.1055 2.0898t2.5 5.2539q0 1.8555-1.0156 3.3594t-3.0664 2.6367q1.6602 0.41016 2.5391 0.95703 1.4258 0.87891 2.207 2.3242 0.80078 1.4258 0.80078 3.418 0 2.5-1.3086 4.8047-1.3086 2.2852-3.7695 3.5352-2.4609 1.2305-6.4648 1.2305-3.9062 0-6.1719-0.91797-2.2461-0.91797-3.7109-2.6758-1.4453-1.7773-2.2266-4.4531l7.9492-1.0547q0.46875 2.4023 1.4453 3.3398 0.99609 0.91797 2.5195 0.91797 1.6016 0 2.6562-1.1719 1.0742-1.1719 1.0742-3.125 0-1.9922-1.0352-3.0859-1.0156-1.0938-2.7734-1.0938-0.9375 0-2.5781 0.46875l0.41016-5.6836q0.66406 0.09766 1.0352 0.09766 1.5625 0 2.5977-0.99609 1.0547-0.99609 1.0547-2.3633 0-1.3086-0.78125-2.0898t-2.1484-0.78125q-1.4062 0-2.2852 0.85938-0.87891 0.83984-1.1914 2.9688z"/></g></svg>
diff --git a/lib/entities/cell.dart b/lib/entities/cell.dart
index e4d2cf5e93e0b9b57e9cfb5d4f9010b74579456f..4632c96fe9d929597b9ed51ab71c1ce2b59e4115 100644
--- a/lib/entities/cell.dart
+++ b/lib/entities/cell.dart
@@ -23,8 +23,6 @@ class Cell {
       imageAsset = 'assets/skins/' + myProvider.skin + '_' + this.value.toString() + '.png';
     }
 
-    int size = myProvider.size;
-
     return Container(
       decoration: BoxDecoration(
         color: this.getBackgroundColor(myProvider),
@@ -101,7 +99,8 @@ class Cell {
   }
 
   static Border getCellBorders(Data myProvider, int row, int col) {
-    int size = myProvider.size;
+    int blockSizeHorizontal = myProvider.blockSizeHorizontal;
+    int blockSizeVertical = myProvider.blockSizeVertical;
 
     Border borders = Border.all(
       color: cellBorderSelectedColor,
@@ -110,10 +109,10 @@ class Cell {
 
     if (col != myProvider.currentCellCol || row != myProvider.currentCellRow) {
       borders = Border(
-        top: BorderSide(width: cellBorderWidth, color: ((row % size) == 0) ? cellBorderDarkColor : cellBorderLightColor),
-        left: BorderSide(width: cellBorderWidth, color: ((col % size) == 0) ? cellBorderDarkColor : cellBorderLightColor),
-        right: BorderSide(width: cellBorderWidth, color: (((col + 1) % size) == 0) ? cellBorderDarkColor : cellBorderLightColor),
-        bottom: BorderSide(width: cellBorderWidth, color: (((row + 1) % size) == 0) ? cellBorderDarkColor : cellBorderLightColor),
+        top: BorderSide(width: cellBorderWidth, color: ((row % blockSizeVertical) == 0) ? cellBorderDarkColor : cellBorderLightColor),
+        left: BorderSide(width: cellBorderWidth, color: ((col % blockSizeHorizontal) == 0) ? cellBorderDarkColor : cellBorderLightColor),
+        right: BorderSide(width: cellBorderWidth, color: (((col + 1) % blockSizeHorizontal) == 0) ? cellBorderDarkColor : cellBorderLightColor),
+        bottom: BorderSide(width: cellBorderWidth, color: (((row + 1) % blockSizeVertical) == 0) ? cellBorderDarkColor : cellBorderLightColor),
       );
     }
 
diff --git a/lib/layout/board.dart b/lib/layout/board.dart
index cd4905eebcc311c65a44d58f0fe5c507210457cc..fcc880691265d333edf860c9767f69c7a69b8ac0 100644
--- a/lib/layout/board.dart
+++ b/lib/layout/board.dart
@@ -28,15 +28,15 @@ class Board {
   }
 
   static Table buildGameTileset(Data myProvider) {
-    int size = myProvider.size;
+    int boardSize = myProvider.blockSizeHorizontal * myProvider.blockSizeVertical;
     List cells = myProvider.cells;
 
     return Table(
       defaultColumnWidth: IntrinsicColumnWidth(),
       children: [
-        for (var row = 0; row < pow(size, 2); row++)
+        for (var row = 0; row < boardSize; row++)
           TableRow(children: [
-            for (var col = 0; col < pow(size, 2); col++)
+            for (var col = 0; col < boardSize; col++)
               Column(children: [
                 cells[row][col].widget(
                   myProvider,
diff --git a/lib/layout/game.dart b/lib/layout/game.dart
index bda08eb0cc9725813dde59daa799e28da34b8974..6b09b41129a308d7fcb666bdb6a921479a19b669 100644
--- a/lib/layout/game.dart
+++ b/lib/layout/game.dart
@@ -26,12 +26,11 @@ class Game {
 
   static Container buildSelectCellValueBar(Data myProvider) {
     List cells = myProvider.cells;
-    int size = myProvider.size;
 
     Color borderColor = Colors.blue;
 
     bool isCellSelected = (myProvider.currentCellCol != null && myProvider.currentCellRow != null);
-    int maxValue = pow(size, 2) + 1;
+    int maxValue = myProvider.blockSizeHorizontal * myProvider.blockSizeVertical;
 
     return Container(
       margin: EdgeInsets.all(2),
@@ -42,7 +41,7 @@ class Game {
         children: [
           TableRow(
             children: [
-              for (var value = 0; value < maxValue; value++)
+              for (var value = 0; value <= maxValue; value++)
                 Column(
                   children: [
                     Cell(
diff --git a/lib/layout/parameters.dart b/lib/layout/parameters.dart
index b4bb302380b2f77ad5baedf5a5c40422f3ee2e59..9ac761c02a5b08b4f55d200518fb1137d3830d34 100644
--- a/lib/layout/parameters.dart
+++ b/lib/layout/parameters.dart
@@ -70,11 +70,11 @@ class Parameters {
   }
 
 
-  static FlatButton _buildParameterButton(Data myProvider, String parameterCode, var parameterValue) {
+  static FlatButton _buildParameterButton(Data myProvider, String parameterCode, String parameterValue) {
     String currentValue = myProvider.getParameterValue(parameterCode).toString();
 
-    bool isActive = (parameterValue.toString() == currentValue);
-    String imageAsset = 'assets/icons/' + parameterCode + '_' + parameterValue.toString() + '.png';
+    bool isActive = (parameterValue == currentValue);
+    String imageAsset = 'assets/icons/' + parameterCode + '_' + parameterValue + '.png';
 
     return FlatButton(
       child: Container(
diff --git a/lib/provider/data.dart b/lib/provider/data.dart
index ea939bfbbbf1c05f6557257cb951136d2ee1f84e..0225b29c001a8cc7671f8ef7ba95b0a9bf6a29e1 100644
--- a/lib/provider/data.dart
+++ b/lib/provider/data.dart
@@ -4,7 +4,7 @@ class Data extends ChangeNotifier {
 
   // Configuration available values
   List _availableDifficultyLevels = ['easy', 'medium', 'hard'];
-  List _availableSizes = [2, 3];
+  List _availableSizes = ['2x2', '3x2', '3x3'];
   List _availableSkins = ['default', 'food', 'nature'];
 
   List get availableDifficultyLevels => _availableDifficultyLevels;
@@ -13,12 +13,14 @@ class Data extends ChangeNotifier {
 
   // Application default configuration
   String _level = 'medium';
-  int _size = 3;
+  String _size = '3x3';
   String _skin = 'default';
   bool _showConflicts = false;
 
   // Game data
   bool _stateRunning = false;
+  int _blockSizeVertical = null;
+  int _blockSizeHorizontal = null;
   List _cells = [];
   int _currentCellCol = null;
   int _currentCellRow = null;
@@ -29,9 +31,13 @@ class Data extends ChangeNotifier {
     notifyListeners();
   }
 
-  int get size => _size;
-  set updateSize(int size) {
+  String get size => _size;
+  int get blockSizeVertical => _blockSizeVertical;
+  int get blockSizeHorizontal => _blockSizeHorizontal;
+  set updateSize(String size) {
     _size = size;
+    _blockSizeHorizontal = int.parse(_size.split('x')[0]);
+    _blockSizeVertical = int.parse(_size.split('x')[1]);
     notifyListeners();
   }
 
@@ -69,7 +75,7 @@ class Data extends ChangeNotifier {
     }
   }
 
-  setParameterValue(String parameterCode, var parameterValue) {
+  setParameterValue(String parameterCode, String parameterValue) {
     switch(parameterCode) {
       case 'difficulty': { updateLevel = parameterValue; }
       break;
diff --git a/lib/utils/board_utils.dart b/lib/utils/board_utils.dart
index 539bf4da6314131c07774df64324da05e77ecbd8..2c9308406a396feb6cc7a6ed902a0c51c4af22ad 100644
--- a/lib/utils/board_utils.dart
+++ b/lib/utils/board_utils.dart
@@ -22,30 +22,33 @@ class BoardUtils {
 
 
   static Future<void> pickGrid(Data myProvider) async {
-    int size = myProvider.size;
-
     String grid;
     RandomPickGrid randomPickGrid;
 
     randomPickGrid = RandomPickGrid();
-    await randomPickGrid.init(myProvider.level, size);
+    await randomPickGrid.init(myProvider.level, myProvider.size);
 
     if (randomPickGrid.grid != null) {
       grid = randomPickGrid.grid;
     }
 
-    if (grid.length == pow(size, 4)) {
-      myProvider.updateCells = BoardUtils.createBoardFromTemplate(grid);
+    int blockSizeHorizontal = myProvider.blockSizeHorizontal;
+    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 size) {
+  static List createEmptyBoard(int boardSize) {
     int index = 0;
     List cells = [];
-    for (var rowIndex = 0; rowIndex < pow(size, 2); rowIndex++) {
+    for (var rowIndex = 0; rowIndex < boardSize; rowIndex++) {
       List row = [];
-      for (var colIndex = 0; colIndex < pow(size, 2); colIndex++) {
+      for (var colIndex = 0; colIndex < boardSize; colIndex++) {
         row.add(Cell(0, false));
       }
       cells.add(row);
@@ -55,44 +58,51 @@ class BoardUtils {
   }
 
 
-  static List createBoardFromTemplate(String grid) {
+  static List createBoardFromTemplate(String grid, bool isSymetric) {
     List cells = [];
-    int size = int.parse(pow(grid.length, 1/4).toStringAsFixed(0));
-    int sideLength = pow(size, 2);
+    int boardSize = int.parse(pow(grid.length, 1/2).toStringAsFixed(0));
 
     int index = 0;
-    for (var rowIndex = 0; rowIndex < sideLength; rowIndex++) {
+    for (var rowIndex = 0; rowIndex < boardSize; rowIndex++) {
       List row = [];
-      for (var colIndex = 0; colIndex < sideLength; colIndex++) {
+      for (var colIndex = 0; colIndex < boardSize; colIndex++) {
         int value = int.parse(grid[index++]);
         row.add(Cell(value, (value != 0)));
       }
       cells.add(row);
     }
 
-    List<String> allowedFlip = ['', 'horizontal', 'vertical'];
-    List<String> allowedRotate = ['', 'left', 'right'];
+    List<String> allowedFlip = ['none', 'horizontal', 'vertical'];
+    List<String> allowedRotate = ['none', 'left', 'right'];
+
+    // Forbid rotation if blocks are not symetric
+    if (!isSymetric) {
+      allowedRotate = ['none'];
+    }
 
     var rand = new Random();
     String flip = allowedFlip[rand.nextInt(allowedFlip.length)];
     String rotate = allowedRotate[rand.nextInt(allowedRotate.length)];
 
+    print('flip board: ' + flip);
+    print('rotate board: ' + rotate);
+
     switch(flip) {
       case 'horizontal': {
-        List transformedBoard = createEmptyBoard(size);
-        for (var rowIndex = 0; rowIndex < sideLength; rowIndex++) {
-          for (var colIndex = 0; colIndex < sideLength; colIndex++) {
-            transformedBoard[rowIndex][colIndex].value = cells[sideLength - rowIndex - 1][colIndex].value;
+        List transformedBoard = createEmptyBoard(boardSize);
+        for (var rowIndex = 0; rowIndex < boardSize; rowIndex++) {
+          for (var colIndex = 0; colIndex < boardSize; colIndex++) {
+            transformedBoard[rowIndex][colIndex].value = cells[boardSize - rowIndex - 1][colIndex].value;
           }
         }
         cells = transformedBoard;
       }
       break;
       case 'vertical': {
-        List transformedBoard = createEmptyBoard(size);
-        for (var rowIndex = 0; rowIndex < sideLength; rowIndex++) {
-          for (var colIndex = 0; colIndex < sideLength; colIndex++) {
-            transformedBoard[rowIndex][colIndex].value = cells[rowIndex][sideLength - colIndex - 1].value;
+        List transformedBoard = createEmptyBoard(boardSize);
+        for (var rowIndex = 0; rowIndex < boardSize; rowIndex++) {
+          for (var colIndex = 0; colIndex < boardSize; colIndex++) {
+            transformedBoard[rowIndex][colIndex].value = cells[rowIndex][boardSize - colIndex - 1].value;
           }
         }
         cells = transformedBoard;
@@ -102,20 +112,20 @@ class BoardUtils {
 
     switch(rotate) {
       case 'left': {
-        List transformedBoard = createEmptyBoard(size);
-        for (var rowIndex = 0; rowIndex < sideLength; rowIndex++) {
-          for (var colIndex = 0; colIndex < sideLength; colIndex++) {
-            transformedBoard[rowIndex][colIndex].value = cells[colIndex][sideLength - rowIndex - 1].value;
+        List transformedBoard = createEmptyBoard(boardSize);
+        for (var rowIndex = 0; rowIndex < boardSize; rowIndex++) {
+          for (var colIndex = 0; colIndex < boardSize; colIndex++) {
+            transformedBoard[rowIndex][colIndex].value = cells[colIndex][boardSize - rowIndex - 1].value;
           }
         }
         cells = transformedBoard;
       }
       break;
       case 'right': {
-        List transformedBoard = createEmptyBoard(size);
-        for (var rowIndex = 0; rowIndex < sideLength; rowIndex++) {
-          for (var colIndex = 0; colIndex < sideLength; colIndex++) {
-            transformedBoard[rowIndex][colIndex].value = cells[sideLength - colIndex - 1][rowIndex].value;
+        List transformedBoard = createEmptyBoard(boardSize);
+        for (var rowIndex = 0; rowIndex < boardSize; rowIndex++) {
+          for (var colIndex = 0; colIndex < boardSize; colIndex++) {
+            transformedBoard[rowIndex][colIndex].value = cells[boardSize - colIndex - 1][rowIndex].value;
           }
         }
         cells = transformedBoard;
@@ -124,8 +134,8 @@ class BoardUtils {
     }
 
     // Fix cells fixed states
-    for (var rowIndex = 0; rowIndex < sideLength; rowIndex++) {
-      for (var colIndex = 0; colIndex < sideLength; colIndex++) {
+    for (var rowIndex = 0; rowIndex < boardSize; rowIndex++) {
+      for (var colIndex = 0; colIndex < boardSize; colIndex++) {
         cells[rowIndex][colIndex].isFixed = (cells[rowIndex][colIndex].value != 0) ? true : false;
       }
     }
@@ -138,21 +148,24 @@ class BoardUtils {
 
   static bool checkBoardIsSolved(Data myProvider) {
     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;
 
     // reset conflict states
-    for (var row = 0; row < sideLength; row++) {
-      for (var col = 0; col < sideLength; col++) {
+    for (var row = 0; row < boardSize; row++) {
+      for (var col = 0; col < boardSize; col++) {
         cells[row][col].conflictsCount = 0;
       }
     }
 
     // check grid is fully completed
-    for (var row = 0; row < sideLength; row++) {
-      for (var col = 0; col < sideLength; col++) {
+    for (var row = 0; row < boardSize; row++) {
+      for (var col = 0; col < boardSize; col++) {
         if (cells[row][col].value == 0) {
           isSolved = false;
         }
@@ -160,9 +173,9 @@ class BoardUtils {
     }
 
     // check lines does not contains a value twice
-    for (var row = 0; row < sideLength; row++) {
+    for (var row = 0; row < boardSize; row++) {
       List values = [];
-      for (var col = 0; col < sideLength; col++) {
+      for (var col = 0; col < boardSize; col++) {
         int value = cells[row][col].value;
         if (value != 0) {
           values.add(value);
@@ -172,7 +185,7 @@ class BoardUtils {
       if (values.length != distinctValues.length) {
         print('line ' + row.toString() + ' contains duplicates');
         // Add line to cells in conflict
-        for (var col = 0; col < sideLength; col++) {
+        for (var col = 0; col < boardSize; col++) {
           cells[row][col].conflictsCount++;
         }
         isSolved = false;
@@ -180,9 +193,9 @@ class BoardUtils {
     }
 
     // check columns does not contains a value twice
-    for (var col = 0; col < sideLength; col++) {
+    for (var col = 0; col < boardSize; col++) {
       List values = [];
-      for (var row = 0; row < sideLength; row++) {
+      for (var row = 0; row < boardSize; row++) {
         int value = cells[row][col].value;
         if (value != 0) {
           values.add(value);
@@ -192,7 +205,7 @@ class BoardUtils {
       if (values.length != distinctValues.length) {
         print('column ' + col.toString() + ' contains duplicates');
         // Add column to cells in conflict
-        for (var row = 0; row < sideLength; row++) {
+        for (var row = 0; row < boardSize; row++) {
           cells[row][col].conflictsCount++;
         }
         isSolved = false;
@@ -200,14 +213,16 @@ class BoardUtils {
     }
 
     // check blocks does not contains a value twice
-    for (var blockRow = 0; blockRow < size; blockRow++) {
-      for (var blockCol = 0; blockCol < size; blockCol++) {
+    int horizontalBlocksCount = blockSizeVertical;
+    int verticalBlocksCount = blockSizeHorizontal;
+    for (var blockRow = 0; blockRow < verticalBlocksCount; blockRow++) {
+      for (var blockCol = 0; blockCol < horizontalBlocksCount; blockCol++) {
         List values = [];
 
-        for (var rowInBlock = 0; rowInBlock < size; rowInBlock++) {
-          for (var colInBlock = 0; colInBlock < size; colInBlock++) {
-            int row = (blockRow * size) + rowInBlock;
-            int col = (blockCol * size) + colInBlock;
+        for (var rowInBlock = 0; rowInBlock < blockSizeVertical; rowInBlock++) {
+          for (var colInBlock = 0; colInBlock < blockSizeHorizontal; colInBlock++) {
+            int row = (blockRow * blockSizeVertical) + rowInBlock;
+            int col = (blockCol * blockSizeHorizontal) + colInBlock;
             int value = cells[row][col].value;
             if (value != 0) {
               values.add(value);
@@ -219,10 +234,10 @@ class BoardUtils {
         if (values.length != distinctValues.length) {
           print('block [' + blockCol.toString() + ',' + blockRow.toString() + '] contains duplicates');
           // Add blocks to cells in conflict
-          for (var rowInBlock = 0; rowInBlock < size; rowInBlock++) {
-            for (var colInBlock = 0; colInBlock < size; colInBlock++) {
-              int row = (blockRow * size) + rowInBlock;
-              int col = (blockCol * size) + colInBlock;
+          for (var rowInBlock = 0; rowInBlock < blockSizeVertical; rowInBlock++) {
+            for (var colInBlock = 0; colInBlock < blockSizeHorizontal; colInBlock++) {
+              int row = (blockRow * blockSizeVertical) + rowInBlock;
+              int col = (blockCol * blockSizeHorizontal) + colInBlock;
               cells[row][col].conflictsCount++;
             }
           }
diff --git a/lib/utils/game_utils.dart b/lib/utils/game_utils.dart
index dd9d43a09f0296a1207398a708c503c2855e558d..4f47e67115e864a51e79525d1141becd7f653365 100644
--- a/lib/utils/game_utils.dart
+++ b/lib/utils/game_utils.dart
@@ -8,8 +8,9 @@ class GameUtils {
   }
 
   static Future<void> startGame(Data myProvider) async {
+    print('Start new game: ' + myProvider.size);
     myProvider.updateStateRunning = true;
-    myProvider.updateCells = BoardUtils.createEmptyBoard(myProvider.size);
+    myProvider.updateCells = BoardUtils.createEmptyBoard(myProvider.blockSizeHorizontal * myProvider.blockSizeVertical);
     BoardUtils.pickGrid(myProvider);
   }
 }
diff --git a/lib/utils/random_pick_grid.dart b/lib/utils/random_pick_grid.dart
index 5348f2747aa601da0fa65529413df9443e1ee65d..58a0c450d24fa74aed98c381338c40ff0f8939f6 100644
--- a/lib/utils/random_pick_grid.dart
+++ b/lib/utils/random_pick_grid.dart
@@ -6,27 +6,25 @@ class RandomPickGrid {
 
   String _grid;
 
-  init(String difficulty, int size) async {
+  init(String difficulty, String size) async {
     _grid = '';
     await gridFromLocalFile(difficulty, size);
   }
 
-  Future<void> gridFromLocalFile(String difficulty, int size) async {
-    String sizeAsString = size.toString() + 'x' + size.toString();
-
+  Future<void> gridFromLocalFile(String difficulty, String size) async {
     // 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];
+      grids = jsonResponse['templates'][size][difficulty];
     } catch (e) {
       print("$e");
     }
 
     // Check we have enough grids
     if (grids.length < 1) {
-      print('Not enough grids [' + sizeAsString + ', ' + difficulty + '] in templates.');
+      print('Not enough grids [' + size + ', ' + difficulty + '] in templates.');
     }
 
     // Randomize grids list