From a2cf6e42d59f03a089a8fba75eaf73b82f021f6d Mon Sep 17 00:00:00 2001 From: Colin DAMON <cdamon@ippon.fr> Date: Wed, 23 Dec 2020 20:17:04 +0100 Subject: [PATCH] First session --- README.md | 2 +- .../main/java/com/gildedrose/GildedRose.java | 14 +- .../java/com/gildedrose/GildedRoseTest.java | 27 +- puissance-4/README.md | 6 +- puissance-4/pom.xml | 53 +- .../java/fr/ippon/kata/puissance4/Joueur.java | 15 + .../fr/ippon/kata/puissance4/Puissance4.java | 638 ++++++++++-------- .../ippon/kata/puissance4/Puissance4Test.java | 203 +++++- 8 files changed, 615 insertions(+), 343 deletions(-) create mode 100644 puissance-4/src/main/java/fr/ippon/kata/puissance4/Joueur.java diff --git a/README.md b/README.md index beb77b5e..40965a40 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 895525c3..76feabff 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 58dbc441..d32eb48d 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 507aff8a..2e9fac53 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 a53e0769..e12d6ecf 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 00000000..06c72a3c --- /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 36a6c90c..130f84f9 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 e329791e..ac3739fa 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; + } + } } -- GitLab