CS 100: Programming Assignment P4

Solution


public class Date
{
   // An instance of this class is a particular date.
   
   private String month;    
   private int day;   
   private int year;
   
   // "Moon" constants.
   
   // T is the average time (in days) between new Moons.
   public static final double T = 29.530588;  // 29 days + 12 hours + 44 minutes + 2.8 seconds
 
   // tBase is the time (in days) since the last new Moon at the (GMT) start of January 1, 1600.
   public static final double tBase    = 14.532069;
   
   
   // Constructor. Creates a Date object with month s, day d, and year y.
   public Date(String s, int d, int y)
   {
      month = s;
      day   = d;
      year  = y;
   }
   
     
   // Yields the relative index of this date. 
   // (Days are indexed from 1 starting with January 1.)
   public int relDayIndex()
   {
       int s;
       if (month.equals("January"))
          s = day;
       else if (month.equals("February"))
          s = day+31;
       else if (month.equals("March"))
          s = day+59;
       else if (month.equals("April"))
          s = day+90;
       else if (month.equals("May"))
          s = day+120;
       else if (month.equals("June"))
          s = day+151;
       else if (month.equals("July"))
          s = day+181;
       else if (month.equals("August"))
          s = day+212;
       else if (month.equals("September"))
          s = day+243;
       else if (month.equals("October"))
          s = day+273;
       else if (month.equals("November"))
          s = day+304;
       else
          s = day+334;
       
       // Make leap year adjustment.
       boolean marchOrLater = !(month.equals("January") || month.equals("February"));
       if (leapYear(year) && marchOrLater)
          return s+1;
       else
          return s;         
   }
   
   // Yields a string that specifies this date.
   public String prettyDate()
      {return month + " " + day + ", " + year;}
      
   // Yields true if y is a leap year.
   public static boolean leapYear(int y)
   {
      if (y%100==0)
         return (y%400==0);
      else
         return (y%4==0);
   }
   
   // Yields the absolute index of this date. 
   // (Days are indexed from 1 starting with January 1, 1600.)
   public int absDayIndex()
   {
      int s=0;
      for(int y=1600;y<=year-1;y++)
      {
         if (leapYear(y))
            s = s+366;
         else
            s = s+365;
      }
      s = s + relDayIndex(); 
      return s;       
   }
   
   // Yields the number of days since the "base" new moon.
   public double sinceBaseNewMoon()
   {
      return (absDayIndex() + tBase - 1);
   }
   
   // Yields true if the Moon is waxing t days after a new Moon.  
   public static boolean isWaxing(double t)
   { 
       double whatsLeft = t - Math.floor(t/T)*T;
       return (whatsLeft <= T/2);
   }
       
}






// Checks the methods leapYear, prettyDate, and relDayIndex.
import java.io.*;
public class P4A
{	
	public static void main(String args[])
	{
       TokenReader in = new TokenReader(System.in);
       
       
       // Print the leap years from 1892 to 2012.
	    
	   System.out.println("Leap years during 1892-2012:\n");
	   int count=0;
	   for (int yr=1892;yr<=2012;yr++)
	   {
	      if (Date.leapYear(yr))
	      {
	         System.out.print("   " + yr);
	         count++;
	         if (count%10==0)
	            System.out.println("");
	      }
	   }
	   
	   // Display the relative day indices for the first of each month
	   // during year y.
	   
	   int y = 1996;
	   
	   Date D;
	   System.out.println("\nSome relative day indices:\n");
	   D = new Date("January",1,y);
	   Format.println(System.out,"     %3d = " + D.prettyDate(),D.relDayIndex());
	   
	   D = new Date("February",1,y);
	   Format.println(System.out,"     %3d = " + D.prettyDate(),D.relDayIndex());
	   
	   D = new Date("March",1,y);
	   Format.println(System.out,"     %3d = " + D.prettyDate(),D.relDayIndex());
	   
	   D = new Date("April",1,y);
	   Format.println(System.out,"     %3d = " + D.prettyDate(),D.relDayIndex());
	   
	   D = new Date("May",1,y);
	   Format.println(System.out,"     %3d = " + D.prettyDate(),D.relDayIndex());
	    
	   D = new Date("June",1,y);
	   Format.println(System.out,"     %3d = " + D.prettyDate(),D.relDayIndex());
	   
	   D = new Date("July",1,y);
	   Format.println(System.out,"     %3d = " + D.prettyDate(),D.relDayIndex());
	   
	   D = new Date("August",1,y);
	   Format.println(System.out,"     %3d = " + D.prettyDate(),D.relDayIndex());
	   
	   D = new Date("September",1,y);
	   Format.println(System.out,"     %3d = " + D.prettyDate(),D.relDayIndex());
	   
	   D = new Date("October",1,y);
	   Format.println(System.out,"     %3d = " + D.prettyDate(),D.relDayIndex());
	   
	   D = new Date("November",1,y);
	   Format.println(System.out,"     %3d = " + D.prettyDate(),D.relDayIndex());
	   
	   D = new Date("December",1,y);
	   Format.println(System.out,"     %3d = " + D.prettyDate(),D.relDayIndex());
	   
	   
	   in.waitUntilEnter();   
     }
}

