import java.awt.*; import java.awt.Graphics; import java.awt.Image; import java.util.Vector; import java.util.*; import java.applet.*; public class AlgebraTiles extends Applet { AlgebraTilesCanvas canvas; Button NewQuadraticButton, StraightenButton; int DifficultyLevel; boolean Practice; MessageCanvas message; public void init() { System.out.println("Begin of init"); setLayout( new BorderLayout() ); String param = getParameter("practice"); if ( param==null || ! param.equalsIgnoreCase("no") ) Practice = true; else Practice = false; param = getParameter("difficulty"); if ( param==null || param.equals("1") ) DifficultyLevel=1; else if ( param.equals("2") ) DifficultyLevel=2; // else if ( param.equals("3") ) // DifficultyLevel=3; else DifficultyLevel=1; canvas = new AlgebraTilesCanvas( size().width, size().height - 100 ); canvas.resize( size().width, size().height - 100 ); System.out.println("NewEquation"); newEquation(); add( "North", canvas ); System.out.println("new q panel"); Panel q = new Panel(); q.setLayout( new BorderLayout() ); // q.add("Center", new Label("test") ); Panel p = new Panel(); p.setLayout( new BorderLayout() ); p.setBackground( Color.white ); p.add("Center", new Label("Click on 'New Quadratic' for a new problem", Label.CENTER)); System.out.println("Before new buttons"); if ( Practice ) NewQuadraticButton = new Button("New Tiles"); else NewQuadraticButton = new Button("New Quadratic"); p.add("East", NewQuadraticButton ); StraightenButton = new Button("Straighten"); p.add("West", StraightenButton ); q.add("North", p ); message = new MessageCanvas(size().width, 75); q.add("South", message ); add("South", q); System.out.println("End of init"); } public boolean action(Event evt, Object what) { if ( evt.target == NewQuadraticButton ) { newEquation(); message.setMessage("New Equation"); } else if ( evt.target == StraightenButton ) { canvas.StraightenTiles(); message.setMessage("Straighten Tiles"); } else return super.action(evt,what); return true; } void newEquation() { int n1=0,n2=0,n3=0,n4=0; n1 = getRandom(2,-1); n3 = getRandom(3,-1); n2 = getRandom(5,2); n4 = getRandom(7,3); if ( DifficultyLevel==1 || Practice ) { n2 = Math.abs( n2 ); n4 = Math.abs( n2 ); } canvas.newEquation(n1*n3,n2*n3,n1*n4,n2*n4, Practice); System.out.println("End of newEquations"); } int getRandom(int n, int m) { return (int)( Math.floor( Math.random() * n ) - m ); } } class AlgebraTilesCanvas extends Canvas { int Width, Height; Font font, smfont; FontMetrics fm, smfm; Image osI; Graphics osG; Color bgColor = new Color( 46, 130, 46); int Acoef=0, B1coef=0, B2coef, Bcoef, Ccoef=0; String Quadratic = ""; int strWidth=0, strHeight; Vector Tiles; int currTile = -1, xoff, yoff; boolean Practice; public AlgebraTilesCanvas(int w, int h) { Width = w; Height = h; osI = null; font = new Font( "TimesRoman", Font.BOLD, 14 ); fm = getFontMetrics( font ); smfont = new Font( "TimesRoman", Font.BOLD, 12 ); smfm = getFontMetrics( smfont ); setFont( font ); strHeight = 3*fm.getAscent()/2; Tiles = new Vector(0); } public void newEquation(int a, int b1, int b2, int c, boolean practice) { Practice = practice; Acoef = a; B1coef = b1; B2coef = b2; Bcoef = B1coef + B2coef; Ccoef = c; boolean Reduced = true; while ( Reduced ) { Reduced = false; if ( (Acoef%2==0) && (Bcoef%2==0) && (Ccoef%2==0) ) { Acoef /= 2; B1coef /= 2; B2coef /= 2; Ccoef /= 2; Reduced = true; } else if ( (Acoef%3==0) && (Bcoef%3==0) && (Ccoef%3==0) ) { Acoef /= 3; B1coef /= 3; B2coef /= 3; Ccoef /= 3; Reduced = true; } Bcoef = B1coef + B2coef; } Tiles = createTiles(); // if ( Acoef>1 ) // Quad1= Acoef + "x^2"; // Quadratic = Acoef + "x^2 + " + (B1coef+B2coef) + "x + "+ Ccoef; // strWidth = fm.stringWidth( Quadratic ); repaint(); } /* StraightenTiles Find tiles which are close to being lined up either horizontally or vertically. Algorithm depends on the fact that tiles are ordered according to size. */ public void StraightenTiles() { int tol = 8; for (int i=0;i=0;i--) { Tile tile1 = (Tile)Tiles.elementAt(i); for (int j=i-1; j>=0; j--) { Tile tile2 = (Tile)Tiles.elementAt(j); if ( Math.abs( tile1.ypos - tile2.ypos ) < tol ) tile2.ypos = tile1.ypos; if ( Math.abs(tile1.ypos + tile1.height - tile2.ypos) < tol ) tile2.ypos = tile1.ypos + tile1.height; if ( Math.abs( tile1.xpos - tile2.xpos ) < tol ) tile2.xpos = tile1.xpos; if ( Math.abs(tile1.xpos + tile1.width - tile2.xpos) < tol ) tile2.xpos = tile1.xpos + tile1.width; } } repaint(); } public boolean isCorrect() { return true; } private Vector createTiles() { currTile = -1; Vector tiles; tiles = new Vector(); int i, sgn; if ( Acoef<0 ) sgn = -1; else sgn = 1; Tile tmptile = new Tile(2,2,1); for (i=0;i=0;i--) { Tile tile = (Tile)Tiles.elementAt(i); if ( tile.inside(x,y) ) { currTile = i; xoff = x - tile.xpos; yoff = y - tile.ypos; repaint(); return true; } } currTile = -1; return super.mouseDown(evt,x,y); } public boolean mouseDrag(Event evt, int x, int y) { if ( currTile>=0 ) { Tile tile = (Tile)Tiles.elementAt( currTile ); tile.move(x-xoff,y-yoff); repaint(); return true; } return super.mouseDrag(evt,x,y); } public boolean keyDown(Event evt, int key) { if ( (currTile>=0) && (key==32) ) { Tile tile = (Tile)Tiles.elementAt(currTile); tile.flip(); repaint(); return true; } return super.keyDown( evt, key ); } public void paint(Graphics g) { if ( osI==null ) { osI = createImage( Width, Height); if ( osI==null ) { System.out.println("osI is null. bailing . . ."); System.exit(1); } osG = osI.getGraphics(); } osG.setColor( bgColor ); osG.fillRect( 0, 0, Width, Height ); osG.setColor( new Color( 215, 255, 215) ); osG.drawRect( 0, 0, Width-1, Height-1 ); if ( ! Practice ) drawEquation(osG); /* osG.setColor( Color.black ); osG.fillRect( 0, 95, 205, 3 ); osG.fillRect( 205, 0, 3, 95 ); osG.setColor( new Color(215, 255, 215) ); osG.drawLine( 0, 97, 97, 97 ); osG.drawLine( 97, 0, 97, 97 ); */ for (int i=0; i= 0 ) { Tile tile = (Tile)Tiles.elementAt(currTile); tile.paint(osG, true, Practice); } g.drawImage(osI,0,0,this); } private void drawEquation(Graphics g) { int xp = Width - 3; String tmp; g.setFont( font ); if ( Ccoef != 0 ) { if ( Ccoef > 0 ) tmp = " + " + Ccoef; else tmp = " - " + Math.abs(Ccoef); xp -= fm.stringWidth(tmp); g.drawString( tmp, xp, strHeight ); } if ( Bcoef != 0 ) { if ( Bcoef > 1 ) tmp = " + " + Bcoef +"x"; else if ( Bcoef == 1 ) tmp = " + x"; else if ( Bcoef < -1 ) tmp = " - " + Math.abs(Bcoef) + "x"; else // Bcoef==-1 tmp = " - x"; xp -= fm.stringWidth(tmp); g.drawString( tmp, xp, strHeight ); } g.setFont( smfont ); xp -= smfm.stringWidth("2"); g.drawString("2", xp, strHeight / 2+2 ); g.setFont( font ); if ( Acoef > 1 ) tmp = "" + Acoef + "x"; else if ( Acoef==1 ) tmp = "x"; else if ( Acoef==-1 ) tmp = "-x"; else tmp = "-" + Math.abs(Acoef) +"x"; xp -= fm.stringWidth(tmp); g.drawString( tmp, xp, strHeight ); g.drawRect( xp - 5, 0, Width-xp+5, strHeight+5 ); } public void update(Graphics g) { paint(g); } } /* type Value 1 1 2 X */ class Tile extends Object { int Base = 21; int WidthType, HeightType; public int xpos, ypos, width, height; Color color; String WidthString, HeightString; public Tile(int wtype, int htype, int x, int y, int sign) { initialize( wtype, htype, sign ); xpos = x; ypos = y; } public Tile(int wtype, int htype, int sign) { initialize( wtype, htype, sign ); xpos = 0; ypos = 0; } private void initialize(int wtype, int htype, int sign) { WidthType = wtype; HeightType = htype; if ( WidthType==1) width = Base; else if ( WidthType==2 ) width = 13*Base/3; else width = 0; if ( HeightType==1 ) height = Base; else if ( HeightType==2 ) height = 13*Base/3; else height = 0; if ( sign < 0 ) color = new Color( 100, 75, 75 ); else color = new Color( 235, 190, 190 ); if ( (sign<0) && ( WidthType==1 ) ) WidthString = "-1"; else if ( (sign>0) && ( WidthType==1 ) ) WidthString = "1"; else if ( (sign<0) && ( WidthType==2 ) ) WidthString = "-X"; else if ( (sign>0) && ( WidthType==2 ) ) WidthString = "X"; else WidthString = ""; if ( (sign<0) && ( HeightType==1 ) ) HeightString = "-1"; else if ( (sign>0) && ( HeightType==1 ) ) HeightString = "1"; else if ( (sign<0) && ( HeightType==2 ) ) HeightString = "-X"; else if ( (sign>0) && ( HeightType==2 ) ) HeightString = "X"; else HeightString = ""; } public void move(int x, int y) { xpos = x; ypos = y; } public void flip() { int tmp = width; width = height; height = tmp; tmp = WidthType; WidthType = HeightType; HeightType = WidthType; String tstr = WidthString; WidthString = HeightString; HeightString = tstr; } public boolean inside(int x, int y) { if ( ( x >= xpos) && (x <= xpos + width) && ( y >= ypos) && (y <= ypos + height) ) return true; return false; } public void paint(Graphics g, boolean active, boolean practice) { g.setColor( color ); g.fillRect( xpos, ypos, width, height ); g.setColor( Color.black ); g.drawRect( xpos, ypos, width-1, height-1 ); g.drawRect( xpos+1, ypos+1, width-3, height-3 ); if ( ! practice ) { g.drawString( HeightString, xpos+3, ypos+height/2+5 ); g.drawString( WidthString, xpos+width/2-5, ypos-1 ); } if (active) { g.setColor( Color.red ); g.drawRect( xpos, ypos, width-1, height-1 ); } } }