/* Auteur: Nicolas JANEY          */
/* nicolas.janey@univ-fcomte.fr   */
/* Fevrier 2005                   */

public class BatailleNavaleTexteEnConsole {

  public static boolean dansTableau(boolean [][] t,int xi,int yi) {
    if ( xi < 0 )
      return(false);
    if ( yi < 0 )
      return(false);
    if ( xi >= t.length )
      return(false);
    if ( yi >= t.length )
      return(false);
    return(true);
  }

  public static boolean placementPossible(boolean [][] t,int xi,int yi,int xf,int yf,int sens) {
    if ( !dansTableau(t,xi,yi) )
      return(false);
    if ( !dansTableau(t,xf,yf) )
      return(false);
    if ( sens == 0 ) {
      for ( int x = xi-1 ; x <= xf+1 ; x++ )
        for ( int y = yi-1 ; y <= yi+1 ; y++ )
          if ( dansTableau(t,x,y) )
            if ( t[y][x] )
              return(false); }
      else {
      for ( int x = xi-1 ; x <= xi+1 ; x++ )
        for ( int y = yi-1 ; y <= yf+1 ; y++ )
          if ( dansTableau(t,x,y) )
            if ( t[y][x] )
              return(false); }
    return(true);
  }

  public static void place(boolean [][] t,int xi,int yi,int xf,int yf,int sens) {
    if ( sens == 0 ) {
      for ( int x = xi ; x <= xf ; x++ )
        t[yi][x] = true; }
      else {
      for ( int y = yi ; y <= yf ; y++ )
        t[y][xi] = true; }
  }

  public static void placeBateau(int taille,boolean [][] t) {
    int xi,yi,xf = 0,yf = 0;
    int sens;
    do {
      xi =(int) (Math.random() * t.length);
      yi =(int) (Math.random() * t.length);
      sens =(int) (Math.random() * 4);
      switch (sens) {
        case 2 : xf = xi;
                 yf = yi+taille-1;
                 break;
        case 3 : xf = xi;
                 yf = yi;
                 yi = yf-taille+1;
                 break;
        case 0 : yf = yi;
                 xf = xi+taille-1;
                 break;
        case 1 : yf = yi;
                 xf = xi;
                 xi = xf-taille+1;
                 break; } }
    while ( !placementPossible(t,xi,yi,xf,yf,sens/2) );
    place(t,xi,yi,xf,yf,sens/2);
  }

  public static boolean [][] genereFlote(int n,int n1,int n2,int n3,int n4, int n5) {
    boolean [][] t = new boolean[n][n];
    for ( int i = 0 ; i < n ; i++ )
      for ( int j = 0 ; j < n ; j++ )
        t[i][j] = false;
    for ( int i = 0 ; i < n5 ; i++ )
      placeBateau(5,t);
    for ( int i = 0 ; i < n4 ; i++ )
      placeBateau(4,t);
    for ( int i = 0 ; i < n3 ; i++ )
      placeBateau(3,t);
    for ( int i = 0 ; i < n2 ; i++ )
      placeBateau(2,t);
    for ( int i = 0 ; i < n1 ; i++ )
      placeBateau(1,t);
    return(t);
  }

  public static boolean bateauPresent(int x,int y,boolean [][] fl) {
    if ( !dansTableau(fl,x,y) )
      return(false);
    return(fl[y][x]);
  }

  public static boolean bateauCoule(int x,int y,boolean [][] fl,int [][] tst) {
    boolean sens = true;
    int xi = x;
    int yi = y;
    while ( ( yi >= 0 ) && ( bateauPresent(xi,yi-1,fl) ) ) {
      yi--;
      sens = true; }
    while ( ( xi >= 0 ) && ( bateauPresent(xi-1,yi,fl) ) ) {
      xi--;
      sens = false; }
    int xf = xi;
    int yf = yi;
    while ( ( yf < fl.length ) && ( bateauPresent(xf,yf+1,fl) ) ) {
      yf++;
      sens = true; }
    while ( ( xf < fl.length ) && ( bateauPresent(xf+1,yf,fl) ) ) {
      xf++;
      sens = false; }
    Console.out.println(xi+" "+yi+" "+xf+" "+yf+" "+sens);
    if ( sens ) {
      for ( y = yi ; y <= yf ; y++ )
        if ( tst[y][xi] != 1 )
          return(false); }
      else {
      for ( x = xi ; x <= xf ; x++ ) {
        Console.out.println(x+" "+yi+" "+tst[yi][x]);
        if ( tst[yi][x] != 1 )
          return(false); } }
    return(true);
  }

  public static void affichage(int [][] tst) {
    for ( int y = 0 ; y < tst.length ; y++ ) {
      for ( int x = 0 ; x < tst.length ; x++ )
        switch ( tst[y][x] ) {
          case -1 : Console.out.print(" .");
                    break;
          case 0  : Console.out.print(" 0");
                    break;
          case 1  : Console.out.print(" X");
                    break; }
      Console.out.println(); }
  }

  public static void affichage(boolean [][] flt) {
    for ( int y = 0 ; y < flt.length ; y++ ) {
      for ( int x = 0 ; x < flt.length ; x++ )
        if ( flt[y][x] )
          Console.out.print(" x");
          else
          Console.out.print(" o");
      Console.out.println(); }
  }

  public static boolean testJeuFiniBatailleNavale(boolean [][] fl,int [][] tst) {
    for ( int y = 0 ; y < fl.length ; y++ )
      for ( int x = 0 ; x < fl.length ; x++ )
        if ( ( fl[y][x] ) && ( tst[y][x] != 1 ) )
          return(false);
    return(true);
  }

  public static void batailleNavale(boolean [][] fl,int [][] tst) {
    int nbt = 0;
    while ( !testJeuFiniBatailleNavale(fl,tst) ) {
      nbt++;
      Console.out.println("Tour numero "+nbt);
      affichage(fl);
      affichage(tst);
      Console.out.print("Abscice testee  : ");
      int x = Integer.valueOf(Console.in.readLine()).intValue();
      Console.out.print("Ordonnee testee : ");
      int y = Integer.valueOf(Console.in.readLine()).intValue();
      if ( fl[y][x] ) {
        tst[y][x] = 1;
        if ( bateauCoule(x,y,fl,tst) )
          Console.out.println("Bateau coule!"); }
        else {
        tst[y][x] = 0;
        Console.out.println("Pas de bateau"); } }
    Console.out.println("Toute la flote est coulee en "+nbt+" tours");
    affichage(tst);
  }

  /* Fonction principale                                  */

  public static void main(String [] args) {
    Console.setTitle("BatailleNavaleTexte");
  /* Lecture au clavier de la taille du damier            */
    Console.out.print("Taille du damier   : ");
    int n = Integer.valueOf(Console.in.readLine()).intValue();
  /* Lecture au clavier des nombres de bateaux            */
  /* de taille 1, 2, 3, 4 et 5                            */
    Console.out.println("Nombres de bateaux : ");
    Console.out.print("Taille 1 : ");
    int n1 = Integer.valueOf(Console.in.readLine()).intValue();
    Console.out.print("Taille 2 : ");
    int n2 = Integer.valueOf(Console.in.readLine()).intValue();
    Console.out.print("Taille 3 : ");
    int n3 = Integer.valueOf(Console.in.readLine()).intValue();
    Console.out.print("Taille 4 : ");
    int n4 = Integer.valueOf(Console.in.readLine()).intValue();
    Console.out.print("Taille 5 : ");
    int n5 = Integer.valueOf(Console.in.readLine()).intValue();
  /* Generation de la flote sur le damier                 */
    boolean [][] fl = genereFlote(n,n1,n2,n3,n4,n5);
  /* Generation et initialisation du tableau              */
  /* des cases testees                                    */
    int [][] tst = new int[n][n];
    for ( int i = 0 ; i < n ; i++ )
      for ( int j = 0 ; j < n ; j++ )
        tst[i][j] = -1;
  /* Lancement du jeu                                     */
    batailleNavale(fl,tst);
  }
}