Java五子棋(人机)二

 

思路

先要有个界面才能开始游戏->窗体

要有选择的娱乐模式->按钮(开始,悔棋,认输 ... 人机,人人)

点击之后可以得到响应,即画出个点->鼠标监听器,画出人下的棋子的方法

人类下完一个棋子,机器自动下一个,在此要考虑在哪里下->权值法,字面意思,下在最重要的点

                                                                                           ->   画出机器下子的点

把窗体的大小改变后,下过的棋子还在->重绘

判断输赢,并且明示输赢->判断输赢的方法,消息提示框(直接调用就好)

知识点总结:

 

1.悔棋

 

 

 

       比较严格,emmm就是懒,只准它悔一步棋。思路就是:我们每下一个点,就会记录他的点坐标。在悔棋按钮被选中时,将该坐标点储存的值改为0;记住count-1(记录下棋次数的要-1,为了保证人人对战时,悔棋结束再下子时颜色不改).再调用窗体类中画窗体棋子方法

        想悔棋多步,可用链表,或两个一维数组组合(之前提过,一维有序)

 

2.权值法

引入哈希表

1.创建权值表:全局变量HashMap<String,Integer> hm = new HashMap<String,Integer>();

泛型<>:(泛指类:类,接口,数组)

 //黑1人 白2机 
  

  hm.put("1", 20);
  hm.put("11", 200);
  hm.put("111", 2000);
  hm.put("1111", 3000);
  hm.put("12", 10);
  hm.put("112", 100);
  hm.put("1112", 1000);
  hm.put("11112", 2000);

  hm.put("2", 21);
  hm.put("22", 210);
  hm.put("222", 2100);
  hm.put("2222", 3100);
  hm.put("21", 11);
  hm.put("221", 110);
  hm.put("2221", 1100);
  hm.put("22221", 2100);

2.确定人机执子颜色:我规定人执黑子先行
3.根据得到的点进行权值最大的判断,在权值最大处下子:

        权值判断单写方法,同样判断以其为中心的八个方向棋子的权值,将数据存在一个二维数组中

        chessValue[i][j]=各个方向累加权值;在棋盘位置为(i,j)的点的权值。

        遍历存权值的数组,找出最大的点 画棋子。

        活点才有权值

   4.机器每画完一个棋子,就清空权值数组

 

  3.这里有个单选按钮的使用方法
 

      因为人机,人人是两个选择,即两个单选按钮。选用一个,则另一个关闭。在这里引入一个全局变量做标记值

        if (jrb1.isSelected()) {
                  m = 1;
          } else if (jrb2.isSelected()) {
                   m = 0;
          }

源代码

public interface Config {
	//接口好像只能写public
	public static final int LINE=15;
	public static final int X1=30;
	public static final int Y1=30;
	public static final int X0=60;
	public static final int Y0=60;
	public static final int SIZE=40;
	public static final int CHESS=30;
}

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;

import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

//画窗体 监听器
public class DrawFrame extends JPanel implements Config {

	public static void main(String[] args) {
		DrawFrame h = new DrawFrame();
		h.ShowUI();
	}

	private ImageIcon icon = new ImageIcon("F:\\java\\timg.jpg");
	public int[][] array = new int[LINE][LINE];
	public int[][] array1 = new int[LINE][LINE];

	public void paint(Graphics gr) {
		super.paint(gr);
		gr.drawImage(icon.getImage(), 0, 0, this.getWidth(), this.getHeight(), null);

		// 画棋盘框框
		gr.drawRect(X1, Y1, X1 + LINE * SIZE, X1 + LINE * SIZE);
		// 画棋盘
		for (int i = 0; i < LINE; i++) {
			gr.drawLine(X0 + SIZE * i, Y0, X0 + i * SIZE, Y0 + SIZE * (LINE - 1));
			gr.drawLine(X0, Y0 + i * SIZE, (LINE - 1) * SIZE + X0, Y0 + i * SIZE);
		}
		// 画出棋子
		for (int i = 0; i < array.length; i++)
			for (int j = 0; j < array[i].length; j++) {
				if (array[i][j] != 0) {
					if (array[i][j] == 1) // 黑棋1 白棋2
					{
						gr.setColor(Color.black);
					} else {
						gr.setColor(Color.white);
					}
					int x = X0 + i * SIZE - CHESS / 2;
					int y = Y0 + j * SIZE - CHESS / 2;
					gr.fillOval(x, y, CHESS, CHESS);
				}
			}
	}

	public void ShowUI() {
		JFrame jf = new JFrame();
		jf.setTitle("简易五子棋");
		jf.setSize(800, 700);
		// 退出窗体方法
		jf.setDefaultCloseOperation(3);
		// 居中显示
		jf.setLocationRelativeTo(null);
		// 设置窗体颜色
		jf.getContentPane().setBackground(Color.gray);
		// 把面板加入窗体中
		this.setBackground(Color.CYAN);
		jf.add(this, BorderLayout.CENTER);
		JPanel p1 = new JPanel();
		String[] str = { "开始", "认输", "悔棋", "博弈 ", "人机博弈", "人人博弈" };
		// BasicArrowButton箭头按钮、JButton、JcheckBox 复选框、
		// JRadioButton单选按钮、JToggleButton切换按钮,开关按钮,触发器按钮
		ButtonGroup bg = new ButtonGroup();
		GobangListener mouse = new GobangListener(array, this, array1);
		for (int i = 0; i < str.length; ++i) {
			if (i <= 2) {
				JButton but = new JButton(str[i]);
				p1.add(but);
				but.addActionListener(mouse);

			} else if (i == 3) {
				JLabel jl = new JLabel(str[i]);
				p1.add(jl);
			} else {
				JRadioButton jrb = new JRadioButton(str[i]);
				jrb.setPreferredSize(new Dimension(90, 30));
				// 如果为 true,则该组件绘制其边界内的所有像素。否则该组件可能不绘制部分或所有像素,从而允许其底层像素透视出来。
				// 对于 JComponent 而言,此属性的默认值是 false。
				// 但是对于大多数标准的 JComponent 子类(如 JButton 和 JTree),此属性的默认值与外观有关。
				// 不透明
				jrb.setOpaque(false);
				// 设置按钮的状态。注意,此方法不会触发 actionEvent
				// 如果选择了按钮,则该参数为 true,否则为 false
				jrb.setSelected(true);
				bg.add(jrb);
				p1.add(jrb);
				jrb.addActionListener(mouse);
				if ("人机博弈".equals(jrb.getActionCommand())) {
					mouse.setb1(jrb);
				} else {
					mouse.setb2(jrb);
				}
			}
		}
		jf.add(p1, BorderLayout.EAST);
		p1.setPreferredSize(new Dimension(90, 0));
		p1.setLayout(new FlowLayout(10, 10, 30));
		// 窗体可见
		jf.setVisible(true);
		// 得到画笔
		Graphics gr = this.getGraphics();
		mouse.setG(gr);
		p1.addMouseMotionListener(mouse);

	}
}

 

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.JCheckBox;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

import com.zn.Gobang0527.Config;

public class GobangListener extends MouseAdapter implements Config, ActionListener {
	private int x, y, xx, yy;
	private int count = 0;
	private Graphics gr;
	private int w, m = 0;
	private int h;
	private int[][] array;
	private int[][] chessValue = new int[LINE][LINE];
	private int chessx, chessy, maxvalue = 0, mayvalue = 0;
	// &&"人机博弈".equals(Str)==false
	private String Str;
	private JPanel jp;
	// 调用方法要写在方法里
	private Judge j;
	private DrawFrame df;
	private JRadioButton jrb1, jrb2;
	public static final HashMap<String, Integer> hm = new HashMap<String, Integer>();

	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand() != null) {
			Str = e.getActionCommand();
			if ("悔棋".equals(Str)) {
				df.addMouseListener(this);
				array[chessx][chessy] = 0;
				count--;
				// System.out.println("count "+count);
				if(m==1){
					array[maxvalue][mayvalue]=0;
				}
				df.repaint();
			}
			if ("开始".equals(Str)) {
				// 为何加监听器
				df.addMouseListener(this);
				for (int i = 0; i < array.length; ++i) {
					for (int j = 0; j < array[i].length; ++j) {
						array[i][j] = 0;
					}
				}
				count = 0;
				df.paint(gr);
			}
		}
		if ("认输".equals(Str)) {
			df.addMouseListener(this);
			JOptionPane.showMessageDialog(null, "Defect");
			for (int i = 0; i < array.length; ++i) {
				for (int j = 0; j < array[i].length; ++j) {
					array[i][j] = 0;
				}
			}
			count = 0;
			df.paint(gr);
		}
		if (jrb1.isSelected()) {
			m = 1;
		} else if (jrb2.isSelected()) {
			m = 0;
		}

		System.out.println("m = " + m);
	}

	private void c() {
		hm.put("1", 20);
		hm.put("11", 200);
		hm.put("111", 2000);
		hm.put("1111", 3000);
		hm.put("12", 10);
		hm.put("112", 100);
		hm.put("1112", 1000);
		hm.put("11112", 2000);

		hm.put("2", 21);
		hm.put("22", 210);
		hm.put("222", 2100);
		hm.put("2222", 3100);
		hm.put("21", 11);
		hm.put("221", 110);
		hm.put("2221", 1100);
		hm.put("22221", 2100);
	}

	/**
	 * 
	 */
	private void AI() {
		// 遍历每一个
		for (int i = 0; i < LINE; ++i) {
			for (int j = 0; j < LINE; ++j) {
				// 活点才有权值
				if (array[i][j] == 0) {
					String code = "";
					int color = 0;
					// 右
					for (int k = i + 1; k < chessValue.length; ++k) {
						// 后面点为空,不要
						if (array[k][j] == 0) {
							break;
						} else {
							if (color == 0) { // 右边第一颗棋子

								color = array[k][j]; // 保存颜色
								code += array[k][j]; // 保存棋局
							} else if (array[k][j] == color) { // 右边第二,三..同颜色棋子
								code += array[k][j]; // 保存棋局
							} else { // 右边不同颜色
								code += array[k][j]; // 保存棋局
								break;
							}
						}
					}
					Integer value = hm.get(code);
					if (value != null) {
						chessValue[i][j] += value; // 权值
						System.out.println("value   "+i+"   "+j+"   "+chessValue[i][j]);
					}
					// 左
					color = 0;
					code = "";
					for (int k = i - 1; k >= 0; --k) {
						// 后面点为空,不要
						if (array[k][j] == 0) {
							break;
						} else {
							if (color == 0) {// first chess
								code += array[k][j];
								color = array[k][j];
							} else if (color == array[k][j]) {// same color
								code += array[k][j];
							} else {
								code += array[k][j];
								break;
							}
						}
					}
					Integer value1 = hm.get(code);
					if (value1 != null) {
						chessValue[i][j] += value1;// 权值
						System.out.println("value   "+i+"   "+j+"   "+chessValue[i][j]);
					}
						// 上
						color = 0;
						code = "";
						for (int k = j + 1; k < chessValue.length; ++k) {
							// 后面点为空,不要
							if (array[i][k] == 0) {
								break;
							} else {
								if (color == 0) {// first chess
									code += array[i][k];
									color = array[i][k];
								} else if (color == array[i][k]) {// same color
									code += array[i][k];
								} else {// different color
									code += array[i][k];
									break;
								}
							}
						}
				
					Integer value2 = hm.get(code);
					if (value2 != null) {
						chessValue[i][j] += value2;// 权值
						System.out.println("value   "+i+"   "+j+"   "+chessValue[i][j]);
					}
					// 下
					color = 0;
					code = "";
					for (int k = j - 1; k >= 0; --k) {
						// 后面点为空,不要
						if (array[i][k] == 0) {
							break;
						} else {
							if (color == 0) {// first chess
								code += array[i][k];
								color = array[i][k];
							} else if (color == array[i][k]) {// same color
								code += array[i][k];
							} else {// different color
								code += array[i][k];
								break;
							}
						}
					}
					Integer value3 = hm.get(code);
					if (value3 != null) {
						chessValue[i][j] += value3;// 权值
						System.out.println("value   "+i+"   "+j+"   "+chessValue[i][j]);
					}
					// 左上
					color = 0;
					code = "";
					for (int k = i - 1, h = j - 1; k >= 0 && h >= 0; --k, --h) {
						if (array[k][h] == 0) {
							break;
						} else {
							if (color == 0) {// first chess
								color = array[k][h];
								code += array[k][h];
							} else if (color == array[k][h]) {// same
								code += array[k][h];
							} else {
								code += array[k][h];
								break;
							}
						}
					}
					Integer value4 = hm.get(code);
					if (value4 != null) {
						chessValue[i][j] += value4;// 权值
						System.out.println("value   "+i+"   "+j+"   "+chessValue[i][j]);
						// color = 0;
						// code = "";
					}
					// 左下
					color = 0;
					code = "";
					for (int k = i + 1, h = y + 1; k < chessValue.length && h < chessValue.length; ++k, ++h) {
						if (array[k][h] == 0) {
							break;
						} else {
							if (color == 0) {// first chess
								color = array[k][h];
								code += array[k][h];
							} else if (color == array[k][h]) {// same
								code += array[k][h];
							} else {
								code += array[k][h];
								break;
							}
						}
					}
					Integer value41 = hm.get(code);
					if (value41 != null) {
						chessValue[i][j] += value41;// 权值
						System.out.println("value   "+i+"   "+j+"   "+chessValue[i][j]);
					}
					// 右上
					color = 0;
					code = "";
					for (int k = i + 1, h = j - 1; k < chessValue.length&& h >= 0; ++k, --h) {
						if (array[k][h] == 0) {
							break;
						} else {
							if (color == 0) {// first chess
								color = array[k][h];
								code += array[k][h];
							} else if (color == array[k][h]) {// same
								code += array[k][h];
							} else {
								code += array[k][h];
								break;
							}
						}
					}
					value3 = hm.get(code);
					if (value3 != null) {
						chessValue[i][j] += value3;// 权值
						System.out.println("value   "+i+"   "+j+"   "+chessValue[i][j]);
						// color = 0;
						// code = "";
					}
					// 右下
					color = 0;
					code = "";
					for (int k = i - 1, h = j + 1; k >= 0 && h < chessValue.length; --k, ++h) {
						if (array[k][h] == 0) {
							break;
						} else {
							if (color == 0) {// first chess
								color = array[k][h];
								code += array[k][h];
							} else if (color == array[k][h]) {// same
								code += array[k][h];
							} else {
								code += array[k][h];
								break;
							}
						}
					}
					Integer value9 = hm.get(code);
					if (value9 != null) {
						chessValue[i][j] += value9;// 权值
						System.out.println("value   "+i+"   "+j+"   "+chessValue[i][j]);
						// color = 0;
						// code = "";
					}
				}
			}
		}
	}

	public GobangListener(int[][] array, DrawFrame df, int[][] array1) {
		this.array = array;
		// 对象只用调用一次
		j = new Judge(array);
		this.df = df;
		c();
	}

	public void setG(Graphics gr) {
		this.gr = gr;
	}

	public void mouseClicked(MouseEvent e) {
		x = e.getX();
		y = e.getY();
		// 只要点击,就是用这个方法,在此中判断
		drawchess(x, y);
		chessx = xx;
		chessy = yy;
	}

	/***
	 * 
	 * @param maxvalue2
	 * @param mayvalue2
	 */
	private void drawai() {
		//找出权值最大
		int max = chessValue[0][0];
		for (int i = 0; i < chessValue.length; i++) {
			for (int j = 0; j < chessValue.length; j++) {
				System.out.print(chessValue[j][i] + " ");
				if (chessValue[i][j] >= max) {
					max = chessValue[i][j];
					maxvalue = i;
					mayvalue = j;
				}
			}
			// 打印权值表
			System.out.println();
		}
		System.out.println();
		//画出人机的棋子
		array[maxvalue][mayvalue]=2;//传参过去
		gr.setColor(Color.WHITE);
		gr.fillOval(X0+maxvalue*SIZE-CHESS/2, Y0+mayvalue*SIZE-CHESS/2, CHESS, CHESS);
		this.judge(maxvalue, mayvalue);
			// 打印权值表
			System.out.println();
		}
//	}

	/**
	 * 
	 * @param x
	 * @param y
	 */
	public void drawchess(int x, int y) {
		w = (x - X0) % SIZE;
		h = (y - Y0) % SIZE;
		if (w < 0.5 * SIZE && h < 0.5 * SIZE) {
			x = x - w;
			y = y - h;
		} else if (w < 0.5 * SIZE && h > 0.5 * SIZE) {
			x = x - w;
			y = y - h + SIZE;

		} else if (w > 0.5 * SIZE && h > 0.5 * SIZE) {
			x = x - w + SIZE;
			y = y - h + SIZE;

		} else if (w > 0.5 * SIZE && h < 0.5 * SIZE) {
			x = x - w + SIZE;
			y = y - h;

		} else if (w == 0.5 * SIZE || h == 0.5 * SIZE) {
			JOptionPane.showMessageDialog(null, "棋子不能下在正中");
		}

		xx = (x - X0) / SIZE;
		yy = (y - Y0) / SIZE;

		if (xx < LINE && yy < LINE) {
			if (array[xx][yy] == 0) {
				if (m == 0) { // 人人
					// 黑棋先手 黑棋存类型为1 白棋为2 无为0
					if (count % 2 == 0) {
						gr.setColor(Color.black);
						array[xx][yy] = 1;
						prin();
					} else {
						gr.setColor(Color.white);
						array[xx][yy] = 2;
						prin();
					}
					gr.fillOval(x - CHESS / 2, y - CHESS / 2, CHESS, CHESS);
					count++;
					this.judge(xx, yy);
				}
				if (m == 1) {// 人机被选中
					gr.setColor(Color.BLACK);
					gr.fillOval(x - CHESS / 2, y - CHESS / 2, CHESS, CHESS);
					array[xx][yy] = 1;
					prin();
					//画一个棋子判断一下
					this.judge(xx, yy);
					AI();// 权值统计
					//画出人机棋子
					drawai();
					for (int i = 0; i < chessValue.length; ++i) {
						for (int j = 0; j < chessValue[i].length; ++j) {
							chessValue[i][j] = 0;
						}
					}
				}
			}
		}
	}
	public void prin(){
		for(int i=0;i<array.length;i++){
			for(int j=0;j<array.length;j++){
				System.out.print(array[j][i]+" ");
			}
			System.out.println();
		}
		System.out.println();
	}

	/**
	 * 
	 * @param xx
	 * @param yy
	 */
	public void judge(int xx, int yy) {
		// 行
		int numh = 1;
		for (int i = xx + 1; i <= LINE; ++i) {
			if (array[i][yy] == array[xx][yy]) {
				numh++;
			} else {
				break;
			}
		}
		for (int j = xx - 1; j >= 0; --j) {
			if (array[j][yy] == array[xx][yy]) {
				numh++;
			} else
				break;
		}
		// 列
		int nums = 1;
		for (int i = yy + 1; i <= LINE; ++i) {
			if (array[xx][i] == array[xx][yy]) {
				nums++;
				System.out.println("nums  " + nums);
			} else
				break;
		}
		for (int j = yy - 1; j >= 0; --j) {
			if (array[xx][j] == array[xx][yy]) {
				nums++;
			} else
				break;
		}
		// 斜left
		int numl = 1;
		for (int i = xx + 1, j = yy + 1; i <= LINE && j <= LINE; ++i, ++j) {
			if (array[i][j] == array[xx][yy]) {
				numl++;

			} else
				break;
		}
		for (int k = xx - 1, h = yy - 1; k >= 0 && h >= 0; --k, --h) {
			if (array[k][h] == array[xx][yy]) {
				numl++;
			} else
				break;
		}
		// 斜右
		int numr = 1;
		for (int i = xx - 1, j = yy + 1; i >= 0 && j <= LINE; --i, ++j) {
			if (array[i][j] == array[xx][yy]) {
				numr++;
			} else
				break;
		}
		for (int k = xx + 1, h = yy - 1; k <= LINE && h >= 0; ++k, --h) {
			if (array[k][h] == array[xx][yy]) {
				numr++;
			} else
				break;
		}
		System.out.println("numl = " + numl);
		if (numl >= 5 || nums >= 5 || numr >= 5 || numh >= 5) {
			if (array[xx][yy] == 1) {
				JOptionPane.showMessageDialog(null, "黑棋获胜");
			} else if (array[xx][yy] == 2) {
				JOptionPane.showMessageDialog(null, "白棋获胜");
			}
			for (int i = 0; i < array.length; ++i) {
				for (int j = 0; j < array[i].length; ++j) {
					array[i][j] = 0;
				}
			}
			
			df.paint(gr);
		}
	}

	public void setb1(JRadioButton jrb) {
		this.jrb1 = jrb;
	}

	public void setb2(JRadioButton jrb) {
		this.jrb2 = jrb;
	}
}

 

 

 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值