From 0c80758adc535b70ef71a1fb6fd2920e07f083c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr>
Date: Thu, 25 Aug 2022 00:22:52 +0200
Subject: [PATCH] Create minimal playable game

---
 android/gradle.properties                     |   4 +-
 assets/icons/colors_5.png                     | Bin 0 -> 1516 bytes
 assets/icons/colors_6.png                     | Bin 0 -> 2010 bytes
 assets/icons/colors_7.png                     | Bin 0 -> 1543 bytes
 assets/icons/colors_8.png                     | Bin 0 -> 2193 bytes
 .../{default_empty.png => default_0.png}      | Bin 251 -> 251 bytes
 assets/skins/default_1.png                    | Bin 0 -> 251 bytes
 assets/skins/default_2.png                    | Bin 0 -> 251 bytes
 assets/skins/default_3.png                    | Bin 0 -> 251 bytes
 assets/skins/default_4.png                    | Bin 0 -> 251 bytes
 assets/skins/default_5.png                    | Bin 0 -> 251 bytes
 assets/skins/default_6.png                    | Bin 0 -> 251 bytes
 assets/skins/default_7.png                    | Bin 0 -> 251 bytes
 assets/skins/default_8.png                    | Bin 0 -> 251 bytes
 .../metadata/android/en-US/changelogs/5.txt   |   1 +
 .../android/en-US/full_description.txt        |   2 +-
 .../metadata/android/fr-FR/changelogs/5.txt   |   1 +
 .../android/fr-FR/full_description.txt        |   2 +-
 .../android/fr-FR/short_description.txt       |   2 +-
 fastlane/metadata/android/fr-FR/title.txt     |   2 +-
 icons/build_game_icons.sh                     |  11 +-
 icons/colors_5.svg                            |   2 +
 icons/colors_6.svg                            |   2 +
 icons/colors_7.svg                            |   2 +
 icons/colors_8.svg                            |   2 +
 icons/skins/default/{empty.svg => 0.svg}      |   2 +-
 icons/skins/default/1.svg                     |   2 +
 icons/skins/default/2.svg                     |   2 +
 icons/skins/default/3.svg                     |   2 +
 icons/skins/default/4.svg                     |   2 +
 icons/skins/default/5.svg                     |   2 +
 icons/skins/default/6.svg                     |   2 +
 icons/skins/default/7.svg                     |   2 +
 icons/skins/default/8.svg                     |   2 +
 lib/entities/cell.dart                        |  49 ++++
 lib/layout/board.dart                         |   9 +-
 lib/layout/game.dart                          |  34 ++-
 lib/provider/data.dart                        | 187 +++++++++++++--
 lib/screens/home.dart                         |  14 +-
 lib/utils/board_utils.dart                    | 217 ++++++++++++++++++
 lib/utils/game_utils.dart                     |   5 +
 pubspec.lock                                  |   2 +-
 42 files changed, 518 insertions(+), 50 deletions(-)
 create mode 100644 assets/icons/colors_5.png
 create mode 100644 assets/icons/colors_6.png
 create mode 100644 assets/icons/colors_7.png
 create mode 100644 assets/icons/colors_8.png
 rename assets/skins/{default_empty.png => default_0.png} (74%)
 create mode 100644 assets/skins/default_1.png
 create mode 100644 assets/skins/default_2.png
 create mode 100644 assets/skins/default_3.png
 create mode 100644 assets/skins/default_4.png
 create mode 100644 assets/skins/default_5.png
 create mode 100644 assets/skins/default_6.png
 create mode 100644 assets/skins/default_7.png
 create mode 100644 assets/skins/default_8.png
 create mode 100644 fastlane/metadata/android/en-US/changelogs/5.txt
 create mode 100644 fastlane/metadata/android/fr-FR/changelogs/5.txt
 create mode 100644 icons/colors_5.svg
 create mode 100644 icons/colors_6.svg
 create mode 100644 icons/colors_7.svg
 create mode 100644 icons/colors_8.svg
 rename icons/skins/default/{empty.svg => 0.svg} (61%)
 create mode 100644 icons/skins/default/1.svg
 create mode 100644 icons/skins/default/2.svg
 create mode 100644 icons/skins/default/3.svg
 create mode 100644 icons/skins/default/4.svg
 create mode 100644 icons/skins/default/5.svg
 create mode 100644 icons/skins/default/6.svg
 create mode 100644 icons/skins/default/7.svg
 create mode 100644 icons/skins/default/8.svg
 create mode 100644 lib/entities/cell.dart
 create mode 100644 lib/utils/board_utils.dart

diff --git a/android/gradle.properties b/android/gradle.properties
index 14eed39..aa51064 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.4
-app.versionCode=4
+app.versionName=0.0.5
+app.versionCode=5
diff --git a/assets/icons/colors_5.png b/assets/icons/colors_5.png
new file mode 100644
index 0000000000000000000000000000000000000000..dd0a276e105a79aa25ca36f6cc4d2f69c77df81f
GIT binary patch
literal 1516
zcmeAS@N?(olHy`uVBq!ia0y~yU^oE69Lx+145>_WOc@v$I14-?iy0WCPk}I_+{y{!
z3=9mCC9V-A!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NHH)l*#`K8xH2#>FfuYQ
zGBGkSF|x2Sv$8X@aj<Z3v2t*;a`Ccp^Re*=aPSIp@CkD8332iZbMlLD3W{<GiE|4}
z@Q6t9h)VH_%koLc@kuKQ$S4cSstU=e2`OrcC~1o->4+-ph^pv{spyHRgv+aBsi^9U
zt41rT#VD#9NvMY?Xc$RonM!HZYH6EEY1eA&SV-$x%jnz48raGj*~=L@$eTFHn>Z<$
z&M`G}RWx@~vhYx{^i;NvQn&F@vGG;4^;5Nt*0A$avk!=~4^(#y3U>@@bPU#T3T|==
z(QppcbP3aR4fk-3&~l5?_K3Fgh|%#*(DP2w_fIkKPc;ZkGYrZw3d%GJ&NL3rG7iZ$
z4vo_f%{~yCV-l9A6_%tQmTMC3s}<>~85N=xRd6b%)FL)WGd4*rw#+iF!ZNYiI=Rj!
zxz0AV(Jn1TF|Eliz1cpa#Xht7ZDy-OW}8D+ihNePW469Zc86n5r&CUsQ*O6YUbk~z
zk8^&nbAF#oLC@d939dyGU5h5V6;F06aaJvz;$Aw{y<AhJe7a}FOwY<$Ue$BFYqZsB
zb<}F-`_wJ)saxP%ztFdSkzd1Nzs4p0O-^df%L1C02ehsXY+Du7wmPW2Sf+hVP=~8V
z$C}_SH;t}R*{<~=-5Wx>H-`3X3hmt-*1t7;!uE&>J0d3Th?ul9a?-BI$-5&b?~a<X
zCu-{6=&Adnr|pZLwm)Y2fta}(+UtDucIX-H)HgmnPw7mg+1W_5v&)p9S=qlkp!q-F
z`TsecI%U2k3=GT$o-U3d6}R5r`5r9nC~@qgv6zr+;E^t&qkU4YZ&rj@CosBhWN7LV
z4Y3gk?BYslR^W)(=q%(BQT_M!8I8j`J{p}k{ou{&^WTr}esiYwnbFB-dHS>30_Gb>
z&rEyA6v29V4Jgg8Z|E}%;!}*-GEq-aX3IobH-_);bb@9+^*uS;L)CohahJ)rUYRji
zY>wN%G-T!VW2rI<Qv}0Tx1V2XqI)ZoqvHF_OTPLG9tbUD(oc96<n@`6fh6!?Kidu?
z?fd|%)whL(t_ynkY<RsnJ%FpfP*S%>*V=d0hMikG%r>pqx^sfrCZDNGkFPb|?rHi>
zc)_Vp?z->f3f}#Y4645Uo4w%a`FRo>OZhLnuU+`%--2M#1CR5k*g@QKfMJ8-N&ohl
z3~^s=AZ}}@m)MZ__0$TD+lNv&dRm{m|D0oj)GmePt)>TNXP$Gt$B;i+dj_*f@TA%1
z4wsc=&oJIn;xBI4)@z**!25mvl!>dD-Q177KWQBnG->{HDSPb$4;HWR3w4;9x+J&z
zpUbUh`{b-|gl~uqZI~aGW7nX0hT+g=7dDm>Bj%3j2RAL~ly+Ehx*@BqA=+rc6xj!@
zJQ`{26<W;eHZk8wZI~;o;BNJ=(NC3;ccr@3-#4$ecr_Ge)lC%5yybGY;=12YS&`K`
z4wn!0?W((9d_slUPm|}umc-d_KYcqUY8SllK-p5pd&kz<7d?O8SrIWyEbY_Wo@E?Y
z8ST~nHYz5&@fiLoKAWz?@b9*M1@p4%3g)J0mh1y7tPV;U{9E^cM`FV=->2QXuR7Yw
z{BPkps=t1B_w?vL^8c39^nWt9*wdDs`S}dn^i58|S-km%n%iEi&wh8Opy>Lo6&))V
zDjwE#R9v_%^riT`-<2z~PU}_A&Ek%)mi@i-_^+qzQ(kS3UBw_*yY!3Ubxuem5KsPz
zb@<Efl|O}XO8WCjx1NWwD9Ge4v1-w3*vHDiz))f<osl{#(s{-CTK4Okc122MY<USX
N+tbz0Wt~$(699v-Cj|fi

literal 0
HcmV?d00001

diff --git a/assets/icons/colors_6.png b/assets/icons/colors_6.png
new file mode 100644
index 0000000000000000000000000000000000000000..2a63916ed00f0570bedd1647e34706d041fbec44
GIT binary patch
literal 2010
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
V4Izr}6dr-ZJzf1=);T3K0RV)w5hnlu

literal 0
HcmV?d00001

diff --git a/assets/icons/colors_7.png b/assets/icons/colors_7.png
new file mode 100644
index 0000000000000000000000000000000000000000..fdc1669a1d89ed225cc4624319ff01558ab987b4
GIT binary patch
literal 1543
zcmeAS@N?(olHy`uVBq!ia0y~yU^oE69Lx+145>_WOc@v$I14-?iy0WCPk}I_+{y{!
z3=9mCC9V-A!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NHH)l*#`K8xH2#>FfuSO
zF)}hUGO{o+vNAETF)^_-GjT98bFwgVu`qM9vhcF9@UgK9u(Jwtu!(ZAi*d3`a&bs=
zbIS8_De!VB@^LHkajRshsPgluty`xqz@sj}tKl!F86>Y+SECgouT`t1EySl?tF7JK
zq$9+q)7qkY=8W#yvwFh(dTz4%!u<Lo{02E$Mxp|yVuGe~OwGgu&BcW*{{Od<5Vn;R
zagr8wmJxOJs(15lbe9$PkQ4W^j`Wt7@R67BHIw(V2=sGz2vC#?FqIE<wh2*|4po*8
z%{~xr;t;9q6s0N~Rd6a=#V$roE><}zR$VSmB|6T)Bwo!pUR^#}LnlR3A;m~J#au5{
zOEFDLF;iP9v-xe7x<a;^LXMeyuC8*fo?@Pka-N=YzP@6<y=;M=N`by|LC@bpeU&0b
z#Ug#xVlU}Zf2ndqwF)EkDn;cgz4mHjjcPNc8e@$*6U};4%?2fv22;&OWz|N5zD85c
zR&(t(E0s=5oi0n=?rf<Z8?`=by*^vDzFg^kYrP3JdXsGQC)w&xw$-0zXE5Dj*>rou
z8TN*=9E@f=7|qqtp66t|&}QQzXOkr^rpsJSSGbw2bTeD!Zob;xe2u&LS`UkLK6>jt
zEjD^uZt}9+>TR{n+iIJS^$tCwo%+VRd~J67+U)kT+3#<=-{0<FfZd@0yTgI@hvz9B
z3A8^NWPdEk;dqe4@nDA&!44;b9Z!Wgo(^$56Y6v(((G)g)7eO~v&)p9S=qlkp!q-F
z`TsecrbiWZ3=GWPo-U3d6}R5re(paxP~`Z>rrTBlce-|@-|bp)LO>+YC2&r|q8*|K
zJDCGR<V2SG9l7RMsJ}or*Y@20vud9XIiEVgIO%!I{qKK$&#9Yd&bl4k&AQMpeXHi#
zTRa;kUdjO_`2P&?i#5zAhL>IPell(DmsX}9-=BA#+PK^3diSZ4o0ElI-hOCjs3>~B
ze_BX}#iJl|F0bBViNMLKy`CRhSoZwXe3>LLq1Gj!Ou!&>;gXdMq=5^I8Sl+G#677`
z^4yUdqD@J{bC1pGoU~}t-i2cEtMfXw)@QGnFn3MH3hn80*BG6CRd{%_RN&UTOe^f}
zK3p}s|BhW@(3N}3-Z99${Za46XDV;F?(d{8Ul$zLX_#HF@)zoqhIQ;URadK4TRfPf
z$(Z}(#o1^5Uox0=o{9%}onlC>`L~lXmEk>yS^W*=AhsLF^%dq#VZ0Z4^UvR`t&ER;
zvc6GEZ8-ig=U?L2Qw)tS|1jxIHgYhWU*8lj`M{fn{f4Jxg7o})OHJlIZ%#jZ|Jg}8
zL2`e?*(E#$?dR=(G#fSKo3PJON^N*t^Dof%6vKP=LI+k&<~0vL>no);sQ>W}_z|4i
zaG<7+G22t}0oVNc2hphw#~#WQG)!UK_W7ss-BS!(|5`rK(qumJ;b%Jg6vlUvQPrLo
z89($tZMeFGCm<p7tEwyOgU14VH(XCKy#Db=@ariC)4di8W=vre`~36x@2QMl(SPQZ
zOfO-)GqL8ML=fAJ<jl{iN53@eVwBm?IfXH7+viD1We1uK_%sw^8UBmd{Xe0W+OS#I
z&WZOD>kpeL=l3^EVKj@lRqOeXAz1gXAnUo$Z%=Ld#y2DTZBW2<y?t5nw%?Yy_)j)D
zU$87aM{vr-cP8gzriV-t&-!_LvPpL563I5@wVxI)IAzja_;~x0_dn&JkwPr>;$lOg
zv8pROqw91QQC3FP`zp5loFCr%2u)2YPt6sb`gGItr`=X>__zLel`ZmA?b9j0s?Ix`
tCfgaEd{w9pD$4(*Zq+=S<+$SVUsiUm)Y%_p|0ja%_H^}gS?83{1OU_kG$a53

literal 0
HcmV?d00001

diff --git a/assets/icons/colors_8.png b/assets/icons/colors_8.png
new file mode 100644
index 0000000000000000000000000000000000000000..b660ef3e29aefc5c940a327aaf7a22d76a73bb23
GIT binary patch
literal 2193
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

literal 0
HcmV?d00001

diff --git a/assets/skins/default_empty.png b/assets/skins/default_0.png
similarity index 74%
rename from assets/skins/default_empty.png
rename to assets/skins/default_0.png
index b5261e3248aa6c8ea427463b0a70a3b5d2241bb1..e543c1a9c0a2f38128c5a48437dcb75ceeaa23e2 100644
GIT binary patch
delta 29
mcmey(_?vM;vT%KU{h~#S_V3?+`0(NX|NrmLJ-2gWSt|hhZW1H_

delta 29
lcmey(_?vM;vT#5^Kz@FHcXxMRU*FNAM{ma#f1X&@3INUO4*&oF

diff --git a/assets/skins/default_1.png b/assets/skins/default_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..50ac7e9dc99ea6cf1e0a0126615e0217ec140023
GIT binary patch
literal 251
zcmeAS@N?(olHy`uVBq!ia0y~yU^oE6EX)iH3=2LLnlLaha29w(7Beu&M1U~k*%{Bz
zFfcGkmbgZg1m~xflqVLYGL)B>>t*I;7bhncr0V4trO$q6BgMeLz#rff;#w>#KS@<%
zjkf*<9fN09_H}zyb}%q7<a)X|hE&XXdxw#eK|z4!;Ohid?hf7~|7QApd~i6YF>{0G
t|6_VNsx!B50J(&LOwjPZ;nP;%?{f9$4R_nyz3c)R<LT<>vd$@?2>>OWK{5aU

literal 0
HcmV?d00001

diff --git a/assets/skins/default_2.png b/assets/skins/default_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..cca70ea9b7cb61319c79a07d8567ae9707f29a8a
GIT binary patch
literal 251
zcmeAS@N?(olHy`uVBq!ia0y~yU^oE6EX)iH3=2LLnlLaha29w(7Beu&M1U~k*%{Bz
zFfcGkmbgZg1m~xflqVLYGL)B>>t*I;7bhncr0V4trO$q6BgMeLz#rff;%ebm=N`E*
zBy(R__Q8UlzxP@M-ZC&S<a)X|hE&XXdxw#eK|z4!;Ohid?hf7~|7QApd~i6YF>{0G
t|6_VNsx!B50J(&LOwjPZ;nP;%?{f9$4R_nyz3c)R<LT<>vd$@?2>^wIL$3e;

literal 0
HcmV?d00001

diff --git a/assets/skins/default_3.png b/assets/skins/default_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..9e4ccd82edd6dea24e3f73a9794d735a268cc11b
GIT binary patch
literal 251
zcmeAS@N?(olHy`uVBq!ia0y~yU^oE6EX)iH3=2LLnlLaha29w(7Beu&M1U~k*%{Bz
zFfcGkmbgZg1m~xflqVLYGL)B>>t*I;7bhncr0V4trO$q6BgMeLz#rff;wt4QrIf6s
zQL3R?u4y{QRN+*5D+2>VuBVG*NX4ADcNjSt6a-ifzD{7}?%+N0Z>G=32ZwVSGdFnt
sKc<(XI&=F5kV_cI1P%WiK5g~=E?0lvaJRkP%Px>Hp00i_>zopr086(&umAu6

literal 0
HcmV?d00001

diff --git a/assets/skins/default_4.png b/assets/skins/default_4.png
new file mode 100644
index 0000000000000000000000000000000000000000..86a9c87e0459697060a91571714765c0078a1403
GIT binary patch
literal 251
zcmeAS@N?(olHy`uVBq!ia0y~yU^oE6EX)iH3=2LLnlLaha29w(7Beu&M1U~k*%{Bz
zFfcGkmbgZg1m~xflqVLYGL)B>>t*I;7bhncr0V4trO$q6BgMeLz#rff;#!|Bwy0TV
z|18DB^OXLd(>a?hpTNMtkn8E<7*a9k?Hxu=1_c3@gRc`<xjT4|{F~|X@xkGo#>@?#
t|BvbAsLtHJ0pt<}GC{-thEH34zsuF1H{5M+_p%FQjHj!g%Q~loCIB)$Lk9o=

literal 0
HcmV?d00001

diff --git a/assets/skins/default_5.png b/assets/skins/default_5.png
new file mode 100644
index 0000000000000000000000000000000000000000..7c4f1cb57586355b4e443d8e6e4d17fc7053f2d1
GIT binary patch
literal 251
zcmeAS@N?(olHy`uVBq!ia0y~yU^oE6EX)iH3=2LLnlLaha29w(7Beu&M1U~k*%{Bz
zFfcGkmbgZg1m~xflqVLYGL)B>>t*I;7bhncr0V4trO$q6BgMeLz#rff;#zO6xX4|5
zf3VTvP~-pk&MLF5)fpHVay?xfLn`LHy~D`Kpdi3<@O1(!cL(p0e=~hPJ~*7yn7P68
t|1rHB)tTEjfLy{rCTRHI@M){>ce(oWhP&<UUUq?u@pScbS?83{1OQD#L1_R0

literal 0
HcmV?d00001

diff --git a/assets/skins/default_6.png b/assets/skins/default_6.png
new file mode 100644
index 0000000000000000000000000000000000000000..4a620e27de46cc9db3742e7d60a5d2e4c8094a4e
GIT binary patch
literal 251
zcmeAS@N?(olHy`uVBq!ia0y~yU^oE6EX)iH3=2LLnlLaha29w(7Beu&M1U~k*%{Bz
zFfcGkmbgZg1m~xflqVLYGL)B>>t*I;7bhncr0V4trO$q6BgMeLz#rff;u;_qk)~Eq
zsoPqu*S^qZ<DU!p3m6y}ay?xfLn`LHy~D`Kpdi3<@O1(!cL(p0e=~hPJ~*7yn7P68
t|1rHB)tTEjfLy{rCTRHI@M){>ce(oWhP&<UUUq?u@pScbS?83{1OV*PLZbix

literal 0
HcmV?d00001

diff --git a/assets/skins/default_7.png b/assets/skins/default_7.png
new file mode 100644
index 0000000000000000000000000000000000000000..988d6fc485453b4f4c0c5c306809eec93a611718
GIT binary patch
literal 251
zcmeAS@N?(olHy`uVBq!ia0y~yU^oE6EX)iH3=2LLnlLaha29w(7Beu&M1U~k*%{Bz
zFfcGkmbgZg1m~xflqVLYGL)B>>t*I;7bhncr0V4trO$q6BgMeLz#rff;wn>Lud-;7
z*8ct4hYwr)|KF=<TEW1;kn8E<7*a9k?Hxu=1_c3@gRc`<xjT4|{F~|X@xkGo#>@?#
t|BvbAsLtHJ0pt<}GC{-thEH34zsuF1H{5M+_p%FQjHj!g%Q~loCIENvLx}(Y

literal 0
HcmV?d00001

diff --git a/assets/skins/default_8.png b/assets/skins/default_8.png
new file mode 100644
index 0000000000000000000000000000000000000000..1f5cc615ca867c90f0004097308dc83d9ae496df
GIT binary patch
literal 251
zcmeAS@N?(olHy`uVBq!ia0y~yU^oE6EX)iH3=2LLnlLaha29w(7Beu&M1U~k*%{Bz
zFfcGkmbgZg1m~xflqVLYGL)B>>t*I;7bhncr0V4trO$q6BgMeLz#rff;#z6xH_J0+
zYgpONh>B0ebIo4{cQ7z8<a)X|hE&XXdxw#eK|z4!;Ohid?hf7~|7QApd~i6YF>{0G
t|6_VNsx!B50J(&LOwjPZ;nP;%?{f9$4R_nyz3c)R<LT<>vd$@?2>@k!Lu&v4

literal 0
HcmV?d00001

diff --git a/fastlane/metadata/android/en-US/changelogs/5.txt b/fastlane/metadata/android/en-US/changelogs/5.txt
new file mode 100644
index 0000000..64563db
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/5.txt
@@ -0,0 +1 @@
+Add minimal playable game
diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt
index 60b134f..2165288 100644
--- a/fastlane/metadata/android/en-US/full_description.txt
+++ b/fastlane/metadata/android/en-US/full_description.txt
@@ -1,3 +1,3 @@
-Jeweled Game:
+Jeweled:
 
 Simple and classic Jeweled game.
\ No newline at end of file
diff --git a/fastlane/metadata/android/fr-FR/changelogs/5.txt b/fastlane/metadata/android/fr-FR/changelogs/5.txt
new file mode 100644
index 0000000..8ebcd9c
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/5.txt
@@ -0,0 +1 @@
+Ajout d'un gameplay minimal
diff --git a/fastlane/metadata/android/fr-FR/full_description.txt b/fastlane/metadata/android/fr-FR/full_description.txt
index c862dd0..5b75511 100644
--- a/fastlane/metadata/android/fr-FR/full_description.txt
+++ b/fastlane/metadata/android/fr-FR/full_description.txt
@@ -1,3 +1,3 @@
 Jeweled :
 
-Jeu simple et classique d'associations
\ No newline at end of file
+Jeu simple et classique d'associations
diff --git a/fastlane/metadata/android/fr-FR/short_description.txt b/fastlane/metadata/android/fr-FR/short_description.txt
index e24645b..f5d1552 100644
--- a/fastlane/metadata/android/fr-FR/short_description.txt
+++ b/fastlane/metadata/android/fr-FR/short_description.txt
@@ -1 +1 @@
-Jeweled, jeu d'associations
\ No newline at end of file
+Jeweled, jeu d'associations
diff --git a/fastlane/metadata/android/fr-FR/title.txt b/fastlane/metadata/android/fr-FR/title.txt
index 32220f7..ca1e85b 100644
--- a/fastlane/metadata/android/fr-FR/title.txt
+++ b/fastlane/metadata/android/fr-FR/title.txt
@@ -1 +1 @@
-Jeweled
\ No newline at end of file
+Jeweled
diff --git a/icons/build_game_icons.sh b/icons/build_game_icons.sh
index ccdf140..b76b628 100755
--- a/icons/build_game_icons.sh
+++ b/icons/build_game_icons.sh
@@ -29,6 +29,7 @@ AVAILABLE_GAME_IMAGES="
 AVAILABLES_GAME_SETTINGS="
   level:easy,medium,hard,nightmare
   size:small,medium,large,extra
+  colors:5,6,7,8
 "
 
 # Skins
@@ -38,7 +39,15 @@ AVAILABLE_SKINS="
 
 # Images per skin
 SKIN_IMAGES="
-  empty
+  0
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
 "
 
 #######################################################
diff --git a/icons/colors_5.svg b/icons/colors_5.svg
new file mode 100644
index 0000000..2f218e9
--- /dev/null
+++ b/icons/colors_5.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 102 102" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x="1" y="1" width="100" height="100" ry="0" fill="#97c05c" stroke="#000" stroke-width="2"/><g transform="translate(-1.0061 .33115)" aria-label="5"><path d="m63.315 55.063q0 2.2656-0.85938 4.2188-0.83984 1.9336-2.4609 3.3203-1.7969 1.4844-4.1406 2.207-2.3242 0.70312-5.3125 0.70312-3.4961-0.01953-5.918-0.56641-2.4023-0.52734-3.9258-1.1914v-6.4258h0.82031q1.7773 1.0547 3.8281 1.7578t4.082 0.70312q1.2305 0 2.6562-0.27344 1.4453-0.29297 2.2852-1.0352 0.66406-0.60547 0.99609-1.2305 0.35156-0.625 0.35156-1.9336 0-1.0156-0.46875-1.7383-0.44922-0.74219-1.1719-1.1914-1.0547-0.64453-2.5391-0.83984-1.4844-0.21484-2.6953-0.21484-1.7578 0-3.3789 0.3125-1.6016 0.29297-2.8125 0.58594h-0.85938v-16.406h20.684v5.5664h-13.633v4.7461q0.60547-0.03906 1.5234-0.05859 0.9375-0.03906 1.6406-0.03906 2.4023 0 4.2773 0.46875 1.8945 0.44922 3.2617 1.2695 1.7773 1.0742 2.7734 2.8516 0.99609 1.7578 0.99609 4.4336z"/></g><rect x="67.01" y="67.01" width="29.323" height="29.323" fill="#ff6f43" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="67.01" y="36.339" width="29.323" height="29.323" fill="#ffce2c" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="67.01" y="5.6672" width="29.323" height="29.323" fill="#359c35" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="36.339" y="5.6672" width="29.323" height="29.323" fill="#708cfd" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="5.6671" y="5.6672" width="29.323" height="29.323" fill="#e63a3f" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/></svg>
diff --git a/icons/colors_6.svg b/icons/colors_6.svg
new file mode 100644
index 0000000..6df1641
--- /dev/null
+++ b/icons/colors_6.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 102 102" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x="1" y="1" width="100" height="100" ry="0" fill="#f29c38" stroke="#000" stroke-width="2"/><g transform="translate(3.8694 .21001)" aria-label="6"><path d="m59.025 55.399q0 2.2461-0.82031 4.2188t-2.3047 3.3203q-1.582 1.4453-3.6719 2.207-2.0703 0.76172-4.8633 0.76172-2.6172 0-4.7852-0.70312-2.1484-0.72266-3.6914-2.1875-1.7773-1.6797-2.7148-4.3359t-0.9375-6.3477q0-3.8281 0.87891-6.7969t2.8711-5.2539q1.9141-2.1875 4.9609-3.3984 3.0664-1.2109 7.2852-1.2109 1.4258 0 3.125 0.19531t2.207 0.29297v5.7227h-0.74219q-0.52734-0.25391-1.7969-0.56641-1.25-0.33203-2.8516-0.33203-3.75 0-5.8398 1.8359t-2.5195 5.1172q1.5039-0.89844 3.1641-1.4453 1.6797-0.56641 3.6133-0.56641 1.6992 0 3.1445 0.39062 1.4648 0.39062 2.7148 1.25 1.6211 1.1328 2.5977 3.0469 0.97656 1.9141 0.97656 4.7852zm-8.8867 4.3945q0.60547-0.66406 0.95703-1.5625 0.37109-0.91797 0.37109-2.4805 0-1.4258-0.41016-2.3242-0.41016-0.91797-1.1328-1.4648-0.70312-0.54688-1.6602-0.74219-0.95703-0.21484-1.9727-0.21484-0.85938 0-1.7969 0.19531-0.9375 0.19531-1.7188 0.48828 0 0.19531-0.01953 0.64453t-0.01953 1.1328q0 2.4023 0.46875 3.9648 0.48828 1.543 1.2891 2.3633 0.54688 0.60547 1.2891 0.89844 0.74219 0.27344 1.6016 0.27344 0.64453 0 1.4258-0.29297t1.3281-0.87891z"/></g><rect x="36.339" y="67.01" width="29.323" height="29.323" fill="#a13cb1" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="67.01" y="67.01" width="29.323" height="29.323" fill="#ff6f43" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="67.01" y="36.339" width="29.323" height="29.323" fill="#ffce2c" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="67.01" y="5.6672" width="29.323" height="29.323" fill="#359c35" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="36.339" y="5.6672" width="29.323" height="29.323" fill="#708cfd" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="5.6671" y="5.6672" width="29.323" height="29.323" fill="#e63a3f" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/></svg>
diff --git a/icons/colors_7.svg b/icons/colors_7.svg
new file mode 100644
index 0000000..7870bc7
--- /dev/null
+++ b/icons/colors_7.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 102 102" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x="1" y="1" width="100" height="100" ry="0" fill="#cd5542" stroke="#000" stroke-width="2"/><g transform="translate(3.9378 .2393)" aria-label="7"><path d="m58.459 42.001-13.164 23.301h-8.3594l13.672-23.516h-14.941v-5.5664h22.793z"/></g><rect x="5.6671" y="67.01" width="29.323" height="29.323" fill="#38ffff" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="36.339" y="67.01" width="29.323" height="29.323" fill="#a13cb1" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="67.01" y="67.01" width="29.323" height="29.323" fill="#ff6f43" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="67.01" y="36.339" width="29.323" height="29.323" fill="#ffce2c" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="67.01" y="5.6672" width="29.323" height="29.323" fill="#359c35" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="36.339" y="5.6672" width="29.323" height="29.323" fill="#708cfd" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="5.6671" y="5.6672" width="29.323" height="29.323" fill="#e63a3f" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/></svg>
diff --git a/icons/colors_8.svg b/icons/colors_8.svg
new file mode 100644
index 0000000..37f3949
--- /dev/null
+++ b/icons/colors_8.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 102 102" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x="1" y="1" width="100" height="100" ry="0" fill="#6041b0" stroke="#000" stroke-width="2"/><g transform="translate(4.1624 .2393)" aria-label="8"><path d="m59.123 57.177q0 3.8672-3.3008 6.3281-3.2812 2.4609-9.0234 2.4609-3.2227 0-5.5273-0.66406-2.3047-0.66406-3.8086-1.8359-1.4844-1.1523-2.207-2.6953-0.70312-1.543-0.70312-3.3203 0-2.1875 1.2695-3.8672 1.2891-1.6992 4.4336-2.9688v-0.11719q-2.5391-1.1719-3.7305-2.9492t-1.1914-4.1211q0-3.457 3.2031-5.6641 3.2031-2.207 8.3398-2.207 5.3906 0 8.4375 2.0117 3.0664 1.9922 3.0664 5.332 0 2.0703-1.2891 3.6914t-3.9453 2.7539v0.11719q3.0469 1.1523 4.5117 3.1055t1.4648 4.6094zm-8.0664-13.438q0-1.4844-1.1523-2.3633-1.1328-0.87891-3.0273-0.87891-0.70312 0-1.4453 0.17578-0.72266 0.17578-1.3281 0.50781-0.56641 0.33203-0.9375 0.87891-0.37109 0.52734-0.37109 1.2109 0 1.1523 0.64453 1.7969 0.66406 0.64453 2.1484 1.2891 0.54688 0.23438 1.4844 0.58594 0.95703 0.33203 2.3047 0.76172 0.89844-1.0547 1.2891-1.8945 0.39062-0.83984 0.39062-2.0703zm0.60547 13.77q0-1.4062-0.70312-2.1289t-2.8906-1.6602q-0.64453-0.29297-1.875-0.72266-1.2305-0.42969-2.0703-0.74219-0.83984 0.76172-1.5234 1.8555-0.66406 1.0742-0.66406 2.4219 0 2.0312 1.4453 3.2422 1.4648 1.1914 3.8086 1.1914 0.625 0 1.4648-0.17578 0.83984-0.19531 1.4453-0.58594 0.70312-0.44922 1.1328-1.0547 0.42969-0.60547 0.42969-1.6406z"/></g><rect x="5.6671" y="36.339" width="29.323" height="29.323" fill="#f2739d" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="5.6671" y="67.01" width="29.323" height="29.323" fill="#38ffff" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="36.339" y="67.01" width="29.323" height="29.323" fill="#a13cb1" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="67.01" y="67.01" width="29.323" height="29.323" fill="#ff6f43" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="67.01" y="36.339" width="29.323" height="29.323" fill="#ffce2c" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="67.01" y="5.6672" width="29.323" height="29.323" fill="#359c35" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="36.339" y="5.6672" width="29.323" height="29.323" fill="#708cfd" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/><rect x="5.6671" y="5.6672" width="29.323" height="29.323" fill="#e63a3f" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width=".76239"/></svg>
diff --git a/icons/skins/default/empty.svg b/icons/skins/default/0.svg
similarity index 61%
rename from icons/skins/default/empty.svg
rename to icons/skins/default/0.svg
index 3999633..c55c649 100644
--- a/icons/skins/default/empty.svg
+++ b/icons/skins/default/0.svg
@@ -1,2 +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="2" fill="none"/><rect width="100" height="100" fill="#c5c5c5" stroke="#505050" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.6"/></svg>
+<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="none"/><rect width="100" height="100" fill="#fff" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width="2.6"/></svg>
diff --git a/icons/skins/default/1.svg b/icons/skins/default/1.svg
new file mode 100644
index 0000000..8381dc6
--- /dev/null
+++ b/icons/skins/default/1.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="2" fill="none"/><rect width="100" height="100" fill="#E63A3F" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width="2.6"/></svg>
diff --git a/icons/skins/default/2.svg b/icons/skins/default/2.svg
new file mode 100644
index 0000000..8306614
--- /dev/null
+++ b/icons/skins/default/2.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="2" fill="none"/><rect width="100" height="100" fill="#708CFD" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width="2.6"/></svg>
diff --git a/icons/skins/default/3.svg b/icons/skins/default/3.svg
new file mode 100644
index 0000000..5b6298b
--- /dev/null
+++ b/icons/skins/default/3.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="2" fill="none"/><rect width="100" height="100" fill="#359C35" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width="2.6"/></svg>
diff --git a/icons/skins/default/4.svg b/icons/skins/default/4.svg
new file mode 100644
index 0000000..b48f425
--- /dev/null
+++ b/icons/skins/default/4.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="2" fill="none"/><rect width="100" height="100" fill="#FFCE2C" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width="2.6"/></svg>
diff --git a/icons/skins/default/5.svg b/icons/skins/default/5.svg
new file mode 100644
index 0000000..68b7610
--- /dev/null
+++ b/icons/skins/default/5.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="2" fill="none"/><rect width="100" height="100" fill="#FF6F43" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width="2.6"/></svg>
diff --git a/icons/skins/default/6.svg b/icons/skins/default/6.svg
new file mode 100644
index 0000000..da1c8ae
--- /dev/null
+++ b/icons/skins/default/6.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="2" fill="none"/><rect width="100" height="100" fill="#A13CB1" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width="2.6"/></svg>
diff --git a/icons/skins/default/7.svg b/icons/skins/default/7.svg
new file mode 100644
index 0000000..da0f69c
--- /dev/null
+++ b/icons/skins/default/7.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="2" fill="none"/><rect width="100" height="100" fill="#38FFFF" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width="2.6"/></svg>
diff --git a/icons/skins/default/8.svg b/icons/skins/default/8.svg
new file mode 100644
index 0000000..0b637b3
--- /dev/null
+++ b/icons/skins/default/8.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="2" fill="none"/><rect width="100" height="100" fill="#F2739D" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" stroke-width="2.6"/></svg>
diff --git a/lib/entities/cell.dart b/lib/entities/cell.dart
new file mode 100644
index 0000000..d5f45d9
--- /dev/null
+++ b/lib/entities/cell.dart
@@ -0,0 +1,49 @@
+import 'package:flutter/material.dart';
+import 'package:jeweled_game/provider/data.dart';
+import 'package:jeweled_game/utils/board_utils.dart';
+
+class Cell {
+  String value = '0';
+
+  Cell(
+    this.value,
+  );
+
+  /*
+  * Build widget for board cell, with interactions
+  * @TODO: remove parameters
+  */
+  Container widget(Data myProvider, int row, int col) {
+    String imageAsset = this.getImageAssetName(myProvider);
+
+    return Container(
+      child: GestureDetector(
+        child: AnimatedSwitcher(
+          duration: const Duration(milliseconds: 100),
+          transitionBuilder: (Widget child, Animation<double> animation) {
+            return ScaleTransition(child: child, scale: animation);
+          },
+          child: Image(
+            image: AssetImage(imageAsset),
+            fit: BoxFit.fill,
+            key: ValueKey<int>(imageAsset.hashCode),
+          ),
+        ),
+        onTap: () {
+          if (!myProvider.isGameFinished) {
+            BoardUtils.tapOnCell(myProvider, row, col);
+          }
+        },
+      ),
+    );
+  }
+
+  /*
+  * Compute image asset name, from skin and cell value/state
+  */
+  String getImageAssetName(Data myProvider) {
+    String imageAsset = 'assets/skins/' + myProvider.parameterSkin + '_' + this.value + '.png';
+
+    return imageAsset;
+  }
+}
diff --git a/lib/layout/board.dart b/lib/layout/board.dart
index 0355470..8d207d1 100644
--- a/lib/layout/board.dart
+++ b/lib/layout/board.dart
@@ -15,18 +15,19 @@ class Board {
   }
 
   static Table buildGameTileset(Data myProvider) {
-    int boardSize = 5;
+    int boardSizeHorizontal = myProvider.sizeHorizontal;
+    int boardSizeVertical = myProvider.sizeVertical;
 
     return Table(
       defaultColumnWidth: IntrinsicColumnWidth(),
       children: [
-        for (var row = 0; row < boardSize; row++)
+        for (var row = 0; row < boardSizeVertical; row++)
           TableRow(
             children: [
-              for (var col = 0; col < boardSize; col++)
+              for (var col = 0; col < boardSizeHorizontal; col++)
                 Column(
                   children: [
-                    Text('[' + col.toString() + ',' + row.toString() + "]"),
+                    myProvider.getCell(row, col).widget(myProvider, row, col),
                   ],
                 ),
             ],
diff --git a/lib/layout/game.dart b/lib/layout/game.dart
index 36fe226..12df4e3 100644
--- a/lib/layout/game.dart
+++ b/lib/layout/game.dart
@@ -35,7 +35,7 @@ class Game {
             Column(
               children: [
                 Text(
-                  'SCORE',
+                  myProvider.score.toString(),
                   style: TextStyle(
                     fontSize: 40,
                     fontWeight: FontWeight.w600,
@@ -43,7 +43,7 @@ class Game {
                   ),
                 ),
                 Text(
-                  'TARGET',
+                  myProvider.movesCount.toString(),
                   style: TextStyle(
                     fontSize: 15,
                     fontWeight: FontWeight.w600,
@@ -55,7 +55,7 @@ class Game {
             Column(
               children: [
                 Text(
-                  'INFOS',
+                  myProvider.availableBlocksCount.toString(),
                   style: TextStyle(
                     fontSize: 20,
                     fontWeight: FontWeight.w600,
@@ -72,27 +72,23 @@ class Game {
 
   static TextButton buildQuitGameButton(Data myProvider) {
     return TextButton(
-      child: Container(
-        child: Image(
-          image: AssetImage('assets/icons/button_back.png'),
-          fit: BoxFit.fill,
-        ),
+      child: Image(
+        image: AssetImage('assets/icons/button_back.png'),
+        fit: BoxFit.fill,
       ),
       onPressed: () => GameUtils.quitGame(myProvider),
     );
   }
 
   static Container buildEndGameMessage(Data myProvider) {
-    String decorationImageAssetName = '';
-    if (myProvider.gameWon()) {
-      decorationImageAssetName = 'assets/icons/game_win.png';
-    } else {
-      decorationImageAssetName = 'assets/icons/game_fail.png';
-    }
+    String decorationImageAssetName = 'assets/icons/game_fail.png';
 
-    Image decorationImage = Image(
-      image: AssetImage(decorationImageAssetName),
-      fit: BoxFit.fill,
+    Widget decorationWidget = TextButton(
+      child: Image(
+        image: AssetImage(decorationImageAssetName),
+        fit: BoxFit.fill,
+      ),
+      onPressed: () => null,
     );
 
     return Container(
@@ -104,13 +100,13 @@ class Game {
           TableRow(
             children: [
               Column(
-                children: [decorationImage],
+                children: [decorationWidget],
               ),
               Column(
                 children: [buildQuitGameButton(myProvider)],
               ),
               Column(
-                children: [decorationImage],
+                children: [decorationWidget],
               ),
             ],
           ),
diff --git a/lib/provider/data.dart b/lib/provider/data.dart
index dd69683..bbeabe5 100644
--- a/lib/provider/data.dart
+++ b/lib/provider/data.dart
@@ -1,14 +1,16 @@
 import 'dart:convert';
 
 import 'package:flutter/foundation.dart';
+import 'package:jeweled_game/entities/cell.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 
 class Data extends ChangeNotifier {
-  // Configuration available values
-  List _availableParameters = ['level', 'size', 'skin'];
+  // Configuration available parameters
+  List _availableParameters = ['level', 'size', 'colors', 'skin'];
 
   List _availableLevelValues = ['easy', 'medium', 'hard', 'nightmare'];
   List _availableSizeValues = ['small', 'medium', 'large', 'extra'];
+  List _availableColorsValues = ['5', '6', '7', '8'];
   List _availableSkinValues = ['default'];
 
   List get availableParameters => _availableParameters;
@@ -21,6 +23,8 @@ class Data extends ChangeNotifier {
   String _parameterLevelDefault = 'medium';
   String _parameterSize = '';
   String _parameterSizeDefault = 'medium';
+  String _parameterColors = '';
+  String _parameterColorsDefault = '6';
   String _parameterSkin = '';
   String _parameterSkinDefault = 'default';
 
@@ -32,15 +36,32 @@ class Data extends ChangeNotifier {
   // Game data
   bool _assetsPreloaded = false;
   bool _gameIsRunning = false;
+  bool _gameIsFinished = false;
+  int _sizeVertical = 0;
+  int _sizeHorizontal = 0;
+  int _colorsCount = 0;
+  List<List<Cell>> _cells = [];
   String _currentState = '';
+  int _availableBlocksCount = 0;
+  int _score = 0;
+  int _movesCount = 0;
 
   void updateParameterLevel(String parameterLevel) {
     _parameterLevel = parameterLevel;
     notifyListeners();
   }
 
+  int get sizeVertical => _sizeVertical;
+  int get sizeHorizontal => _sizeHorizontal;
   void updateParameterSize(String parameterSize) {
     _parameterSize = parameterSize;
+    updateBoardSize(getBoardSizeFromParameter(parameterSize));
+    notifyListeners();
+  }
+
+  void updateParameterColors(String parameterColors) {
+    _parameterColors = parameterColors;
+    updateColorsCount(getColorsCountFromParameter(parameterColors));
     notifyListeners();
   }
 
@@ -52,11 +73,21 @@ class Data extends ChangeNotifier {
   String getParameterValue(String parameterCode) {
     switch (parameterCode) {
       case 'level':
-        return _parameterLevel;
+        {
+          return _parameterLevel;
+        }
       case 'size':
-        return _parameterSize;
+        {
+          return _parameterSize;
+        }
+      case 'colors':
+        {
+          return _parameterColors;
+        }
       case 'skin':
-        return _parameterSkin;
+        {
+          return _parameterSkin;
+        }
     }
     return '';
   }
@@ -64,11 +95,21 @@ class Data extends ChangeNotifier {
   List getParameterAvailableValues(String parameterCode) {
     switch (parameterCode) {
       case 'level':
-        return _availableLevelValues;
+        {
+          return _availableLevelValues;
+        }
       case 'size':
-        return _availableSizeValues;
+        {
+          return _availableSizeValues;
+        }
+      case 'colors':
+        {
+          return _availableColorsValues;
+        }
       case 'skin':
-        return _availableSkinValues;
+        {
+          return _availableSkinValues;
+        }
     }
     return [];
   }
@@ -76,13 +117,24 @@ class Data extends ChangeNotifier {
   void setParameterValue(String parameterCode, String parameterValue) async {
     switch (parameterCode) {
       case 'level':
-        updateParameterLevel(parameterValue);
+        {
+          updateParameterLevel(parameterValue);
+        }
         break;
       case 'size':
-        updateParameterSize(parameterValue);
+        {
+          updateParameterSize(parameterValue);
+        }
+        break;
+      case 'colors':
+        {
+          updateParameterColors(parameterValue);
+        }
         break;
       case 'skin':
-        updateParameterSkin(parameterValue);
+        {
+          updateParameterSkin(parameterValue);
+        }
         break;
     }
     final prefs = await SharedPreferences.getInstance();
@@ -93,16 +145,79 @@ class Data extends ChangeNotifier {
     final prefs = await SharedPreferences.getInstance();
     setParameterValue('level', prefs.getString('level') ?? _parameterLevelDefault);
     setParameterValue('size', prefs.getString('size') ?? _parameterSizeDefault);
+    setParameterValue('colors', prefs.getString('colors') ?? _parameterColorsDefault);
     setParameterValue('skin', prefs.getString('skin') ?? _parameterSkinDefault);
   }
 
+  String getBoardSizeFromParameter(String parameterSize) {
+    switch (parameterSize) {
+      case 'small':
+        {
+          return '6x6';
+        }
+      case 'medium':
+        {
+          return '10x10';
+        }
+      case 'large':
+        {
+          return '14x14';
+        }
+      case 'extra':
+        {
+          return '20x20';
+        }
+    }
+    return getBoardSizeFromParameter(_parameterSizeDefault);
+  }
+
+  int getColorsCountFromParameter(String parameterColors) {
+    switch (parameterColors) {
+      case '5':
+        {
+          return 5;
+        }
+      case '6':
+        {
+          return 6;
+        }
+      case '7':
+        {
+          return 7;
+        }
+      case '8':
+        {
+          return 8;
+        }
+    }
+    return getColorsCountFromParameter(_parameterColorsDefault);
+  }
+
+  void updateBoardSize(String boardSize) {
+    _sizeHorizontal = int.parse(boardSize.split('x')[0]);
+    _sizeVertical = int.parse(boardSize.split('x')[1]);
+  }
+
+  int get colorsCount => _colorsCount;
+  void updateColorsCount(int colorsCount) {
+    _colorsCount = colorsCount;
+  }
+
   String get currentState => _currentState;
 
   String computeCurrentGameState() {
+    String cellsValues = '';
+    for (var rowIndex = 0; rowIndex < _cells.length; rowIndex++) {
+      for (var colIndex = 0; colIndex < _cells[rowIndex].length; colIndex++) {
+        cellsValues += _cells[rowIndex][colIndex].value;
+      }
+    }
+
     var currentState = {
       'level': _parameterLevel,
       'size': _parameterSize,
       'skin': _parameterSkin,
+      'board': cellsValues,
     };
 
     return json.encode(currentState);
@@ -151,19 +266,61 @@ class Data extends ChangeNotifier {
     _assetsPreloaded = assetsPreloaded;
   }
 
-  bool get gameIsRunning => _gameIsRunning;
-  bool get isGameFinished => !_gameIsRunning;
+  List<List<Cell>> get cells => _cells;
+  void updateCells(List<List<Cell>> cells) {
+    _cells = cells;
+    notifyListeners();
+  }
+
+  Cell getCell(int row, int col) {
+    return cells[row][col];
+  }
+
+  String getCellValue(int row, int col) {
+    return getCell(row, col).value;
+  }
+
+  updateCellValue(int col, int row, String value) {
+    _cells[row][col].value = value;
+    notifyListeners();
+  }
+
+  bool get isGameRunning => _gameIsRunning;
   void updateGameIsRunning(bool gameIsRunning) {
     _gameIsRunning = gameIsRunning;
     notifyListeners();
   }
 
-  bool gameWon() {
-    return isGameFinished;
+  bool get isGameFinished => _gameIsFinished;
+  void updateGameIsFinished(bool gameIsFinished) {
+    _gameIsFinished = gameIsFinished;
+    notifyListeners();
+  }
+
+  int get availableBlocksCount => _availableBlocksCount;
+  void updateAvailableBlocksCount(int availableBlocksCount) {
+    _availableBlocksCount = availableBlocksCount;
+    notifyListeners();
+  }
+
+  int get score => _score;
+  void increaseScore(int increment) {
+    _score += increment;
+    notifyListeners();
+  }
+
+  int get movesCount => _movesCount;
+  void increaseMovesCount() {
+    _movesCount++;
+    notifyListeners();
   }
 
   void resetGame() {
     _gameIsRunning = false;
+    _gameIsFinished = false;
+    _availableBlocksCount = 0;
+    _score = 0;
+    _movesCount = 0;
     notifyListeners();
   }
 }
diff --git a/lib/screens/home.dart b/lib/screens/home.dart
index 0ea0de4..ca3fb6d 100644
--- a/lib/screens/home.dart
+++ b/lib/screens/home.dart
@@ -42,7 +42,15 @@ class _HomeState extends State<Home> {
     gameImages.forEach((image) => assets.add('assets/icons/' + image + '.png'));
 
     List skinImages = [
-      'empty',
+      '0',
+      '1',
+      '2',
+      '3',
+      '4',
+      '5',
+      '6',
+      '7',
+      '8',
     ];
 
     myProvider.availableSkinValues.forEach((skin) => skinImages
@@ -63,7 +71,7 @@ class _HomeState extends State<Home> {
 
     List<Widget> menuActions = [];
 
-    if (myProvider.gameIsRunning) {
+    if (myProvider.isGameRunning) {
       menuActions = [
         TextButton(
           child: Container(
@@ -91,7 +99,7 @@ class _HomeState extends State<Home> {
       ),
       body: SafeArea(
         child: Center(
-          child: myProvider.gameIsRunning
+          child: myProvider.isGameRunning
               ? Game.buildGameWidget(myProvider)
               : Parameters.buildParametersSelector(myProvider),
         ),
diff --git a/lib/utils/board_utils.dart b/lib/utils/board_utils.dart
new file mode 100644
index 0000000..f270797
--- /dev/null
+++ b/lib/utils/board_utils.dart
@@ -0,0 +1,217 @@
+import 'dart:math';
+
+import 'package:jeweled_game/entities/cell.dart';
+import 'package:jeweled_game/provider/data.dart';
+
+class BoardUtils {
+  static printGrid(List cells) {
+    print('');
+    print('-------');
+    for (var rowIndex = 0; rowIndex < cells.length; rowIndex++) {
+      String row = '';
+      for (var colIndex = 0; colIndex < cells[rowIndex].length; colIndex++) {
+        row += cells[rowIndex][colIndex].value;
+      }
+      print(row);
+    }
+    print('-------');
+    print('');
+  }
+
+  static createNewBoard(Data myProvider) {
+    int boardSizeHorizontal = myProvider.sizeHorizontal;
+    int boardSizeVertical = myProvider.sizeVertical;
+    int maxValue = myProvider.colorsCount;
+
+    var rand = new Random();
+
+    List<List<Cell>> grid = [];
+    for (var rowIndex = 0; rowIndex < boardSizeVertical; rowIndex++) {
+      List<Cell> row = [];
+      for (var colIndex = 0; colIndex < boardSizeHorizontal; colIndex++) {
+        int value = 1 + rand.nextInt(maxValue);
+        row.add(Cell(value.toString()));
+      }
+      grid.add(row);
+    }
+    printGrid(grid);
+
+    myProvider.resetGame();
+    myProvider.updateCells(grid);
+    myProvider.updateAvailableBlocksCount(getAvailableBlocks(myProvider).length);
+  }
+
+  // static List createBoardFromSavedState(Data myProvider, String savedBoard) {
+  //   List<List<Cell?>> board = [];
+  //   int boardSize = pow((savedBoard.length / 6), 1 / 2).round();
+  //   String boardSizeAsString = boardSize.toString() + 'x' + boardSize.toString();
+  //   myProvider.updateParameterSize(boardSizeAsString);
+
+  //   int index = 0;
+  //   for (var rowIndex = 0; rowIndex < boardSize; rowIndex++) {
+  //     List<Cell?> row = [];
+  //     for (var colIndex = 0; colIndex < boardSize; colIndex++) {
+  //       String value = savedBoard[index++];
+
+  //       Cell cell = Cell(value);
+
+  //       row.add(cell);
+  //     }
+  //     board.add(row);
+  //   }
+
+  //   printGrid(board);
+
+  //   return board;
+  // }
+
+  static List<List<int>> getSiblingCells(
+      Data myProvider, row, col, List<List<int>> siblingCells) {
+    int boardSizeHorizontal = myProvider.sizeHorizontal;
+    int boardSizeVertical = myProvider.sizeVertical;
+
+    String referenceValue = myProvider.getCellValue(row, col);
+
+    for (var deltaRow = -1; deltaRow <= 1; deltaRow++) {
+      for (var deltaCol = -1; deltaCol <= 1; deltaCol++) {
+        if (deltaCol == 0 || deltaRow == 0) {
+          int candidateRow = row + deltaRow;
+          int candidateCol = col + deltaCol;
+
+          if ((candidateRow >= 0 && candidateRow < boardSizeVertical) &&
+              (candidateCol >= 0 && candidateCol < boardSizeHorizontal)) {
+            if (myProvider.getCellValue(candidateRow, candidateCol) == referenceValue) {
+              bool alreadyFound = false;
+              for (var index = 0; index < siblingCells.length; index++) {
+                if ((siblingCells[index][0] == candidateRow) &&
+                    (siblingCells[index][1] == candidateCol)) {
+                  alreadyFound = true;
+                }
+              }
+              if (!alreadyFound) {
+                siblingCells.add([candidateRow, candidateCol]);
+                siblingCells =
+                    getSiblingCells(myProvider, candidateRow, candidateCol, siblingCells);
+              }
+            }
+          }
+        }
+      }
+    }
+
+    return siblingCells;
+  }
+
+  static List getAvailableBlocks(Data myProvider) {
+    int boardSizeHorizontal = myProvider.sizeHorizontal;
+    int boardSizeVertical = myProvider.sizeVertical;
+
+    List blocks = [];
+
+    for (var row = 0; row < boardSizeVertical; row++) {
+      for (var col = 0; col < boardSizeHorizontal; col++) {
+        if (myProvider.getCellValue(row, col) != '0') {
+          // if current cell not already in a found block
+          bool alreadyFound = false;
+          blocks.forEach((foundBlock) {
+            foundBlock.forEach((foundBlockCell) {
+              if ((foundBlockCell[0] == row) && (foundBlockCell[1] == col)) {
+                alreadyFound = true;
+              }
+            });
+          });
+          if (!alreadyFound) {
+            List<List<int>> block = getSiblingCells(myProvider, row, col, []);
+            if (block.length >= 3) {
+              blocks.add(block);
+            }
+          }
+        }
+      }
+    }
+
+    return blocks;
+  }
+
+  static bool checkBoardIsBlocked(Data myProvider) {
+    int boardSizeHorizontal = myProvider.sizeHorizontal;
+    int boardSizeVertical = myProvider.sizeVertical;
+
+    for (var row = 0; row < boardSizeVertical; row++) {
+      for (var col = 0; col < boardSizeHorizontal; col++) {
+        if (myProvider.getCellValue(row, col) != '0') {
+          List<List<int>> block = getSiblingCells(myProvider, row, col, []);
+          if (block.length >= 3) {
+            // found one block => ok, not locked
+            return false;
+          }
+        }
+      }
+    }
+
+    print('Board is locked');
+    return true;
+  }
+
+  static String getFillValue(Data myProvider, int row, int col) {
+    var rand = new Random();
+    int maxValue = myProvider.colorsCount;
+    int value = 1 + rand.nextInt(maxValue);
+
+    return value.toString();
+  }
+
+  static moveCellsDown(Data myProvider) {
+    int boardSizeHorizontal = myProvider.sizeHorizontal;
+    int boardSizeVertical = myProvider.sizeVertical;
+
+    for (int row = 0; row < boardSizeVertical; row++) {
+      for (int col = 0; col < boardSizeHorizontal; col++) {
+        if (myProvider.getCellValue(row, col) == '0') {
+          for (int r = row; r > 0; r--) {
+            myProvider.updateCellValue(col, r, myProvider.getCellValue(r - 1, col));
+          }
+          myProvider.updateCellValue(col, 0, getFillValue(myProvider, row, col));
+        }
+      }
+    }
+  }
+
+  static deleteCell(Data myProvider, int row, int col) {
+    myProvider.updateCellValue(col, row, '0');
+  }
+
+  static void deleteBlock(Data myProvider, List<List<int>> block) {
+    // Sort cells from top to bottom
+    block.sort((cell1, cell2) => cell1[0].compareTo(cell2[0]));
+    // Delete all cells
+    block.forEach((element) {
+      deleteCell(myProvider, element[0], element[1]);
+    });
+    // Gravity!
+    moveCellsDown(myProvider);
+  }
+
+  static int getScoreFromBlock(int blockSize) {
+    return 3 * (blockSize - 2);
+  }
+
+  static void tapOnCell(Data myProvider, int row, int col) {
+    String cellValue = myProvider.getCellValue(row, col);
+    print('Tap on cell[' + col.toString() + '][' + row.toString() + ']: ' + cellValue);
+
+    if (cellValue != '0') {
+      List<List<int>> block = getSiblingCells(myProvider, row, col, []);
+      if (block.length >= 3) {
+        deleteBlock(myProvider, block);
+        myProvider.increaseMovesCount();
+        myProvider.increaseScore(block.length);
+        myProvider.updateAvailableBlocksCount(getAvailableBlocks(myProvider).length);
+      }
+    }
+
+    if (checkBoardIsBlocked(myProvider)) {
+      myProvider.updateGameIsFinished(true);
+    }
+  }
+}
diff --git a/lib/utils/game_utils.dart b/lib/utils/game_utils.dart
index 9ece9ce..3515d2f 100644
--- a/lib/utils/game_utils.dart
+++ b/lib/utils/game_utils.dart
@@ -1,4 +1,6 @@
 import 'package:jeweled_game/provider/data.dart';
+import 'package:jeweled_game/utils/board_utils.dart';
+// import 'package:jeweled_game/utils/board_utils.dart';
 
 class GameUtils {
   static Future<void> quitGame(Data myProvider) async {
@@ -11,6 +13,7 @@ class GameUtils {
     print('- size: ' + myProvider.parameterSize);
 
     myProvider.resetGame();
+    BoardUtils.createNewBoard(myProvider);
 
     myProvider.updateGameIsRunning(true);
   }
@@ -27,6 +30,8 @@ class GameUtils {
         myProvider.setParameterValue('size', savedState['size']);
         myProvider.setParameterValue('skin', savedState['skin']);
 
+        // myProvider.updateCells(
+        //     BoardUtils.createBoardFromSavedState(myProvider, savedState['board']));
         myProvider.updateGameIsRunning(true);
       } catch (e) {
         print('Failed to resume game. Will start new one instead.');
diff --git a/pubspec.lock b/pubspec.lock
index c6a8d1d..522d85c 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -134,7 +134,7 @@ packages:
       name: path_provider_platform_interface
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.4"
+    version: "2.0.5"
   path_provider_windows:
     dependency: transitive
     description:
-- 
GitLab