思路
先要有个界面才能开始游戏->窗体
要有选择的娱乐模式->按钮(开始,悔棋,认输 ... 人机,人人)
点击之后可以得到响应,即画出个点->鼠标监听器,画出人下的棋子的方法
人类下完一个棋子,机器自动下一个,在此要考虑在哪里下->权值法,字面意思,下在最重要的点
-> 画出机器下子的点
把窗体的大小改变后,下过的棋子还在->重绘
判断输赢,并且明示输赢->判断输赢的方法,消息提示框(直接调用就好)
知识点总结:
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;
}
}