精华内容
下载资源
问答
  • 一切从五子棋开始

    2016-06-12 18:31:54
    题引:作为一个迫不及待想掌握一门养家糊口技能的大二新人,被一位前辈建议学习Java开发Android,他还说会写五子棋就能找到工作。 写五子棋的要点有两点:棋局展示、胜负判定。 一、棋局展示 忽略交互效果,仅以...

    题引:作为一个迫不及待想掌握一门养家糊口技能的大二新人,被一位前辈建议学习Java开发Android,他还说会写五子棋就能找到工作。


    写五子棋的要点有两点:棋局展示、胜负判定。

    一、棋局展示

    忽略交互效果,仅以实现基本功能为目标,展示的方法可通过文本或图片实现。

    使用文本展示可通过“o”表示白子,“x”表示黑子,“-”表示空位来进行最简单的展示。用TextView控件及其setText(CharSequence)方法即可实现棋子的更替。

    使用图片展示可使交互更直观。最先想到的方法是在底部设置一张棋盘背景,落子后将对应位置的ImageView的显示图片更改为落子贴图。苦于没找到合适的棋盘背景,最后使用三张落子贴图分别代表白子、黑子、无子,在落子后将棋格贴图更改为对应落子贴图即可。


    接下来就是如何显示这些贴图了,通过以下代码即可将ImageView控件的图片内容设置为资源文件内的图片。

    mImageView.setImageResource(R.drawable.mImage);

    光显示贴图还远远不够,我们需要将ImageView按棋盘进行定位布局。考虑到棋盘大小的易变性,控件的创建和定位都通过Java代码动态进行。

    /**
     * 初始化布局
     * @param count 棋盘行列数
     * @return 棋格控件数组
     */
    private ImageView[][] initView(int count) {
    	RelativeLayout container=new RelativeLayout(this);
    	setContentView(container);
    	ImageView[][] views=new ImageView[count][count];
    	int pWidth=getResources().getDisplayMetrics().widthPixels,pHeight=getResources().getDisplayMetrics().heightPixels; //获取屏幕宽高
    	int length=pWidth>pHeight?pHeight/count:pWidth/count; //计算棋格宽高
    	int left=pWidth>pHeight?(pWidth-pHeight)/2:0; //局中显示水平偏移
    	int top=pWidth>pHeight?0:(pHeight-pWidth)/2; //局中显示垂直偏移
    	for(int x=0;x<count;x++) {
    		for(int y=0;y<count;y++) {
    			ImageView iv=new ImageView(this);
    			RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(length, length);
    			lp.setMargins(left+x*length, top+y*length, 0, 0);
    			iv.setLayoutParams(lp);
    			container.addView(iv);
    			views[x][y]=iv;
    		}
    	}
    	return views;
    }

    最后是添加交互事件,可以通过View的setOnClickListener(OnClickListener)方法实现点击事件。

    这里需要注意的是,由于多个控件设置点击事件,我们需要在处理点击时识别所点击对象。标识点击对象的方法有很多种:

    1、关键字final。

    2、用回调view遍历比对控件数组。

    3、通过view的setTag(Object)方法标记控件,使用回调view的getTag()方法获取唯一标识。

    4、继承OnClickListener类,提供两个int型数据进行初始化的构造器。添加新抽象方法onClick(int,int),原抽象方法onClick(View)通过构造传入的int数据调用新抽象方法。

    以下代码通过关键字final实现标识。

    private ImageView[][] mViews;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	mViews=initView(15);
    	for(int x=0;x<mViews.length;x++) {
    		for(int y=0;y<mViews[0].length;y++) {
    			final int finalX=x;
    			final int finalY=y;
    			mViews[x][y].setOnClickListener(new OnClickListener() {
    				
    				@Override
    				public void onClick(View v) {
    					// TODO Auto-generated method stub
    					handleClick(finalX, finalY);
    				}
    			});
    		}
    	}
    	
    }
    private void handleClick(int x, int y) {
    	//这里处理点击逻辑
    }


    二、胜负判定

    正在进行的棋局只会因下一次落子导致结束,因此胜负判定在每次落子后根据落子位置进行判定即可。

    判定思路为由落子位置向四个方向延伸,任意方向连通总量大于五子则落子方获胜。需要注意的是五子棋还存在和棋的可能性,在获胜判定后需统计落子总量,若棋盘已满则产生和局。以下代码为落点胜负判定。

    private int[][] mArgs; //棋盘数据数组
    private int pieceCount; //棋盘已落子量
    private int chessSize; //棋盘行列数
    
    /**
     * 胜负判定
     * @param x 落子横坐标
     * @param y 落子纵坐标
     * @return
     */
    private int win(int x, int y) {
    	if(getItemCount(x,y,0,1)+getItemCount(x,y,0,-1)+1>=5) return 1; //落子方获胜
        if(getItemCount(x,y,1,0)+getItemCount(x,y,-1,0)+1>=5) return 1; //落子方获胜
        if(getItemCount(x,y,1,1)+getItemCount(x,y,-1,-1)+1>=5) return 1; //落子方获胜
        if(getItemCount(x,y,1,-1)+getItemCount(x,y,-1,1)+1>=5) return 1; //落子方获胜
        if(pieceCount>=chessSize*chessSize) return -1; //平局
        return 0; //未分胜负
    }
    /**
     * 连通量统计
     * @param x 落子横坐标
     * @param y 落子纵坐标
     * @param i 延伸方向
     * @param j 延伸方向
     * @return
     */
    private int getItemCount(int x, int y, int i, int j) {
    	int itemCount=0;
    	int mType=mArgs[x][y];
    	int readX=x+i;
    	int readY=y+j;
    	while(true) {
    		if(readX<0||readX>=chessSize||readY<0||readY>=chessSize) break;
    		if(mType==mArgs[readX][readY]) {
    			itemCount++;
    			readX+=i;
    			readY+=j;
    		}
    		else break;
    	}
    	return itemCount; //返回该方向累计同色棋数
    }


    最后再搭配上棋盘的复位功能,一个Android的简单五子棋程序就完成了。(当然现在还存在一个严重的交互问题,在小屏手机上触控容易点错位置,后来我的解决方案是添加了棋盘的双指缩放和单指挪动,这里就不进行详细描述了)


    展开全文
  • AI算法实现五子棋

    万次阅读 2018-08-05 17:26:11
    首先,实现一个五子棋要有一个棋盘,然后在这个棋盘上我们再来画出图画,五子棋棋盘有固定的行数和列数,再加上界面的大小和菜单栏,这些数据可能很多个类都需要用到,我们可以先考虑自己写一个接口用来存储这些数据...

    首先,实现一个五子棋要有一个棋盘,然后在这个棋盘上我们再来画出图画,五子棋棋盘有固定的行数和列数,再加上界面的大小和菜单栏,这些数据可能很多个类都需要用到,我们可以先考虑自己写一个接口用来存储这些数据:

    public interface Config {
    	public static final int SIZE=703;
    	//面板大小
    	public static final int X0=SIZE/19*2-8;
    	public static final int Y0=X0-15;
    	//棋盘网格起始点
    	public static final int WID=SIZE/19;
    	//行宽
    	public static final int LINE=15;
    	//行数
    	public static final int CHESS=WID;
    	//五子棋棋子大小
    
    }
    

    这个时候我们来考虑写一个五子棋界面,除了常用的界面写法之外,考虑到五子棋的悔棋和重新开始,我们需要重写paint方法,在需要的时候调用来达到更新棋盘的作用。

    import java.awt.BasicStroke;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    
    import javax.swing.JPanel;
    
    
    public class Fivebord extends JPanel implements Config{
    	private static final long serialVersionUID = 1L;
    	private int point[][]=new int [SIZE][SIZE];
    	
    	public static void main(String[] args) {
    		Fivebord fb = new Fivebord();
    		fb.showFivebord();
    	}
    	
    	public void showFivebord() {
    		//一下是关于界面的常规设置
    		javax.swing.JFrame jf = new javax.swing.JFrame();
    		jf.setTitle("FIVEBORD");
    		jf.setSize(SIZE+100, SIZE);
    		jf.setDefaultCloseOperation(3);
    		jf.setLocationRelativeTo(null);
    		jf.setLayout(new BorderLayout());		
    		
    		JPanel jp1=new JPanel();
    		jp1.setBackground(Color.ORANGE);
    		jp1.setPreferredSize(new Dimension(100, SIZE));
    		jf.add(jp1,BorderLayout.EAST);		
    		
    		javax.swing.JButton jbu1 = new javax.swing.JButton("悔棋");
    		jp1.add(jbu1); 
    				
    		javax.swing.JButton jbu2 = new javax.swing.JButton("人机");
    		jp1.add(jbu2);
    		
    		javax.swing.JButton jbu3 = new javax.swing.JButton("人人");
    		jp1.add(jbu3);
    		
    		this.setBackground(Color.YELLOW);
    		jf.add(this,BorderLayout.CENTER);
    		
    		jf.setVisible(true); 
    		
    		//以下给界面添加监听器,包括画板和按钮
            DrawMouse mouse=new DrawMouse(this);
            jbu1.addActionListener(mouse);
            jbu2.addActionListener(mouse);
            jbu3.addActionListener(mouse);
            this.addMouseListener(mouse);
            //监听器中需要考虑当前棋盘上的棋子和位置
            mouse.setpoint(point);
               		
    		
    	}
    	public void paint(Graphics g) {
    		super.paint(g);		
    		//super.paint 
    		//由于paint函数是界面自带的函数且在某些时候会自动调用
    		//super.paint(g)表示屏蔽父类的函数内容,换做自己接下来改写的内容
    		Graphics2D gr = (Graphics2D)g;		
    		gr.setStroke(new BasicStroke(1));
    		//2D画笔变粗度为1
    		for(int i=X0;i<=X0+LINE*WID;i+=WID){
    			for(int j=Y0;j<=Y0+LINE*WID;j+=WID){
    				g.drawLine(X0, j, X0+LINE*WID, j);
    				g.drawLine(i, Y0, i,Y0+LINE*WID);
    			}
    		}	
    		//画内部16格
    		gr.setStroke(new BasicStroke(2));
    		//画笔粗度变为2
    		g.drawLine(X0-WID, Y0-WID, X0-WID, Y0+(LINE+1)*WID);
    		g.drawLine(X0-WID, Y0-WID, X0+(LINE+1)*WID, Y0-WID);
    		g.drawLine(X0+(LINE+1)*WID, Y0-WID, X0+(LINE+1)*WID, Y0+(LINE+1)*WID);
    		g.drawLine(X0-WID, Y0+(LINE+1)*WID, X0+(LINE+1)*WID, Y0+(LINE+1)*WID);
    		//画四周较粗的边框(美观起见,没有实际意义)
    		for(int i=X0;i<=X0+(WID*(LINE+1));i+=WID){
            	for(int j=Y0;j<=Y0+(LINE+1)*WID;j+=WID){
            		if(point[i][j]==1){
            			//画黑棋
            			g.setColor(Color.BLACK);
            			g.fillOval(i-WID/2, j-WID/2, WID, WID);
            		}
            		else if(point[i][j]==2){
            			//画白棋
            			g.setColor(Color.WHITE);
            			g.fillOval(i-WID/2, j-WID/2, WID, WID);
            		}
            	}
            }
    		//根据point的内容画出相应的点(即棋子)
    	}   
    	
    }
    

    最最重要的就是监听器部分了,除了具有相应的监听功能,还要在每次人下棋之后智能判断出机器所需要下的位置,于此同时,每下一个棋子,都要判断是否已经有五子连成线进而提示输赢。

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.util.HashMap;
    
    import javax.swing.JOptionPane;
    
    public class DrawMouse extends MouseAdapter implements Config,ActionListener{
    	//添加动作监听器(监听按钮)和鼠标监听器(鼠标所点位置画棋子)
    	private Graphics g;
    	private int x,y,CO=1,index=0;
    	private int point[][];
    	private int pointweight[][]=new int [X0+(LINE+1)*WID][Y0+(LINE+1)*WID];
    	private int orderx[]=new int [X0+(LINE+1)*WID],ordery[]=new int [Y0+(LINE+1)*WID];
    	private Fivebord fb;
    	private int pc=0;
    	public HashMap <String,Integer> hm = new HashMap <String,Integer>();
    	//哈希表用来存放不同棋子布局下的不同权值
    	
    	
    	DrawMouse(Fivebord fb) {
    		this.g = fb.getGraphics();
    		this.fb=fb;
    		sethashmap();
    	}
    	//传棋子数组
    	public void setpoint(int point[][]){
    	    this.point=point;
        }
    	public  void sethashmap(){
    		hm.put("1", 1);
    		//某一方向线上只有一个黑棋
    		hm.put("12", 5);
    		//某一方向线上紧接着一个黑棋有一个白棋
    		hm.put("11", 10);
    		hm.put("112", 15);
    		//某一方向线上紧接着两个相邻的黑棋后有一个白棋(以此类推)
    		hm.put("111", 100);
    		hm.put("1112", 105);
    		hm.put("1111", 1000);
    		
    		hm.put("2", 1);
    		hm.put("21", 5);
    		hm.put("22", 10);
    		hm.put("221", 15);
    		hm.put("222", 100);
    		hm.put("2221", 105);
    		hm.put("2222", 1000);
    	}
    	
    	public void actionPerformed(ActionEvent e){
    		//悔棋操作,将棋子数目减一,然后重绘界面即可
    		if("悔棋".equals(e.getActionCommand())&&index>0){
    			System.out.println("悔棋");
    			index--;
    			point[orderx[index]][ordery[index]]=0;
    			fb.paint(g);
    		}
    		//人机模式一旦点击,界面所有棋子清零,开始人机对战(pc=1)
    		if("人机".equals(e.getActionCommand())){
    			System.out.println("人机");
    		    pc=1;
    		    index=0;
    		    for(int i=X0;i<=X0+WID*LINE;i+=WID){
    			    for(int j=Y0;j<=Y0+WID*LINE;j+=WID){
    			    	point[i][j]=0;		  
    			    }
    		    }
    		    fb.paint(g);
    		}
    		//人人对战,也是点击按钮棋子清零,开始人人对战(pc=0)
    		if("人人".equals(e.getActionCommand())){
    			System.out.println("人机");
    		    pc=0;
    		    index=0;
    		    for(int i=X0;i<=X0+WID*LINE;i+=WID){
    			    for(int j=Y0;j<=Y0+WID*LINE;j+=WID){
    			    	point[i][j]=0;		  
    			    }
    		    }
    		    fb.paint(g);
    		}
    	}
    	
    	public void mouseClicked(MouseEvent e) {
    		x=e.getX();
    		y=e.getY();
    		//得到点击的点
    		if((x-X0)%WID>=WID/2){
    			x=x-(x-X0)%WID+WID;
    		}
    		else{
    			x=x-(x-X0)%WID;
    		}
    		if((y-Y0)%WID>=WID/2){
    			y=y-(y-Y0)%WID+WID;
    		}
    		else{
    			y=y-(y-Y0)%WID;
    		}
    		//对点的位置进行修正(保证每次点击都正好下在网格交汇处)
    		if(point[x][y]==0&&x>=X0&&x<=X0+WID*LINE&&y>=Y0&&y<=Y0+WID*LINE){
    			//人人对战:直接用鼠标检测,依次变换颜色黑或白
    			if(pc==0){
    				if(g.getColor()==Color.black){
    					g.setColor(Color.WHITE);
    					CO=2;
    				}
    				else{
    					g.setColor(Color.BLACK);
    					CO=1;
    				}
    			}
    			//人机对战,每次人下过棋子之后,计算机根据现有棋盘布局对棋局分析和总和并判断机器需要下的位置
    			else if(pc==1){
    				g.setColor(Color.BLACK);
    				CO=1;
    			}
    			g.fillOval(x-WID/2, y-WID/2, WID, WID);
    		    point[x][y]=CO;
    		    System.out.println(index+ " "+ x+" "+y);
    		    orderx[index]=x;
    		    ordery[index]=y;
    		    index++;
    		    if(exam()==0){
    		    	//自己敲代码过程中的验证、、、、、、可以不用在意这类输出。
    		    	System.out.println("hahahahhhaahhahah");
    		    	if(pc==1){
    		    		System.out.println("HEHEHEHEHEHEHEHEHEHEHE");
    		    		g.setColor(Color.WHITE);
    		    		CO=2;
    		    		AI();
    		    		exam();
    		    	}
    		    }
    		}
    		
    	}
        //检测是否有一方获胜,跳出提示框提示某一方获胜
    	public int exam(){
    		int w=0;
    		for(int i=X0-WID;i<=X0+WID*(LINE+1);i+=WID){
    			for(int j=Y0-WID;j<=Y0+WID*(LINE+1);j+=WID){
    				if(point[i][j]!=0){
    					int exam1=0,exam2=0,exam3=0,exam4=0;
    					//水平、竖直、左斜、右斜四个方向上同色棋子相连最多的个数
    					for(int t=WID;t<5*WID;t+=WID){
    						if(i+t<=X0+WID*(LINE+1)&&point[i+t][j]==point[i][j]){
    							exam1++;
    						}
    						if(j+t<=Y0+WID*(LINE+1)&&point[i][j+t]==point[i][j]){
    							exam2++;
    						}
    						if(i+t<=X0+WID*(LINE+1)&&j+t<=Y0+WID*(LINE+1)&&point[i+t][j+t]==point[i][j]){
    							exam3++;
    						}
    						if(i+t<=X0+WID*(LINE+1)&&j>=t&&point[i+t][j-t]==point[i][j]){
    							exam4++;
    						}
    					}
    					System.out.println(exam1+" "+exam2+" " +exam3+" "+exam4);
    					if(exam1==4||exam2==4||exam3==4||exam4==4){//某一方向上同色5子相连,一方获胜
    						if(point[i][j]==1){
    							w=1;
    							//弹出提示框
    							JOptionPane.showMessageDialog(null, "黑子胜");
    						}
    						else{
    							w=2;
    							JOptionPane.showMessageDialog(null, "白子胜");							
    						}
    						i=X0+WID*(LINE+1)+1;
    						break;
    					}
    				}
    			}
    		}
    		return w;
    	}
    	//AI算法
    	//分别向左、香油、左下、、、、、等8个方向检测棋子布局情况并累加在该点的权值上
    	//再找出图片上没有棋子并且权值最大的点下棋子
    	//记得每次下棋将各个空位置的权值归0,以便下一次计算权值累加
    	public void AI(){
    		for(int i=X0;i<X0+WID*(LINE+1);i+=WID){
    		   	for(int j=Y0;j<Y0+WID*(LINE+1);j+=WID){
    				if(point[i][j]==0){
    					//像右寻找
    					//System.out.print("pointweight["+(i-X0)/WID+"]["+(j-Y0)/WID+"]:");
    					int color=0;
    					String code="";
    					for(int k=i+WID;k<=X0+WID*LINE;k+=WID){
    						if(point[k][j]!=0){
    							if(color==0){
    								color=point[k][j];
    								code+=point[k][j];
    							}
    							else{
    								if(point[k][j]==color){
    									code+=point[k][j];
    								}
    								else{
    									code+=point[k][j];
    									break;
    								}
    							}
    						}
    						else{
    							break;
    						}
    					}
    					Integer value=hm.get(code);
    					if(value != null){
    						pointweight[i][j] += value;
    					}
    					//向下寻找
    //					System.out.print(pointweight[i][j]+" ");
    					code="";
    					color=0;
    					for(int k=j+WID;k<=X0+WID*LINE;k+=WID){
    						if(point[i][k]!=0){
    							if(color==0){
    								color=point[i][k];
    								code+=point[i][k];
    							}
    							else{
    								if(point[i][k]==color){
    									code+=point[i][k];
    								}
    								else{
    									code+=point[i][k];
    									break;
    								}
    							}
    						}
    						else{
    							break;
    						}
    					}
    					value=hm.get(code);
    					if(value != null){
    						pointweight[i][j] += value;
    					}
    					//向左
    //					System.out.print(pointweight[i][j]+" ");
    					code="";
    					color=0;
    					for(int k=i-WID;k>=X0;k-=WID){
    						if(point[k][j]!=0){
    							if(color==0){
    								color=point[k][j];
    								code+=point[k][j];
    							}
    							else{
    								if(point[k][j]==color){
    									code+=point[k][j];
    								}
    								else{
    									code+=point[k][j];
    									break;
    								}
    							}
    						}
    						else{
    							break;
    						}
    					}
    					value=hm.get(code);
    					if(value != null){
    						pointweight[i][j] += value;
    					}
    					//向上
    //					System.out.print(pointweight[i][j]+" ");
    					code="";
    					color=0;
    					for(int k=j-WID;k>=Y0;k-=WID){
    						if(point[i][k]!=0){
    							if(color==0){
    								color=point[i][k];
    								code+=point[i][k];
    							}
    							else{
    								if(point[i][k]==color){
    									code+=point[i][k];
    								}
    								else{
    									code+=point[i][k];
    									break;
    								}
    							}
    						}
    						else{
    							break;
    						}
    					}
    					value=hm.get(code);
    					if(value != null){
    						pointweight[i][j] += value;
    					}
    					//向右上寻找
    //					System.out.print(pointweight[i][j]+" ");
    					code="";
    					color=0;
    					for(int k=i+WID,w=j+WID;k<=X0+WID*LINE&&w<=Y0+WID*LINE;k+=WID,w+=WID){
    						if(point[k][w]!=0){
    							if(color==0){
    								color=point[k][w];
    								code+=point[k][w];
    							}
    							else{
    								if(point[k][w]==color){
    									code+=point[k][w];
    								}
    								else{
    									code+=point[k][w];
    									break;
    								}
    							}
    						}
    						else{
    							break;
    						}
    					}
    					value=hm.get(code);
    					if(value != null){
    						pointweight[i][j] += value;
    					}
    //					System.out.print(pointweight[i][j]+" ");
    					code="";
    					color=0;
    					for(int k=i-WID,w=j-WID;k>=X0&&w>=Y0;k-=WID,w-=WID){
    						if(point[k][w]!=0){
    							if(color==0){
    								color=point[k][w];
    								code+=point[k][w];
    							}
    							else{
    								if(point[k][w]==color){
    									code+=point[k][w];
    								}
    								else{
    									code+=point[k][w];
    									break;
    								}
    							}
    						}
    						else{
    							break;
    						}
    					}
    					value=hm.get(code);
    					if(value != null){
    						pointweight[i][j] += value;
    					}
    //					System.out.print(pointweight[i][j]+" ");
    					code="";
    					color=0;
    					for(int k=i+WID,w=j-WID;k<=X0+LINE*WID&&w>=Y0;k+=WID,w-=WID){
    						if(point[k][w]!=0){
    							if(color==0){
    								color=point[k][w];
    								code+=point[k][w];
    							}
    							else{
    								if(point[k][w]==color){
    									code+=point[k][w];
    								}
    								else{
    									code+=point[k][w];
    									break;
    								}
    							}
    						}
    						else{
    							break;
    						}
    					}
    					value=hm.get(code);
    					if(value != null){
    						pointweight[i][j] += value;
    					}
    //					System.out.print(pointweight[i][j]+" ");
    					code="";
    					color=0;
    					for(int k=i-WID,w=j+WID;k>=X0&&w<=Y0+LINE*WID;k-=WID,w+=WID){
    						if(point[k][w]!=0){
    							if(color==0){
    								color=point[k][w];
    								code+=point[k][w];
    							}
    							else{
    								if(point[k][w]==color){
    									code+=point[k][w];
    								}
    								else{
    									code+=point[k][w];
    									break;
    								}
    							}
    						}
    						else{
    							break;
    						}
    					}
    					value=hm.get(code);
    					if(value != null){
    						pointweight[i][j] += value;
    					}
    //					System.out.println(pointweight[i][j]);
    				}			
    			}
    		}
    		//寻找最大权值的点并画棋子
    		int maxx=X0,maxy=Y0;
    	    for(int i=X0;i<=X0+WID*LINE;i+=WID){
    		    for(int j=Y0;j<=Y0+WID*LINE;j+=WID){
    		    	System.out.print(pointweight[i][j]+" ");
    		    	if(pointweight[i][j]>pointweight[maxx][maxy]){
    		    		maxx=i;
    		    		maxy=j;
    		    	}
    			  
    		    }
    		    System.out.println();
    	    }
    	    g.fillOval(maxx-WID/2, maxy-WID/2, WID, WID); 
    	    point[maxx][maxy]=CO;
    	    System.out.println(index+ " "+ maxx+" "+maxy);
    	    orderx[index]=maxx;
    	    ordery[index]=maxy;
    	    index++;
    	    //全部权值归零方便下次使用
    	    for(int i=X0;i<=X0+WID*LINE;i+=WID){
    		    for(int j=Y0;j<=Y0+WID*LINE;j+=WID){
    		    	pointweight[i][j]=0;		  
    		    }
    	    }
    	}
    	
    }

    大概就是这个样子了,有时候还是有点人工智障,不用太费心就可以下赢它。。。。。。权值那里设置的还是需要调整一下。运行结果截图如下:

    展开全文
  • Java Applet实现五子棋游戏 从谷歌的AlphaGo到腾讯的绝艺,从人脸识别到无人驾驶,从谷歌眼镜到VR的兴起,人工智能领域在不断的向前迈进,也在不断深入的探索。但背后错综复杂的技术和利益成本也是很多...

    从谷歌的AlphaGo到腾讯的绝艺,从人脸识别到无人驾驶,从谷歌眼镜到VR的兴起,人工智能领域在不断的向前迈进,也在不断深入的探索。但背后错综复杂的技术和利益成本也是很多企业亟待解决的难题。对于人工智能,我们可能还帮不上什么忙,但我相信以后的人工智能技术会越来越开源,也会提供给我们便捷开发的接口。由围棋大战引发的思考才是我们今天的主题,我们今天是利用Java Applet窗口应用程序来实现五子棋的一个小游戏,最基础的一个版本,主要回顾一下Applet的应用以及Graphics画图技术。

    首先,我们先来看一下运行结果的预览图:

    第一眼看上去是不是觉得很多元素,不太好下手,其实右边的按钮和和其他的文字都是背景图片自带的,只有中间的纵横线和棋子是我们画上去的,而且托朋友@郑宇轩多做了几张图,点击右上角的换肤按钮可以实现换肤效果,游戏设置可以设置游戏时间,下方有分别针对黑方和白方的计时器,哪一方的规定时间一到如果还没落子就算输。顶部有本轮该谁的信息提醒。

    一、需求分析

    要想实现这样一个功能其实也不难,其实就是一张背景图,上面有各种按钮,我们可以通过获取鼠标坐标来设置点击事件,至于棋盘的格子,我们可以采用Graphics画图就是了,包括棋子也是,时间的计算就以落子开始以秒为单位向下递减。5子连一线有多种情况,横连,竖连,左45度斜连,右45度斜连,同样可以根据坐标位置来判断,我们开始就可以定义一个数组,分别记录每一次黑白落子的坐标位置。基本的功能也就这些,我们这里就不考虑国际规定的禁手规则了。

    二、开发

    1.首先定义一个类OperatorPane,这个类用来布置整个布局,包括画棋盘棋子什么的,判断几种连法,时间的设置等。如下图:

     

     

    我们需要建一个存放背景图片的文件夹,如下图:

     

     

     

    接下来,我们写个测试类GomokuGrame,导入我们刚刚定义的布局类。

     

    三、测试

    接下来我们就开始运行程序,如下:

     

     

    好玩吗?今天就到这里了,主要是关于Applet窗体应用程序和Graphics画图的一些技术的使用,都是一些基础的东西,主要是先理清这里面的逻辑思维,明白了需求再下手,一切就都变的很清晰,很明朗。

    如果您对本文观点有什么异议,欢迎您的留言,我们一起交流!

    posted on 2017-03-28 17:40  ++i和i++ 阅读( ...) 评论( ...) 编辑 收藏

    转载于:https://www.cnblogs.com/ao-xiang/p/6636003.html

    展开全文
  • 游戏截图: 看一下运行效果 这里我使用的开发工具是Eclipse 主要代码Main.java: ... final JLabel logoLabel = new JLabel("开心五子棋"); final JLabel logo = new JLabel(); final JButton logi

    游戏截图:
    在这里插入图片描述

    看一下运行效果

    在这里插入图片描述
    这里我使用的开发工具是Eclipse

    主要代码Main.java:

    public class Main extends JFrame{
    	/*
    	 * 用户登录
    	 */
    	private static final long servialVersionUID = 1L;
    	
    	final JLabel logoLabel = new JLabel("开心五子棋");
    	final JLabel logo = new JLabel();
    	final JButton loginButton = new JButton("登陆");
    	final JLabel registerLabel = new JLabel("立即注册");
    	final JLabel userLabel = new JLabel("账号:");
    	final JLabel passwordLabel = new JLabel("密码:");
    	final static JTextField userjt = new JTextField(11);
    	final JPasswordField passwordjt = new JPasswordField(11);
    	final JCheckBox rememberPasswordjcb = new JCheckBox();
    	final JLabel rememberPasswordjl = new JLabel("记住密码");
    	final JCheckBox automaticLoginjcb = new JCheckBox();
    	final JLabel automaticLoginjl = new JLabel("自动登录");
    	final JLabel promptPasswordFalse = new JLabel("密码错误!");
    	final JLabel promptRegister = new JLabel("该账号还未注册!");
    	final JLabel promptUserNameEmpty = new JLabel("请输入账号!");
    	final JLabel prompPasswordEmpty = new JLabel("请输入密码!");
    	final Color color = new Color(255, 218, 185);
    	final FileOperation read = new FileOperation();//创建文件对象
    	final FileOperation f = new FileOperation();
    	public Main() {
    		setTitle("开心五子棋");
    		setBounds(200, 200, 500, 500);
    		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    		setVisible(true);
    		
    		//基本布局设置
    		SpringLayout springLayout = new SpringLayout();//使用弹簧布局管理器
    		Container c = getContentPane();//创建容器
    		c.setBackground(new Color(255, 218, 185));
    		c.setLayout(springLayout);
    		
    		userjt.setFont(new Font("微软雅黑", 0, 18 ));
    		userjt.setText(Register.userName);
    		passwordjt.setFont(new Font("微软雅黑", 0, 18));
    		passwordjt.setText(Register.password);
    		logoLabel.setFont(new Font("微软雅黑", 1, 48));
    		logoLabel.setForeground(Color.pink);
    		ImageIcon logoimage = new ImageIcon(Main.class.getResource("/image/logo5.jpg"));
    		logoimage.setImage(logoimage.getImage().getScaledInstance(260, 130, Image.SCALE_DEFAULT));
    		logo.setIcon(logoimage);
    		userLabel.setFont(new Font("微软雅黑", 1, 20));
    		passwordLabel.setFont(new Font("微软雅黑", 1, 20));
    		rememberPasswordjl.setFont(new Font("微软雅黑", 0, 14));
    		rememberPasswordjl.setForeground(Color.gray);
    		automaticLoginjl.setFont(new Font("微软雅黑", 0, 14));
    		automaticLoginjl.setForeground(Color.gray);
    		loginButton.setFont(new Font("微软雅黑", 1, 16));
    		registerLabel.setFont(new Font("微软雅黑", 1, 13));
    		registerLabel.setForeground(Color.gray);
    		promptPasswordFalse.setFont(new Font("微软雅黑", 0, 13));
    		promptPasswordFalse.setForeground(Color.red);
    		promptUserNameEmpty.setFont(new Font("微软雅黑", 0, 13));
    		promptUserNameEmpty.setForeground(Color.red);
    		prompPasswordEmpty.setFont(new Font("微软雅黑", 0, 13));
    		prompPasswordEmpty.setForeground(Color.red);
    		promptRegister.setFont(new Font("微软雅黑", 0, 13));
    	    promptRegister.setForeground(Color.red);
    	    rememberPasswordjcb.setBackground(new Color(255, 218, 185));
    	    automaticLoginjcb.setBackground(new Color(255, 218, 185));
    	    
    	    c.add(logo);//首页图标
    	    springLayout.putConstraint(springLayout.NORTH, logo, 40, springLayout.NORTH, c);
    	    springLayout.putConstraint(springLayout.WEST, logo, 115, springLayout.WEST, c);
    		c.add(logoLabel);//标题“开心五子棋”
    		springLayout.putConstraint(springLayout.NORTH, logoLabel, 100, springLayout.NORTH, c);
    		springLayout.putConstraint(springLayout.WEST, logoLabel, 120, springLayout.WEST, c);
    		logoLabel.setVisible(false);
    		
    		c.add(userLabel);//用户名
    		springLayout.putConstraint(springLayout.NORTH, userLabel, 35, springLayout.SOUTH, logoLabel);
    		springLayout.putConstraint(springLayout.WEST, userLabel, 110, springLayout.WEST, c);
    		c.add(userjt);
    		springLayout.putConstraint(springLayout.NORTH, userjt, 35, springLayout.SOUTH, logoLabel);
    		springLayout.putConstraint(springLayout.WEST, userjt, 10, springLayout.EAST, userLabel);
    		
    		c.add(passwordLabel);//密码
    		springLayout.putConstraint(springLayout.NORTH, passwordLabel, 10, springLayout.SOUTH, userLabel);
    		springLayout.putConstraint(springLayout.WEST, passwordLabel, 110, springLayout.WEST, c);
    		c.add(passwordjt);
    		springLayout.putConstraint(springLayout.NORTH, passwordjt, 10, springLayout.SOUTH, userjt);
    		springLayout.putConstraint(springLayout.WEST, passwordjt, 10, springLayout.EAST, passwordLabel);
    		
    		c.add(rememberPasswordjcb);//复选框
    		springLayout.putConstraint(springLayout.NORTH, rememberPasswordjcb, 10, springLayout.SOUTH, passwordLabel);
    		springLayout.putConstraint(springLayout.WEST, rememberPasswordjcb, 175, springLayout.WEST, c);
    		c.add(rememberPasswordjl);
    		springLayout.putConstraint(springLayout.NORTH, rememberPasswordjl, 10, springLayout.SOUTH, passwordjt);
    		springLayout.putConstraint(springLayout.WEST, rememberPasswordjl, 5, springLayout.EAST, rememberPasswordjcb);
    		c.add(automaticLoginjcb);
    		springLayout.putConstraint(springLayout.NORTH, automaticLoginjcb, 10, springLayout.SOUTH, passwordjt);
    		springLayout.putConstraint(springLayout.WEST, automaticLoginjcb, 30, springLayout.EAST, rememberPasswordjl);
    		c.add(automaticLoginjl);
    		springLayout.putConstraint(springLayout.NORTH, automaticLoginjl, 10, springLayout.SOUTH, passwordjt);
    		springLayout.putConstraint(springLayout.WEST, automaticLoginjl, 5, springLayout.EAST, automaticLoginjcb);
    		
    		c.add(loginButton);//登陆按钮
    		springLayout.putConstraint(springLayout.NORTH, loginButton, 20, springLayout.SOUTH, rememberPasswordjl);
    		springLayout.putConstraint(springLayout.WEST, loginButton, 110, springLayout.WEST, c);
    		c.add(registerLabel);//注册按钮
    		springLayout.putConstraint(springLayout.NORTH, registerLabel, 5, springLayout.SOUTH, loginButton);
    		springLayout.putConstraint(springLayout.WEST, registerLabel, 320, springLayout.WEST, c);
    		
    		c.add(promptRegister);//账号未注册提示
    		promptRegister.setVisible(false);
    	    springLayout.putConstraint(springLayout.NORTH, promptRegister, 41, springLayout.SOUTH, logoLabel);
    		springLayout.putConstraint(springLayout.WEST, promptRegister, 5, springLayout.EAST, userjt);
    		c.add(promptUserNameEmpty);//请输入账号
    		promptUserNameEmpty.setVisible(false);
    	    springLayout.putConstraint(springLayout.NORTH, promptUserNameEmpty, 41, springLayout.SOUTH, logoLabel);
    		springLayout.putConstraint(springLayout.WEST, promptUserNameEmpty, 5, springLayout.EAST, userjt);
    		
    		c.add(promptPasswordFalse);//密码错误提示
    		promptPasswordFalse.setVisible(false);
    		springLayout.putConstraint(springLayout.NORTH, promptPasswordFalse, 20, springLayout.SOUTH, promptRegister);
    		springLayout.putConstraint(springLayout.WEST, promptPasswordFalse, 5, springLayout.EAST, passwordjt);
    		c.add(prompPasswordEmpty);//密码为空提示
    		prompPasswordEmpty.setVisible(false);
    		springLayout.putConstraint(springLayout.NORTH, prompPasswordEmpty, 20, springLayout.SOUTH, promptRegister);
    		springLayout.putConstraint(springLayout.WEST, prompPasswordEmpty, 5, springLayout.EAST, passwordjt);
    		
    		//设置文本框鼠标点击事件
    		userjt.addMouseListener(new MouseAdapter() {//文本框
    			public void mouseClicked(MouseEvent e) {
    				userjt.setText("");
    			}
    		});
    		passwordjt.addMouseListener(new MouseAdapter() {//密码框
    			public void mouseClicked(MouseEvent e) {
    				passwordjt.setText("");
    			}
    		});
    		
    		//设置登陆按钮单击事件
    		loginButton.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				String userName = userjt.getText().trim();//获取用户输入的账号和密码
    				String Password = new String(passwordjt.getPassword()).trim();
    				//判断账号和密码
    			    if(userName.length() != 0) {//用户名不为空
    			    	promptUserNameEmpty.setVisible(false);//关闭账号为空显示
    			    	if(Password.length() != 0) {//密码不为空
    			    		if(f.readData("user.xls", userName) && Password.equals(f.backData("user.xls", userName, "password"))) {//用户输入的账号和密码正确
    							promptRegister.setVisible(false);//隐藏提示信息
    							promptPasswordFalse.setVisible(false);
    							prompPasswordEmpty.setVisible(false);
    							loginButton.setText("                登 陆 中...               ");
    							new Chessboard();//跳转到五子棋棋盘页面
    							dispose();//销毁当前页面
    						}
    			    		else if( f.readData("user.xls", userName) && !Password.equals(f.backData("user.xls", userName, "password"))) {//用户输入密码错误
    							promptPasswordFalse.setVisible(true);//显示密码错误提示
    							promptRegister.setVisible(false);
    							prompPasswordEmpty.setVisible(false);
    							passwordjt.setText("");//密码框清空
    							passwordjt.requestFocus();//光标定位到密码框
    						}else {//账号还未注册
    							promptRegister.setVisible(true);
    					    	promptPasswordFalse.setVisible(false);
    							prompPasswordEmpty.setVisible(false);
    						}
    			        }
    			        else {//密码为空
    			        	if(userName.equals("admin")) {//用户名已经注册, 提示输入密码
    			        		prompPasswordEmpty.setVisible(true);
    				        	promptUserNameEmpty.setVisible(false);
    				        	promptRegister.setVisible(false);
    					    	promptPasswordFalse.setVisible(false);
    			        	}else {//用户名未注册
    			        		prompPasswordEmpty.setVisible(false);
    				        	promptUserNameEmpty.setVisible(false);
    				        	promptRegister.setVisible(true);
    					    	promptPasswordFalse.setVisible(false);
    			        	}
    			        	
    			        }
    			    }else {//用户名为空
    			    	promptUserNameEmpty.setVisible(true);//提示输入账号
    			    	promptRegister.setVisible(false);
    			    	promptPasswordFalse.setVisible(false);
    			    	prompPasswordEmpty.setVisible(false);
    			    	passwordjt.setText("");//将密码框置为空
    			    	if(Password.length() == 0) {//密码为空
    			    		prompPasswordEmpty.setVisible(true);
    			    		promptRegister.setVisible(false);
    				    	promptPasswordFalse.setVisible(false);
    			    	}
    			    }
    			}
    		});
    		
    		//注册标签监听器
    		registerLabel.addMouseListener(new MouseListener() {
    			public void mouseClicked(MouseEvent e) {
                    dispose();
    				new Register();
    			}
    			public void mouseEntered(MouseEvent e) {
    				registerLabel.setForeground(Color.red);;
    			}
    			public void mouseExited(MouseEvent e) {
    			    registerLabel.setForeground(Color.black);
    			}
    			public void mousePressed(MouseEvent e) {}
    			public void mouseReleased(MouseEvent e) {}
    		});
    	}
    	public static void main(String[] args) {
    		// TODO 自动生成的方法存根
            new Main();
    	}
    
    }
    

    选择Main.java点击运行,第一次登陆之前需要注册,注册后会在目录中生成user.xls
    在这里插入图片描述
    在这里插入图片描述

    user.xls用于记录用户名;密码;积分:用户当前积分,初级,中级和高级对应获得100,200和300分,如果已经出现一方获胜,则悔棋不能改变积分;胜场;总场,是否记住密码,是否自动登录和注册日期,充当的是简易版的数据库。

    源码获取

    1.CSDN积分下载地址:

    https://download.csdn.net/download/qq_44273429/15210290

    2.关注作者公众号海拥回复java五子棋小游戏免费获取

    更多内容

    长按识别二维码关注微信公众号

    在这里插入图片描述
    最后,不要忘了❤或📑支持一下哦

    展开全文
  •  我写五子棋界面与画图板的方法相类似,也是用到了JFrame中创建窗体的方法,并且用JButton创建“悔棋”按键对象,添加到窗体上(我在窗体右边添加了一个JPanel对象来放置按键)。既然要实现下棋,那就需要用到监听...
  • 最近设计了一款经典的小游戏,五子棋。网上应该能找的都是海量的,不过我希望通过设计该五子棋,完成更有难度的联网版游戏设计,真实实践之后才会收获新的技能。  本次将真正从无到有,手把手一步一步交给各位完整...
  • 画板和五子棋的保存

    2011-04-08 16:18:24
    画板重绘、保存的总结 重绘: 最初制作的画板在窗体缩小后再打开便没有了所画的图形,要想使改变窗体后所画的东西...在给形状按钮添加动作监听时,需要使用 按钮名.setActioncommand("sth"); 命令,...
  • 基于人工神经网络的五子棋博弈(Details)

    万次阅读 多人点赞 2016-07-24 10:21:09
    基于ANN的Gobang AI 关键词:五子棋博弈;人工神经网络;强化学习;博弈树搜索;α-β剪枝
  • 人工智能:五子棋项目 这是我的第一篇博客。 最近刚好有空,整理一下上学期《人工智能基础》课程的大作业项目。 四个实验代码已上传至我的github:https://github.com/TommyGong08/Gobang_AI 有兴趣的小伙伴可以...
  • 数据集地址: ...相关大作业进度的博客: 【BIT大作业】人工智能+五子棋实战(一)棋子目标检测 【BIT大作业】人工智能+五子棋实战(二)...同时由于目标比较好识别,所以使用轻量级的MobileNet作为主干网络。 写代码不
  • Java swing + socket 写的一个五子棋网络对战游戏

    千次阅读 多人点赞 2018-05-12 23:51:27
    网络对战版本的五子棋游戏,包含服务端和客户端(c/s模式) ,写成此文章给需要或想研究的人一些参考(相关代码我会放在本文的最后) 游戏效果图: ![这里写图片描述]...
  • matlab五子棋代码大学_项目 我在大学里做过的一系列项目 FFA报告中的飞机野生动植物罢工分类:通过使用降维和PCA分析等技术准备数据集而贡献。 为8个ML模型创建了测试环境和编码方法,并在性能最佳的模型上调整了超...
  • java实现网络五子棋源码人工智能数独 一个用人工智能解决数独棋盘的实验 介绍 2017年,我加入了一个讨论人工智能基础知识的俱乐部,并尝试制作自己的人工智能项目。 我发现它非常有趣,然而,当时我在数学和计算机...
  • //记录每一步棋子的坐标位置 int chess_num = 0; //总棋子数 char p1_time = time; //黑棋剩余时间 char p2_time = time; //白棋剩余时间 extern u16 POINT_COLOR; //画笔颜色 void start1()//开始游戏 { Oninit...
  •  //画完棋盘之后就要找到落棋点并画上棋子,而我们都知道鼠标单击一下落一个子,那么就需要加入一个鼠标监听里监听鼠标的动作,在MouseListener这个接口中有很多方法,比如单击,释放,退出等等,我们要找到...
  • :自定义挑战对手、自定义头像、人机对战、发送视频(原理同语音消息),画框来提示上一步落子的位置 有待改进 :发送大数据包导致的掉线和内存占用率高问题、刷新玩家列表导致玩家掉线的问题,接收数据时延迟较...
  • 有关监听事件的这个插件实际上并不完善不过当前的应用层次已经足够,该插件支持识别鼠标动作和移动设备触屏动作,但缺点是目前还不能识别多指触屏,因为还是比较懒的……当然,我们不是去做一个MOBA游戏,没那么复杂...
  •  abc模块中还有一个叫abstractmethon,通过这个包装,可以将方法包装为抽象方法, 必须要求子类重写。 rom abc import ABCMeta, abstractmethod class Employee(object, metaclass= ABCMeta): """ ...
  • python opencv人脸识别考勤系统 如需安装运行环境或远程调试,可加QQ905733049,或QQ2945218359由专业技术人员远程协助! 运行结果如下: 代码如下: import wx import wx.grid from time import localtime,...
  • VC++公安指纹识别系统

    千次阅读 2014-03-25 22:40:00
    论文题目:公安指纹识别系统 开发语言:VC 包括内容:论文+可执行程序+源码+外文翻译+程序操作演示录像 数 据 库:无 论文字数:39000字以上 联系电话:15325823781 ...
  •  最简单平凡的分类也许是那种死记硬背式的分类,记住所有的训练数据,对于新的数据则直接和训练数据匹配,如果存在相同属性的训练数据,则直接用它的分类来作为新数据的分类。这种方式有一个明显的缺点,那就是...
  • 1、五子棋棋盘棋子识别检测 2021.2.25:开始,初版,找到了棋盘边缘图像 *****************************************************************************************/ #include<opencv2/opencv.hpp..
  • android安卓源码海量项目合集打包-1

    万次阅读 多人点赞 2019-06-11 16:16:24
    下载地址 最后更新共计113个分类5177套源码29.2 GB。 卷 新加卷 的文件夹 PATH 列表 卷序列号为 00000200 5E7A:7F30 ...│ │ Android 实现 标签 拖动 改变位置.rar │ │ android 流式布局和热门标签.zip │ │ ...
  • 深度学习模型

    2018-12-07 08:44:20
    官方模型 mnist:对来自MNIST数据集的数字进行分类的基本模型...由于深度学习模型的练习次数达到某一个值时识别准确率以及识别性能会下降,因而开发出了可以提高学习深度的网络。 wide_deep:将广泛的模型和深...
  • 输入一张包含手写数学题的图片,AI就能识别出输入的数学公式,然后给出计算结果。 不仅加减乘除基本运算,就连高等数学中的微积分都不在话下。 就像下面这样: 还在苦苦纠结高数作业如何求解?还在东奔西走的找...
  • 玩PyTorch?你不得不看的PyTorch资源大列表

    万次阅读 多人点赞 2020-02-29 18:16:32
    : TorchCraft的Python包装,TorchCraft是连接Torch和StarCraft的桥梁。 1000- aorun : Aorun试图以PyTorch为后端实现类似于Keras的API。 1000- logger : 机器学习记录(logger)。 1000- PyTorch-...
  • 《HelloGitHub》第 65 期

    2021-08-27 13:27:41
    包括五子棋、坦克大战、动态背景、动画粒子特效等 地址:https://github.com/bxm0927/canvas-special 34、brave-browser:快速、干净、开源的网页浏览器。由 JavaScript 的创造者布兰登·艾克基于 Chromium 网页...
  • 自动识别pojo字段的注释,并添加为sql注释。 11、控制台日志 高亮 Grep Console 推荐指数:☆☆☆☆☆ 推荐理由:没什么好说的, 基本是必备! 图片 图片 12、反编译插件 IdeaJad 推荐指数:☆☆☆☆☆ 推荐理由...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 456
精华内容 182
关键字:

五子棋位置识别器