This is the Java source code of my memory applet.
Good luck.
Sieuwert van Otterloo
/*This applet plays memory
made by Sieuwert van Otterloo, 1998
*/
import java.awt.*;//basic
import java.applet.*;//because this is an applet
import java.net.*;//because we load gif files
public class memory extends Applet
//the main of the applet
{
table t;//the panel with the cards on it
Button newgame,surrender;//pressable buttons
Label l1;//to show the scores
public void init()//preparations
{
resize(9*table.SIZE+20,8*table.SIZE+50);
Panel buttons=new Panel();//to keep the button together
buttons.setLayout(new GridLayout(1,3,2,2));//3 positions
buttons.add(newgame=new Button("New game"));
buttons.add(surrender=new Button("Show me all"));
buttons.add(l1=new Label("Welcome to memory"));
add("Center",t=new table(this,l1));
add("South",buttons);
}
public boolean action(Event ev, Object obj)
/*a button is touched*/
{
if(ev.target==newgame)
t.randomcards();//shuffle the cards
else if(ev.target==surrender)
t.showall();//show all cards
return true;
}
}
class table extends Canvas
{
int[] visbuf;//what can be seen on table
int[] card;//where are the cards
/*card stores the places of the cards. A card entry is either NONE,
if the card that was originally there is removed,
or a picturenumber (0 to and including 35).
Visbuf can also have the value BACK, if the back of the
card is visible. */
Applet applet;//needed to get the documentbase
final static int TOTAL=72;//total # of cards in play
final static int BACK=36;//a facedown card
final static int NONE=-2;//no card at all
final static int SIZE=39;//cardsize (in pixels)
final static int PICOFFSET=2;//#pixels the pictures are translated.
final static int PCMEMSIZE=16;
int pos1,pos2;/*position of the open cards.*/
final static int USER1=21,USER2=22,USER3=23,PC1=24,PC2=25,PC3=26,WAIT=27;
int state;
/*The state determines what happens after a mouseclick.*/
int pcmemstart;
int pcchoice1,pcchoice2;
int[] pcmem;
int pointsuser,pointspc;
Image[] picture;//the pictures used
Label l1;//for messages
table(Applet a,Label a_label)
{
l1=a_label;//the label for messages
applet=a;//the applet we are running in.
visbuf=new int[TOTAL];
card=new int[TOTAL];
pcmem=new int[PCMEMSIZE];
resize(9*SIZE,8*SIZE);//the size needed to display it all
picture= new Image[37];//36 cards, plus BACK
URL base=applet.getDocumentBase();
for(int i=0;i<37;i++)
{try
{picture[i]=applet.getImage(new URL(base,i+".jpg"));}
catch(MalformedURLException e)
{System.out.println("loading failed");}
}
randomcards();//shuffle all
showall();
}
int pcmakechoice1()
{
//seek a pair of cards if possible...
for(int i=0;i<PCMEMSIZE;i++)
if(pcmem[i]!=-1&&visbuf[pcmem[i]]==BACK)
for(int j=i+1;j<PCMEMSIZE;j++)
if(pcmem[j]!=-1
&&pcmem[i]!=pcmem[j]
&&card[pcmem[i]]==card[pcmem[j]])
return pcmem[i];
//or pick a card you haven't seen:
return pcunseencard();
}
int pcunseencard()
{ int result;
boolean good;
do
{
good=true;
result=(int)(Math.random()*TOTAL);
if(visbuf[result]!=BACK)
good=false;
for(int i=0;i<PCMEMSIZE;i++)
if(pcmem[i]==result)
good=false;
}
while(!good);
return result;
}
int pcmakechoice2()
{
for(int i=0;i<PCMEMSIZE;i++)
if(pcmem[i]!=-1&&
card[pos1]==card[pcmem[i]]&&
pos1!=pcmem[i])
return pcmem[i];
return pcunseencard();
}
void clearpcmem()
{
for(int i=0;i<PCMEMSIZE;i++)
pcmem[i]=-1;
pcmemstart=0;
}
void pcremember(int card)
{
pcmem[pcmemstart]=card;
pcmemstart=(pcmemstart+1)%PCMEMSIZE;
}
void showall()//show all cards
{
for(int i=0;i<TOTAL;i++)
visbuf[i]=card[i];//set cards in visbuf
repaint();//update the screen
state=WAIT;//in the waitstate mouseclicks are ignored.
}
void addpoints(int a,int b)
{
pointsuser+=a;
pointspc+=b;
showscores();
}
void showscores()
{
l1.setText("you "+pointsuser+" ,pc "+pointspc);
}
void randomcards()
//shuffle the cards, lay them facedown on table
{
clearpcmem();
pointsuser=pointspc=0;
showscores();
for(int i=0;i<TOTAL;i++)
{visbuf[i]=BACK;
card[i]=NONE;
}
state=USER1;
repaint();//we have changed the visbuf
for(int cards=0;cards<TOTAL;cards++)
{//for any card we lay down
int r=(int)(Math.random()*(TOTAL-cards));
//r is one of the empty spots.
int i=0;
while(true)
//we are searching the r'th empty spot.
{
if(card[i]==NONE)
{r--;}//empty spot found
if(r<0)//enough empty spots found
break;//leave the loop
else
i++;//search ahead
}
card[i]=cards/2;//lay the card at the empty spot
//every number between 0 and 35 is laid down twice
}
}
public boolean mouseDown(Event ev,int x,int y)
/*There are 6 possibilities:
-> state==USER1: no card open yet. Store the clicked
card in pos1, and turn it around.
-> state==USER2.One card allready turned around.
Turn the clicked card, and store it in pos2
-> state==USER3: two cards open. if the same, remove, else
lay them face down.
PC1,PC2,PC3 are the same for the PC to move.
*/
{
if(pointsuser+pointspc==36||state==WAIT)
return true;
if(state==USER3||state==PC3)//already two cards open
{
if(card[pos2]==card[pos1])//same cards
{visbuf[pos2]=card[pos2]=NONE;
visbuf[pos1]=card[pos1]=NONE;//remove the cards
if(state==USER3)
{
addpoints(1,0);
state=USER1;
}
else
{
addpoints(0,1);
state=PC1;
}
}
else
{
visbuf[pos2]=visbuf[pos1]=BACK;//flip them back
state=(state==USER3)?PC1:USER1;
}
repaint();
return true;
}
//one or no card open:
if(state==USER1||state==USER2)
{
x=x/SIZE;
y=y/SIZE;//calcuate coordinates in cards.
int pos=x+9*y;//conversion to 1D coordinates
if(x<0||x>=9||y<0||y>=8||visbuf[pos]!=BACK)
return true;
/*The mouseclick must be inside the table, and point
at a facedown card.*/
visbuf[pos]=card[pos];//show the card
pcremember(pos);
repaint();
if(state==USER1)
pos1=pos; //just store it
else
pos2=pos;//also store it
state++;
return true;
}
else if(state==PC1)
{
pos1=pcmakechoice1();
visbuf[pos1]=card[pos1];//show the card
pcremember(pos1);
repaint();
state++;
}
else
{
pos2=pcmakechoice2();
visbuf[pos2]=card[pos2];//show the card
pcremember(pos2);
repaint();
state++;
}
return true;
}
public void paint(Graphics g)
/*paint all cards. They are drawen like they are in
visbuf: Most of them facedown. */
{
for(int i=0;i<TOTAL;i++)
{int x=i%9;
int y=i/9;//conversion to 2D coordinates
paintfield(g,x,y,visbuf[i]);
}
}
void paintfield(Graphics g,int x,int y,int value)
/*displays a field. value can be 0 to 35, indicating a
picture, or BACK(=36), or NONE.*/
{
int sx=x*SIZE;
int sy=y*SIZE;
g.setColor(Color.white);
g.fillRect(sx,sy,SIZE,SIZE);
if(value!=NONE)
drawimage(g,sx+PICOFFSET,sy+PICOFFSET,value);
}
void drawimage(Graphics g,int sx,int sy,int imno)
/*draws one of the pictures at the specified position.*/
{
if(g.drawImage(picture[imno],sx,sy,null)!=true)
{
g.setColor(Color.gray);
g.fillRect(sx+PICOFFSET,sy+PICOFFSET,
SIZE-PICOFFSET,SIZE-PICOFFSET);
}
/*if the picture is not available yet, we draw
a gray square instead.*/
}
public void update(Graphics g)
//if not redefined, update clears the screen and then paints.
//this causes flickering.
{ paint(g);}
}