/*
Output:

Leap years during 1892-2012:

   1892   1896   1904   1908   1912   1916   1920   1924   1928   1932
   1936   1940   1944   1948   1952   1956   1960   1964   1968   1972
   1976   1980   1984   1988   1992   1996   2000   2004   2008   2012

Some relative day indices:

       1 = January 1, 1996
      32 = February 1, 1996
      61 = March 1, 1996
      92 = April 1, 1996
     122 = May 1, 1996
     153 = June 1, 1996
     183 = July 1, 1996
     214 = August 1, 1996
     245 = September 1, 1996
     275 = October 1, 1996
     306 = November 1, 1996
     336 = December 1, 1996

*/

// Checks the methods absDayIndex and elapsed.
import java.io.*;
public class P4B
{	
	public static void main(String args[])
	{
       TokenReader in = new TokenReader(System.in);
	   
	   System.out.println("\nSome Absolute Day Indices:\n");
	   Date D1 = new Date("July",4,1776);
	   Date D2 = new Date("August",27,1998);
	   Date D3 = new Date("March",11,1999);
	   D3 = new Date("January",9,1997);
	   
	   Format.println(System.out,"%8d = " + D1.prettyDate(),D1.absDayIndex());
	   Format.println(System.out,"%8d = " + D2.prettyDate(),D2.absDayIndex());
	   Format.println(System.out,"%8d = " + D3.prettyDate(),D3.absDayIndex());
	   
	   System.out.println("\nThe associated values of sinceBaseNewMoon:\n");
	   double t1 = D1.sinceBaseNewMoon();
	   Format.println(System.out,"%14.4f = " + D1.prettyDate(),t1);
	   double t2 = D2.sinceBaseNewMoon();
	   Format.println(System.out,"%14.4f = " + D2.prettyDate(),t2);
	   double t3 = D3.sinceBaseNewMoon();
	   Format.println(System.out,"%14.4f = " + D3.prettyDate(),t3);
	   
	   System.out.println("\nWaxing or Waning?:\n");
	   if (Date.isWaxing(t1))
	      { System.out.println("The Moon is waxing on " + D1.prettyDate()); }
	   else
	      { System.out.println("The Moon is waning on " + D1.prettyDate()); }
	      
	   if (Date.isWaxing(t2))
	      { System.out.println("The Moon is waxing on " + D2.prettyDate()); }
	   else
	      { System.out.println("The Moon is waning on " + D2.prettyDate()); }
	   
	   if (Date.isWaxing(t3))
	      { System.out.println("The Moon is waxing on " + D3.prettyDate()); }
	   else
	      { System.out.println("The Moon is waning on " + D3.prettyDate()); }
	      
	      
	      
       in.waitUntilEnter();
     }
}

/*
Output:

Some Absolute Day Indices:

   64469 = July 4, 1776
  145606 = August 27, 1998
  145011 = January 9, 1997

The associated values of sinceBaseNewMoon:

    64482.5321 = July 4, 1776
   145619.5321 = August 27, 1998
   145024.5321 = January 9, 1997

Waxing or Waning?:

The Moon is waning on July 4, 1776
The Moon is waxing on August 27, 1998
The Moon is waning on January 9, 1997

*/

import java.awt.*;
public class MoonPhase extends Frame
{
    
    // Graphics g draws a moon with t-value t0. 
    // The center is at (hc,vc) and the radius is r.
    public static void drawMoon(Graphics g, int hc, int vc, int r, double t0)
    {
      // Draw a darkened moon and set the "ink" to the chosen illumination color.
      g.setColor(Color.black);
      g.fillOval(hc-r,vc-r,2*r,2*r);
      g.setColor(Color.yellow);
      
      double dh;  // Half the length of the current "coloring" line segment".
      int hLeft;  // Left  endpoint  of the current "coloring" line segment".
      int hRight; // Right endpoint  of the current "coloring" line segment".
      
      
      // Illuminate the moon by drawing appropriately colored horizontal line segments.
      for(int v=vc+r;v>=vc-r;v=v-1)
      {
         // Draw the illumination line segment having vertical component v.
         dh = Math.sqrt(r*r-(v-vc)*(v-vc));
         
         // Its endpoints depend on whether the moon is in the first or second half
         // of its revolution.
         
         if (Date.isWaxing(t0))
         {
            // Between new moon and full moon so the illumination is in the "right" half.
            hLeft  = (int) (hc + Math.cos(2*Math.PI*t0/Date.T)*dh);
            hRight = (int) (hc + dh);
         }
         else
         {
            // Between full moon and new moon so the illumination is in the "left" half.
            hLeft  = (int) (hc - dh);
            hRight = (int) (hc - Math.cos(2*Math.PI*t0/Date.T)*dh);
         }
         g.drawLine(hLeft,v,hRight,v);
      }
      
    }
    
    // Graphics g draws a moon row.
    // A moon row is a horizontal row of 7 moons all with radius r. 
    // The leftmost moon has center (hc,vc).
    // The moon centers all have vertical component vc.
    // The center-to-center spacing of the moons equals 3*r.
    // Left-to-right the moons have t-values equal to t0,t0+1,...,t0+6 respectively.
    public static void drawWeekOfMoons(Graphics g, int hc, int vc, int r, double t0)
    {
       int h;     // The horizontal coordinate of the current moon.
       double t;  // The t-value of the current moon. 
       h = hc;
       t = t0;
       for(int k=1;k<=7;k++)
       {
          drawMoon(g,h,vc,r,t);
          t++;
          h=h+3*r;
       }
    }
    
    // Graphics g draws 5 moon rows. 
    // All moons have radius r.
    // The leftmost moon of the top moon row has center (hc,vc).
    // The vertical spacing of the moon rows is 3*r.
    // Top to bottom, the leftmost moons in each moon row have t-values equal to
    // t0,t0+7,t0+14,t0+21,and t0+28 respectively.
    public static void drawMonthOfMoons(Graphics g, int hc, int vc, int r, double t0)
    {
       int v;     // The vertical coordinate of the current moon row.
       double t;  // The t-value of the leftmost moon in the current moon row.
       v = vc;
       t = t0;
       for(int k=1;k<=5;k++)
       {
          drawWeekOfMoons(g,hc,v,r,t);
          t=t+7;
          v=v+3*r;
       }
    }
	public void paint(Graphics g)
	{
	  // drawMoon(g,300,300,100,10);
	  // drawMoon(g,600,300,100,20);
	  // drawWeekOfMoons(g,100,200,30,0.0);
	  // drawWeekOfMoons(g,100,300,30,16.0);
	  // drawMonthOfMoons(g,100,100,30,0.0);
	  
	  
	         
	  // Date D = new Date("December", 25, 1776);      // Washington crosses the Delaware
	  // Date D = new Date("June",6,1944);             // D-Day
	  // Date D = new Date("July",20,1969);            // Man on Moon
	   
	  Date D = new Date("February",21,1999); 
	  
	 
	  
	  double t0 = D.sinceBaseNewMoon();
	  drawMonthOfMoons(g,100,100,30,t0);
	  g.setFont(new Font("TimesRoman",Font.BOLD,24));
	  g.setColor(Color.black);
	  String s = D.prettyDate();
	  g.drawString(s,300,550);
	  
	}
	
}

public class P4C
{
	public static void main(String args[])
	{
		MoonPhase d = new MoonPhase();
		d.resize(800,600);                    
		d.move(0,75);
		d.setTitle("Moons");                 
		d.show();
		d.toFront();
	}
}