CHAPTER 26

COLLECTION OF PROGRAMS

In this chapter, we will see both applications and applets. We will try to cover problems from different walks of life.

26.1 Projectile

When we see a fielder standing on boundary line, throwing the ball straight into the gloves of the wicket keeper, we think that he is a genius. Well, he may or may not be, but one thing is sure. He has done his college physics seriously. A projectile starting at an angle of 45 degrees travels farthest, before hitting the ground.

Let us develop an applet to show the trajectory of a projectile.

Problem: Write an applet to show the trajectory of a projectile.

Solution: Let us assume the following:

When a projectile starts, it has velocities both in horizontal and vertical direction. Horizontal velocity remains constant with time, whereas the vertical velocity reduces because of gravity. After some time, it becomes negative and the projectile starts coming down. The vertical displacement becomes zero when the projectile touches the ground (see Program 26.1).

 

PROGRAM 26.1 Projectile

 //      proj2.java

 import java.applet.*;

 import java.awt.*;

 import java.lang.Math;

 public class proj2 extends Applet

 {   public void init ()

       { setBackground(Color.white);

         setForeground(Color.red);

       }

     public void paint(Graphics g)

       { char box[] = new char[100];

         int k;

         int X0=20, Y0=200;

         g.setColor(Color.red);

         String st1 = new String(“<-------    X axis    ------>”);

         Font f1 = new Font(“Arial” , Font.PLAIN , 16);

         g.setFont(f1);

         g.drawString(st1,X0+200,Y0+30 );

         g.drawLine(X0,Y0,X0,20); // Y-axis

         g.drawLine(X0,Y0,540-X0,Y0);//X-axis

         int x=20, y=300;

         int alpha = 45;

         double gravity=9.8,u=70.0;

         float valsin,valcos;

         double t ;

         int totaltime = 10;

         valsin=(float)Math.sin(2*3.14159*alpha/360);

         valcos=(float)Math.cos(2*3.14159*alpha/360);

         g.setColor(Color.blue);

         for(t=0; t<=totaltime; t= t + 0.1)

           { x=X0 + (int)(u * valcos * t );

             y=Y0 - (int)(u * valsin * t -0.5*gravity*t*t);

             g.drawLine(x,y,x,y);

             g.drawLine(x+1,y,x+1,y);

             g.drawLine(x,y+1,x,y+1);

             g.drawLine(x+1,y+1,x+1,y+1);

             delay();

           }

       }

     public static void delay()

       {     double a,b;

             long i,j=350000;

             for(i=0;i<4000000;i++)

                { j--;

                  a = 2.33 /3.11 ;

                }

       }

 }

To watch the projectile, we need a small HTML file as shown hereafter.

Proj2.html

<applet code = “proj2” width =600 height =400 >

</applet>

If you use the browser, you will see the projectile moving through the sky. We have taken the snapshot of the flight.

 

Output

Projectile

Confession: Though it is enjoyable to watch the applet, the code we have written is not quite ideal. You may show one or two additional projectiles starting at angles little different from the one shown. We have used trial and error method to decide when the projectile hits the ground. Use of for loop is a proof of that. You may try while loop with suitable condition so that you do not need any trials.

26.2 Wall Clock

All of us glance at the wall clock but we hardly bother to know how it works or what are its components. Let us try to develop an applet which displays a running wall clock.

Problem: Write an applet to display a running wall clock.

Solution: See Program 26.2.

 

PROGRAM 26.2 Wall Clock

 // clock2.java

 import java.util.*;

 import java.awt.*;

 import java.applet.*;

 import java.text.*;

 public class clock2 extends Applet implements Runnable

 {

     Thread clock;

     int xcenter=100,ycenter=70;

     int s,m,h;

     int xs,ys,xm,ym,xh,yh,lastxs,lastys,lastxm,lastym,

         lastxh,lastyh;

     Font myclock;

     int degree,i;

     int placex,placey;

     public void init()

     {

         resize(300,300);

         setForeground(Color.red);

         setBackground(Color.black);

         lastxs = lastys = lastxm = lastym

             = lastxh = lastyh = 0;

         myclock=new Font("Arial",Font.BOLD,14);

 }

 public void plotpoints(int x0, int y0, int x, int y,

                             Graphics g )

   {  g.fillRect(x0-x,y0-y,2,2);

   }

 public void circle(int x0, int y0, int r, Graphics g)

   {

      int x = x0 ;//+ xcenter;

      int y = y0 ;//- ycenter;

      g.drawOval(x-2,y-2,4,4);

   }

 public void paint(Graphics g)

   {

      SimpleDateFormat formatter;Date currdate;

      currdate=new Date();

      formatter=new

         SimpleDateFormat("HH:mm:ss",Locale.getDefault());

      formatter.applyPattern("ss");

      s=Integer.parseInt(formatter.format(currdate));

      formatter.applyPattern("mm");

      m=Integer.parseInt(formatter.format(currdate));

      formatter.applyPattern("HH");

      h=Integer.parseInt(formatter.format(currdate));

      g.drawRoundRect(40,10,125,115,10,10);

      g.setFont(myclock);

      i=1;

      for(degree=28;degree<=360;degree=degree+30)

      {

      placex=(int) (Math.cos(degree*3.14/180-3.14/2)

         * 45 + xcenter);

      placey=(int) (Math.sin(degree*3.14/180-3.14/2)

      * 45 + ycenter);

      g.drawString(Integer.toString(i),placex,placey);

      i++;

   }

   // following equations calculate the positions of

   // hands in clock.

   xs=(int) (Math.cos(s*3.14/30-3.14/2) *50 +xcenter);

   ys=(int) (Math.sin(s*3.14/30-3.14/2) *50 +ycenter);

   xm=(int) (Math.cos(m*3.14/30-3.14/2) *45 +xcenter);

   ym=(int) (Math.sin(m*3.14/30-3.14/2) *45 +ycenter);

   xh=(int) (Math.cos((h*30+m/2)*3.14/180-3.14/2)

                  *30 + xcenter);

   yh=(int) (Math.sin((h*30+m/2)*3.14/180-3.14/2)

                  *30 + ycenter);

   // these drawLine functions draw hands.

   g.setColor(getBackground());

   if (xs != lastxs || ys != lastys) {

       g.drawLine(xcenter, ycenter, lastxs, lastys);

       circle(lastxs,lastys,3,g);

   }

   if (xm != lastxm || ym != lastym)

      {  g.drawLine(xcenter, ycenter, lastxm, lastym);

      }

   if (xh != lastxh || yh != lastyh)

      {  g.drawLine(xcenter, ycenter, lastxh, lastyh);

      }

   g.setColor(Color.red);

   g.drawLine(xcenter,ycenter,xs,ys);

   circle(xs,ys,3,g); //circle on second hand

   g.setColor(Color.orange);

   g.drawLine(xcenter,ycenter,xm,ym);

   g.drawLine(xcenter,ycenter,xh,yh);

   lastxs=xs; lastys=ys;

   lastxm=xm; lastym=ym;

   lastxh=xh; lastyh=yh;

 }

 public void start()

 {   clock=new Thread(this);

     clock.start();

 }

 public void update(Graphics g)

 { paint(g);

 }

 public void run()

 {  Thread me=Thread.currentThread();

     while(clock==me)

     {  try {

             Thread.currentThread().sleep(100);

         } catch(InterruptedException e) {}

         repaint();

     }

   }

 }

To run the applet, we will write a small HTML file as shown.

clock1.html

<applet code = “clock2” width =200 height =150 align=middle vspace=80 hspace=175>

</applet>

If you load this HTML page in any browser of your choice, you will get a clock ticking. The following diagram shows a freeze shot of the display.

 

Output

Wall Clock

Please note that the clock shows the current time.

26.3 Drawing Ellipses

Problem: Write a program to draw multiple ellipses.

Solution: The method drawOval can draw the ellipse in a rectangle with either vertical or horizontal lines. Hence, this method is not suitable for drawing ellipses which are oriented in different directions (angles). Here, we first imagine a point on an ellipse which has zero inclination and then rotate it through desired angle (see Program 26.3).

 

PROGRAM 26.3 Ellipses

    //     ele1.java

   import java.awt.* ;

   import javax.swing.*;

   class VP extends JFrame

      { VP (int xdim, int ydim) //constructor

         { setSize(xdim,ydim);

           setBackground(Color.white);

           setVisible(true);

         }

       public void delay(long n)

         { long t1,t2;

           t1 = System.currentTimeMillis();

           t1 = t1 + n;

           t2= System.currentTimeMillis();

           while ( t2 < t1 ) t2= System.currentTimeMillis();

          }

     public void paint (Graphics g)

        {  int k ;

           int x0=200, y0=210, r1=100;

           int x1 , y1,x2,y2 ;

           double mult = 3.1416 /180.0 ;

           double abc =0.6 ,mag,ang;

           g.clearRect(0,0,400,400);

           g.setColor( Color.blue );

           for(double z =0;z<180;z=z+30)

           for(k=0; k< 360; k++)

             {  delay(1);

                x1 = (int) Math.ceil( r1* Math.cos(mult*k) ) ;

                y1 = (int) Math.floor( abc*r1* Math.sin(mult*k) ) ;

               mag = Math.hypot(y1,x1);

                ang = Math.atan2(y1,x1)+ Math.toRadians(z);

                x2 = (int) Math.ceil( x0+mag* Math.cos(ang) ) ;

                y2 = (int) Math.floor( y0+mag* Math.sin(ang) ) ;

                g.fillOval(x2,y2,2,2);

             }

         }

  }

 public class ele1

 { public static void main(String[] args)

        { VP vp1= new VP( 400,400);

            vp1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        };

 }

When you run this program, you will see the following output.

 

Output

Ellipses

26.4 Area of Circle by Monte Carlo Method

The estimation methods based on statistics are common. Here we will use a method known as Monte Carlo method for finding area of the circle.

Problem: Write a program to find the area of a circle with a unit diameter.

Solution: In this program, we will use Monte Carlo method. We will imagine a square with unit side. Its area will, therefore, be “one” (unit area). We will use random number technique to create a point lying in this area and check mathematically if the point lies in the circle inscribed in the square. In any statistical method, we have to keep the sample size very large. Hence, we will create many such points. The ratio of points lying in the circle to total points will describe/represent the area of circle with unit diameter. See Program 26.4.

 

PROGRAM 26.4 Area of Circle—Monte Carlo Method

 import java.awt.* ;

 import javax.swing.* ;

 import java.util.* ;

 class monte2 extends JFrame

 {

   monte2 (int xdim, int ydim) //constructor

        { setSize(xdim,ydim);

        { setTitle("Area of circle :Monte carlo Method");

    //      setBackground(Color.white);

        { setVisible(true);

        { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      }

 public static void main(String[] args)

       { monte2 thisprog = new monte2( 400,300);

         thisprog.setVisible(true);

       };

 public void delay(long n)

    { long t1,t2;

      t1 = System.currentTimeMillis();

      t1 = t1 + n;

      t2= System.currentTimeMillis();

      while ( t2 < t1 ) t2= System.currentTimeMillis();

    }

 int test(int x, int y, int z)

 { int ans = 0;

   Double R = z /2.0;

   Double x1 = x - z/2.0;

   Double y1 = y - z/2.0;

   if ( Math.sqrt( x1*x1 + y1*y1) <= R ) ans =1;

    return ans;

 };

 public void paint (Graphics g)

   {int x, y;

    Color drawcol;

    long i, count = 0;

    long simu_max =1200*8*2 ;

    float val_pi;

    final int max = 200 ;

    g.setColor(Color.white);

    g.fillRect(0,0,400,300);

    delay(500);

    Random rand = new Random();

    for (i=10;i<simu_max; i++)

     {   x=rand.nextInt(max);

         y=rand.nextInt(max);

         if (test(x, y, max) ==1)

                { drawcol = Color.red; //RED

                  count ++;

                }

            else drawcol = Color.yellow ; //YELLOW

          g.setColor( drawcol ) ;

          g.drawLine(x+50, y+50, x+50 ,y+50);

          if (i %10 == 0) delay(1);

      }

     g.drawString( Double.toString((double)count/simu_max), 50,270);

     }

 }

When you run this program, you will see the following output.

 

Output

Area of Circle—Monte Carlo Method

Please note that the value printed at the bottom is the area of circle with unit diameter.

26.5 Display of Binary Tree

Earlier we have worked with a dynamic data structure called binary tree. Teaching and learning such structures is fairly tough task. It will be a nice idea to see (graphically) how a binary tree grows. It will make teaching and learning of this topic somewhat simpler. Let us try this with the help of a program.

Problem: Write a program to display a binary tree on the screen.

Solution: In this program, we will develop a method show_me to do the complete task. It will create its own thread. In the run method of the thread, we will first build the tree and then visit all nodes. While visiting the nodes, we will plot the nodes on the screen.

Recursion comes very handy for visiting and displaying the nodes. The logic is unbelievably simple. We keep a track of left and right margins as well as the level of the node. The y position is proportional to level of the node. The x position is the centre of left and right margins (see Program 26.5).

 

PROGRAM 26.5 Display of Binary Tree

 //     tree3.java

 //   Binary Search Tree

 //   graphics version

 import javax.swing.*;

 import java.awt.Color;

 import java.awt.* ;

 class BPtimer

  { public static void delay(long n)

     { long t1,t2;

       t1 = System.currentTimeMillis();

       t1 = t1 + n;

       t2= System.currentTimeMillis();

       while ( t2 < t1 ) t2= System.currentTimeMillis();

     }

   }

 class Node

  { int key; // isbn number

    Node left, right;

    Node(int n) // constructor

     { key = n ;

       left = null ;

       right = null ;

     }

   };

 class VP extends JFrame

   { static Graphics g1;

     Node root ;

     Node temp ;

     int i;

     int A[] = { 12, 4, 6, 18, 10,56,1,45,99,88,5,17 } ;

     VP (int xdim, int ydim) //constructor

       { setSize(xdim,ydim);

         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

         setBackground(Color.white);

         setVisible(true);

         g1=getGraphics();

         g1.setColor(Color.blue);

       }

 class A extends Thread

   { public void run()

      { root = new Node(A[0]); // First nodeof the tree

        // building tree

        for( i=1;i<A.length;i++)

          { build(root,A[i]) ;

          }

        BPtimer.delay(250);

        // printing tree

         visitAllx(root,1,80,1,g1);

        }

       }

     public void show_me()

      {  A th1 = new A();

         th1.setPriority(Thread.NORM_PRIORITY);

         th1.start();

      }

   static void build( Node root, int num )

     {if(root == null) { System.out.println("error!");

                           System.exit(1);

                        }

         else

          if(root.key > num)

            {if ( root.left == null ) root.left = new Node(num);

                  else     build(root.left, num);

            }

           else {if(root.right == null) root.right = new Node(num);

                    else build(root.right,num);

     }

 }

 static void visitAllx( Node root, int lm, int rm,

               int h, Graphics g1)

     {int x ;

      if (root != null)

        { x=(lm+rm)/2;

          g1.drawString(String.valueOf(root.key),50+x*3,50+h*40);

          BPtimer.delay(500);

          visitAllx(root.left,lm,x,h+1,g1);

          visitAllx(root.right,x,rm,h+1,g1);

         }

      }

   }

  public class tree3

   { public static void main(String args[])

       { VP vp1= new VP( 500,400);

         vp1.setTitle("tree3");

         vp1.setVisible(true);

         vp1.show_me();

       }

 }

When you run this program, the tree is constructed node by node. At the end you will see the following output.

 

Output

Display of Binary Tree

26.6 Drawing with Data from a File

When we draw many diagrams, we have to repeat many patterns like rectangles. If we can create instructions from drawing and put them in a file, it will be very useful. Our program can read it and draw the diagram. If we have to modify something, we have to only make changes in the text file. Let us see this concept in action.

Problem: Write a program to draw rectangles as specified in a file

Solution: See Program 26.6.

 

PROGRAM 26.6 Drawing Diagrams

   //     draw2.java

 import java.awt.* ;

 import java.io.* ;

 import java.util.* ;

 import java.awt.event.* ;

 import javax.swing.*;

 class draw2 extends JFrame

 {  static Color faintBlue = new Color(200,200,255);

    static FileReader file1 ;

    static BufferedReader br ;

    static String[] buff;

    static int buffLength ; // note using buff.length!

 /*

    draw2(String str1)

    {super(str1);

    }

 */  public void paint(Graphics g)

    { int i;

      int[] cor = new int[4] ;

      int x0=30,y0=30;

      int width =25 ;

      int numline = 16 ; // also dist between lines 25

      g.clearRect(0,0,450,450);

      g.setColor(faintBlue);

      for(i=0;i<=numline;i++)

        { g.drawLine( x0,    y0+i*width,

                      x0+numline*width, y0+i*width); //hol line

          g.drawLine(x0+i*width, y0,

                     x0+i*width, y0+numline*width ); // ver line

         }

       g.setColor(Color.red);

 // executing code

       i=0;

       while (i<buffLength)

        {  getcor(cor,buff[i]);

           g.drawRect(cor[0],cor[1],cor[2],cor[3]);

           i++;

        }

   };

 public static void main(String[] args) throws IOException

   { String line;

     buff = new String[50] ;

     file1 = new FileReader("draw2.txt");

     br = new BufferedReader( file1);

     buffLength = 0;

     while ((line = br.readLine()) != null)

         { System.out.println("line read is: " + line);

           buff[buffLength++] = new String(line);

         };

 //   System.out.println(buffLength);

     draw2 f1= new draw2();

     f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

     f1.setTitle("Drawing from file");

     f1.setSize(450,450);

     f1.setBackground(Color.white);

     f1.setVisible(true);

   }

 public static void getcor(int[] a, String line)

   { String str1;

     try

     {

       StringTokenizer st = new StringTokenizer(line);

       int j=0;

       while (st.hasMoreTokens()&& j<4)

          {  str1 = st.nextToken() ;

             a[j] = Integer.parseInt(str1);

             j++;

          }

     } catch(Exception e) { System.out.println("Some Error") ;}

    };

 }

 /* file draw2.txt

    50 60 40 80

   120 60 40 80

   190 60 40 80

   260 60 40 80

 */

If you run this program, you will get the following output.

 

Output

Drawing Diagrams

Please note that while reading the data file, program prints data on the console. When we run Java programs with GUI, we can still make use of console. Since the main output is GUI, use of console should be only for debugging information and not for the end-user output. It will be absurd to expect the end-user at both the Frame as well as the console.

26.7 Animation

Earlier we had seen a simple animation under Chapter 13 on “Graphics”. After studying AWT and Swing, we are better equipped to handle animation. Let us try a simple program.

Problem: Write a program to show a rotating red square on the screen.

Solution: We have fillPoly()method to plot a filled polygon. When a square is rotating, its vertices will be changing with time. We will have to calculate them first before calling the fillPoly(). As in any animation, the following actions are repeated in a loop. First, the previous figure is erased, and then a new figure is drawn. Thereafter we call for a delay (see Program 26.7).

 

PROGRAM 26.7 Animation

 import java.awt.* ;

 import javax.swing.* ;

 import java.util.* ;

 class ani2 extends JFrame

 { static double a0 = Math.toRadians(0.0);

   static double a90 = Math.toRadians(90.0);

   static double a180 = Math.toRadians(180.0);

   static double a270 = Math.toRadians(270.0);

   static Graphics g1 ;

   ani2 (int xdim, int ydim) //constructor

        { setSize(xdim,ydim);

          setBackground(Color.white);

          setVisible(true);

          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        }

   public static void main(String[] args)

         { ani2 thisprog = new ani2( 500,400);

 thisprog.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

           thisprog.setVisible(true);

           try

              { Thread.currentThread().sleep(200); }

           catch(InterruptedException e){}

           g1=thisprog.getGraphics();

           A a1 = new A();

           a1.start();

         };

   public void delay(long n)

     {

       try

         { Thread.currentThread().sleep(100);}

      catch(InterruptedException e){}

     }

   public static void compute_sq(double theta, int[] x, int[] y ,int len)

   { x[0]=250 +(int) Math.floor( len*Math.sin(theta + a0 ));

     y[0]=250 +(int) Math.floor( len*Math.cos(theta + a0) );

     x[1]=250 +(int) Math.floor( len*Math.sin(theta + a90) );

     y[1]=250 +(int) Math.floor( len*Math.cos(theta + a90) );

     x[2]=250 +(int) Math.floor( len*Math.sin(theta + a180) );

     y[2]=250 +(int) Math.floor( len*Math.cos(theta + a180) );

     x[3]=250 +(int) Math.floor( len*Math.sin(theta + a270) );

     y[3]=250 +(int) Math.floor( len*Math.cos(theta + a270) );

   }

 static   class A extends Thread

    { public void run()

        { paint_me( g1) ;

        }

    }

 public static void paint_me (Graphics g)

   { int x0=50, y0=50;

     Color drawcol = Color.red ;

     Color bgcol = Color.white ;

     g.setColor(bgcol);

     g.fillRect(0,0,500,500);

     g.setColor(drawcol);

     try

          { Thread.currentThread().sleep(200); }

     catch(InterruptedException e){}

     int i,j,N,temp;

     int [] x = new int[4] ;

     int [] y = new int[4] ;

     N=15 ; // no of loops

     for (j=0;j<100;j++)

      {

        compute_sq(j*0.01,x,y,100);

        g.fillPolygon(x,y,4);

        try

          { Thread.currentThread().sleep(200); }

        catch(InterruptedException e){}

        g.setColor(bgcol);

        g.fillPolygon(x,y,4);

        g.setColor(drawcol);

      }

   }

 }

When you run this program, you see the following output.

 

Output

Animation

26.8 Graphical Display of Bubble Sort

Our teachers emphasized that a figure is worth thousand words. Hence, it is worth trying algorithms like bubble sort be given a graphical display. The famous Java Tutorials graphically demonstrates a few sorting techniques, the demo of which is worth studying and enjoying. Let us see whether we can also attempt such a task ourselves.

Problem: Write a program to graphically demonstrate sorting by bubble sort.

Solution: In this program, we will consider a small array of integers as our data for sorting. We will use horizontal lines to represent the data. The length will be the indicator of the data value. The lines corresponding to successive array elements are displayed one below the other (see Program 26.8).

 

PROGRAM 26.8 Graphic Bubble Sort

  //      bubgra2

 import java.awt.* ;

 import javax.swing.* ;

 import java.util.* ;

 class bubgra2 extends JFrame

 {

   bubgra2 (int xdim, int ydim) //constructor

        { setSize(xdim,ydim);

          setBackground(Color.white);

          setTitle("Bubble sort");

          setVisible(true);

          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        }

  public static void main(String[] args)

        { bubgra2 thisprog = new bubgra2( 400,300);

          thisprog.setVisible(true);

        };

 public void delay(long n)

    { try

         { Thread.currentThread().sleep(100);}

      catch(InterruptedException e){}

    }

 public void paint (Graphics g)

   {int x0=50, y0=50;

    Color drawcol = Color.red ;

    Color bgcol = Color.white ;

    g.clearRect(0,0,400,300);

    g.setColor(drawcol);

 //*****

       int i,j,N,temp;

       int[] a = {50,23,18,67,35,42,15,38,33,15,88,27,77,9,61};

       N=15 ;  // size of the array +1

       for (j=0;j<N;j++)

          g.drawLine(x0,y0+j*10,x0+a[j]*2,y0+j*10);

       delay(1000);

 //    Now sorting starts

       for(i=0;i< N-1;i++)

         { for (j=0;j<N-1;j++)

            { if ( a[j] > a[j+1] )

              { temp = a[j];

                g.setColor(bgcol);

                g.drawLine(x0,y0+j*10,x0+a[j]*2,y0+j*10);

                a[j] = a[j+1];

                g.setColor(drawcol);

                g.drawLine(x0,y0+j*10,x0+a[j]*2,y0+j*10);

                delay(100);

                g.setColor(bgcol);

 g.drawLine(x0,y0+j*10+10,x0+a[j+1]*2,y0+j*10+10);

                a[j+1]= temp;

                g.setColor(drawcol);

 g.drawLine(x0,y0+j*10+10,x0+a[j+1]*2,y0+j*10+10);

                delay(100);

              }

            }

           delay(1000);

          }

        }

 }

At the end of sorting, you will get the following output.

 

Output

Graphic Bubble Sort

26.9 Astrology: Strength of a Horoscope

It is believed that a person reaches heights in life if his horoscope is strong. It is possible to calculate/specify the strength of a horoscope by a single value. Let us see how far we succeed in the task.

26.9.1 Strength of planets located in different signs

In any horoscope, each planet is placed in any one particular sign. The following table illustrates the strength of planets located in different signs.

Strength of planets located in different signs

Planet Guru in sign “Kark” has the highest marks, 100. Planet Shani in sign “Mesha” has only 5 marks. These cells are marked in bold in the aforementioned table.

26.9.2 Strength of planets depending on the position

A planet has different percentage power if located in different position. Position means position from the ascendant. If the planet is in the ascendant, its position is 1. The following table specifies the power of the planet in percentage, depending on the position. This table needs little explanation. The top row represents the power as percentage. Its value ranges from 100% to 11%. The leftmost column represents the planets.

Strength of planets depending on the position

If the planet Ravi is in the 10th position, then it has 100% power. If the planet Shani is in the 3rd position, then it has 83% power. These entries are marked in bold in the above table.

To avoid interactive computing, we can enter the details of a horoscope in a text file with the following format:

line 1 Name
line 2 Date of birth
line 3 Time of birth
line 4 to 14 Number of the sign in which ascendants and planets Sun, Moon, Mars, Mercury, Jupiter, Venus, Saturn, Herschel, Neptune, and Pluto are present.

Note:

Data in lines 1, 2, and 3 is not processed in this particular program.

Only the ascendant and the first seven planets are used in this program.

File design is done considering the future developments.

The // and contents thereafter are just for information.

A sample data file named Sunder is as follows.

Sunder A.Rajan     // name

xx:yy:19zz     // date

aa:bb   // time     // data changed to hide identity

9       // Asc

11      // sun

4       // moon

11       // mars

10       // mercury

11       // Jupiter

12       // venus

6       // Saturn

3       // Harchel

6       //neptune

4       //Pluto

The rules or assumptions for evaluating are as follows.

  • The planet present in a particular sign has a particular value.
  • The planet placed in a particular house (with respect to ascendant) has a particular multiplying factor.
  • The final strength of a planet is the product of these two quantities.
  • The value is the sum of values of all the seven planets.
  • Only seven planets are considered for this evaluation.
  • The data needed is location (sign) of all planets and sign of the ascendant.
  • In the main evaluation (method A), we take sum of powers of all the seven planets. A power of a planet is computed as position value * percentage/100.
  • When a percentage value is low, it reduces the power of a planet significantly. The resulting value may not represent the true planet power. Therefore, an alternate method (say B) is used. Here average of rashi power and position power is found by the formula (rashi power + position power)/2.

With these assumptions, we are in a position to write a program.

Problem: Write a program to evaluate the strength of a given horoscope.

Solution: See Program 26.9.

 

PROGRAM 26.9 Evaluating Horoscope

 //      value1.java

 import java.io.* ;

 interface horo1

     { final int RAVI = 0;

       final int CHANDRA = 0;

       final String[] Pname =

             { " ravi", " chandra", "  mangal", "   budh" ,

               " guru" ,"  shukra", "   shani", "   rahu" ,

               " ketu", " harshal", " neptune", "  pluto"

             } ;

     final String[] Rname =

       { "mesha", "vrishabha", "mithun", "kark",

         "sinha", "kanya",     "tula",   "vrischik",

         "dhanu", "makar",     "kumbha", "meena"

       };

 final int Rpower[][] =

   {

    { 100, 15, 55,  80, 90,  60,   5, 80, 80, 15, 15, 80 }, //ravi

    {  60, 95, 65,  85, 80,  65,  35,  5, 60, 40, 35, 55 }, //chandra

    {  90, 50, 20,  10, 80,  20,  45, 85, 80, 95, 35, 80 }, //mangal

    {  40, 80, 85,  30, 75, 100,  80, 35, 40, 60, 55,  5 }, //budha

    {  80, 20, 20, 100, 80,  20,  20, 80, 90, 10, 45, 85 }, //guru

    {  45, 85, 80,  20, 15,  10,  90, 50, 35, 80, 80, 95 }, //shukra

    {   5, 80, 60,  20, 15,  60, 100, 20, 45, 85, 90, 50 }  //shani

   };

 final int percent[] =

    { 100, 91, 83, 75, 67, 59, 51, 43, 35, 27, 19, 11}; //percent

 final int Lpower[][] =

    {

     { 10, 11,  6,  3, 1,  9, 5,  7, 4,  2,  8, 12 }, //ravi

     {  4, 11,  3,  1, 7,  9, 5, 10, 2,  6, 12,  8 }, //chandra

     { 10, 11,  6,  3, 9,  5, 1,  4, 2, 12,  8,  7 }, //mangal

     {  1, 11, 10,  3, 4,  5, 9,  2, 6, 12,  8,  7 }, //budha

     {  9,  5,  1, 11, 2, 10, 4,  7, 6, 12,  8,  3 }, //guru

     {  4, 11,  5,  7, 9,  2, 1, 10, 3, 12,  8,  6 }, //shukra

     { 11,  6,  3, 10, 7,  9, 5,  4, 2,  8, 12,  1 } // shani

    };

   }

 class Patrika2 implements horo1

 { String name,date,time;

   int asc ;

   int[] Planets = new int[12] ;

   Patrika2()

      { int i;

        for (i=0;i<12;i++)

          Planets[i]=0;

      } ;

 public void showData()

 {  int i, k=0;

    System.out.println("name : " + name);

    System.out.println("date : " + date);

    System.out.println("time : " + time);

    System.out.println("Ascendent : " + Rname[asc] );

    for ( i=0 ;i<12 ; i++)

      { System.out.println( Pname[i] +" in " + Rname[Planets[i]] );

      }

 }

 boolean valid(int k)

 { boolean flag = true; // valid

   if ( k < 0 ) flag = false;

   if ( k > 11) flag = false;

   return flag;

 }

 public void eval1()

 {  int i, j, k, ans, sum1, sum2, sum3 ;

    int box[][] = new int[12][6] ;

    System.out.println("<---evaluation--->");

 // part I

      sum1 = 0;

      for (i=0;i<7;i++)

       {  k = Rpower[i][Planets[i]];

          box[i][0] = k ;

          sum1 = sum1 + k ;

       };

       sum1 = sum1 / 7 ;

       // colomn 0 for rashi power

 // part II

      for (i=0;i<7;i++)

         {  k = ( Planets[i] - asc +12) % 12 + 1; // k range 1 to 12

            ans = -1 ;

            for (j=0;j<12;j++)

                if ( k == Lpower[i][j] ) { ans = j; break; } ;

            if ( ans == -1 )

                   { System.out.println("Error 2") ;

                               return;

                   }

                else

                 { box[i][1] = percent[ans] ;}

         } ;

         // column 1 for positional power

 // part III

       // column 2 product

        sum2 = 0 ;

        for (i=0;i<7;i++)

          {  box[i][2] = box[i][0] * box[i][1] /100 ;

             sum2 = sum2 + box[i][2];

          }

        sum2 = sum2 / 7 ;

       // column 3 average

        sum3 = 0 ;

        for (i=0;i<7;i++)

         {   box[i][3] = ( box[i][0] + box[i][1] ) / 2 ;

             sum3 = sum3 + box[i][3];

         }

        sum3 = sum3 / 7 ;

        System.out.println("planet Rashi Position A B " );

        System.out.println(" name power power mult avg" );

        for (i=0;i<7;i++)

           System.out.println( Pname[i] +" : "

                                + box[i][0] + " "

                                + box[i][1] + " "

                                + box[i][2] + " "

                                + box[i][3]);

           System.out.println("----------------------------------------");

           System.out.println( " " + sum1 + " **** "

         + sum2 + " " + sum3 );

   }

  public void fetchFromFile() throws IOException

   { int i,j; // ,j,k ;

     String fname,temp;

     String Z[] = new String[13];

     BufferedReader Cin = new BufferedReader

                           (new InputStreamReader(System.in) ) ;

     System.out.println("Give name of the file");

     fname = Cin.readLine();

     File fx = new File(fname);

     if ( ! fx.exists() )

        { System.out.println(" Can not read from named file");

          System.exit(1); //return;

        }

     FileReader f1 = new FileReader(fx);

     BufferedReader Jin = new BufferedReader(f1) ;

     System.out.println("<---reading file starts--->");

     name = Jin.readLine();

     date = Jin.readLine();

     time = Jin.readLine();

     System.out.println("name = " + name);

     System.out.println("date = " + date);

     System.out.println("time = " + time );

     temp = Jin.readLine();

     j=Integer.parseInt(temp.substring(0,3).trim() );

     asc = j-1 ;

     if ( ! valid (asc) ) asc = 0;

     i=0;

     while ( (Jin.ready()) && (i<7) )

     { temp = Jin.readLine();

        j=Integer.parseInt(temp.substring(0,3).trim() );

        j= j-1;

        if ( ! valid (j) ) j = 0;

        Planets[i] = j ;

        i++;

     }

    }

 }

 class value1

 {  public static void main (String argv[])

     { System.out.println("<---value1.java--->");

       Patrika2 p1 = new Patrika2();

       try

         { p1.fetchFromFile(); }

       catch (IOException e ) { } ;

       p1.eval1();

     }

 }

If you run this program and give the file name as Sunder, you will see the following output.

 

Output

 <---value1.java--->

 Give name of the file

 sunder

 <---reading file starts--->

 name = Sunder A.Rajan // name

 date = xx:yy:19zz // date

 time = aa:bb // time // data changed to hide identity

 <---evaluation--->

 planet     Rashi   Position   A      B

 name       power   power      mult   avg

    ravi :  15      75         11     45

 chandra :  85      11         9      48

  mangal :  35      75         26     55

    budh :  60      43         25     51

    guru :  45      11         4      28

  shukra :  95     100         95     97

   shani :  60      75         45     67

----------------------------------------

            56     ****        30     55

The main evaluation (method A) results in value as 30.

The alternate evaluation (method B) gives value as 55.

In general, value obtained by method B for any horoscope is always higher than the corresponding method A value.

26.10 Freehand Drawing

In school days, we are expected to draw what is known as “freehand drawing”. It is really a matter of skill to draw symmetric left and right sides. But with the computer at your disposal, you can do a neat job. We can use the interface MouseMotionListener for this task.

Problem: Write a program to draw a “freehand drawing” the mouse.

Solution: We have to draw only one side. The other side will be generated automatically. (see Program 26.10).

 

PROGRAM 26.10 Freehand Drawing

  //   mouse2.java

 import java.awt.* ;

 import java.awt.event.* ;

 import javax.swing.* ;

 class myFrame extends JFrame implements MouseMotionListener

 { public static Graphics myG ;

   public static int width =400, height =300;

   myFrame()

       { super("***mouse2***") ;

         setSize(width,height);

         setResizable(false);

         setBackground(Color.white);

         setVisible(true);

       }

 public void init()

  { addMouseMotionListener(this);

    requestFocus();

    myG = getGraphics() ;

    myG.setColor(Color.blue);

  }

 public void paint (Graphics myG)

  { myG.clearRect(0,0,width,height);

    myG.setColor(Color.blue);

    myG.drawLine( 200,20,200,300);

  }

 public void mouseMoved(MouseEvent e)

      {

      }

 public void mouseDragged(MouseEvent e)

   {  int x = e.getX() ;

      int y = e.getY() ;

      myG.drawRect( x,y,1,2);

      myG.drawRect( 400-x,y,1,2);

   }

 }

 public class mouse2

  {  public static void main( String args[])

     {   myFrame k1 = new myFrame();

         k1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

         k1.init();

     }

 }

If you run this program, you create a freehand drawing. A sample drawing is as follows.

 

Output

Freehand Drawing

Please note the following statement.

myG.drawRect( 400-x,y,1,2);

This statement is responsible for drawing on the other side.

26.11 Sudoku I

These days all the newspapers have “Sudoku” puzzles everyday. These are interesting brain-teasers. Let us develop a program to aid the solution of it. The puzzle consists of nine rows of nine cells each. It is further divided into nine 3 × 3 boxes. Initially, 25 to 30 numbers are present in the grid, one number in one cell. All the numbers are between 1 and 9.

Rules of play

Fill the remaining cells with numbers 1 to 9 such that digits 1 to 9 do not repeat in the same row, column, or box.

Here is a sample puzzle. (See Figure 26.1)

Figure 26.1

Figure 26.1 Sudoku Puzzle

When solved correctly, you will get the following answer. (See Figure 26.2)

Figure 26.2

Figure 26.2 Sudoku Puzzle Solution

Problem: Write a program to solve a given Sudoku puzzle.

Solution: Developing a solution for Sudoku is quite complex. Here is a humble attempt. This program will help you to solve the puzzle.

We know that around 25 to 35 numbers are given (specified) at the start. These numbers predict as to which numbers cannot be present in a particular cell. It is quite possible that some particular cell can have only one number as all the remaining numbers are ruled out. We have to mentally locate such a cell and the corresponding number. It will be a great idea if we can see such a possibility visually. It means that we should be able to see each and every cell and what numbers it can take.

By visual inspection, we will be able to decide the cell and the number. If we put this number in this cell, it will rule out more numbers from some more cells. We can hope that every time we find at least one cell such that there is only one possible number in it. This process will continue till the puzzle is completely solved.

Let us assume that initially there is no given data. Hence, all the 81 cells can have any number. This fact can be displayed by showing all 1 to 9 numbers in each cell.

We say that we start with data entry phase. Now take the first number in the data and put it in its cell. Give effect of this placement. Then take the remaining numbers one by one till the given data is exhausted. Now start solving the puzzle.

By visual inspection, identify the cell which contains only one possible number. Give this data to the program (row number, column number, and value number). The program will enter this data into a puzzle grid and will mark its effect. Now we have to merely repeat this procedure till we mark all the cells.

The program always displays 9 × 9 grid. Each cell displays (in two rows) all numbers which can occupy this cell. When we enter a number in any cell, it is displayed with two stars before and after (**2**). By chance if we give inconsistent data, program will refuse to accept it and halt.

With this general scheme, we have designed the program as follows. The first phase is called data entry phase. The program prompts you to type data. Give data as say “3 4 5”, meaning third row, fourth column, and value 5. Note that at least one blank is necessary between the elements.

Program will accept the data and show **5** in third row fourth column. If for some reason the cell cannot accept this data (error), program will report it and stop. When you finish data entry, just type some single character and press return. Though this is an error, it will be treated as the end of data entry signal.

Now the puzzle-solving phase starts. If the program finds a number for a cell, it will tell you the same. It will request you to press return to accept. Just press return and it will enter that data and go to next one.

With sufficient numbers given as data, you do not have to think yourself. The program will do that for you.

If you wish to solve the puzzle yourself, do not end the data entry phase. After the given data is over, add solution on your own. Data entry phase does not give you ready-made solution. However, it gives you a graphical view to aid your judgement (see Program 26.11).

 

PROGRAM 26.11 Sudoku I

  //   sudoku1.java

 import java.io.* ;

 import java.util.StringTokenizer ;

 //   This interface defines Constant TEN = 10

 interface STDH

    { final int TEN = 10;

    };

 //     This class defines method getString()

 class MyIO

     { public static String getString() throws IOException

       { String st1;

         BufferedReader Jin = new BufferedReader

                  (new InputStreamReader (System.in) );

         st1= Jin.readLine();

         return st1;

       }

     } ;

 // This Class handles a unit of

 // row number,column number and the value

 class Unit { int row, col, val; } ;

 public class sudoku1 implements STDH

 { static int a,b,c;

   static String str1 ;

   static boolean flag = true;

   public static boolean readme() throws IOException

   { int k;

     boolean answer = true;

     System.out.println( " type data :" );

     str1 = MyIO.getString();

     StringTokenizer st = new StringTokenizer(str1);

     k=st.countTokens();

     // System.out.println("k="+k);

     if (k!=3) { System.out.println("error in input" );

                 answer = false;

               }

         else

             {

               try

                   { a= Integer.parseInt( st.nextToken() );

                     b= Integer.parseInt( st.nextToken() );

                     c= Integer.parseInt( st.nextToken() );

                     // System.out.println(a + "," + b + "," + c);

                     // usefun while debugging

                   }

                   catch (Exception e)

                     { System.out.println(" Exceptin in parse

 int ***error in input" );

                   answer = false;

                  }

                 } ;

      return answer;

   };

 public static void main(String args[]) throws IOException

     { int k;

       int tdc =0;

       boolean dataEntry = true;

       System.out.println("sudoku1.java starts ");

       T1 box[][] = new T1[TEN][TEN] ;

       Unit z = new Unit();

       int master_count = 0;

       String str1 ;

       char ch ;

       int i,j ;

       for( i=1; i<TEN; i++)

       for( j= 1; j<TEN; j++)

          { box[i][j] = new T1();

          };

       welcome();

       MyIO.getString();

 // data entry phase

        display(box);

        while ( dataEntry )

         {

           if ( !readme()) // error in reading

                 { dataEntry =false ;

                   break;//if (!dataEntry) break;

                 }

            master_count++ ;

           if ( effect(a,b,c,box) )

               { display(box);

                 if ( master_count==81 )

                       { flag = false;

                         System.out.print(" congradulations ") ;

                       };

               }

               else

                 { System.out.print(" error in data");

                   dataEntry = false;

                   flag = false;

                 } ;

            } ; // while

         System.out.println(" data entry phase over");

         System.out.println(" press return to continue ");

          MyIO.getString();

          flag = true;

 // solving phase

       display(box);

 //    flag is initialised at the begining. If there is any error

 //    in data entry phase the flag is reseted.

 //    Hence solving phase is bypassed.

         while ( flag )

           { tdc = findSolution(box,z);

             if ( (tdc == 2) )

                { System.out.print("press return to accept - - - ");

                  str1 = MyIO.getString();

                  a= z.row ; b = z.col ; c = z.val ;

                }

             else

              {

               if (! readme()) // error

                  { flag= false ;

                    break;

                  }

               }

             // if (flag )

             //   {

                 master_count++ ;

                   if ( effect(a,b,c,box) )

                      { display(box);

                        if ( master_count==81 )

                             { flag = false;

                               System.out.print(" congradulations ") ;

                             };

                       }

                       else flag = false;

               // } ;

             } ; // while

           System.out.print("program over");

          // return ;

         }; // main

       static void welcome()

       {

         System.out.println("             welcome to ");

         System.out.println(       "            SUDOKU     ");

         System.out.println("             ver 1.0    ");

         System.out.println( "... press return key to start" ) ;

       }

       static void display(T1 box[][])

       {  int i, j,k;

          System.out.println(

          " 1      2      3      4      5      6      7      8      9");

          System.out.println(

          "----------------------------------------------------------------");

          for( i=1; i < TEN; i++)

           {

             for( j= 1; j<TEN; j++)

               { //first line

                 if ( box[i][j].free )

                    {

                      for (k=1;k<6;k++)

                          if ( box[i][j].choise[k] !=0 )

                          System.out.print( box[i][j].choise[k]) ;

                     else System.out.print(' '),

                   System.out.print(" ") ;

                  }

                 else System.out.print("**" + box[i][j].value + "** " );

             } ;

           System.out.println(" | ");

           //second line

           for( j= 1; j<TEN; j++)

            { //second line

              if ( box[i][j].free )

                 { for (k=6;k<TEN;k++)

                     if ( box[i][j].choise[k] !=0 )

                           System.out.print( box[i][j].choise[k]) ;

                         else System.out.print(' '),

                     System.out.print(" ") ;

                 }

                else System.out.print( " ");

              }

           System.out.println(" | " + i );

           if( i%3 == 0)

        System.out.println(

         "---------------------------------------------------------------");

         }

 };

 // this method checks if the choice is acceptable

 // if so it effect i.e accepts it!

 static boolean effect(int row,int col,int val,T1 box[][])

 { int i,j ;

   int R,C;

   boolean returnvalue = true ;

   if (   (row<1) || (row>9)

       || (col<1) || (col>9)

       || (val<1) || (val>9)

      )

        { System.out.print ( "error1");

          returnvalue = false ;

          return returnvalue ;

          // exit(1);

       };

 if ( box[row][col].free == false )

         { System.out.println( "error2 duplicate entry ") ;

               System.out.println("at " + row +',' + col) ;

               System.out.print("press any key to quit") ;

           //    getch();

           returnvalue = false ;

           return returnvalue ;

       } ;

 if ( box[row][col].choise[val] != val)

         { System.out.println("error3 choice NOT available ");

               System.out.println("at " + row + ','+ col) ;

               System.out.print( "press any key to quit") ;

           //    getch();

          returnvalue = false ;

          return returnvalue ;

            //    exit(1);

     } ;

 box[row][col].value = val ;

 box[row][col].free = false ;

 for( i=1; i < TEN; i++)

    box[i][col].choise[val] = 0 ;

 for( j=1; j < TEN; j++)

    box[row][j].choise[val] = 0 ;

 R = (row-1) /3*3 +1 ;

 C = (col-1) /3*3 +1 ;

 for( i=0; i < 3 ; i++)

    for( j= 0; j<3 ; j++)

      { box[R+i][C+j].choise[val] =0 ; };

  return returnvalue;

 };

 static int findSolution(T1 box[][] ,Unit z )

 { int result =0;

   int found = 0;

   int flag = 0;

   int i, j, k ;

   int simple_count = 0;

   int cnt[] = new int[TEN] ;

 // simple rule

  for( i=1; i < TEN; i++) // go to all rows

  for( j=1; j < TEN; j++) // and columns ie every cell

   if (box[i][j].free )

    { simple_count = 0;

      for (k=1;k<TEN;k++)

         if ( box[i][j].choise[k] == k ) simple_count++;

      if ( simple_count == 1) // find choice

         { for (k=1;k<TEN;k++)

             if ( box[i][j].choise[k] == k )

              { z.col = j;

                z.row = i ;

                z.val = k ;

              }

                System.out.println( "rule A : suggests ->" + z.row + " ," + z.col + " ," + z.val );

                result = 2;

                return result;

        }

    }

 //  cout << "analysis by rule 3" << endl;

 // rule 3A row wise

   for( i=1; i < TEN; i++)       // go to all rows

    { for (k=0;k<TEN;k++)

           cnt [k] = 0;

      for( j=1; j < TEN; j++)    // go to all column of a given row

        { if (box[i][j].free )

          for (k=1;k<TEN;k++)

               if ( box[i][j].choise[k] == k ) cnt[k]++;

        }

      // inspect cnt for value one!

      k= 1; found = 0;

      while ( ( k < TEN )&& (found ==0) )

        {   if ( cnt[k] == 1 ) found = 1;

               else k++;

        }

      if ( found ==1 )

        { // now finding the column

          j=1; flag = 0;

                      while ( ( j<TEN ) && ( flag==0 ) )

             if ( (box[i][j].free ) &&

                      (box[i][j].choise[k] == k ) )

                { flag = 1;

                  z.col = j;

                  z.row = i ;

                  z.val = k ;

                }   else j++;

               //

                System.out.println("rule B : suggests ->" + z.row + " ," + z.col + " ," + z.val );

         result = 2;

         return result;

       }

     };

 // now by columns

   for( j=1; j < TEN; j++) // go to all colums

     { for (k=0;k<TEN;k++)

            cnt [k] = 0;

       for( i=1; i < TEN; i++) // go to all rows in a given col

         { if (box[i][j].free )

           for (k=1;k<TEN;k++)

                if ( box[i][j].choise[k] == k ) cnt[k]++;

         }

         // inspect cnt for value one!

         k= 1; found = 0;

         while ( ( k < TEN )&& (found ==0) )

           {   if ( cnt[k] == 1 ) found = 1;

                   else k++;

           } ;

         if ( found ==1 )

          { // now finding the row

            i=1; flag = 0;

                    while ( ( i<TEN ) && ( flag==0) )

               if ( (box[i][j].free ) &&

                        (box[i][j].choise[k] == k ) )

                  { flag = 1;

                    z.col = j;

                    z.row = i ;

                    z.val = k ;

                  }  else i++;

                     System.out.println("rule C : suggests ->" + z.row + " ," + z.col + " ," + z.val);

  //              cout << "rule3 -> col"<<i<<",choice "<<k<<endl;

                result = 2;

                return result;

               }

       };

      return result ;

 }

 }

 // class T1 represents a single cell. It has a value

 // as well as choices if free

 class T1 implements STDH

   {  boolean free ;

      int value ;

      int choise[]= new int[TEN];

      void show()

        {  int i ;

           if ( !free ) System.out.print("**" + value + "**" ) ;

                 else

                   { for( i=1; i < TEN; i++)

                       if ( choise[i] == i )

                            System.out.print( choise[i] ) ;

                   }

            System.out.println( " ; " );

          } ;

        T1()

         { int i ;

           free = true ; // false

           value = -1 ; //invalid value;

           for( i=0; i < TEN; i++) choise [i] = i ;

         }

 };

If you start running this program and give data as given in the puzzle shown earlier, you will see the following screen.

Output

Sudoku I

 type data :

Now you have two choices to proceed.

If you wish to solve the puzzle on your own, you should continue typing data. The program output is of great help to you. A glance at the console will tell you that in cell (4,7) there is only one choice, that is value 3. You can enter data as 4 7 3. The program will accept it and refresh the screen. Some new cell will start showing single choice.

If you are interested only in getting the solution, you may take active help of the program. For that, you have to end the data entry phase and simply type any character and press return. It will signal an error to data entry section and close that phase. Program will enter the problem-solving phase and show you what data can be entered. You have to simply press return to accept it. In no time, you will come at the end of the puzzle.

Here are some more problems with solution for practice.

problems with solution
problems with solution
problems with solution
problems with solution
problems with solution

26.12 Sudoku II

Let us try using GUI for this problem.

Problem: Write a program to solve Sudoku puzzle using swing components.

Solution: This program uses a JTextArea to display the output. It uses a JTextField to enter data. The same field is also used for flagging error messages.

This is not an ideal design but saves the required components. See Program 26.12.

 

PROGRAM 26.12 Sudoku II

  // su2.java

 import java.awt.* ;

 import java.awt.event.* ;

 import javax.swing.* ;

 import java.util.* ;

 interface STDH

     {  final int TEN = 10;

     };

 class MainData implements STDH // da drawing area

  { public int k ;

    char[] display;

 T1 box[][] = new T1[TEN][TEN] ;

 MainData()

   { k=0;

     int i,j ;

     display = new char[45*18];

     for(i=0;i<45*18;i++)

        display[i] = ' '; // Character.forDigit(i%10,10);

     for( i=1; i<TEN; i++)

        for( j= 1; j<TEN; j++)

           { box[i][j] = new T1();

           };

    }

 public void draw_Num( int n, int row, int col)

  {

     display[(row-1)*45*2 + (col-1)*5 + 0 ] = ' ';

     display[(row-1)*45*2 + (col-1)*5 + 1 ] = '*';

     display[(row-1)*45*2 + (col-1)*5 + 2 ] =

                              Character.forDigit(n,10);

     display[(row-1)*45*2 + (col-1)*5 + 3 ] = '*';

     display[(row-1)*45*2 + (col-1)*5 + 4 ] = ' ';

     display[(row-1)*45*2+45 + (col-1)*5 + 0 ] = ' ';

     display[(row-1)*45*2+45 + (col-1)*5 + 1 ] = ' ';

     display[(row-1)*45*2+45 + (col-1)*5 + 2 ] = ' ';

     display[(row-1)*45*2+45 + (col-1)*5 + 3 ] = ' ';

     display[(row-1)*45*2+45 + (col-1)*5 + 4 ] = ' ';

  }

 public void draw_String( int n, int row, int col,int k)

 { char ch ='.';

   if (k<6)

     { if ( ( 0< n ) && ( n<TEN ) )

             display[(row-1)*45*2 + (col-1)*5 +k-1 ] =

                              Character.forDigit(n,10);

           else display[(row-1)*45*2 + (col-1)*5 +k-1] = ch;

     }

     else //secondline

     { if ( ( 0< n ) && ( n<TEN ) )

             display[(row-1)*45*2+45 + (col-1)*5+ k-6 ] =

                                      Character.forDigit(n,10);

           else display[(row-1)*45*2+45 + (col-1)*5 +k-6] = ch;

     }

 }

 public void paint_me ()

  { int i,j,k;

    final int fc = 4 ;

    int x0,y0;

    for( i=1; i < TEN; i++)

    {for( j= 1; j<TEN; j++)

     {//first line

      if( box[i][j].free == true )

          { for (k=1;k<6;k++)

              if ( box[i][j].choise[k] !=0 )

                   draw_String( box[i][j].choise[k],i,j,k) ;

               else draw_String(-1, i , j ,k);

          }

        else draw_Num( box[i][j].value, i, j );

      }

   };

   // second line

   for( i=1; i < TEN; i++)

   {for( j= 1; j<TEN; j++)

     {if( box[i][j].free == true )

          {for (k=6;k<TEN;k++)

             if ( box[i][j].choise[k] !=0 )

                  draw_String( box[i][j].choise[k], i,j,k) ;

                else draw_String(-1, i,j,k );

          }

        }

      }

  } //paint_me

 String effect(int row,int col,int val)

   {

     int i,j ;

     int R,C;

     String errorMessage ="";

 //  boolean returnvalue = true ;

     if ( (row<1) || (row>9)

         || (col<1) || (col>9)

         || (val<1) || (val>9)

        )

          { errorMessage = "error1";

            //returnvalue = false ;

            return errorMessage ; // returnvalue ;

          } ;

    if ( box[row][col].free == false)

          { errorMessage = "error2 : duplicate entry " ;

            return errorMessage; //returnvalue ;

          } ;

    if ( box[row][col].choise[val] != val)

          { errorMessage= "error3 : choice NOT available ";

            return errorMessage;//returnvalue ;

               // exit(1);

          } ;

    box[row][col].value = val ;

    box[row][col].free = false;

    for( i=1; i < TEN; i++)

     box[i][col].choise[val] = 0 ;

    for( j=1; j < TEN; j++)

    box[row][j].choise[val] = 0 ;

    R = (row-1) /3*3 +1 ;

    C = (col-1) /3*3 +1 ;

    for( i=0; i < 3 ; i++)

    for( j= 0; j<3 ; j++)

      { box[R+i][C+j].choise[val] =0 ;

      };

    return errorMessage;//returnvalue;

   };

 int findSolution(UNIT z )

 {  int result =0;

     int found = 0;

     int flag = 0;

     int i, j, k ;

     int simple_count = 0;

     int cnt[] = new int[TEN] ;

 //    simple rule

    for( i=1; i < TEN; i++) // go to all rows

    for( j=1; j < TEN; j++) // and columns ie every cell

     if (box[i][j].free == true )

      { simple_count = 0;

        for (k=1;k<TEN;k++)

           if ( box[i][j].choise[k] == k ) simple_count++;

        if ( simple_count == 1) // find choice

           { for (k=1;k<TEN;k++)

               if ( box[i][j].choise[k] == k )

                { z.col = j;

                  z.row = i ;

                  z.val = k ;

                }

          // System.out.println( "rule A : suggests ->" +

          // z.row + " ," + z.col + " ," + z.val );

                    result = 2;

                    return result;

           }

    }

 // cout << "analysis by rule 3" << endl;

 // rule B row wise

   for( i=1; i < TEN; i++) // go to all rows

    { for (k=0;k<TEN;k++)

           cnt [k] = 0;

      for( j=1; j < TEN; j++) // go to all column of a given row

        { if (box[i][j].free == true )

          for (k=1;k<TEN;k++)

               if ( box[i][j].choise[k] == k ) cnt[k]++;

        }

      // inspect cnt for value one!

      k= 1; found = 0;

      while ( ( k < TEN )&& (found ==0) )

        {    if ( cnt[k] == 1 ) found = 1;

                 else k++;

        }

      if ( found ==1 )

          { // now finding the column

            j=1; flag = 0;

                        while ( ( j<TEN ) && ( flag==0 ) )

               if ( (box[i][j].free == true ) &&

                        (box[i][j].choise[k] == k ) )

                  { flag = 1;

                    z.col = j;

                    z.row = i ;

                    z.val = k ;

                  }   else j++;

            // System.out.println("ruleB : suggests ->" + z.row

            //            + " ," + z.col + " ," + z.val );

            result = 2;

            return result;

          }

     };

 // now by columns

   for( j=1; j < TEN; j++)      // go to all colums

     { for (k=0;k<TEN;k++)

            cnt [k] = 0;

       for( i=1; i < TEN; i++)  // go to all rows in a given col

         { if (box[i][j].free == true )

           for (k=1;k<TEN;k++)

                if ( box[i][j].choise[k] == k ) cnt[k]++;

         }

       // inspect cnt for value one!

       k= 1; found = 0;

       while ( ( k < TEN )&& (found ==0) )

         {   if ( cnt[k] == 1 ) found = 1;

                 else k++;

         } ;

       if ( found ==1 )

        { // now finding the row

          i=1; flag = 0;

                  while ( ( i<TEN ) && ( flag==0) )

            if ( (box[i][j].free == true )

                     && (box[i][j].choise[k] == k ) )

               { flag = 1;

                 z.col = j;

                 z.row = i ;

                 z.val = k ;

               }  else i++;

            // System.out.println("rule3B : suggests ->" + z.row

            //               + " ," + z.col + " ," + z.val);

         //    cout << "rule3 -> col"<<i<<",choice "<<k<<endl;

             result = 2;

             return result;

           }

      };

     return result ;

 }

 } // MainData

 public class su2 extends JFrame implements ActionListener

  { JTextField tf1;

    static Font f = new Font("courier",Font.BOLD,18);

    MainData data ;

    JTextArea jt ;; //= new JTextArea(20,20);

    static int n=100;

    int master_count = 0 ;

    su2() // constructor

      { super("SUDOKU II ");

        data = new MainData() ;

        this.getContentPane().setLayout( null );

        tf1 = new JTextField( 20);

        tf1.addActionListener(this);

        tf1.setActionCommand("txt");

        tf1.setBounds(10,490,100,40);

        tf1.setBorder( BorderFactory.createLineBorder(Color.black) );

        this.getContentPane().add(tf1);

        jt = new JTextArea();//45,20);

        jt.setColumns(45);

        jt.setRows(18);

        jt.setLocation(10,10);

        jt.setFont(f);

        jt.setLineWrap(true);

        jt.setText(new String(data.display));

        jt.setBounds(10,10,45*11,550);

        jt.setEditable(false);

        jt.append("hello world");

        this.getContentPane().add(jt);

     //   tf1.setVisible(true);

     //   jt.setVisible(true);

        this.setVisible(true);

    }

 public static void main( String args[])

     { su2 thisprog = new su2();

       thisprog.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

       thisprog.setBounds(10,10,520,580);

       thisprog.setResizable(false); //

       thisprog.data.paint_me();

       thisprog.jt.setText( new String(thisprog.data.display) );

     }

 public void actionPerformed(ActionEvent e)

  { String stline,s1="",s2="",s3="";

    int a=0,b=0,c=0;

    int T;

    UNIT z= new UNIT();

    if( e.getActionCommand().equals("quit") )

         { System.exit(0);

         };

    if( e.getActionCommand().equals("txt") )

       {stline= tf1.getText();

        tf1.setText("");

         // jt.setText(stline);

        StringTokenizer stn = new StringTokenizer(stline);

        if (stn.hasMoreTokens())    s1 = stn.nextToken() ;

        if (stn.hasMoreTokens())    s2 = stn.nextToken() ;

        if (stn.hasMoreTokens())    s3 = stn.nextToken() ;

        try

          { a=Integer.parseInt(s1);

            b=Integer.parseInt(s2);

            c=Integer.parseInt(s3);

          }

        catch (NumberFormatException nfe) { a=0;b=0;c=0; }

        stline= data.effect(a,b,c) ;

        if( stline.length() == 0) // zero means ok

           {data.paint_me();

            jt.setText(new String(data.display));

            if ( ++master_count==81 )

                 { tf1.setText("Congradulations! you win ");

                 }

               else if ( data.findSolution(z) == 2 )

                         tf1.setText(z.toString() );

            }

            else

              {tf1.setText(stline); // error message

               // jt.setText("MAHESH"); // for debugging

              }

          }

      }

 }

 class T1  implements STDH

      {  boolean free ;

         int value ;

         int choise[]= new int[TEN];

         T1(){ int i ;

               free = true ;

               value = -1 ; //invalid value;

               for( i=0; i < TEN; i++) choise [i] = i ;

              }

       };

 class UNIT

  { int row, col, val;

    public String toString()

      { return String.valueOf(row) + " " +

             String.valueOf(col) + " " +

             String.valueOf(val) ;

      }

  } ;

If you start solving the puzzle and type

1 1 1

2 2 2

3 3 3

as data, you will get the following output.

Output

Sudoku II

Please note some changes from the console version. There are no separate phases for data entry and solution.

As you go along entering the data and some definite answer is present for some cell, it will appear in the TextField. It is upon you to accept or reject it and continue to enter data.

When all the given data is entered and the puzzle has a solution, the program will suggest entries. If you accept them, it will solve the puzzle completely.

You can make this program work similar to the console one by adding a button to signify the end of data entry and slight tuning of the code.

26.13 Moon Revolves Around Earth

Applets and graphics together can be a great tool in computer-aided education. In school physics, there is a topic on stars and planets. Students are taught that Earth is a planet which rotates around the Sun, which is a star. Moon is a sub-planet which revolves around the Earth. It will be interesting to see this in action on a screen. Students will get a better understanding of the topic. Let us write an applet to see this in action.

Problem: Write an applet to show how Moon and Earth revolve around the Sun.

Solution: We will need to make some simplifying assumptions. They are

  • Orbits of Earth and Moon are circular.
  • Moon, Earth, and Sun are always in a plane.
  • Diameter of Sun is 20 pixels.
  • Diameter of Earth is 16 pixels.
  • Diameter of Moon is 10 pixels.
  • Earth is at 100 pixels from Sun.
  • Moon is at 30 pixels from Earth.

The other assumptions are that the Earth completes a revolution around the Sun in 365.25 days. The Moon completes one revolution around the Earth in 29.5 days. We will display the positions of each day in a year. We will use delay of 200 milliseconds to symbolize a day and define classes Planet and SubPlanet (which extends Planet). We will assume and display Sun as a circle at the centre. See Program 26.13.

 

PROGRAM 26.13 The Moon Revolves Around the Earth

 //     circle1.java

 import java.awt.* ;

 import java.applet.* ;

 class Planet

     { Color myCol =Color.green;

       int rad ;

       int hsize=8;//half size

       double omega ;

       int X0,Y0;

       int x,y;

       public Planet(int xcentre, int ycentre )

        {rad =100 ;

         X0 = xcentre;

         Y0 = ycentre ;

         x=X0;y=Y0;

         omega = 2*Math.PI/365.25;//2 Pi radians in 365.25 days

       };

       void getpos(int t)

        { x = (int) ( X0 + rad * Math.cos ( omega*t ) ) ;

          y = (int) ( Y0 + rad * Math.sin ( omega*t ) ) ;

        } ;

       void show(Graphics g)

        { g.setColor(myCol);

          g.fillOval(x-hsize, y-hsize, 2*hsize, 2*hsize);

        }

       void hide(Graphics g)

        { g.setColor(Color.gray);

          g.fillOval(x-hsize, y-hsize, 2*hsize, 2*hsize);

        };

      } ;

 class SubPlanet extends Planet

   { //int rad1 =30;

     int hsize =5; //half size

     Color myCol =Color.blue;

        void getpos(int t,int a, int b)

          {  x = (int) ( a + rad * Math.cos ( omega*t ) ) ;

             y = (int) ( b + rad * Math.sin ( omega*t ) ) ;

          } ;

        public SubPlanet(int a, int b)

          { super(a,b);

            rad =30;

            omega = 2*Math.PI/29.5; // 2 Pi radians in 29.5 days

          };

        public void show(Graphics g)

          { g.setColor(myCol);

            g.fillOval(x-hsize, y-hsize, 2*hsize, 2*hsize);

          }

        public void hide(Graphics g)

          { g.setColor(Color.gray);

            g.fillOval(x-5, y-5, 10, 10);

          }

       };

 public class planet3 extends Applet

  {  final int xcentre = 150, ycentre = 150;

     final int moon_rad = 30 ;

     int moonX =0, moonY = 0 ;

     int moon_temp = 0;

     Planet earth;

     SubPlanet moon;

     public void init()

       {   setBackground(Color.gray);

           earth = new Planet(xcentre, ycentre) ;

           moon = new SubPlanet(xcentre, ycentre) ;

       }

     public void delay(long n)

      { long t1,t2;

        t1 = System.currentTimeMillis();

        t1 = t1 + n;

        t2 = System.currentTimeMillis();

        while ( t2 < t1 ) t2= System.currentTimeMillis();

       }

     public void paint (Graphics g)

       { int j ;

         g.setColor(Color.red ) ;

         g.fillOval(xcentre-10, ycentre-10, 20, 20); // sun

         g.setColor(Color.red ) ;

         g.drawOval(earth.X0-earth.rad, earth.Y0-earth.rad,

       2*earth.rad,2*earth.rad);

 //      g.drawString(“start”,100,100); for debugging only

         for( j= 0 ; j<360; j++)

            {  earth.getpos(j);

               moon.getpos(j,earth.x,earth.y);

               moon.show(g);

               earth.show(g);

               delay(100);

               earth.hide(g);

               moon.hide(g);

            }

         g.setColor(Color.red ) ;

 //      g.drawString(“over”,100,130); for debugging only

      }

 }

We will place this applet in a HTML file as follows:

 

File planet3.html

 <applet code=”planet3” width=”300”

 height=”300”></applet>

When we see the applet running in the browser, at one moment we will see the following snapshot.

 

Output

The Moon Revolves Around the Earth

You can very easily modify/develop the applet further to show Full Moon and no Moon days. Is it possible to show when eclipses occur?

26.14 Astronomy: Retrograde Motion

The concept of retrograde motion of a planet is difficult to understand. Here is a simple program which will demonstrate the retrograde behaviour of an outer planet.

Problem: Write a program to demonstrate the retrograde motion of a planet.

Solution: See Program 26.14.

 

PROGRAM 26.14 Retrograde Demo

  //     retro2.java

 import java.awt.* ;

 import java.applet.* ;

 class Planet

     { Color myCol,bgCol;

       int rad ;

       int hsize=8;//half size

       double omega ;

       int X0,Y0;

       int x,y;

       public Planet(int xcentre, int ycentre ,int radius,

                     double orb, Color c1 )

         { rad =radius ;

           X0 = xcentre;

           Y0 = ycentre ;

           myCol=c1;

           bgCol=Color.white;

           x=X0;y=Y0;

           omega = 2*Math.PI/(365*orb);

           // 2 Pi radians in 365.25 days

          };

        void getpos(int t)

          {  x = (int) ( X0 + rad * Math.cos ( omega*t ) ) ;

             y = (int) ( Y0 + rad * Math.sin ( omega*t ) ) ;

          } ;

        void show(Graphics g)

          { g.setColor(myCol);

            g.fillOval(x-hsize, y-hsize, 2*hsize, 2*hsize);

          }

        void hide(Graphics g)

          { g.setColor(bgCol);

            g.fillOval(x-hsize, y-hsize, 2*hsize, 2*hsize);

          };

      } ;

 public class retro2 extends Applet

  { final int xcentre = 320, ycentre = 250;

    Planet earth;

    Planet jupitor;

    public void init()

      { setBackground( new Color(250,255,250));

        earth = new Planet(xcentre, ycentre, 20, 1.0, Color.blue) ;

        jupitor= new Planet(xcentre, ycentre,104, 30.0,Color.yellow) ;

      }

    public void delay(long n)

      { long t1,t2;

        t1 = System.currentTimeMillis();

        t1 = t1 + n;

        t2 = System.currentTimeMillis();

        while ( t2 < t1 ) t2= System.currentTimeMillis();

      }

     public void paint (Graphics g)

      {int j ;

       double angle;

       g.setColor(Color.red ) ;

       g.fillOval(xcentre-10, ycentre-10, 20, 20); // sun

 //    g.setColor(Color.red ) ;

       g.drawOval(earth.X0-earth.rad, earth.Y0-earth.rad,

                           2*earth.rad,2*earth.rad);

       drawCircle(earth.X0,earth.Y0,earth.rad,g);

 //         g.setColor(Color.yellow ) ;

       drawCircle(earth.X0,earth.Y0,295,g);

       for(int i=-30;i<+30;i=i+3)

          drawLines5 (i,g);

       for( j= 0 ; j<360*2; j+=2)

         { earth.getpos(j);

           earth.show(g);

           jupitor.getpos(j);

           jupitor.show(g);

           g.setXORMode(Color.white);//background

           g.setColor(Color.green);

           g.drawLine(earth.x, earth.y, jupitor.x,

              jupitor.y);

           angle = Math.atan2 ( (jupitor.y - earth.y) ,

                        (jupitor.x - earth.x) );

           g.fillOval(earth.X0+(int)(270*Math.cos(angle)),

               earth.Y0+(int)(270*Math.sin(angle)), 8,8);

           delay(100);

           g.drawLine(earth.x, earth.y, jupitor.x,

             jupitor.y);

           g.fillOval(earth.X0+(int)( 270*Math.cos(angle) ),

               earth.Y0+(int)(270*Math.sin(angle) ), 8,8);

           g.setPaintMode();

           g.setColor(Color.white);

           earth.hide(g);

           jupitor.hide(g);

         }

       g.setColor(Color.red ) ;

 //      g.drawString("over",100,130); for debugging only

       }

     public static void drawCircle(int x, int y, int r, Graphics g)

      {   g.drawOval(x-r,y-r,2*r,2*r);

      }

     public void drawLines5( int t, Graphics g)

      {   int x1,y1,x2,y2;

          x1= (int) ( xcentre +

             295 * Math.cos ( Math.toRadians(t)));

          y1= (int) ( ycentre +

             295 * Math.sin ( Math.toRadians(t)));

          x2= (int) ( xcentre +

             (295+10) * Math.cos ( Math.toRadians(t)));

          y2= (int) ( ycentre +

             (295+10) * Math.sin ( Math.toRadians(t)));

          g.drawLine(x1,y1,x2,y2);

     }

 }

 

File retro1.html

 <body>

 <applet code="retro1" width="700" height="500"></applet>

 #x003C;/body>

The following figure is a snapshot of the output.

 

Output

Retrograde Demo

Please note that the Sun is shown in red, Earth in blue, and Jupiter in yellow. Program runs for two rounds of Earth around the Sun, that is two years time. A green straight line is for the proof that the position of Jupiter shown on the zodiac is genuine. The outer red circle represents zodiac. A small green dot indicates visible position of the Jupiter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.255.187