diff --git a/README.md b/README.md
index beb77b5ec7bd0442aa93cfc9c09f13237b92bed2..40965a4056fa6b2357e023ddad1bf394ef9751cb 100644
--- a/README.md
+++ b/README.md
@@ -41,4 +41,4 @@ Ce dépôt Git a pour but de partager les différents ateliers pouvant être ré
 | [Back from GDCR avec Maxime, Séraphin, Anthony et Colin](https://www.youtube.com/watch?v=CHfUGdnSX6I)                 | Discussion  |            |
 | [Factory patterns](/factory-patterns)                                                                                 | Code&coffee | Facile     |
 | [Exceptions](/exceptions)                                                                                             | Code&coffee | Facile     |
-| [Puissance 4](/puissance-4)                                                                                           | Kata        | ?          |
+| [Puissance 4](/puissance-4)                                                                                           | Kata        | Moyenne    |
diff --git a/gilded-rose/src/main/java/com/gildedrose/GildedRose.java b/gilded-rose/src/main/java/com/gildedrose/GildedRose.java
index 895525c33dd2031c247a356564501eb6a6b62770..76feabff2b8aacc482678166f7fc35566f21dffe 100644
--- a/gilded-rose/src/main/java/com/gildedrose/GildedRose.java
+++ b/gilded-rose/src/main/java/com/gildedrose/GildedRose.java
@@ -4,14 +4,14 @@ class GildedRose {
   private static final String SULFURAS_NAME = "Sulfuras, Hand of Ragnaros";
   private static final String BACKSTAGE_PASSES_NAME = "Backstage passes to a TAFKAL80ETC concert";
   private static final String AGED_BRIE_NAME = "Aged Brie";
-  Item[] items;
+  private Item[] items;
 
   public GildedRose(Item[] items) {
-    this.items = items;
+    this.setItems(items);
   }
 
   public void updateQuality() {
-    for (Item item : items) {
+    for (Item item : getItems()) {
       if (SULFURAS_NAME.equals(item.name)) {
         continue;
       }
@@ -71,4 +71,12 @@ class GildedRose {
       item.quality = item.quality - 1;
     }
   }
+
+  public Item[] getItems() {
+    return items;
+  }
+
+  public void setItems(Item[] items) {
+    this.items = items;
+  }
 }
diff --git a/gilded-rose/src/test/java/com/gildedrose/GildedRoseTest.java b/gilded-rose/src/test/java/com/gildedrose/GildedRoseTest.java
index 58dbc4418aed0536e27175f7060089b51e3505c4..d32eb48d3c3184efbaaa4e016ecf9a95ebf8dc6c 100644
--- a/gilded-rose/src/test/java/com/gildedrose/GildedRoseTest.java
+++ b/gilded-rose/src/test/java/com/gildedrose/GildedRoseTest.java
@@ -1,33 +1,12 @@
 package com.gildedrose;
 
-import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.*;
 
 import java.util.Arrays;
 import org.junit.jupiter.api.Test;
 
 class GildedRoseTest {
 
-  @Test
-  void shouldUpdateForOneDay() {
-    GildedRose rose = new GildedRose(ItemsProvider.get());
-
-    rose.updateQuality();
-
-    assertThat(rose.items).extracting(item -> item.sellIn).containsExactly(9, 1, 4, 0, -1, 14, 9, 4);
-    assertThat(rose.items).extracting(item -> item.quality).containsExactly(19, 1, 6, 80, 80, 21, 50, 50);
-  }
-
-  @Test
-  void shouldUpdateForTwoDays() {
-    GildedRose rose = new GildedRose(ItemsProvider.get());
-
-    rose.updateQuality();
-    rose.updateQuality();
-
-    assertThat(rose.items).extracting(item -> item.sellIn).containsExactly(8, 0, 3, 0, -1, 13, 8, 3);
-    assertThat(rose.items).extracting(item -> item.quality).containsExactly(18, 2, 5, 80, 80, 22, 50, 50);
-  }
-
   @Test
   void shouldBehaveLikeGoldenMaster() {
     GildedRose rose = new GildedRose(ItemsProvider.get());
@@ -37,10 +16,10 @@ class GildedRoseTest {
       rose.updateQuality();
       golden.updateQuality();
 
-      assertThat(rose.items)
+      assertThat(rose.getItems())
         .extracting(item -> item.sellIn)
         .containsExactly(Arrays.stream(golden.items).map(item -> item.sellIn).toArray(Integer[]::new));
-      assertThat(rose.items)
+      assertThat(rose.getItems())
         .extracting(item -> item.quality)
         .containsExactly(Arrays.stream(golden.items).map(item -> item.quality).toArray(Integer[]::new));
     }
diff --git a/puissance-4/README.md b/puissance-4/README.md
index 507aff8a3a7eae8e400e8b6d4457b6d3cfcd5616..2e9fac5315c6f0abee9766228d2a947cec2750b4 100644
--- a/puissance-4/README.md
+++ b/puissance-4/README.md
@@ -1,9 +1,9 @@
 # Puissance IV
 
-Résolution, en live, de [Puissance 4](/puissance-4).
+Refactoring, en live, d'un code de puissance 4 fait en première année d'études
 
 -   **Auteurs** : Colin DAMON & Cyril DUPONT
 -   **Date** : 22/12/2020
 -   **Langage** : Java
--   **Niveau** : ?
--   **Replay** : [Puissance 4 - Cyril & Colin](?)
+-   **Niveau** : Moyen
+-   **Replay** : TODO
diff --git a/puissance-4/pom.xml b/puissance-4/pom.xml
index a53e07693296b5b704a322bf84620745e7669fc3..e12d6ecf29bd69c76ea0e1010f9c6944ee4de466 100644
--- a/puissance-4/pom.xml
+++ b/puissance-4/pom.xml
@@ -1,29 +1,38 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
 
-    <parent>
-        <version>1.0.0</version>
-        <groupId>fr.ippon.kata</groupId>
-        <artifactId>java-parent</artifactId>
-        <relativePath>../java-parent</relativePath>
-    </parent>
+  <parent>
+    <version>1.0.0</version>
+    <groupId>fr.ippon.kata</groupId>
+    <artifactId>java-parent</artifactId>
+    <relativePath>../java-parent</relativePath>
+  </parent>
 
-    <version>1.0.0-SNAPSHOT</version>
-    <artifactId>puissance-4</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+  <artifactId>puissance-4</artifactId>
 
-    <name>Puissance4</name>
+  <name>Puissance4</name>
 
-    <developers>
-        <developer>
-            <email>cdamon@ippon.fr</email>
-            <name>Colin DAMON</name>
-        </developer>
-        <developer>
-            <email>cdupont@ippon.fr</email>
-            <name>Cyril DUPONT</name>
-        </developer>
-    </developers>
+  <developers>
+    <developer>
+      <email>cdamon@ippon.fr</email>
+      <name>Colin DAMON</name>
+    </developer>
+    <developer>
+      <email>cdupont@ippon.fr</email>
+      <name>Cyril DUPONT</name>
+    </developer>
+  </developers>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.awaitility</groupId>
+      <artifactId>awaitility</artifactId>
+      <version>3.0.0</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
 </project>
diff --git a/puissance-4/src/main/java/fr/ippon/kata/puissance4/Joueur.java b/puissance-4/src/main/java/fr/ippon/kata/puissance4/Joueur.java
new file mode 100644
index 0000000000000000000000000000000000000000..06c72a3cb6608c7ae2fefff2ffa1654257ed1c8d
--- /dev/null
+++ b/puissance-4/src/main/java/fr/ippon/kata/puissance4/Joueur.java
@@ -0,0 +1,15 @@
+package fr.ippon.kata.puissance4;
+
+public enum Joueur {
+  JOUEUR_1('X'),
+  JOUEUR_2('O');
+  private final char pion;
+
+  private Joueur(char pion) {
+    this.pion = pion;
+  }
+
+  public char getPion() {
+    return pion;
+  }
+}
diff --git a/puissance-4/src/main/java/fr/ippon/kata/puissance4/Puissance4.java b/puissance-4/src/main/java/fr/ippon/kata/puissance4/Puissance4.java
index 36a6c90c9300af58170ba6168cb4e6d2e1c5fe60..130f84f92dc05b24f5bd32731849c5cc52fa6605 100644
--- a/puissance-4/src/main/java/fr/ippon/kata/puissance4/Puissance4.java
+++ b/puissance-4/src/main/java/fr/ippon/kata/puissance4/Puissance4.java
@@ -1,340 +1,402 @@
 package fr.ippon.kata.puissance4;
 
+import static fr.ippon.kata.puissance4.Joueur.*;
+
 import java.util.Scanner;
 
 public class Puissance4 {
+  private static final Integer N = 20;
 
-    private static final Integer N = 20;
+  private Character grille[][];
 
-    public static int menu(){
-        int choix;
-        Scanner sc = new Scanner(System.in);
-        System.out.println("\n\t\t\t***************************\n\t\t\t***\tPuissance 4\t***\n\t\t\t***************************");
-        System.out.println("\n\n[1] Un joueur\n");
-        System.out.println("[2] Deux joueurs\n");
-        System.out.println("[3] Regle du jeu");
+  private Puissance4() {
+    grille = new Character[N][N];
 
-        do{
-            choix = sc.nextInt();
-        }while(choix<1 ||choix>3);
-        return choix;
+    for (int i = 0; i <= 12; i++) {
+      for (int j = 0; j <= 13; j++) {
+        grille[i][j] = '$';
+      }
     }
 
-    public static int afficherGrille(Character grille[][]){
-        int j,i,k;
+    for (int i = 3; i <= 9; i++) {
+      for (int j = 3; j <= 10; j++) {
+        grille[i][j] = '*';
+      }
+    }
+  }
+
+  public static int menu() {
+    int choix;
+    Scanner sc = new Scanner(System.in);
+    System.out.println("\n\t\t\t***************************\n\t\t\t***\tPuissance 4\t***\n\t\t\t***************************");
+    System.out.println("\n\n[1] Un joueur\n");
+    System.out.println("[2] Deux joueurs\n");
+    System.out.println("[3] Regle du jeu");
+
+    do {
+      choix = sc.nextInt();
+    } while (choix < 1 || choix > 3);
+    return choix;
+  }
+
+  public void afficherGrille() {
+    afficherEntete();
+
+    for (int ligne = 3; ligne <= 9; ligne++) {
+      for (int colonne = 3; colonne <= 10; colonne++) {
+        System.out.print("| ");
+        System.out.print(grille[ligne][colonne]);
+      }
+
+      System.out.println("|");
+    }
 
-        System.out.println("\n ");
-        for(k=1;k<=8;k++){
-            System.out.print("["+k+"]");
+    System.out.println(" ------------------------");
+  }
 
-        }
-        System.out.println("\n");
+  private void afficherEntete() {
+    System.out.println("\n ");
 
-        for(i=3;i<=9;i++){/*9*/
-            for(j=3;j<=10;j++){/*10*/
-                System.out.print("| ");
-                System.out.print(grille[i][j]);
-            }
-            System.out.println("|");
-        }
-        System.out.println(" ------------------------");
-        return 0;
+    for (int k = 1; k <= 8; k++) {
+      System.out.print("[" + k + "]");
     }
 
-    public static int jouerJ1(Character grille[][]){
-        int choix,res,j,i=9;
-        Scanner sc = new Scanner(System.in);
-        do{
-            choix = sc.nextInt();
-            if(choix>8 || choix<1){
-                System.out.println("Choix incorecte, entrez un nombre entre 1 et8");
-            }
-        }while(choix>8 || choix<1);
-        j=choix+2;
+    System.out.println("\n");
+  }
 
-        while(grille[i][j]=='O' || grille[i][j]=='X'){
-            i=i-1;
-        }
-        grille[i][j]='X';
+  public boolean jouer(Joueur joueur) {
+    int colonne = colonneJouee();
+    int ligne = getLigne(colonne);
 
-        afficherGrille(grille);
-        res=estgagne(i,(j),grille);
-        return res;
-    }
+    grille[ligne][colonne] = joueur.getPion();
+    afficherGrille();
 
+    return estGagne(ligne, colonne);
+  }
 
-    public static int jouerJ2(Character grille[][]){
-        int choix,res,j,i=9;
-        Scanner sc = new Scanner(System.in);
-        do{
-            choix = sc.nextInt();
-            if(choix>8 || choix<1){
-                System.out.println("Choix incorecte, entrez un nombre entre 1 et 7.");
-            }
-        }while(choix>8 || choix<1);
-        j=choix+2;
+  private static int colonneJouee() {
+    int choix;
+    Scanner sc = new Scanner(System.in);
+    do {
+      choix = sc.nextInt();
+      if (choix > 8 || choix < 1) {
+        System.out.println("Choix incorrect, entrez un nombre entre 1 et 8");
+      }
+    } while (choix > 8 || choix < 1);
 
-        while(grille[i][j]=='O' || grille[i][j]=='X'){
-            i=i-1;
-        }
-        grille[i][j]='O';
+    return choix + 2;
+  }
 
+  private int getLigne(int colonne) {
+    int ligne = 9;
 
-        afficherGrille(grille);
-        res=estgagne(i,(choix+2),grille);
-        return res;
+    while (ligneJouee(colonne, ligne)) {
+      ligne = ligne - 1;
     }
 
-
-    public static int jouerIA(Character grille[][]){
-        int res,i=0,j=0,x=0,y=0,choix=0;
-
-
-        if(choix==0){
-            for(i=3;i<=9;i++){
-                for(j=3;j<=10;j++){
-                    if(choix==0){
-                        if(grille[i][j]=='*' && (grille[i+1][j]=='X' || grille[i+1][j]=='O' || grille[i+1][j]=='$')){
-                            if((grille[i+1][j]=='O' && grille[i+1][j]==grille[i+2][j] && grille[i+2][j]==grille[i+3][j])
-                                    || (grille[i+1][j-1]=='O' && grille[i+1][j-1]==grille[i+2][j-2] && grille[i+2][j-2]==grille[i+3][j-3])
-                                    || (grille[i][j-1]=='O' && grille[i][j-1]==grille[i][j-2] && grille[i][j-2]==grille[i][j-3])
-                                    || (grille[i-1][j-1]=='O' && grille[i-1][j-1]==grille[i-2][j-2] && grille[i-2][j-2]==grille[i-3][j-3])
-                                    || (grille[i-1][j+1]=='O'&& grille[i-1][j+1]==grille[i-2][j+2] && grille[i-2][j+2]==grille[i-3][j+3])
-                                    || (grille[i][j+1]=='O' && grille[i][j+1]==grille[i][j+2] && grille[i][j+2]==grille[i][j+3])
-                                    || (grille[i+1][j+1]=='O' && grille[i+1][j+1]==grille[i+2][j+2] && grille[i+2][j+2]==grille[i+3][j+3])
-                                    /*new*/
-                                    || (grille[i+1][j+1]=='O' && grille[i-1][j-1]==grille[i+1][j+1] && grille[i-1][j-1]==grille[i-2][j-2])
-                                    ||(grille[i-1][j-1]=='O' && grille[i+1][j+1]==grille[i-1][j-1] && grille[i+1][j+1]==grille[i+2][j+2])
-                                    ||(grille[i-1][j-1]=='O' && grille[i+1][j+1]==grille[i-1][j-1] && grille[i+1][j+1]==grille[i+2][j+2])
-                                    || (grille[i-1][j+1]=='O' && grille[i-1][j-1]==grille[i-1][j+1] && grille[i-1][j-1]==grille[i-2][j-2])
-                                    ||(grille[i][j-1]=='O' && grille[i][j+1]==grille[i][j-1] && grille[i][j]==grille[i][j+2])
-                                    ||(grille[i][j+1]=='O' && grille[i][j-1]==grille[i][j+1] && grille[i][j-1]==grille[i][j-2])
-                            ){
-                                grille[i][j]='O';
-                                choix=1;
-                                x=i;
-                                y=j;
-                            }
-                        }
-                    }
-                }
+    return ligne;
+  }
+
+  private boolean ligneJouee(int colonne, int ligne) {
+    return grille[ligne][colonne] == JOUEUR_1.getPion() || grille[ligne][colonne] == JOUEUR_2.getPion();
+  }
+
+  public boolean jouerIA() {
+    int i = 0, j = 0, x = 0, y = 0, choix = 0;
+
+    if (choix == 0) {
+      for (i = 3; i <= 9; i++) {
+        for (j = 3; j <= 10; j++) {
+          if (choix == 0) {
+            if (grille[i][j] == '*' && (grille[i + 1][j] == 'X' || grille[i + 1][j] == 'O' || grille[i + 1][j] == '$')) {
+              if (
+                (grille[i + 1][j] == 'O' && grille[i + 1][j] == grille[i + 2][j] && grille[i + 2][j] == grille[i + 3][j]) ||
+                (
+                  grille[i + 1][j - 1] == 'O' &&
+                  grille[i + 1][j - 1] == grille[i + 2][j - 2] &&
+                  grille[i + 2][j - 2] == grille[i + 3][j - 3]
+                ) ||
+                (grille[i][j - 1] == 'O' && grille[i][j - 1] == grille[i][j - 2] && grille[i][j - 2] == grille[i][j - 3]) ||
+                (
+                  grille[i - 1][j - 1] == 'O' &&
+                  grille[i - 1][j - 1] == grille[i - 2][j - 2] &&
+                  grille[i - 2][j - 2] == grille[i - 3][j - 3]
+                ) ||
+                (
+                  grille[i - 1][j + 1] == 'O' &&
+                  grille[i - 1][j + 1] == grille[i - 2][j + 2] &&
+                  grille[i - 2][j + 2] == grille[i - 3][j + 3]
+                ) ||
+                (grille[i][j + 1] == 'O' && grille[i][j + 1] == grille[i][j + 2] && grille[i][j + 2] == grille[i][j + 3]) ||
+                (
+                  grille[i + 1][j + 1] == 'O' &&
+                  grille[i + 1][j + 1] == grille[i + 2][j + 2] &&
+                  grille[i + 2][j + 2] == grille[i + 3][j + 3]
+                ) /* new */
+                ||
+                (
+                  grille[i + 1][j + 1] == 'O' &&
+                  grille[i - 1][j - 1] == grille[i + 1][j + 1] &&
+                  grille[i - 1][j - 1] == grille[i - 2][j - 2]
+                ) ||
+                (
+                  grille[i - 1][j - 1] == 'O' &&
+                  grille[i + 1][j + 1] == grille[i - 1][j - 1] &&
+                  grille[i + 1][j + 1] == grille[i + 2][j + 2]
+                ) ||
+                (
+                  grille[i - 1][j - 1] == 'O' &&
+                  grille[i + 1][j + 1] == grille[i - 1][j - 1] &&
+                  grille[i + 1][j + 1] == grille[i + 2][j + 2]
+                ) ||
+                (
+                  grille[i - 1][j + 1] == 'O' &&
+                  grille[i - 1][j - 1] == grille[i - 1][j + 1] &&
+                  grille[i - 1][j - 1] == grille[i - 2][j - 2]
+                ) ||
+                (grille[i][j - 1] == 'O' && grille[i][j + 1] == grille[i][j - 1] && grille[i][j] == grille[i][j + 2]) ||
+                (grille[i][j + 1] == 'O' && grille[i][j - 1] == grille[i][j + 1] && grille[i][j - 1] == grille[i][j - 2])
+              ) {
+                grille[i][j] = 'O';
+                choix = 1;
+                x = i;
+                y = j;
+              }
             }
+          }
         }
+      }
+    }
 
-        if(choix==0){
-            for(i=3;i<=9;i++){
-                for(j=3;j<=10;j++){
-                    if(choix==0){
-                        if(grille[i][j]=='*' && (grille[i+1][j]=='X' || grille[i+1][j]=='O' || grille[i+1][j]=='$')){
-                            if((grille[i+1][j]=='X' && grille[i+1][j]==grille[i+2][j] && grille[i+2][j]==grille[i+3][j])
-                                    || (grille[i+1][j-1]=='X' && grille[i+1][j-1]==grille[i+2][j-2] && grille[i+2][j-2]==grille[i+3][j-3])
-                                    || (grille[i][j-1]=='X' && grille[i][j-1]==grille[i][j-2] && grille[i][j-2]==grille[i][j-3])
-                                    || (grille[i-1][j-1]=='X' && grille[i-1][j-1]==grille[i-2][j-2] && grille[i-2][j-2]==grille[i-3][j-3])
-                                    || (grille[i-1][j+1]=='X'&& grille[i-1][j+1]==grille[i-2][j+2] && grille[i-2][j+2]==grille[i-3][j+3])
-                                    || (grille[i][j+1]=='X' && grille[i][j+1]==grille[i][j+2] && grille[i][j+2]==grille[i][j+3])
-                                    || (grille[i+1][j+1]=='X' && grille[i+1][j+1]==grille[i+2][j+2] && grille[i+2][j+2]==grille[i+3][j+3])
-                                    || (grille[i+1][j+1]=='X' && grille[i-1][j-1]==grille[i+1][j+1] && grille[i-1][j-1]==grille[i-2][j-2])
-                                    ||(grille[i-1][j-1]=='X' && grille[i+1][j+1]==grille[i-1][j-1] && grille[i+1][j+1]==grille[i+2][j+2])
-                                    ||(grille[i-1][j-1]=='X' && grille[i+1][j+1]==grille[i-1][j-1] && grille[i+1][j+1]==grille[i+2][j+2])
-                                    || (grille[i-1][j+1]=='X' && grille[i-1][j-1]==grille[i-1][j+1] && grille[i-1][j-1]==grille[i-2][j-2])
-                                    ||(grille[i][j-1]=='X' && grille[i][j+1]==grille[i][j-1] && grille[i][j]==grille[i][j+2])
-                                    ||(grille[i][j+1]=='X' && grille[i][j-1]==grille[i][j+1] && grille[i][j-1]==grille[i][j-2])
-                            ){
-                                grille[i][j]='O';
-                                choix=1;
-                                x=i;
-                                y=j;
-                            }
-                        }
-                    }
-                }
+    if (choix == 0) {
+      for (i = 3; i <= 9; i++) {
+        for (j = 3; j <= 10; j++) {
+          if (choix == 0) {
+            if (grille[i][j] == '*' && (grille[i + 1][j] == 'X' || grille[i + 1][j] == 'O' || grille[i + 1][j] == '$')) {
+              if (
+                (grille[i + 1][j] == 'X' && grille[i + 1][j] == grille[i + 2][j] && grille[i + 2][j] == grille[i + 3][j]) ||
+                (
+                  grille[i + 1][j - 1] == 'X' &&
+                  grille[i + 1][j - 1] == grille[i + 2][j - 2] &&
+                  grille[i + 2][j - 2] == grille[i + 3][j - 3]
+                ) ||
+                (grille[i][j - 1] == 'X' && grille[i][j - 1] == grille[i][j - 2] && grille[i][j - 2] == grille[i][j - 3]) ||
+                (
+                  grille[i - 1][j - 1] == 'X' &&
+                  grille[i - 1][j - 1] == grille[i - 2][j - 2] &&
+                  grille[i - 2][j - 2] == grille[i - 3][j - 3]
+                ) ||
+                (
+                  grille[i - 1][j + 1] == 'X' &&
+                  grille[i - 1][j + 1] == grille[i - 2][j + 2] &&
+                  grille[i - 2][j + 2] == grille[i - 3][j + 3]
+                ) ||
+                (grille[i][j + 1] == 'X' && grille[i][j + 1] == grille[i][j + 2] && grille[i][j + 2] == grille[i][j + 3]) ||
+                (
+                  grille[i + 1][j + 1] == 'X' &&
+                  grille[i + 1][j + 1] == grille[i + 2][j + 2] &&
+                  grille[i + 2][j + 2] == grille[i + 3][j + 3]
+                ) ||
+                (
+                  grille[i + 1][j + 1] == 'X' &&
+                  grille[i - 1][j - 1] == grille[i + 1][j + 1] &&
+                  grille[i - 1][j - 1] == grille[i - 2][j - 2]
+                ) ||
+                (
+                  grille[i - 1][j - 1] == 'X' &&
+                  grille[i + 1][j + 1] == grille[i - 1][j - 1] &&
+                  grille[i + 1][j + 1] == grille[i + 2][j + 2]
+                ) ||
+                (
+                  grille[i - 1][j - 1] == 'X' &&
+                  grille[i + 1][j + 1] == grille[i - 1][j - 1] &&
+                  grille[i + 1][j + 1] == grille[i + 2][j + 2]
+                ) ||
+                (
+                  grille[i - 1][j + 1] == 'X' &&
+                  grille[i - 1][j - 1] == grille[i - 1][j + 1] &&
+                  grille[i - 1][j - 1] == grille[i - 2][j - 2]
+                ) ||
+                (grille[i][j - 1] == 'X' && grille[i][j + 1] == grille[i][j - 1] && grille[i][j] == grille[i][j + 2]) ||
+                (grille[i][j + 1] == 'X' && grille[i][j - 1] == grille[i][j + 1] && grille[i][j - 1] == grille[i][j - 2])
+              ) {
+                grille[i][j] = 'O';
+                choix = 1;
+                x = i;
+                y = j;
+              }
             }
+          }
         }
+      }
+    }
 
-        if(choix==0){
-            for(i=3;i<=9;i++){
-                for(j=3;j<=10;j++){
-                    if(choix==0){
-                        if(grille[i][j]=='*' && (grille[i+1][j]=='X' || grille[i+1][j]=='O' || grille[i+1][j]=='$')){
-                            if((grille[i+1][j]=='O' && grille[i+1][j]==grille[i+2][j])
-                                    || (grille[i+1][j-1]=='O' && grille[i+1][j-1]==grille[i+2][j-2])
-                                    || (grille[i][j-1]=='O' && grille[i][j-1]==grille[i][j-2])
-                                    || (grille[i-1][j-1]=='O' && grille[i-1][j-1]==grille[i-2][j-2])
-                                    || (grille[i-1][j+1]=='O'&& grille[i-1][j+1]==grille[i-2][j+2])
-                                    || (grille[i][j+1]=='O' && grille[i][j+1]==grille[i][j+2])
-                                    || (grille[i+1][j+1]=='O' && grille[i+1][j+1]==grille[i+2][j+2])
-                                    || (grille[i+1][j+1]=='O' && grille[i-1][j-1]==grille[i+1][j+1] )						 ||(grille[i-1][j-1]=='O' && grille[i+1][j+1]==grille[i-1][j-1])
-                                    ||(grille[i-1][j-1]=='O' && grille[i+1][j+1]==grille[i-1][j-1] )
-                                    || (grille[i-1][j+1]=='O' && grille[i-1][j-1]==grille[i-1][j+1] )
-                                    ||(grille[i][j-1]=='O' && grille[i][j+1]==grille[i][j-1])
-                                    ||(grille[i][j+1]=='O' && grille[i][j-1]==grille[i][j+1])
-                            ){
-                                grille[i][j]='O';
-                                choix=1;
-                                x=i;
-                                y=j;
-                            }
-                        }
-                    }
-                }
-            } }
-
-
-        if(choix==0){
-            for(i=3;i<=9;i++){
-                for(j=3;j<=10;j++){
-                    if(choix==0){
-                        if(grille[i][j]=='*' && (grille[i+1][j]=='X' || grille[i+1][j]=='O' || grille[i+1][j]=='$')){
-                            if(grille[i+1][j]=='O'
-                                    || grille[i+1][j-1]=='O'
-                                    || grille[i][j-1]=='O'
-                                    || grille[i-1][j-1]=='O'
-                                    || grille[i-1][j+1]=='O'
-                                    || grille[i][j+1]=='O'
-                                    || grille[i+1][j+1]=='O'){
-
-                                grille[i][j]='O';
-                                choix=1;
-                                x=i;
-                                y=j;
-                            }
-                        }
-                    }
-                }
+    if (choix == 0) {
+      for (i = 3; i <= 9; i++) {
+        for (j = 3; j <= 10; j++) {
+          if (choix == 0) {
+            if (grille[i][j] == '*' && (grille[i + 1][j] == 'X' || grille[i + 1][j] == 'O' || grille[i + 1][j] == '$')) {
+              if (
+                (grille[i + 1][j] == 'O' && grille[i + 1][j] == grille[i + 2][j]) ||
+                (grille[i + 1][j - 1] == 'O' && grille[i + 1][j - 1] == grille[i + 2][j - 2]) ||
+                (grille[i][j - 1] == 'O' && grille[i][j - 1] == grille[i][j - 2]) ||
+                (grille[i - 1][j - 1] == 'O' && grille[i - 1][j - 1] == grille[i - 2][j - 2]) ||
+                (grille[i - 1][j + 1] == 'O' && grille[i - 1][j + 1] == grille[i - 2][j + 2]) ||
+                (grille[i][j + 1] == 'O' && grille[i][j + 1] == grille[i][j + 2]) ||
+                (grille[i + 1][j + 1] == 'O' && grille[i + 1][j + 1] == grille[i + 2][j + 2]) ||
+                (grille[i + 1][j + 1] == 'O' && grille[i - 1][j - 1] == grille[i + 1][j + 1]) ||
+                (grille[i - 1][j - 1] == 'O' && grille[i + 1][j + 1] == grille[i - 1][j - 1]) ||
+                (grille[i - 1][j - 1] == 'O' && grille[i + 1][j + 1] == grille[i - 1][j - 1]) ||
+                (grille[i - 1][j + 1] == 'O' && grille[i - 1][j - 1] == grille[i - 1][j + 1]) ||
+                (grille[i][j - 1] == 'O' && grille[i][j + 1] == grille[i][j - 1]) ||
+                (grille[i][j + 1] == 'O' && grille[i][j - 1] == grille[i][j + 1])
+              ) {
+                grille[i][j] = 'O';
+                choix = 1;
+                x = i;
+                y = j;
+              }
             }
+          }
         }
+      }
+    }
 
-        if(choix==0){
-            x=9;
-            if(grille[x][7]=='X'){
-                y=8;
-                grille[x][y]='O';
-            }
-            else{
-                y=7;
-                grille[x][y]='O';
+    if (choix == 0) {
+      for (i = 3; i <= 9; i++) {
+        for (j = 3; j <= 10; j++) {
+          if (choix == 0) {
+            if (grille[i][j] == '*' && (grille[i + 1][j] == 'X' || grille[i + 1][j] == 'O' || grille[i + 1][j] == '$')) {
+              if (
+                grille[i + 1][j] == 'O' ||
+                grille[i + 1][j - 1] == 'O' ||
+                grille[i][j - 1] == 'O' ||
+                grille[i - 1][j - 1] == 'O' ||
+                grille[i - 1][j + 1] == 'O' ||
+                grille[i][j + 1] == 'O' ||
+                grille[i + 1][j + 1] == 'O'
+              ) {
+                grille[i][j] = 'O';
+                choix = 1;
+                x = i;
+                y = j;
+              }
             }
+          }
         }
-        res=estgagne(x,y,grille);
-        afficherGrille(grille);
-        return res;
+      }
     }
 
-    public static int estgagne(int i, int j ,Character grille[][]){
-        int res=0;
-        if( (grille[i][j]==grille[i+1][j] && grille[i+1][j]==grille[i+2][j] && grille[i+2][j]==grille[i+3][j])
-                || (grille[i][j]==grille[i+1][j-1] && grille[i+1][j-1]==grille[i+2][j-2] && grille[i+2][j-2]==grille[i+3][j-3])
-                || (grille[i][j]==grille[i][j-1] && grille[i][j-1]==grille[i][j-2] && grille[i][j-2]==grille[i][j-3])
-                ||(grille[i][j]==grille[i-1][j-1] && grille[i-1][j-1]==grille[i-2][j-2] && grille[i-2][j-2]==grille[i-3][j-3])
-                ||(grille[i][j]==grille[i-1][j+1] && grille[i-1][j+1]==grille[i-2][j+2] && grille[i-2][j+2]==grille[i-3][j+3])
-                ||(grille[i][j]==grille[i][j+1] && grille[i][j+1]==grille[i][j+2] && grille[i][j+2]==grille[i][j+3])
-                ||(grille[i][j]==grille[i+1][j+1] && grille[i+1][j+1]==grille[i+2][j+2] && grille[i+2][j+2]==grille[i+3][j+3])
-                || (grille[i][j]==grille[i+1][j+1] && grille[i][j]==grille[i-1][j-1] && grille[i-1][j-1]==grille[i-2][j-2])
-                ||(grille[i][j]==grille[i-1][j-1] && grille[i][j]==grille[i+1][j+1] && grille[i+1][j+1]==grille[i+2][j+2])
-                ||(grille[i][j]==grille[i-1][j-1] && grille[i][j]==grille[i+1][j+1] && grille[i+1][j+1]==grille[i+2][j+2])
-                || (grille[i][j]==grille[i-1][j+1] && grille[i][j]==grille[i-1][j-1] && grille[i-1][j-1]==grille[i-2][j-2])
-                ||(grille[i][j]==grille[i][j-1] && grille[i][j]==grille[i][j+1] && grille[i][j]==grille[i][j+2])
-                ||(grille[i][j]==grille[i][j+1] && grille[i][j]==grille[i][j-1] && grille[i][j-1]==grille[i][j-2])
-        )
-            res=1;
-
-        if(res==1)
-            return res;
-        return 0;
+    if (choix == 0) {
+      x = 9;
+      if (grille[x][7] == 'X') {
+        y = 8;
+        grille[x][y] = 'O';
+      } else {
+        y = 7;
+        grille[x][y] = 'O';
+      }
     }
-
-    public static Integer afficherRegle(){
-        int retour;
-        Scanner sc = new Scanner(System.in);
-        System.out.println("\tLe but du jeu est d'aligner 4 pions sur une grille comptant 7 rangées et 8 colonnes. Chaque joueur dispose de 28 pions d'une certain forme (par convention X ou O). Tour à tour les deux joueurs placent un pion dans la colonne de leur choix. Le vainqueur est le joueur qui réalise le premier un alignement (horizontal, vertical ou diagonal) d'au moins quatre pions de sa meme forme. Si alors que toutes les cases de la grille de jeu sont remplies aucun des deux joueurs n'a réalisé un tel alignement, la partie est déclarée nulle.\n");
-        do{
-            System.out.println("[1] Retour");
-            retour = sc.nextInt();
-        }while(retour>1 || retour<1);
-        return retour;
+    boolean gagne = estGagne(x, y);
+    afficherGrille();
+    return gagne;
+  }
+
+  public boolean estGagne(int i, int j) {
+    if (
+      (grille[i][j] == grille[i + 1][j] && grille[i + 1][j] == grille[i + 2][j] && grille[i + 2][j] == grille[i + 3][j]) ||
+      (
+        grille[i][j] == grille[i + 1][j - 1] && grille[i + 1][j - 1] == grille[i + 2][j - 2] && grille[i + 2][j - 2] == grille[i + 3][j - 3]
+      ) ||
+      (grille[i][j] == grille[i][j - 1] && grille[i][j - 1] == grille[i][j - 2] && grille[i][j - 2] == grille[i][j - 3]) ||
+      (
+        grille[i][j] == grille[i - 1][j - 1] && grille[i - 1][j - 1] == grille[i - 2][j - 2] && grille[i - 2][j - 2] == grille[i - 3][j - 3]
+      ) ||
+      (
+        grille[i][j] == grille[i - 1][j + 1] && grille[i - 1][j + 1] == grille[i - 2][j + 2] && grille[i - 2][j + 2] == grille[i - 3][j + 3]
+      ) ||
+      (grille[i][j] == grille[i][j + 1] && grille[i][j + 1] == grille[i][j + 2] && grille[i][j + 2] == grille[i][j + 3]) ||
+      (
+        grille[i][j] == grille[i + 1][j + 1] && grille[i + 1][j + 1] == grille[i + 2][j + 2] && grille[i + 2][j + 2] == grille[i + 3][j + 3]
+      ) ||
+      (grille[i][j] == grille[i + 1][j + 1] && grille[i][j] == grille[i - 1][j - 1] && grille[i - 1][j - 1] == grille[i - 2][j - 2]) ||
+      (grille[i][j] == grille[i - 1][j - 1] && grille[i][j] == grille[i + 1][j + 1] && grille[i + 1][j + 1] == grille[i + 2][j + 2]) ||
+      (grille[i][j] == grille[i - 1][j - 1] && grille[i][j] == grille[i + 1][j + 1] && grille[i + 1][j + 1] == grille[i + 2][j + 2]) ||
+      (grille[i][j] == grille[i - 1][j + 1] && grille[i][j] == grille[i - 1][j - 1] && grille[i - 1][j - 1] == grille[i - 2][j - 2]) ||
+      (grille[i][j] == grille[i][j - 1] && grille[i][j] == grille[i][j + 1] && grille[i][j] == grille[i][j + 2]) ||
+      (grille[i][j] == grille[i][j + 1] && grille[i][j] == grille[i][j - 1] && grille[i][j - 1] == grille[i][j - 2])
+    ) return true;
+
+    return false;
+  }
+
+  public static Integer afficherRegle() {
+    int retour;
+    Scanner sc = new Scanner(System.in);
+    System.out.println(
+      "\tLe but du jeu est d'aligner 4 pions sur une grille comptant 7 rangées et 8 colonnes. Chaque joueur dispose de 28 pions d'une certain forme (par convention X ou O). Tour à tour les deux joueurs placent un pion dans la colonne de leur choix. Le vainqueur est le joueur qui réalise le premier un alignement (horizontal, vertical ou diagonal) d'au moins quatre pions de sa meme forme. Si alors que toutes les cases de la grille de jeu sont remplies aucun des deux joueurs n'a réalisé un tel alignement, la partie est déclarée nulle.\n"
+    );
+    do {
+      System.out.println("[1] Retour");
+      retour = sc.nextInt();
+    } while (retour > 1 || retour < 1);
+    return retour;
+  }
+
+  public static void main(String[] args) {
+    int choixMenu, exit;
+    String prenom1;
+    String prenom2;
+
+    Scanner sc = new Scanner(System.in);
+
+    choixMenu = menu();
+    if (choixMenu == 3) {
+      exit = afficherRegle();
+      if (exit == 1) choixMenu = menu();
     }
 
-    public static void main(String[] args) {
-
-       int j, res, i, choixMenu, exit;
-       String prenom1;
-       String prenom2;
-       Character[][] grille = new Character[N][N];
-        Scanner sc = new Scanner(System.in);
-
-        choixMenu = menu();
-        if (choixMenu == 3) {
-            exit = afficherRegle();
-            if (exit == 1)
-                choixMenu = menu();
-        }
-
-        if (choixMenu == 2) {
-            for (i = 0; i <= 12; i++) {
-                for (j = 0; j <= 13; j++) {
-                    grille[i][j] = '$';
-                }
-            }
-            for (i = 3; i <= 9; i++) {
-                for (j = 3; j <= 10; j++) {
-                    grille[i][j] = '*';
-                }
-            }
-
-            System.out.println("\tEntrez le prenom d'un des deux joueurs\n");
-            prenom1 = sc.nextLine();
-            System.out.println("\tEntrez le prenom d'un des deux joueurs\n");
-            prenom2 = sc.nextLine();
-            System.out.println("\t " + prenom1 + " vs  " + prenom2 + "\n");
+    boolean gagner;
+    if (choixMenu == 2) {
+      Puissance4 game = new Puissance4();
 
-                  do {
-                      afficherGrille(grille);
-                     res = jouerJ1(grille);
+      System.out.println("\tEntrez le prenom d'un des deux joueurs\n");
+      prenom1 = sc.nextLine();
+      System.out.println("\tEntrez le prenom d'un des deux joueurs\n");
+      prenom2 = sc.nextLine();
+      System.out.println("\t " + prenom1 + " vs  " + prenom2 + "\n");
 
-                     if (res == 1)
-                         System.out.println(prenom1 + " a gagnee !");
+      do {
+        game.afficherGrille();
+        gagner = game.jouer(JOUEUR_1);
 
-                     if (res != 1) {
-                         res = jouerJ2(grille);
-                         if (res == 1)
-                             System.out.println(prenom2 +" a gagnee !");
-                     }
-
-                  } while (res != 1);
+        if (gagner) System.out.println(prenom1 + " a gagné !");
 
+        if (!gagner) {
+          gagner = game.jouer(JOUEUR_2);
+          if (gagner) System.out.println(prenom2 + " a gagné !");
         }
+      } while (!gagner);
+    }
 
-        if (choixMenu == 1) {
-            for (i = 0; i <= 12; i++) {
-                for (j = 0; j <= 13; j++) {
-                    grille[i][j] = '$';
-                }
-            }
-            for (i = 3; i <= 9; i++) {
-                for (j = 3; j <= 10; j++) {
-                    grille[i][j] = '*';
-                }
-            }
-
-            System.out.println("\tEntrez le prenom d'un des deux joueurs\n");
-            prenom1 = sc.nextLine();
-            System.out.println("\t "+prenom1+" vs ordinateur");
-
+    if (choixMenu == 1) {
+      Puissance4 game = new Puissance4();
 
-           do {
-               afficherGrille(grille);
-               res = jouerJ1(grille);
+      System.out.println("\tEntrez le prenom d'un des deux joueurs\n");
+      prenom1 = sc.nextLine();
+      System.out.println("\t " + prenom1 + " vs ordinateur");
 
-               if (res == 1)
-                   System.out.println(prenom1 +" a gagnee !");
+      do {
+        game.afficherGrille();
+        gagner = game.jouer(JOUEUR_1);
 
-               if (res != 1) {
-                   res = jouerIA(grille);
-                   if (res == 1)
-                       System.out.println(" L'ordinareur a gagnee !");
-               }
+        if (gagner) System.out.println(prenom1 + " a gagné !");
 
-           } while (res != 1);
-       }
+        if (!gagner) {
+          gagner = game.jouerIA();
+          if (gagner) System.out.println(" L'ordinateur a gagné !");
+        }
+      } while (!gagner);
     }
+  }
 }
diff --git a/puissance-4/src/test/java/fr/ippon/kata/puissance4/Puissance4Test.java b/puissance-4/src/test/java/fr/ippon/kata/puissance4/Puissance4Test.java
index e329791e7df2522f43e5a40fbb196244b31b3028..ac3739fa306f434d7db628588c70113391375c03 100644
--- a/puissance-4/src/test/java/fr/ippon/kata/puissance4/Puissance4Test.java
+++ b/puissance-4/src/test/java/fr/ippon/kata/puissance4/Puissance4Test.java
@@ -1,7 +1,206 @@
 package fr.ippon.kata.puissance4;
 
-import static org.junit.jupiter.api.Assertions.*;
+import static org.assertj.core.api.Assertions.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.NoSuchElementException;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 class Puissance4Test {
-    // todo writing tests
+  private PrintStream systemOut;
+  private InputStream systemIn;
+
+  private ByteArrayOutputStream out;
+  private SystemInMock in = new SystemInMock();
+  private Thread runner;
+
+  @BeforeEach
+  void changeOutput() {
+    systemOut = System.out;
+    systemIn = System.in;
+
+    out = new ByteArrayOutputStream();
+    System.setOut(new PrintStream(out));
+    System.setIn(in);
+  }
+
+  @AfterEach
+  void resetOutput() {
+    System.setOut(systemOut);
+    System.setIn(systemIn);
+  }
+
+  @AfterEach
+  void stopGame() {
+    runner.interrupt();
+  }
+
+  @Test
+  void shouldDisplayMenu() {
+    play();
+
+    assertGameOrder("Puissance 4", "[3] Regle du jeu");
+  }
+
+  @Test
+  void shouldDisplayRules() throws InterruptedException {
+    play("3", "1");
+
+    assertGameOrder("[3] Regle du jeu", "Le but du jeu", "la partie est déclarée nulle", "[3] Regle du jeu");
+  }
+
+  @Test
+  void shouldPlayTwoPlayerGame() {
+    play("2", "Colin", "Cyril", "1", "2", "1", "2", "1", "2", "1");
+
+    assertGameOrder("Colin a gagné !");
+  }
+
+  @Test
+  void shouldAskMenuAgainForOutOfBoundOption() {
+    play("5", "0", "3");
+
+    assertGameOrder("[3] Regle du jeu");
+  }
+
+  @Test
+  void shouldAskColumnAgainForBadPlayerOneInput() {
+    play("2", "Colin", "Cyril", "0", "9", "1");
+
+    assertGameOrder(
+      "Choix incorrect, entrez un nombre entre 1 et 8",
+      "Choix incorrect, entrez un nombre entre 1 et 8",
+      "| X| *| *| *| *| *| *| *|"
+    );
+  }
+
+  @Test
+  void shouldAskColumnAgainForBadPlayerTwoInput() {
+    play("2", "Colin", "Cyril", "1", "9", "0", "2");
+
+    assertGameOrder(
+      "Choix incorrect, entrez un nombre entre 1 et 8",
+      "Choix incorrect, entrez un nombre entre 1 et 8",
+      "| X| O| *| *| *| *| *| *|"
+    );
+  }
+
+  @Test
+  void shouldPlayAgainsIA() {
+    play("1", "Colin", "4", "5", "6", "7", "8");
+
+    assertGameOrder(
+      "| *| *| *| X| *| *| *| *|",
+      "| *| *| *| X| O| *| *| *|",
+      "| *| *| *| *| X| *| *| *|",
+      "| *| *| *| O| X| *| *| *|",
+      "| *| *| *| X| O| X| *| *|",
+      "| *| *| *| O| *| *| *| *|",
+      "L'ordinateur a gagné !"
+    );
+  }
+
+  private void play(String... inputs) {
+    in.provideText(Arrays.stream(inputs).collect(Collectors.joining("\n")));
+
+    runner = startGame();
+  }
+
+  private Thread startGame() {
+    Thread runner = new Thread(
+      () -> {
+        try {
+          Puissance4.main(null);
+        } catch (NoSuchElementException e) {
+          // Nothing to do
+        }
+      }
+    );
+    runner.start();
+
+    return runner;
+  }
+
+  private void assertGameOrder(String... elements) {
+    Awaitility
+      .await()
+      .pollDelay(5, TimeUnit.MILLISECONDS)
+      .atMost(1000, TimeUnit.MILLISECONDS)
+      .untilAsserted(
+        () -> {
+          String message = new String(out.toByteArray()).intern();
+
+          for (String element : elements) {
+            assertThat(message).contains(element);
+            message = message.substring(message.indexOf(element) + element.length());
+          }
+        }
+      );
+  }
+
+  private static class SystemInMock extends InputStream {
+    private StringReader currentReader;
+    private IOException ioException;
+    private RuntimeException runtimeException;
+
+    void provideText(String text) {
+      currentReader = new StringReader(text);
+    }
+
+    @Override
+    public int read() throws IOException {
+      if (currentReader == null) {
+        return 0;
+      }
+
+      int character = currentReader.read();
+      if (character == -1) handleEmptyReader();
+      return character;
+    }
+
+    private void handleEmptyReader() throws IOException {
+      if (ioException != null) throw ioException; else if (runtimeException != null) throw runtimeException;
+    }
+
+    @Override
+    public int read(byte[] buffer, int offset, int len) throws IOException {
+      if (buffer == null) throw new NullPointerException(); else if (
+        offset < 0 || len < 0 || len > buffer.length - offset
+      ) throw new IndexOutOfBoundsException(); else if (len == 0) return 0; else return readNextLine(buffer, offset, len);
+    }
+
+    private int readNextLine(byte[] buffer, int offset, int len) throws IOException {
+      int c = read();
+      if (c == -1) return -1;
+      buffer[offset] = (byte) c;
+
+      int i = 1;
+      for (; (i < len) && !isCompleteLineWritten(buffer, i - 1); ++i) {
+        byte read = (byte) read();
+        if (read == -1) break; else buffer[offset + i] = read;
+      }
+      return i;
+    }
+
+    private boolean isCompleteLineWritten(byte[] buffer, int indexLastByteWritten) {
+      byte[] separator = System.lineSeparator().getBytes();
+      int indexFirstByteOfSeparator = indexLastByteWritten - separator.length + 1;
+      return indexFirstByteOfSeparator >= 0 && contains(buffer, separator, indexFirstByteOfSeparator);
+    }
+
+    private boolean contains(byte[] array, byte[] pattern, int indexStart) {
+      for (int i = 0; i < pattern.length; ++i) if (array[indexStart + i] != pattern[i]) return false;
+      return true;
+    }
+  }
 }