diff --git a/android/gradle.properties b/android/gradle.properties
index 7e6b4cd36d9877b2acd1b762e65740d34ebaa0ce..d6af5de7dd3b01541eb540fa8dfd4d0caed97461 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.44
-app.versionCode=44
+app.versionName=0.0.45
+app.versionCode=45
diff --git a/fastlane/metadata/android/en-US/changelogs/45.txt b/fastlane/metadata/android/en-US/changelogs/45.txt
new file mode 100644
index 0000000000000000000000000000000000000000..dbd9e101e0263dac8194c1c3307b53debdf0f9b7
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/45.txt
@@ -0,0 +1 @@
+Add board animations (start game and win)
diff --git a/fastlane/metadata/android/fr-FR/changelogs/45.txt b/fastlane/metadata/android/fr-FR/changelogs/45.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f29cf0765196d0808c13b083861bffd388c4f0f9
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/45.txt
@@ -0,0 +1 @@
+Ajout d'animations sur le plateau (début de partie et victoire)
diff --git a/lib/entities/cell.dart b/lib/entities/cell.dart
index 080a53596b35da46b632bb424419b4e71e0d263d..78b448f9054635e116c5a9bf3b9bebe01df3bb11 100644
--- a/lib/entities/cell.dart
+++ b/lib/entities/cell.dart
@@ -7,6 +7,7 @@ class Cell {
   int value;
   bool isFixed;
   int conflictsCount = 0;
+  bool isAnimated = false;
 
   Cell(
     @required this.value,
@@ -84,6 +85,14 @@ class Cell {
       }
     }
 
+    if (this.isAnimated) {
+      if (this.isFixed) {
+        backgroundColor = Colors.green[300];
+      } else {
+        backgroundColor = Colors.green[200];
+      }
+    }
+
     return backgroundColor;
   }
 
diff --git a/lib/layout/game.dart b/lib/layout/game.dart
index dc593976ea90f2cdb6ba9c92cf1cd9b90e6656b7..67c817727bc9333726a51a03220b88e99dab4a21 100644
--- a/lib/layout/game.dart
+++ b/lib/layout/game.dart
@@ -5,12 +5,18 @@ import 'package:flutter/material.dart';
 import '../entities/cell.dart';
 import '../layout/board.dart';
 import '../provider/data.dart';
