// Mastermind Java implementation // By Karl Hörnell import java.awt.*; import java.lang.Math; public final class mastermind extends java.applet.Applet { int i,j,k; int pointX,pointY,pickX=-1,pickY=-1,dragX=-1,dragY=-1; int dotMap[],pointMap[],secretCol[]; static int shadX[]={0,8,142,142,136,136,0}, shadY[]={242,246,246,10,0,242,242}; int pickedCol=0,changedCol; int pickedDot,changedGrfx,currentRow; boolean drawBoard=true,gameGoing=false; boolean pickable[]={true,true,true,true,false,false}; boolean finished; Color lights[],darks[],darkGray; Image buffer,peg; Graphics bufg,pegg; Math m; public void init() { dotMap = new int[32]; // Holds colored pin info pointMap = new int[32]; // Holds B&W score pin info secretCol = new int[4]; // Holds computer's choice of colors lights = new Color[6]; darks = new Color[6]; darkGray=new Color(60,60,60); darks[0]=new Color(0,0,255); // Blue lights[0]=new Color(128,128,255); darks[1]=new Color(0,192,0); // Green lights[1]=new Color(64,255,64); darks[2]=new Color(255,0,0); // Red lights[2]=new Color(255,128,128); darks[3]=new Color(255,192,0); // Yellow lights[3]=new Color(255,255,70); darks[4]=new Color(210,150,0); // Orange lights[4]=new Color(245,185,0); darks[5]=new Color(255,0,255); // Purple lights[5]=new Color(255,128,255); buffer=createImage(250,250); // Prepare drawing buffers bufg=buffer.getGraphics(); peg=createImage(48,40); // Used for drawing peg symbol pegg=peg.getGraphics(); resize(250,250); clearBoard(); } public void clearBoard() // Reset all variables and prepare for game { for (i=0;i<32;i++) { dotMap[i]=-1; pointMap[i]=-1; } currentRow=0; for (i=0;i<4;i++) { secretCol[i]=-1; while (secretCol[i]<0) { k=(int)(m.random()*6); if (pickable[k]) secretCol[i]=k; } } repaint(); } // Various graphical elements public void fixBox(Graphics g,int x,int y,int w,int h,Color c) { g.setColor(c); g.fillRect(x,y,w,h); } public void fixDisc(Graphics g,int x,int y,int r,Color c) { g.setColor(c); g.fillOval(x,y,r,r); } public void fixCircle(Graphics g,int x,int y,int r,Color c) { g.setColor(c); g.drawOval(x,y,r,r); } public void boardDot(Graphics g,int x,int y,int c) { fixDisc(g,x+2,y+2,18,darkGray); fixDisc(g,x,y,18,darks[c]); fixDisc(g,x+1,y+1,14,lights[c]); fixDisc(g,x+3,y+3,6,Color.white); } public void boardHole(Graphics g,int x,int y) { fixDisc(g,x+5,y+5,7,Color.black); g.setColor(Color.lightGray); g.drawArc(x+4,y+4,9,9,-135,180); } public void pointDot(Graphics g,int x,int y,int c) { fixDisc(g,x+2,y+2,10,Color.black); if (c==1) { fixDisc(g,x,y,10,darkGray); g.setColor(Color.white); g.drawArc(x+2,y+2,7,7,70,130); } else { fixDisc(g,x,y,10,Color.white); fixDisc(g,x+3,y+3,4,Color.lightGray); fixDisc(g,x+5,y+5,4,Color.white); } } public void pointHole(Graphics g,int x,int y) { fixDisc(g,x+3,y+3,4,Color.black); g.setColor(Color.lightGray); g.drawArc(x+2,y+2,6,6,-135,180); } public void bigPeg(Graphics g, int c) { fixBox(pegg,0,0,48,40,Color.lightGray); fixDisc(pegg,0,0,40,darks[c]); fixDisc(pegg,2,2,29,lights[c]); fixDisc(pegg,7,6,8,Color.white); fixCircle(pegg,0,0,39,Color.black); fixBox(pegg,22,0,26,40,Color.lightGray); fixBox(pegg,22,15,26,10,darks[c]); fixBox(pegg,31,15,17,8,lights[c]); pegg.setColor(Color.black); pegg.drawLine(22,0,22,40); pegg.drawRect(22,15,25,10); g.drawImage(peg,188,46,this); } public boolean mouseDown(java.awt.Event evt, int x, int y) { int whichCol,i,j,k,l; // Peg placed? for (j=0;j<4;j++) if (((x-(23+j*21))*(x-(23+j*21))+ (y-(219-currentRow*28))*(y-(219-currentRow*28)) <100 )&& gameGoing) { pickedDot=currentRow*4+j; changedGrfx=0; drawBoard=false; repaint(); } // Color selected? for (i=0;i<3;i++) for (j=0;j<2;j++) if ((x-(185+j*40))*(x-(185+j*40))+ (y-(115+i*40))*(y-(115+i*40))<225) { whichCol=i*2+j; // New color if (gameGoing && pickable[whichCol]) { pickedCol=whichCol; changedGrfx=1; drawBoard=false; repaint(); } else if (!gameGoing) // Toggle color { changedCol=whichCol; pickable[changedCol]=!pickable[changedCol]; l=0; for (k=0;k<6;k++) if (pickable[k]) l++; if (l<2) pickable[changedCol]=!pickable[changedCol]; else { changedGrfx=2; drawBoard=false; repaint(); } } } // Start or End clicked? if ((x>174)&&(x<235)&&(y>217)&&(y<236)) { gameGoing=!gameGoing; if (gameGoing) { clearBoard(); } else { changedGrfx=3; drawBoard=false; repaint(); } } return false; } public void checkDots(Graphics g) // Check the pegs { boolean temp=true; int holdDots[]; int rightCol=0,rightPlace=0; for (j=0;j<4;j++) temp=(temp && (dotMap[currentRow*4+j]>=0)); if (temp) // Guess complete? { holdDots=new int[4]; for (j=0;j<4;j++) holdDots[j]=dotMap[currentRow*4+j]; for (i=0;i<4;i++) // Award white pegs for (j=0;j<4;j++) if (holdDots[j]==secretCol[i]) { pointMap[currentRow*4+rightCol++]=0; holdDots[j]=-1; j=4; } for (j=0;j<4;j++) // And black ones { if (secretCol[j]==dotMap[currentRow*4+j]) rightPlace++; } for (j=0;j=0) pointDot(g,101+k*12, 206-currentRow*28+j*12,pointMap[currentRow*4+j*2+k]); if (rightPlace==4) // All correct? { g.setColor(Color.black); g.drawString("WELL DONE!",168,20); currentRow=8; } currentRow++; if (currentRow>7) // Game over? { if (rightPlace<4) // Didn't make it? { g.setColor(Color.black); g.drawString("Sorry!",188,15); for (j=0;j<4;j++) boardDot(g,163+j*21,20,secretCol[j]); } gameGoing=false; g.setColor(Color.gray); g.fill3DRect(175,218,60,18,true); g.setColor(Color.white); g.drawString("Start",191,231); } } } public void paint(Graphics g) { bufg.setColor(Color.lightGray); // Clear offcreen image buffer bufg.fillRect(0,0,250,250); // Draw the board itself bufg.setColor(Color.gray); for (i=0;i<5;i++) bufg.fill3DRect(i,i,136-2*i,242-2*i,true); for (i=0;i<8;i++) { bufg.draw3DRect(10,10+i*28,88,25,false); bufg.draw3DRect(100,10+i*28,25,25,false); } bufg.fillPolygon(shadX,shadY,7); for (i=0;i<8;i++) { // Draw colored pins or just holes for (j=0;j<4;j++) if (dotMap[i*4+j]<0) boardHole(bufg,13+j*21,209-i*28); else boardDot(bufg,13+j*21,209-i*28,dotMap[i*4+j]); // Draw the score pins or holes for (j=0;j<2;j++) for (k=0;k<2;k++) if (pointMap[i*4+j*2+k]<0) pointHole(bufg,101+k*12,206-i*28+j*12); else pointDot(bufg,101+k*12, 206-i*28+j*12,pointMap[i*4+j*2+k]); } // Draw the right field bufg.setColor(Color.gray); bufg.fill3DRect(160,92,90,151,true); bufg.fill3DRect(161,93,88,149,true); bufg.setColor(Color.gray); bufg.fill3DRect(175,218,60,18,true); bufg.setColor(Color.white); if (gameGoing) bufg.drawString("End",195,231); else bufg.drawString("Start",191,231); for (i=0;i<3;i++) for (j=0;j<2;j++) { fixDisc(bufg,169+j*40,99+i*40,32,Color.black); fixDisc(bufg,170+j*40,100+i*40,30,darks[i*2+j]); fixDisc(bufg,171+j*40,101+i*40,25,lights[i*2+j]); fixDisc(bufg,175+j*40,105+i*40,7,Color.white); if (pickable[i*2+j]) fixCircle(bufg,168+j*40,98+i*40,34,Color.white); } bigPeg(bufg,pickedCol); g.drawImage(buffer,0,0,this); // Copy image buffer to screen } public void update(Graphics g) { if (drawBoard) paint(g); else { // Process small changes switch(changedGrfx) { case 0: // Peg placed in hole? i=pickedDot/4; j=pickedDot-i*4; dotMap[pickedDot]=pickedCol; boardDot(g,13+j*21,209-i*28,pickedCol); checkDots(g); break; case 1: // New color selected? bigPeg(g,pickedCol); break; case 2: // Color availability toggled? i=changedCol/2; j=changedCol-i*2; if (pickable[changedCol]) // Enable fixCircle(g,168+j*40,98+i*40,34,Color.white); else // Disable { fixCircle(g,168+j*40,98+i*40,34,Color.gray); if (pickedCol==changedCol) // Big peg color not allowed? { for (i=5;i>=0;i--) if (pickable[i]) j=i; pickedCol=j; bigPeg(g,pickedCol); } } break; case 3: // Given up? g.setColor(Color.gray); g.fill3DRect(175,218,60,18,true); g.setColor(Color.white); g.drawString("Start",191,231); break; default: break; } drawBoard=true; } } }