返回列表 发帖

一个绝对值得改善的围棋代码

import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Qipan extends Panel{
public static final int _rectlen=22,_rectnum=19;
// 默认的方格长度和数目
protected Vector qizis;
/*
  * 保存所有已下的棋子,包括在棋盘上的所有棋子和被提掉的
  * 若某一次落子没有造成了提子,则Vector qizis中保存的就是这个棋子
  * 若某一次落子造成了提子,则Vector qizis 中保存的就是一个Vector
  * 这个Vector中包括所有被这个棋子提子提掉的棋子及这个棋子本身
  * 这棋子本身位于这个Vector的最后
  */
protected int num;        // 已下数目
protected int currentTurn;//轮到谁下
protected int rectnum,rectlen;//方格长度及数目
protected int qizilen;
protected Qizi[][] map;

protected Image offscreen;
protected Graphics offg;

protected int size;

protected int top,left;

protected Point mouseLoc;

protected ControlPanel controlPanel;//  控制面板
public int getWidth(){
  return size+controlPanel.getWidth()+35;
}
public int getHeight(){
  return size;
}

public Qipan(){
  top=left=20;
  rectnum = _rectnum;
  rectlen = _rectlen;
  qizilen = rectlen*9/10;
  size = 2*left+rectnum*rectlen;
  
  addMouseListener(new ML());
  addMouseMotionListener(new MML());
  
  setLayout (new BorderLayout());
  controlPanel = new ControlPanel();
  
  setSize(getWidth(),size);
  add(controlPanel,"East");
  //初始化
  start();
}
public void addNotify(){
  super.addNotify();
  offscreen = createImage(size,size);
  offg = offscreen.getGraphics();
}
public void paint(Graphics g){
  offg.setColor(new Color(180,150,100));
  offg.fillRect(0, 0, size, size);
  //画出棋盘格子
  offg.setColor(Color.BLACK);
  for(int i=0;i<rectnum+1;i++){
   int x1=left+i*rectlen;
   int x2=x1;
   
   int y1=top;
   int y2=top+rectnum*rectlen;
   offg.drawLine(x1, y1, x2, y2);
   
   x1=left;
   x2=left+rectnum*rectlen;
   y1=top+i*rectlen;
   y2=y1;
   offg.drawLine(x1, y1, x2, y2);
  }
  //画出棋子
  for(int i=0;i<rectnum+1;i++){
   for(int j=0;j<rectnum+1;j++){
    if(map[j]==null)
     continue;
    offg.setColor(map[j].color==Qizi._black?Color.black:Color.white);
    offg.fillOval(left+i*rectlen-qizilen/2, top+j*rectlen-qizilen/2, qizilen, qizilen);
   
   }
   //画出鼠标的位置,即下一步将要下的位置
   if(mouseLoc!=null){
    offg.setColor(currentTurn==Qizi._black?Color.gray:new Color(200,200,250));
    offg.fillOval(left+mouseLoc.x*rectlen-qizilen/2, top+mouseLoc.y*rectlen-qizilen/2, qizilen, qizilen);
   
   }
   //画出画面
   g.drawImage(offscreen,0,0,this);
  }
}
  public void update(Graphics g){
   paint(g);
  }
  class ML extends MouseAdapter{
   public void mousePressed(MouseEvent evt){
    int xoff = left/2;
    int yoff = top/2;
    int x = (evt.getX()-xoff)/rectlen;
    int y = (evt.getY()-yoff)/rectlen;
   
    if(x<0||x>rectnum||y<0||y>rectnum)
     return ;
    if(map[x][y]!=null)
     return ;
    //删除多余的棋子
    if(num<qizis.size()){
     int size = qizis.size();
     for(int i=size-1;i>=num;i--)
      qizis.removeElementAt(i);
    }
    Qizi qizi = new Qizi(x,y,currentTurn);
    map[x][y]=qizi;
    qizis.addElement(qizi);
    num++;
    if(currentTurn==Qizi._black)
     currentTurn=Qizi._white;
    else
     currentTurn=Qizi._black;
    //判断在【x,y】落子后,是否可以提掉对方的子
    tizi(x,y);
    // 判断是否挤死了自己来,若是则已落的子无效
    if(allDead(qizi).size()!=0){
     map[x][y]=null;
     repaint();
     controlPanel.setMsg("挤死自己");
     
     qizis.removeElement(qizi);
     num--;
     if(currentTurn==Qizi._black)
      currentTurn=Qizi._white;
     else
      currentTurn=Qizi._black;
    }
    mouseLoc=null;
    //更新控制面板
    controlPanel.setLabel();
   }
   public void mouseExited(MouseEvent e){
    mouseLoc=null;
    repaint();
   }
  }
  private class MML extends MouseMotionAdapter{
   public void mouseMoved(MouseEvent e){
    int xoff = left/2;
    int yoff = top/2;
    int x=(e.getX()-xoff)/rectlen;
    int y=(e.getY()-yoff)/rectlen;
    if(x<0||x>rectnum||y<0||y>rectnum)
     return ;
    if(map[x][y]!=null)
     return ;
   
    mouseLoc=new Point(x,y);
    repaint();
   }
  }
  public static int[] xdir={0,0,1,-1};
  public static int[] ydir={1,-1,0,0};
  public void tizi(int x,int y){
   Qizi qizi;
   if((qizi=map[x][y])==null)
    return;
   int color=qizi.color;
   Vector v=around(qizi);//取得qizi四周围的几个棋子
   for(int i=0;i<v.size();i++){
    Qizi q = (Qizi)(v.elementAt(i));
    if(q.color==color)
     continue;
    /*
     * 若颜色不同,取得和q连在一起的所有已死的子,
     * 若没有已死的子则返回一个空的Vector
     */
    Vector dead = allDead(q);
    removeAll(dead);//移去所有已死的子
    /****若造成提子,则保存所有被提掉的棋子*/
    if(dead.size()!=0){
     Object obj = qizis.elementAt(num-1);
     if(obj instanceof Qizi){
      qizi = (Qizi)(qizis.elementAt(num-1));
      dead.addElement(qizi);
      
     }
     else{
      Vector vector = (Vector)obj;
      for(int j=0;j<vector.size();j++)
       dead.addElement(vector.elementAt(j));
     }
     /**更新Vector qizis 中的第num个元素**/
     qizis.setElementAt(dead, num-1);
    }
   }
   repaint();
  }
  public boolean sideByBlank(Qizi qizi){
   /**判断qizi周围是否有空白****/
   for(int l=0;l<xdir.length;l++){
    int x1 = qizi.x+xdir[l];
    int y1 = qizi.y+ydir[l];
   
    if(x1<0||x1>rectnum||y1<0||y1>rectnum)
     continue;
    if(map[x1][y1]==null)
     return true;
   }
   return false;
  }
  public Vector around(Qizi qizi){
   Vector v = new Vector();
   for(int l=0;l<xdir.length;l++){
    int x1 = qizi.x+xdir[l];
    int y1 = qizi.y+ydir[l];
   
    if(x1<0||x1>rectnum||y1<0||y1>rectnum||map[x1][y1]==null)
     continue;
    v.addElement(map[x1][y1]);
   
   }
   return v;
  }
  /*
   * 取得而后q连在一起的所有已死的子,
   * 若没有已死的子则返回一个空的Vector
   */
  public Vector allDead(Qizi q){
   Vector v = new Vector();
   v.addElement(q);
   
   int count = 0;
   while(true){
    int origsize = v.size();
    for(int i=count;i<origsize;i++){
     Qizi qizi = (Qizi)(v.elementAt(i));
     if(sideByBlank(qizi))
      return new Vector();
     Vector around = around(qizi);
     for(int j=0;j<around.size();j++){
      Qizi a = (Qizi)(around.elementAt(j));
      if(a.color!=qizi.color)
       continue;
      if(v.indexOf(a)<0)
       v.addElement(a);
     }
    }
    if(origsize==v.size())
     break;
    else
     count=origsize;
   }
   return v;
  }
  /**从棋盘上移去Vector v中棋子**/
  public void removeAll(Vector v){
   for(int i=0;i<v.size();i++){
    Qizi q = (Qizi)(v.elementAt(i));
    map[q.x][q.y]=null;
   }
   repaint();
  }
  /***********悔棋********/
  public void back(){
   if(num==0){
    controlPanel.setMsg("无子可悔");
    return;
   }
   Object obj = qizis.elementAt(--num);
   if(obj instanceof Qizi){
    Qizi qizi = (Qizi)obj;
    map[qizi.x][qizi.y]=null;
   
    currentTurn=qizi.color;
   }else
   {
    Vector v = (Vector)obj;
    for(int i=0;i<v.size();i++){
     Qizi q = (Qizi)(v.elementAt(i));
     if(i==v.size()-1){
      map[q.x][q.y]=null;
      int index = qizis.indexOf(v);
      qizis.setElementAt(q, index);
      currentTurn = q.color;
     }
     else{
      map[q.x][q.y]=q;
     }
    }
   }
   controlPanel.setLabel();
   repaint();
  }
  /*******悔棋后再次前进*********/
  public void forward(){
   if(num==qizis.size()){
    controlPanel.setMsg("不能前进");
    return;
   }
   Object obj = qizis.elementAt(num++);
   Qizi qizi;
   if(obj instanceof Qizi){
    qizi = (Qizi)(obj);
    map[qizi.x][qizi.y]=qizi;
   }else
   {
    Vector v = (Vector)obj;
    qizi=(Qizi)(v.elementAt(v.size()-1));
    map[qizi.x][qizi.y]=qizi;
   }
   if(qizi.color==Qizi._black)
    currentTurn=Qizi._white;
   else
    currentTurn=Qizi._black;
   tizi(qizi.x,qizi.y);
   controlPanel.setLabel();
   repaint();
  }
  /******重新开始游戏**********/
  public void start()
  {
   qizis = new Vector();
   num=0;
   map = new Qizi[rectnum+1][rectnum+1];
   currentTurn = Qizi._black;
   controlPanel.setLabel();
   repaint();
  }
  /********控制面板类*********/
  class ControlPanel extends Panel
  {
   protected Label lblTurn = new Label("",Label.CENTER);
   protected Label lblNum = new Label("",Label.CENTER);
   protected Label lblMsg = new Label("",Label.CENTER);
   
   protected Choice choice = new Choice();
   protected Button back = new Button("悔棋");
   protected Button forward = new Button("前进");
   protected Button start = new Button("重新开始");
   
   public int getWidth(){
    return 45;
   }
   public int getHeight(){
    return size;
   }
   /*********选择棋盘的大小***************/
   public ControlPanel(){
    setSize(this.getWidth(),this.getHeight());
    setLayout(new GridLayout(12,1,0,12));
    setLabel();
   
    choice.add("19 X 19");
    choice.add("15 X 15");
    choice.add("13 X 13");
    choice.add("11 X 11");
    choice.add("7 X 7");
    choice.addItemListener(new IL());
   
    add(lblTurn);
    add(lblNum);
    add(start);
    add(choice);
    add(lblMsg);
    add(back);
    add(forward);
    back.addActionListener(new AL());
    forward.addActionListener(new AL());
    start.addActionListener(new AL());
   
    setBackground(new Color(120,120,120));   
   }
   public Insets getInsets(){
    return new Insets(5,5,5,5);
   }
   private class AL implements ActionListener{
    //悔棋与前进
    public void actionPerformed(ActionEvent evt){
     if(evt.getSource()==back)
      Qipan.this.back();
     else if(evt.getSource()==forward)
      Qipan.this.forward();
     else if(evt.getSource()==start)
      Qipan.this.start();
    }
   }
   private class IL implements ItemListener{
    public void itemStateChanged(ItemEvent evt){
     String s = (String)(evt.getItem());
     int rects = Integer.parseInt(s.substring(0, 2).trim());
     if(rects!=Qipan.this.rectnum){
      Qipan.this.rectlen=(_rectlen*_rectnum)/rects;
      Qipan.this.qizilen=rectlen*9/10;
      Qipan.this.rectnum=rects;
      Qipan.this.start();
     }
    }
   }
   public void setLabel(){
    lblTurn.setText(Qipan.this.currentTurn==Qizi._black?"黑方":"白方");
    lblTurn.setForeground(Qipan.this.currentTurn==Qizi._black?Color.black:Color.white);
    lblNum.setText("第"+(Qipan.this.num)+"手");
    lblNum.setForeground(Qipan.this.currentTurn==Qizi._black?Color.black:Color.white);
    lblMsg.setText("");
   }
   public void setMsg(String msg){
    lblMsg.setText(msg);
   }
  }
}

//Weiqi.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.applet.*;
import java.util.EventListener;
public class Weiqi extends Applet{
Qipan qipan;
public void init(){
qipan = new Qipan();
setLayout(new BorderLayout());
setSize(qipan.getSize());
add(qipan,"Center");
}
public int getHeight(){
return qipan.getHeight();
}
public int getWidth(){
return qipan.getWidth();
}
public static void main(String[] args){
JFrame f = new JFrame("JAVA實現-阿魚翻版-圍棋");
f.setResizable(false);
f.setLayout(new BorderLayout());
Weiqi weiqi = new Weiqi();//开始下期程序
weiqi.init();
weiqi.start();
f.setSize(weiqi.getWidth(), 20+weiqi.getHeight());
f.add(weiqi,"Center");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}

TOP

//Qizi.java
public class Qizi {
public static int _black=0,_white=1;
protected int x,y;
protected int color;
public Qizi(int i,int j,int c){
x=i;
y=j;
color=c;
}
public String toString(){
//存储x,y位置和颜色
String c=(color==_black?"black":"white");
return "["+x+","+y+"]:"+c;
}
}

TOP

学习中..................

TOP

返回列表