+import '../utils/board_animate.dart';
 import '../utils/board_utils.dart';
 import '../utils/game_utils.dart';
 
 class Game {
 
   static Container buildGameWidget(Data myProvider) {
+    bool gameIsFinished = BoardUtils.checkBoardIsSolved(myProvider);
+    if (gameIsFinished) {
+      BoardAnimate.startAnimation(myProvider, 'win');
+    }
+
     return Container(
       child: Column(
         mainAxisAlignment: MainAxisAlignment.start,
@@ -18,7 +24,7 @@ class Game {
         children: [
           Board.buildGameBoard(myProvider),
           SizedBox(height: 2),
-          BoardUtils.checkBoardIsSolved(myProvider) ? Game.buildWinMessage(myProvider) : Game.buildSelectCellValueBar(myProvider),
+          gameIsFinished ? Game.buildWinMessage(myProvider) : Game.buildSelectCellValueBar(myProvider),
         ],
       ),
     );
diff --git a/lib/provider/data.dart b/lib/provider/data.dart
index 77e1bed1df38640c094364719d7af501910f3863..073682d4af00a95e09a19f0c28a1eea5d6a795ad 100644
--- a/lib/provider/data.dart
+++ b/lib/provider/data.dart
@@ -32,6 +32,7 @@ class Data extends ChangeNotifier {
   int _currentCellRow = null;
   int _currentCellValue = null;
   int _givenTipsCount = 0;
+  bool _animationInProgress = false;
   List _shuffledCellValues = [];
 
   String get level => _level;
@@ -182,4 +183,28 @@ class Data extends ChangeNotifier {
     _stateRunning = stateRunning;
     notifyListeners();
   }
+
+  bool get animationInProgress => _animationInProgress;
+  void updateAnimationInProgress(bool animationInProgress) {
+    _animationInProgress = animationInProgress;
+    notifyListeners();
+  }
+
+  void setAnimatedBackground(List animatedCellsPattern) {
+    int boardSideLength = _blockSizeHorizontal * _blockSizeVertical;
+    for (var row = 0; row < boardSideLength; row++) {
+      for (var col = 0; col < boardSideLength; col++) {
+        _cells[row][col].isAnimated = animatedCellsPattern[row][col];
+      }
+    }
+    notifyListeners();
+  }
+  void resetAnimatedBackground() {
+    int boardSideLength = _blockSizeHorizontal * _blockSizeVertical;
+    for (var row = 0; row < boardSideLength; row++) {
+      for (var col = 0; col < boardSideLength; col++) {
+        _cells[row][col].isAnimated = false;
+      }
+    }
+  }
 }
diff --git a/lib/utils/board_animate.dart b/lib/utils/board_animate.dart
new file mode 100644
index 0000000000000000000000000000000000000000..e328a0e72f855814dc843f7fb084cb92b8799cee
--- /dev/null
+++ b/lib/utils/board_animate.dart
@@ -0,0 +1,85 @@
+import 'dart:async';
+import 'dart:math';
+
+import '../entities/cell.dart';
+import '../provider/data.dart';
+
+class BoardAnimate {
+
+  // Start game animation: blinking tiles
+  static List createStartGameAnimationPatterns(Data myProvider) {
+    List<List> patterns = [];
+
+    int patternsCount = 3;
+    int boardSideLength = myProvider.blockSizeHorizontal * myProvider.blockSizeVertical;
+
+    for (var patternIndex = 0; patternIndex < patternsCount; patternIndex++) {
+      List<List> pattern = [];
+      for (var row = 0; row < boardSideLength; row++) {
+        List<bool> patternRow = [];
+        for (var col = 0; col < boardSideLength; col++) {
+          patternRow.add(((patternIndex + row + col) % 2 == 0));
+        }
+        pattern.add(patternRow);
+      }
+      patterns.add(pattern);
+    }
+
+    return patterns;
+  }
+
+  // Win game animation: fill board with colored rows, from bottom to top
+  static List createWinGameAnimationPatterns(Data myProvider) {
+    List<List> patterns = [];
+
+    int boardSideLength = myProvider.blockSizeHorizontal * myProvider.blockSizeVertical;
+    int patternsCount = boardSideLength + 6;
+
+    for (var patternIndex = 0; patternIndex < patternsCount; patternIndex++) {
+      List<List> pattern = [];
+      for (var row = 0; row < boardSideLength; row++) {
+        List<bool> patternRow = [];
+        for (var col = 0; col < boardSideLength; col++) {
+          patternRow.add(row > (patternIndex - 3));
+        }
+        pattern.add(patternRow);
+      }
+      patterns.add(pattern);
+    }
+
+    return patterns;
+  }
+
+  static void startAnimation(Data myProvider, String animationType) {
+    List patterns = [];
+
+    switch(animationType) {
+      case 'start':
+        patterns = createStartGameAnimationPatterns(myProvider);
+        break;
+      case 'win':
+        patterns = createWinGameAnimationPatterns(myProvider);
+        break;
+    }
+
+    int _patternIndex = patterns.length;
+
+    myProvider.updateAnimationInProgress(true);
+
+    Timer _timerAnimateBoard;
+    const interval = const Duration(milliseconds: 200);
+    _timerAnimateBoard = new Timer.periodic(
+      interval,
+      (Timer timer) {
+        if (_patternIndex == 0) {
+          timer.cancel();
+          myProvider.resetAnimatedBackground();
+          myProvider.updateAnimationInProgress(false);
+        } else {
+          _patternIndex--;
+          myProvider.setAnimatedBackground(patterns[_patternIndex]);
+        }
+      },
+    );
+  }
+}
diff --git a/lib/utils/game_utils.dart b/lib/utils/game_utils.dart
index 508c3d621d5aca7d9990efe8448aa046d9b2424e..51758ba590946cc723330e4b777cd5259eccbdc0 100644
--- a/lib/utils/game_utils.dart
+++ b/lib/utils/game_utils.dart
@@ -1,4 +1,5 @@
 import '../provider/data.dart';
+import '../utils/board_animate.dart';
 import '../utils/board_utils.dart';
 import '../utils/game_utils.dart';
 
@@ -15,6 +16,7 @@ class GameUtils {
     myProvider.shuffleCellValues();
     myProvider.updateCells = BoardUtils.createEmptyBoard(myProvider.blockSizeHorizontal * myProvider.blockSizeVertical);
     BoardUtils.pickGrid(myProvider);
+    BoardAnimate.startAnimation(myProvider, 'start');
   }
 
   static void showTip(Data myProvider) {