⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abacus.java

📁 java编程的一些Applets例子。值得深入研究一下。
💻 JAVA
字号:

/*
 * Copyright (c) 1995 Luis Fernandes
 *
 * Permission to use, copy, hack, and distribute this software and its
 * documentation for NON-COMMERCIAL purposes and without fee is hereby
 * granted provided that this copyright notice appears in all copies.
 * 
 */

/* $Id: Abacus.java,v 1.1 1995/09/25 20:15:07 elf Exp elf $ */

/* $Log: Abacus.java,v $
 * Revision 1.1  1995/09/25  20:15:07  elf
 * Initial revision
 */ 

import java.awt.*;

/** This is a java-applet simulation of a Chinese abacus. 
 *
 * Each column is stored internally in an integer array called
 * 'column' that is initialized to represent the resting positions of
 * the beads: 2 bead on top deck row-pos 0 & 1, pos 2 empty; 5 beads
 * lower deck pos 4-8, pos 3 empty. The initial value is
 * 499d=111110011 where a '1' represents a position that is occupied
 * by a bead and a '0' represents an empty position. As the beads are
 * moved, the 1's are shifted (using << and >>) accordingly to
 * represent their new locations.
 *
  
   The illustration below represents 1 column of the abacus.

<pre> 
   O represents the bead; 
   | represents an empty position (the rod)
   = represents the frame
  
  	=============	Row Position (index 'r' )
  		O			0
  		O			1			Upper Deck
  		|			2
  	=============
  		|			3
  		O			4
  		O			5			Lower Deck
  		O			6
  		O			7
  		O			8
	=============
</pre>
 
   @author Luis Fernandes

*/

public class Abacus extends java.applet.Applet 
{
  /*  initial attributes of the abacus*/
  static final int MAXCOLS=10;	/* number of columns the abacus will have */
  
  static final int BEADHEIGHT=17;
  static final int BEADWIDTH=17;
  static final int FRAMEWIDTH=10; /* thickness of the frame*/

  static final int COLGAP=2;	/* gap between 2 cols*/
  static final int ROWGAP=2;	/* gap between 2 rows*/
  
  static final int NTOPROWS=3;	/*(2 beads, 1 gap on top-deck)*/
  static final int NBOTROWS=6;	/*(5 beads, 1 gap on top-deck)*/

  static final int NCOLS=MAXCOLS; /* number of columns*/
  static final int NROWS=(NTOPROWS+NBOTROWS); /* number of rows*/
  
  static final int MIDFRAME=(FRAMEWIDTH+(NTOPROWS*BEADHEIGHT)+((NTOPROWS+1)*ROWGAP));
  
  //size().width & size().height of window depends on attributes of the abacus
  static final int INITWIDTH=((2*FRAMEWIDTH)+(NCOLS*BEADWIDTH)+((NCOLS+1)*COLGAP));
  static final int INITHEIGHT=((3*FRAMEWIDTH)+(NROWS*BEADHEIGHT)+((NROWS+1)*ROWGAP));
  
  private int column[]=new int[MAXCOLS];
  
  private int cx, cy;	// for xlating x,y to row,col
  private int ux, uy;	// for clipping region

  private boolean overflow;	// when the abacus overflows this is true
  private boolean carry; // when a calc causes a carry to the next col 
  
  Image bead, nobead;			// holds picture of a bead and an empty loc
  Font valueFont;				// to paint the value

  /**
	Initialize the Abacus by initializing the internal column
	array. If a "VALUE" resource is specified, set the column array
	according to it, instead.
	*/

  public 
	void init()
	  {
		
		String valattr;
		
		/* Init the internal configuration of the beads: 499d=111110011
		 * (2 bead on top deck pos 0 & 1; 5 beads lower deck pos 4-8,
		 * pos 2 & 3 are empty initially) */
		for(int i=0; i<MAXCOLS; i++) column[i]=499;
		
		/* check for user-specified value resource*/

		valattr=getParameter("value");
/*		System.out.println("==>"+valattr); */

		if((valattr==null) || (valattr.length()>MAXCOLS) )
		  {
			/* if no attribute is specified, or the value is too big,
			 * use default*/
			System.out.println(valattr+"(VALUE resource) is either too big or unspecified; ignoring.\n"); 

		  }
		else		/* set each column according to the user-specified value*/
		  {
			int len=valattr.length();
			
			for(int i=0; i<len; i++)
			  {
				int val=Integer.valueOf(valattr.substring(i,i+1)).intValue();
				
				// set value in the upper-deck
				if(val>4)
				  {	
/*					System.out.println("Col "+i+"%5="+val%5); */
					
					animateBead(1, i);
				  }

				// set value in the lower-deck 
				int remainder=val%5;
				
				if(remainder>0)
				  {
					animateBead(3+remainder, i);
				  }
			  }
		  }
		
		bead=getImage(getCodeBase(), "images/diamond.gif");
		nobead=getImage(getCodeBase(), "images/nodiamond.gif");

		valueFont=new java.awt.Font("Courier", Font.BOLD, 10);
		
		resize(INITWIDTH, INITHEIGHT); /* initial size */
		
	  }
  
  private 
	void displayValue(Graphics g)
	  {
		char valchars[]= new char [MAXCOLS*3];

		String value= new String (valchars);
		
		if(overflow) value+="*";
		
		/* look at each column*/
		for(int col=0; col<MAXCOLS; col++)
		  {
			int r;
			int val=0;
			
			/* find the empty row, and determine what the value is*/
			/* top-deck*/
			for(r=2; r>=0; r--)
			  {
				if(!RowOccupied(r, column[col])) break;
			  }

			val+=((2-r)*5);
			
			/* bottom-deck*/
			for(r=3; r<9; r++)
			  {
				if(!RowOccupied(r, column[col])) break;
			  }

			val+=(r-3);
			
/*			System.out.println("\tColumn"+col+"value="+val);*/

			value=value+" "+Integer.toString(val);
			
		  }

		if(overflow)
		  g.setColor(Color.red);
		else 
		  g.setColor(Color.yellow);

		g.drawString(value, 5, 10);
		
	  }
  
  /**
	Draw the abacus (draw the frame, draw the rods & draw the
	beads). Display the value in the frame.  */
  public 
	void paint(Graphics g)
	  {
	      if (bead == null) {
			return;
	      }

		  drawFrame(g);

		  for(int i=0; i<MAXCOLS; i++)
			{
			  drawColumn(g, i);
			}

		  displayValue(g);
		
	  }/* init()*/
  
  public void update(Graphics g) 
	{
	  paint(g);
	  g.setColor(Color.black);
	  g.fillRect(0,0,INITWIDTH, FRAMEWIDTH);
	  displayValue(g);
    }

  /**
	Handle a mouse-click.
	
	Convert the x/y position of the click to a row/column equivalent
	and move the corresponding bead.
	@param evt is the internal AWT event varaible
	@param x is the x-position of the click, in pixels
	@param y is the y-position of the click, in pixels
	
	@return ux as a global (used for clipping calculations)
	@return uy as a global (used for clipping calculations)

	*/
  public 
	boolean mouseUp(java.awt.Event evt, int x, int y) {
	  
	  /* row,col returned in cx,cy*/
	  boolean i=translateXY2RowCol(x, y);
	  
	  if(i)						/*valid row,col...*/
		{

		  if(RowOccupied(cy,column[cx]))
			{
			  animateBead(cy,cx);

			  ux=FRAMEWIDTH+(cx*(COLGAP+BEADWIDTH));

			  uy=FRAMEWIDTH+(cy*(ROWGAP+BEADHEIGHT));
			  repaint();
			  
			}
		}
	  return true;
	} /*mouseUp()*/


  private 
	void drawColumn(Graphics g, int col)
	  {
		
		for(int beadnum=0; beadnum<9; beadnum++) 
		  {
			if(RowOccupied(beadnum,column[col]))
			  {
				drawBead(g, beadnum, col);
			  }
			else
			  {
				undrawBead(g, beadnum, col);
			  }
		  }
		
	  } /*drawColumn()*/
  
  private 
	void drawBead(Graphics g, int row, int col)
	  {
		
		if(row<3)				/* beads in the top-deck */
		  {
			g.drawImage(bead, FRAMEWIDTH+COLGAP+(col*(BEADWIDTH+COLGAP)), 
						FRAMEWIDTH+(row*(BEADHEIGHT+ROWGAP))+2, this);
		  }
		else					/* account for the middle-rail */
		  {
			g.drawImage(bead, FRAMEWIDTH+COLGAP+(col*(BEADWIDTH+COLGAP)), 
						(2*FRAMEWIDTH)+(row*(BEADHEIGHT+ROWGAP))+2, this); 
		  }
		
	  } /*drawBead()*/

  private 
	void undrawBead(Graphics g, int row, int col)
	  {
		
		if(row<3)				/* beads in the top-deck */
		  {
			g.drawImage(nobead, FRAMEWIDTH+COLGAP+(col*(BEADWIDTH+COLGAP)), 
						FRAMEWIDTH+(row*(BEADHEIGHT+ROWGAP))+2, this);
		  }
		else					/* account for the middle-rail */
		  {
			g.drawImage(nobead, FRAMEWIDTH+COLGAP+(col*(BEADWIDTH+COLGAP)), 
						(2*FRAMEWIDTH)+(row*(BEADHEIGHT+ROWGAP))+2, this); 
		  }
		
	  } /*undrawBead()*/



