public class ErdosTableaux {

    final static double XMIN = -1.2;
    final static double XMAX = +1.2;
    final static double YMIN = -1.2;
    final static double YMAX = +1.2;

    public static void main(String[] args) {
        StdDraw.enableDoubleBuffering();
        // pour centrer la fenêtre en (0,0)

        StdDraw.setXscale(XMIN, XMAX);
        StdDraw.setYscale(YMIN, YMAX);

        final double penR = 0.02;
        int nbPoints = Integer.parseInt(args[0]);
        double proba = Double.parseDouble(args[1]);

        double[] tPointsX = new double[nbPoints];
        double[] tPointsY = new double[nbPoints];;

        // des gros points noirs
        StdDraw.setPenRadius(penR);
        setPoints(tPointsX, tPointsY);
        tracePoints(tPointsX, tPointsY);

        // des segments fins en gris
        StdDraw.setPenRadius();
        StdDraw.setPenColor(StdDraw.GRAY);
        traceSegments(tPointsX, tPointsY, proba);


        StdDraw.show();
    }


    /**
     * Calcule les coordonnées de points répartis sur le cercle trigo
     * et les range dans 2 tableaux 1D
     * @param tX tableau des abscisses
     * @param tY tableau des ordonnées
     */
    public static void setPoints(double[] tX, double[] tY) {
        int n = tX.length;
        final double ANGLE_STEP = 2 * Math.PI / n;
        for (int i = 0; i < n; i++) {
            tX[i] = Math.cos(i * ANGLE_STEP);
            tY[i] = Math.sin(i * ANGLE_STEP);
        }
    }

    /**
     * Trace les points dont les coordonnées cartésiennes sont passées en paramètre
     * @param tX tableau des abscisses
     * @param tY tableau des ordonnées
     */
    public static void tracePoints(double[] tX, double[] tY) {
        for (int i=0; i< tX.length ; i++) {
            StdDraw.point(tX[i], tY[i]);
        }
    }

    /**
     * Effectue un tirage vrai/faux avec la probabilité p de tirer vrai.
     *
     * @param p proba de tirer vrai
     * @return le résultat du tirage
     */
    public static boolean tireProba(double p) {
        return  (Math.random() < p) ;
    }


    /**
     * Effectue le tracé des segments.
     *      Tous les segments sont évalués, mais un tirage est fait avant le tracé.
     *      Le segment n'est effectivement tracé que si le tirage donne 'vrai'
     *      Le ratio effectif de tracé est affiché au bas de la fenêtre graphique.
     * @param tX tableau des abcisses
     * @param tY tableau des ordonnées
     * @param p  proba de tracer un segment
     * @return   le ratio réel (nb de segments tracés / nb de segments traçables)
     */
    public static void traceSegments(double[] tX, double[] tY, double p) {
        int n = tX.length;
        int cptTotal = 0;
        int cptTrace = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                cptTotal++;
                if (tireProba(p)){
                    StdDraw.line(tX[i], tY[i], tX[j], tY[j]);
                    cptTrace++;
                }
            }
        }
        int ratio = (int)((double)cptTrace/cptTotal*100);
        String outString = "ratio : " + String.valueOf(ratio/100.0) ;
        StdDraw.text((XMIN+XMAX)/2, YMIN*0.9, outString);
    }

}
