⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qipan.java

📁 有书籍对照的双人下围棋`虽然没有AI但是 基本围棋功能都可以实现了!
💻 JAVA
字号:

import java.awt.*;
import java.awt.event.*;

import java.util.*;


//**********************************************************
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;            //轮到谁下  Qizi._black Or Qizi._white
	
	protected int rectnum,rectlen;	      //方格长度及数目
	protected int qizilen;				  //棋子的直径	
	protected Qizi[][] map;  //在棋盘上的所有棋子
	//**********************************
	protected Image offscreen;   //双缓冲用的Image,Graphics 
	protected Graphics offg;
	//**********************************
	protected int size;          //棋盘的宽度及高度
	
	protected int top,left;		//棋盘左边及上边的边距
	//****************************************
	protected Point mouseLoc;	//鼠标的位置,即在map数组中的下标
	//****************************************
	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[i][j]==null)
					continue;
									
				offg.setColor(map[i][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("挤死自己");
				//******************back**************
				qizis.removeElement(qizi);
				num--;
				if(currentTurn==Qizi._black)
					currentTurn=Qizi._white;
				else
					currentTurn=Qizi._black;
				return;
			}				
			
			mouseLoc=null;
            //更新控制面板
			controlPanel.setLabel();
		}
		
		public void mouseExited(MouseEvent evt)
		{//鼠标退出时,清除将要落子的位置
			mouseLoc=null;
			repaint();
		}
	}
	
	private class MML extends MouseMotionAdapter
    {//取得将要落子的位置
		public void mouseMoved(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;	
				
			mouseLoc=new Point(x,y);
			repaint();		
		}
	}
	//******************提掉自己的子,不用**********************
	/*public void tiziMyself(int x,int y)
	{
		int x1=-1;
		int y1=-1;
		for(int l=0;l<xdir.length;l++)
		{
			x1=x+xdir[l];
			y1=y+ydir[l];
			
			if(x1<0 || x1>rectnum || y1<0 || y1>rectnum || map[x1][y1]==null)
				continue;								
					
			break;	
		}					
		if(x1!=-1)
			tizi(x1,y1);							
	}*/
    //**************判断在[x,y]落子后,是否可以提掉对方的子**********************
	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;
		//*************取得qizi四周围的几个子*************
		Vector v=around(qizi);		
		
		for(int l=0;l<v.size();l++)
		{		
			Qizi q=(Qizi)(v.elementAt(l) );
			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 i=0;i<vector.size();i++)
						dead.addElement(vector.elementAt(i) );
				}
                //更新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;
	}
	//*************取得qizi四周围的几个子*************
	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,10));
		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,200));								
	}
	
	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+1)+" 手");
		lblNum.setForeground(Qipan.this.currentTurn==Qizi._black?Color.black:Color.white);
		
		lblMsg.setText("");
	}
	
	public void setMsg(String msg)
	{
		lblMsg.setText(msg);
	}
}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -