import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.awt.image.*; import java.applet.Applet; public class gameBoard extends Canvas implements MouseListener,MouseMotionListener,Runnable{ mothello app; BufferedImage off;//image pentru duble-buffering board tablajoc;//configuratia curenta a tablei boolean flag;//flag pentru creare buffer offscreen int xc,yc;//pe ce patratica e pozitonat mouseul Player ply1,ply2;//cei doi jucatori int whoplays;//care jucator (1 sau 2) este la mutare boolean wantinput;//flag care indica daca urmatoarea mutare vine sau nu de la mouse public int gameOver;//jocul se termina cand au loc doua pasuri consecutive sau a fost oprit de butonul stop public gameBoard(mothello app){ super(); this.app=app; tablajoc=new board(); setSize(new Dimension(270,270)); addMouseListener(this); addMouseMotionListener(this); flag=false;xc=-1;yc=-1; ply1=null;ply2=null; whoplays=0;wantinput=false;gameOver=0; } public void paint(Graphics g){ int w=this.getWidth()-1; int h=this.getHeight()-1; float ws=(float)w/8; float hs=(float)h/8; Graphics2D g2; if (!flag){ off=(BufferedImage)this.createImage(getWidth(),getHeight()); flag=true; } g2=(Graphics2D)off.getGraphics(); g2.setColor(Color.gray); g2.fillRect(0,0,w,h); //desenare linii tabla g2.setColor(Color.black); g2.drawRect(0,0,w,h); for (int i=1;i<=7;i++){ Line2D.Float line=new Line2D.Float((float)ws*i+2,0,(float)ws*i+2,(float)h); g2.draw(line); line=new Line2D.Float(0,(float)hs*i+2,(float)w,(float)hs*i+2); g2.draw(line); } //desenare piese de pe tabla for (int i=1;i<=8;i++) for (int j=1;j<=8;j++){ RoundRectangle2D.Float rect=new RoundRectangle2D.Float((float)(j-1)*ws+2,(float)(i-1)*hs+2,ws-4,hs-4,25,25); Rectangle2D.Float rt=new Rectangle2D.Float((float)(j-1)*ws,(float)(i-1)*hs,ws,hs); if (((i%2==0)&&(j%2!=0))||((i%2!=0)&&(j%2==0))){ g2.setColor(Color.lightGray); }else{ g2.setColor(Color.darkGray); } if ((xc==i)&&(yc==j)){ g2.setColor(g2.getColor().darker().darker()); } g2.fill(rt); if ((xc==i)&&(yc==j)){ if (whoplays==1) g2.setColor(Color.red); else g2.setColor(Color.green); if (tablajoc.getElementAt(i,j)==0) g2.draw(rect); } switch (tablajoc.getElementAt(i,j)){ case 1://piesa a jucatorului 1 - rosie g2.setColor(Color.red); g2.fill(rect); break; case 2://piesa a jucatorului 2 - verde g2.setColor(Color.green); g2.fill(rect); break; default: break; } } g.drawImage(off,0,0,this); } public void update(Graphics g){ paint(g); } //start mouse listener methods public void mouseClicked(MouseEvent me){ if (wantinput){ int row=getRand(me.getY()); int column=getCol(me.getX()); if (tablajoc.getElementAt(row,column)==0){//patratel liber makeMove(row,column); } } } public void mousePressed(MouseEvent me){ } public void mouseReleased(MouseEvent me){ } public void mouseEntered(MouseEvent me){ } public void mouseExited(MouseEvent me){ xc=-1;yc=-1; app.pozmouse.setText(""); repaint(); } //end mouse listener methods public int getRand(int x){ int h=this.getHeight()-1; float hs=(float)h/8; return (int)Math.floor(x/hs)+1; } public int getCol(int y){ int w=this.getWidth()-1; float ws=(float)w/8; return (int)Math.floor(y/ws)+1; } //start mousemotion listener methods public void mouseMoved(MouseEvent me){ app.pozmouse.setText("Row="+getRand(me.getY())+",Column="+getCol(me.getX())); if (wantinput){ xc=getRand(me.getY()); yc=getRand(me.getX()); if (tablajoc.getElementAt(xc,yc)!=0) {xc=-1;yc=-1;} repaint(); } } public void mouseDragged(MouseEvent me){ } //end mouse-motion listener methods //game methods public void startGame(int p1,int l1,int p2,int l2){ if (p1==1){ ply1=new HumanPlayer("Human",1); app.p1l.setText("Player 1 (Human)"); }else{ ply1=new AIPlayer("Computer",l1,1); app.p1l.setText("Player 1 (AI)"); } if (p2==1){ ply2=new HumanPlayer("Human",2); app.p2l.setText("Player 2 (Human)"); }else{ ply2=new AIPlayer("Computer",l2,2); app.p2l.setText("Player 2 (AI)"); } whoplays=1; tablajoc=new board(); xc=-1;yc=-1; wantinput=false;//deocamdata nu stim daca urmatorul player este uman gameOver=0;//jocul abia a inceput app.p1score.setText(""); app.p2score.setText(""); } public void makeMove(int row,int column){ boolean rep=false;//flag care sa indice daca mutarea curenta //este legala, si deci trebuie pasat randul adversarului int legal; wantinput=false; switch (whoplays){ case 1: legal=ply1.isLegalMove(tablajoc,row,column); if (legal>0){//mutarea este valida rep=true;//trebuie sa facem repaint gameOver=0; ply1.addMove(row,column,legal); app.p1score.append(ply1.getLastMove()+"\n"); turnPieces(row,column,1); }else{ if (legal==-1){//jucatorul 1 nu are mutare app.status.setText("Player 1 has no move.Pass to player 2"); rep=true; gameOver++; }else app.status.setText("Illegal move.Try again, player 1"); } break; case 2: legal=ply2.isLegalMove(tablajoc,row,column); if (legal>0){//mutarea este valida rep=true;gameOver=0; ply2.addMove(row,column,legal); app.p2score.append(ply2.getLastMove()+"\n"); turnPieces(row,column,2); }else{ if (legal==-1){//jucatorul 2 nu are mutare app.status.setText("Player 2 has no move.Pass to player 1"); rep=true;gameOver++; }else app.status.setText("Illegal move.Try again, player 2"); } break; default: break; } if (rep){ if (whoplays==1) whoplays=2; else whoplays=1; } } public int getPlayerScore(int which){ int ret=0; for (int i=1;i<=8;i++) for (int j=1;j<=8;j++) if (tablajoc.getElementAt(i,j)==which) ret++; return ret; } public int refreshScores(){ int p=getPlayerScore(1); app.piese1.setText(new Integer(p).toString()+" pieces"); int r=getPlayerScore(2); app.piese2.setText(new Integer(r).toString()+" pieces"); return (p+r); } public void gameOver(){ int p1=this.getPlayerScore(1); int p2=this.getPlayerScore(2); if (p1>p2){ app.status.setText("Player 1 wins!Press start to restart"); }else if (p1==p2){ app.status.setText("It's a draw!Press start to restart"); } else app.status.setText("Player 2 wins!Press start to restart"); app.start.setEnabled(true); app.stop.setEnabled(false); } public void run(){ int k=refreshScores(); while ((gameOver<2)&&(k<64)){ switch (whoplays){ case 1: if (ply1.getType()==1){//player 1 uman app.status.setText("Waiting for player 1 to move"); wantinput=true; }else{//player 1 AI wantinput=false; AIPlayer calc=(AIPlayer)ply1; app.status.setText("Player 1 (Computer) is about to move..."); move mv=calc.makeMove(tablajoc); if (mv==null){//jucatorul 1 nu poate sa mute app.status.setText("Player 1 can't move.Pass to player 2"); gameOver++; }else{ gameOver=0; ply1.addMove(mv.getRow(),mv.getColumn(),mv.getCastig()); app.p1score.append(ply1.getLastMove()+"\n"); //turnPieces(mv.getRow(),mv.getColumn(),1); tablajoc=calc.mkMov(tablajoc,mv.getRow(),mv.getColumn(),1); } whoplays=2; } try{ Thread.currentThread().sleep(1000); }catch(Exception e){ } break; case 2: if (ply2.getType()==1){//player 2 uman app.status.setText("Waiting for player 2 to move"); wantinput=true; }else{//player 2 AI wantinput=false; AIPlayer calc=(AIPlayer)ply2; app.status.setText("Player 2 (Computer) is about to move..."); move mv=calc.makeMove(tablajoc); if (mv==null){//jucatorul 2 nu poate sa mute app.status.setText("Player 2 can't move.Pass to player 1"); gameOver++; }else{ gameOver=0; ply2.addMove(mv.getRow(),mv.getColumn(),mv.getCastig()); app.p2score.append(ply2.getLastMove()+"\n"); //turnPieces(mv.getRow(),mv.getColumn(),2); tablajoc=calc.mkMov(tablajoc,mv.getRow(),mv.getColumn(),2); } whoplays=1; } try{ Thread.currentThread().sleep(1000); }catch(Exception e){ } break; default: break; } repaint(); k=refreshScores(); long sleeptime=1000; if ((ply1.getType()==2)&&(ply2.getType()==2)){ sleeptime=1000; } } gameOver(); } public void turnPieces(int row, int column,int culoare){ int howmany=0; for (int i=-1;i<2;i++) for (int j=-1;j<2;j++) if ((i==0)&&(j==0)){ } else{ howmany+=turnDirection(row,column,culoare,i,j); } } public boolean offLimits(int row,int column){ return ((row<1)||(row>8)||(column<1)||(column>8)); } public void endGameDaemon(){ this.gameOver=100; } public int turnDirection(int row,int column,int culoare,int dx,int dy){ int sum=0,oposite,i,j; oposite=3-culoare; i=row;j=column; if (!offLimits(i+2*dx,j+2*dy)){ i+=dx;j+=dy; if (tablajoc.getElementAt(i,j)==oposite){//daca ma aflu langa un element opus boolean gata=false,bun=false; int ii=i,jj=j; do{ ii+=dx;jj+=dy; if (offLimits(ii,jj)) gata=true; else if (tablajoc.getElementAt(ii,jj)!=oposite){ gata=true; if (tablajoc.getElementAt(ii,jj)==culoare) bun=true; } }while (!gata); if (bun){ if (dx!=0) sum+=Math.abs(i-ii); else sum+=Math.abs(j-jj); i=row;j=column; while ((i!=ii)||(j!=jj)){ tablajoc.setElementAt(i,j,(byte)culoare); i+=dx;j+=dy; } } } } return sum; } }