  private 
	void drawFrame(Graphics g)
	  {

		g.setColor(Color.blue);

		/* the rails*/
		for(int i=0; i<NCOLS; i++)
		  g.drawLine(FRAMEWIDTH+COLGAP+(BEADWIDTH/2)+(i*(BEADWIDTH+COLGAP)), 0,
					 FRAMEWIDTH+COLGAP+(BEADWIDTH/2)+(i*(BEADWIDTH+COLGAP)), 
					 INITHEIGHT);

		g.setColor(Color.black);
		
		g.fillRect(0,0,INITWIDTH, FRAMEWIDTH); /*top bar*/
		g.fillRect(0,INITHEIGHT-FRAMEWIDTH, INITWIDTH, FRAMEWIDTH); /*bot bar*/
		
		g.fillRect(INITWIDTH-FRAMEWIDTH, 0, INITWIDTH, INITHEIGHT); /*right bar*/
		g.fillRect(0,0, FRAMEWIDTH, INITHEIGHT-FRAMEWIDTH); /*left bar*/

		/* middle bar*/
		g.fillRect(0, MIDFRAME, INITWIDTH, FRAMEWIDTH);

	  }/*drawFrame()*/
  
  /**
	* Moves the bead specified by r & c in the appropriate direction
	*
	* @param r is the row number for the bead
	* @param c is the column number for the bead
	*/
  public 
	void animateBead(int r, int c)
	  {
		
		if(r<3)						/* selection in upper deck*/
		  {
			int i;
			
			/* find empty row in upperdeck; pos 0,1,2*/
			for(i=0; i<3; i++) if(!RowOccupied(i,column[c])) break;
			
			if(i<r)		/* if empty row is above cur bead...*/
			  moveBeadUp(r,c);
			else
			  moveBeadDn(r,c);
		  }
		else						/* selection in lower deck*/
		  {
			int i;
			
			/* find empty row in lowerdeck; pos 3-8 */
			for(i=3; i<9; i++) if(!RowOccupied(i,column[c])) break;
			
			if(i<r)     /* if empty row is above cur bead...*/
			  moveBeadUp(r,c);
			else
			  moveBeadDn(r,c);

		  }


	  }/*animateBead()*/
  
  private 
	void moveBeadUp(int r, int c)
	  {
		/* keep looking for an empty position directly above*/
		if(RowOccupied(r-1,column[c])) moveBeadUp(r-1,c);
		
		column[c]=column[c]-(1<<r); /* row 'r' is now empty */
		column[c]=column[c]+(1<<((r-1))); /* row 'r-1' now is occupied*/

		// check whether we have to carry to next column
		if(!RowOccupied(0,column[c]))
		  {
			System.out.println("Carry to col"+(c-1));
			carry=true;
		  }
		else if(c==0 && r==1)
		  {
			overflow=false;
		  }			
		
	  } /*moveBeadUp()*/
  
  private 
	void moveBeadDn(int r, int c)
	  {

		/* keep looking for an empty position directly below*/
		if(RowOccupied(r+1,column[c])) moveBeadDn(r+1,c);

		column[c]=column[c]-(1<<r); /* row 'r' is now empty */
		column[c]=column[c]+(1<<((r+1))); /* row 'r+1' now is occupied*/

		// check whether we have to carry to next column if in the top frame
		if(!RowOccupied(0,column[c]) && r<3)
		  {
			if(c==0)
			  {
				System.out.println("***OVERFLOW***");
				overflow=true;
				return;
			  }
			
			
			System.out.println("Carry to col"+(c-1));
			carry=true;
		  }


	  }/* moveBeadDown()*/

  
	/** translateXY2RowCol, converts x,y coord a row,col coord. The top
	 * deck has 3 rows (1 is empty), the bottom deck has 6 rows (1 is
	 * empty). Row # 3 is invalid because the middle-frame occupies this
	 * position. Coordinates for the bottom deck are adjusted for this
	 * anomaly, i.e. row #4 on the screen, is actually index #3 into the
	 * Column array.
	 *
	 * @param absolute x,y coordinates representing the click-location
	 * @return as globals cx: the row (0-9) & cy: the col (0-NCOLS) index
	 * @return True if click was on a bead or empty position
	 * @return False if click was at mid-frame location 
	 */
	
	private 
	  boolean translateXY2RowCol(int x, int y)
		{
		  
		  cx=(x-FRAMEWIDTH)/(COLGAP+BEADWIDTH);
		  
		  if(cy<MIDFRAME)
			{
			  cy=(y-FRAMEWIDTH)/(ROWGAP+BEADHEIGHT);
			}
		  else	/* account for the middle-frame (+1 bead size().height) (+4 is fudge)*/
			{
			  cy=(y-((2*FRAMEWIDTH)-BEADHEIGHT))/(ROWGAP+BEADHEIGHT);
			}
		  
		  /* technically, the mid-frame occupies position 3 & click is invalid*/
		  if(cy==3) return(false);
		  
		  else if(cy>2)				/* if pos (row) is greater than 3 ...*/
			{	
			  cy--;					/* ...adjust by 1 row*/
			  return(true);
			}
		  else 
			{
			  return(true);
			}
		  
		}/*translateXY2RowCol()*/
  
  
  final private 
	boolean RowOccupied(int r, int c)
	  {
		
		if((c & 1<<(r))==0)
		  {
			return false;
		  }
		else
		  {
			return true;
		  }
		
	  }/*RowOccupied()*/

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -