五子棋人机对战实践项目

总的任务和目标

完成一个人机对战的五子棋项目,基本效果如下:

第一部分 Java绘图原理

1.   基本概念

像素,坐标

第二部分 绘制棋盘

1.   基本思路

在一个JPanel上绘制一个背景,然后绘制水平和垂直的若干条线,使其构成等距离的格子,通常是15*15(条线)。

2.   代码实现

第三部分 绘制棋子

1.   基本思路

使用drawOval()可以绘制空心的圆,使用fillOval()可以填充实心的圆。

2.   坐标计算

由于格子是水平和垂直的有下标的,而绘制时需要使用实际的像素坐标,所以,需要进行行列下标到像素坐标的转换:

int x = col * GRID_WIDTH;

int y = row * GRID_WIDTH;

3.   代码实现

(1)     ChessPanel代码:

第四部分 鼠标下棋

1.   基本思路

需要处理鼠标单点事件,获取鼠标所在的位置,然后计算出应该绘制棋子的行列下标,并使用一个二维数组来全局存储棋子的位置。

2.   鼠标位置与行列下标计算

int x = e.getX();

int y = e.getY();

int row = y / GRID_WIDTH;

 int col = x / GRID_WIDTH;

3.   代码实现

(1)      ChessPanel属性和构造方法代码:

(2)监听器类(内部类)代码:

(3)绘图代码:

第五部分 判断胜负

1.   基本思路

判断胜负是因为在当前位置(row, col)落子导致了胜负,所以,判断胜负其实是在当前落子位置为中心,横向搜索左边第4个位置开始到右边第4个位置(其余位置不需要考虑),或者从上到下,或者正向45度,或者反向45度位置。

2.   处理方法

处理方法有很多,可以采用计数的方式,也可以采用字符串连接的方式,此处采用了将从左边第4颗开始,到右边第4颗结束,将每颗的颜色表示成字符1(黑色)或者2(白色),只需要判断其中是否有连续的5个1或5个2,即“11111”或“22222”即可知道胜负。

3.   代码实现

(1)     监听器类(内部类)代码:

(2)checkWin判断胜负的代码:

/** 判断胜负

* @param row      落子的行下标

* @param col       落子的列下标

* @return 是否获胜,true-是,false-否

*/

public boolean checkWin(int row, int col) {}

(3)重置游戏状态

【目前代码】

 package wuziqi;

 import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel; public class wuziqijiemianDemo {
//创建窗口为主类的类部类并且继承自JFrame
public class Myjframe extends JFrame {
/**
* 用一个构造方法创建窗口
*/
public Myjframe() {
this.setTitle("五子棋");
this.setSize(620, 640);
//获取内容面板
Container cp = getContentPane();
//创建一个面板JPanel
JPanel jPanel = new MyJanel();
cp.add(jPanel);
//面板的背景颜色为黄色,便于下白棋与黑棋
jPanel.setBackground(Color.yellow);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
//窗口默认设置为显示屏的正中间
this.setLocationRelativeTo(null);
//不可改变窗口的大小
this.setResizable(false);
}
}
/**
* 创建一个面板继承自JPanel
* @author Administrator
*
*/
public class MyJanel extends JPanel {
//表示每个方格的大小
private static final int GRID_WIDTh = 40;
//棋盘的大小,代表棋盘的线的条数
private static final int LINE_COUNT = 15;
//设置黑棋子为1、白棋子为2、没有棋子为0(默认值)
public static final int BLACK=1;
public static final int WHITE=2;
//定义一个棋盘大小的数组用来存放黑棋和白棋的位置
int[][] chessItems=new int[LINE_COUNT][LINE_COUNT];
//定义一个标志位,代表黑棋先下(黑棋和白棋轮流下棋)
int flag=BLACK;
/**
* 构造方法用来画棋盘的棋子
*/
public MyJanel(){
/**
* 为这个面板添加一个鼠标点击事件,鼠标每点击一次,就在棋盘上下一个棋子
*使用适配器的方式添加鼠标点击事件
*/
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e){
/**
* 获取当前的鼠标点击的位置
*/
int x=e.getX();
int y=e.getY();
/**
* 因为棋盘是用二维数组的方式表示的,所以最后表示为二维数组的行与列
*/
int row=y/GRID_WIDTh;
int col=x/GRID_WIDTh;
//当前这个位置没有棋子(为零),可以下一个黑棋子
if(chessItems[row][col]==0){
if(flag==BLACK){
chessItems[row][col]=flag;
//下完黑棋下白棋
flag=WHITE;
//必须有,不然后面的白棋会覆盖黑棋
}
//当前这个位置没有棋子(为零),可以下一个白棋子
else{
chessItems[row][col]=flag;
//下完白棋下黑棋
flag=BLACK;
}
}
/**
* 每当下完一步棋之后便判断是否已经取胜
*/
if(checkImage(row,col)){
//显示对话窗口
JOptionPane.showMessageDialog(null, "your win");
//清空棋盘
clear();
}
//System.out.println(chessItems[row][col]);
}
});
}
/**
* 调用public void paintComponent(Graphics arg0){};方法画图
*/
public void paintComponent(Graphics g) {
//系统调用
super.paintComponent(g);
// g.setColor(Color.yellow);
// g.fillRect(0, 0, jPanel.width(),jPanel.height());
/**
* 画横线,起始位置在窗口左上定点(GRID_WIDTh/2,GRID_WIDTh/2)
*/
for (int i = 0; i < LINE_COUNT; i++) {
int x1 = GRID_WIDTh / 2;
int y1 = GRID_WIDTh / 2 + i * GRID_WIDTh;
int x2 = x1 + (LINE_COUNT-1)* GRID_WIDTh;
int y2 = y1;
//画线
g.drawLine(x1, y1, x2, y2);
}
/**
* 画竖线
*/
for (int i = 0; i < LINE_COUNT; i++) {
int x1 = GRID_WIDTh / 2 + i * GRID_WIDTh;
int y1 = GRID_WIDTh / 2;
int x2 = x1;
int y2 = y1 + (LINE_COUNT-1) * GRID_WIDTh;
//画线
g.drawLine(x1, y1, x2, y2);
}
/**
* 遍历这个数组
*/
for(int row=0;row<LINE_COUNT;row++){
for(int col=0;col<LINE_COUNT;col++){
//判断数组当前值,来画棋子
switch (chessItems[row][col]) {
case WHITE:chessItem(row, col, Color.WHITE, g);break;
case BLACK:chessItem(row, col, Color.BLACK, g);break;
}
repaint();
}
}
};
/**
* 清空数组,便于下次下棋
*/
private void clear() {
for(int row=0;row<LINE_COUNT;row++){
for(int col=0;col<LINE_COUNT;col++){
//全部置为0
chessItems[row][col]=0;
}
}
//重画一遍棋盘
repaint();
}
/**
* 用于判断是否已经取胜
* @param row
* @param col
* @return
*/
private boolean checkImage(int row, int col) {
/**
* 判断横行是否win
*/
StringBuilder stringBuilder=new StringBuilder();
//记录当前存在字符串中的数据个数
int count=0;
for(int i=-4;i<=4;i++){
int Newcol=col+i;
if(Newcol>=0&&Newcol<LINE_COUNT){
count++;
stringBuilder.append(chessItems[row][Newcol]);
}
}
if(stringBuilder.indexOf("11111")>=0||stringBuilder.indexOf("22222")>=0){
return true;
}else {
//如果当前不能赢,则清空字符串
stringBuilder.delete(0, count);
count=0;
}
/**
* 判断竖行是否win
*/
for(int i=-4;i<=4;i++){
int Newrow=row+i;
if(Newrow>=0&&Newrow<LINE_COUNT){
count++;
stringBuilder.append(chessItems[Newrow][col]);
}
}
if(stringBuilder.indexOf("11111")>=0||stringBuilder.indexOf("22222")>=0){
return true;
}else {
stringBuilder.delete(0, count);
count=0;
}
/**
* 判断负45°是否win
*/
for(int i=-4;i<=4;i++){
int Newcol=col+i;
int Newrow=row+i;
if(Newcol>=0&&Newcol<LINE_COUNT&&Newrow>=0&&Newrow<LINE_COUNT){
count++;
stringBuilder.append(chessItems[Newrow][Newcol]);
}
}
if(stringBuilder.indexOf("11111")>=0||stringBuilder.indexOf("22222")>=0){
return true;
}else {
stringBuilder.delete(0, count);
count=0;
}
/**
* 判断正45°是否win
*/
for(int i=-4;i<=4;i++){
int Newcol=col+i;
int Newrow=row-i;
if(Newcol>=0&&Newcol<LINE_COUNT&&Newrow>=0&&Newrow<LINE_COUNT){
count++;
stringBuilder.append(chessItems[Newrow][Newcol]);
}
}
if(stringBuilder.indexOf("11111")>=0||stringBuilder.indexOf("22222")>=0){
return true;
}else {
stringBuilder.delete(0, count);
count=0;
}
return false;
}
//画棋子
public void chessItem(int row,int col,Color color,Graphics graphics){
//x与y分别代表在面板上的位置
int x=col*GRID_WIDTh;
int y=row*GRID_WIDTh;
graphics.setColor(color);
//画圆
graphics.fillOval(x, y, GRID_WIDTh,GRID_WIDTh);
}
} public static void main(String[] args) {
/**
* 使用一个java类来创建一个主类为wuziqijiemianDemo,其中的窗口与棋盘为该主类的内部类
*/
//使用类部类的方式创建一个窗口引用对象(方式为 外部类名.内部类名 变量名=new 外部类名().new 内部类名();)
wuziqijiemianDemo.Myjframe myjframe = new wuziqijiemianDemo().new Myjframe();
//设置窗口可见
myjframe.setVisible(true);
} }

第六部分 人机对战

1.   基本思路

当人点了鼠标落子以后,轮到电脑下棋,电脑的基本思想就是,在棋盘的空白处的每个位置,进行判断,当前位置的进攻指数和防守指数分别为多少,在进攻指数和防守指数中取一个较大值作为当前位置的评估值,在整个棋盘的所有空白处找到一个最大值,最大值的那个位置即为应该落子的位置。

2.  代码实现

(1)监听器类(内部类)代码:

(2)电脑下棋的代码

(3)     评估关键参数代码:

(4) 评估方法代码:

【自己代码】

 package wuziqi;

 import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException; import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel; public class wuziqijiemianDemo {
// 创建窗口为主类的类部类并且继承自JFrame
public class Myjframe extends JFrame {
/**
* 用一个构造方法创建窗口
*/
public Myjframe() {
this.setTitle("五子棋");
this.setSize(620, 640);
// 获取内容面板
Container cp = getContentPane();
// 创建一个面板JPanel
JPanel jPanel = new MyJanel();
cp.add(jPanel);
// 面板的背景颜色为黄色,便于下白棋与黑棋
jPanel.setBackground(Color.yellow);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
// 窗口默认设置为显示屏的正中间
this.setLocationRelativeTo(null);
// 不可改变窗口的大小
this.setResizable(false);
}
} /**
* 创建一个面板继承自JPanel
*
* @author Administrator
*
*/
public class MyJanel extends JPanel {
// 表示每个方格的大小
private static final int GRID_WIDTh = 40;
// 棋盘的大小,代表棋盘的线的条数
private static final int LINE_COUNT = 15;
// 设置黑棋子为1、白棋子为2、没有棋子为0(默认值)
public static final int BLACK = 1;
public static final int WHITE = 2;
// 定义一个棋盘大小的数组用来存放黑棋和白棋的位置
int[][] chessItems = new int[LINE_COUNT][LINE_COUNT];
// 定义一个标志位,代表黑棋先下(黑棋和白棋轮流下棋)
int flag = BLACK;
//定义一个方框标记计算机下棋的棋子
private Point lastpoint=new Point();
//利用图片代表棋子
Image blackImage=null;
Image whiImage=null;
//定义一个进攻的数组
String[] defendstring={
"11111","011110","11110","01111","11011",
"10111","11101","01110","11100","00111",
"0111","1110","1011","1101","111",
"01100","00110","011","110","11"
};
//定义一个防守的数组
String[] attackstring={
"22222","022220","22220","02222","22022",
"20222","22202","02220","22200","00222",
"0222","2220","2022","2202","222",
"02200","00220","022","220","22"
};
//定义一个防守与进攻对应的得分
int[] score={
100,90,80,80,80,
80,80,70,60,60,
50,50,50,50,40,
30,30,20,20,10,
};
/**
* 构造方法用来画棋盘的棋子
*/
public MyJanel() {
/**
* 将棋子改变为图片,将黑子白子图片导入进来
*/
try {
blackImage=ImageIO.read(new File("imgs/black.png"));
whiImage=ImageIO.read(new File("imgs/WHITE.png"));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
/**
* 为这个面板添加一个鼠标点击事件,鼠标每点击一次,就在棋盘上下一个棋子 使用适配器的方式添加鼠标点击事件
*/
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
/**
* 获取当前的鼠标点击的位置
*/
int x = e.getX();
int y = e.getY();
/**
* 因为棋盘是用二维数组的方式表示的,所以最后表示为二维数组的行与列
*/
int row = y / GRID_WIDTh;
int col = x / GRID_WIDTh;
// 当前这个位置没有棋子(为零),可以下一个黑棋子
if (chessItems[row][col] == 0) {
//人先下黑棋
chessItems[row][col] = flag;
/**
* 每当下完一步棋之后便判断是否已经取胜
*/
if (checkImage(row, col)) {
JOptionPane.showMessageDialog(null, "你赢了");
clear();
return;
}
// 人下完黑棋下白棋,之后再给计算机下黑棋的机会
flag = WHITE;
//计算机下棋
computerPlay();
// 计算机下完摆起之后,给人下黑棋的机会
flag = BLACK;
// 必须有,不然后面的白棋会覆盖黑棋
}
// System.out.println(chessItems[row][col]);
}
//计算机下棋调用方法
private void computerPlay() {
// 当前初始化找到的位置和期望值
int tempRow = -1, tempCol = -1, maxValue = 0;
// 遍历数组一个位置一个位置的找
for (int i = 0; i < LINE_COUNT; i++) {
for (int j = 0; j < LINE_COUNT; j++) {
// 如果这个位置已经下棋,则跳过
if (chessItems[i][j] > 0) {
continue;
}
// 表示进攻得分和防守得分
int attack = CheckMax(i, j, WHITE);
int defend= CheckMax(i, j, BLACK);
int max = Math.max(attack, defend);
// 获取最大值,并记录下标
if (max > maxValue) {
tempRow = i;
tempCol = j;
maxValue = max;
}
}
}
//如果当前计算机没有找到下棋的位置,表明为平局
if(tempCol<0||tempRow<0){
JOptionPane.showMessageDialog(null, "平局");
clear();
return;
}else{
// 计算机下白棋,下完之后人下黑棋,画一遍
chessItems[tempRow][tempCol] = WHITE;
lastpoint.x=tempRow;
lastpoint.y=tempCol;
repaint();
}
// 计算机下完棋之后便判断自己是否已经获胜
if (checkImage(tempRow, tempCol)) {
JOptionPane.showMessageDialog(null, "你输了");
clear();
return;
}
}
//计算机查看当前位置(黑棋与白棋)
private int CheckMax(int row, int col, int current_colorpointer) {
//max记录最大的期望,而tempmax记录当前的期望
int max=0,tempmax=0;
//判断当前是进攻还是防守
String[] array=current_colorpointer==WHITE?attackstring:defendstring;
//用一个字符串存放当前的状态
StringBuilder stringBuilder=new StringBuilder();
//水平方向
for (int i = -4; i <= 4; i++) {
int Newcol = col + i;
if (Newcol<0 ||Newcol >= LINE_COUNT) {
continue;
}
//假装先把这个位置下棋,实质上并没有下棋
if(i==0){
stringBuilder.append(current_colorpointer);
}else{
stringBuilder.append(chessItems[row][Newcol]);
}
}
for(int i=0;i<array.length;i++){
String string=array[i];
//查找匹配字符串数组,并计算出期望值,找到即跳出循环
if(stringBuilder.indexOf(string)>=0){
max=score[i];
break;
}
}
//如果当前为最大的期望,即可以获胜,就直接return
if(max==100){
return max;
}
//每次在每个方向判断之后,应该清空当前的stringBuilder字符串
stringBuilder.delete(0, stringBuilder.length());
//垂直方向
for (int i = -4; i <= 4; i++) {
int Newrow = row + i;
if (Newrow<0 ||Newrow >= LINE_COUNT) {
continue;
}
if(i==0){
stringBuilder.append(current_colorpointer);
}else{
stringBuilder.append(chessItems[Newrow][col]);
}
}
tempmax=0;
for(int i=0;i<array.length;i++){
String string=array[i];
if(stringBuilder.indexOf(string)>=0){
tempmax=score[i];
break;
}
}
if(max<tempmax){
max=tempmax;
}
if(max==100){
return max;
}
//每次在每个方向判断之后,应该清空当前的stringBuilder字符串
stringBuilder.delete(0, stringBuilder.length());
//负45°
for (int i = -4; i <= 4; i++) {
int Newrow = row + i;
int Newcol = col + i;
if ((Newrow<0 ||Newrow >= LINE_COUNT||Newcol<0 ||Newcol >= LINE_COUNT)) {
continue;
}
if(i==0){
stringBuilder.append(current_colorpointer);
}else{
stringBuilder.append(chessItems[Newrow][Newcol]);
}
}
tempmax=0;
for(int i=0;i<array.length;i++){
String string=array[i];
if(stringBuilder.indexOf(string)>=0){
tempmax=score[i];
break;
}
}
if(max<tempmax){
max=tempmax;
}
if(max==100){
return max;
}
//每次在每个方向判断之后,应该清空当前的stringBuilder字符串
stringBuilder.delete(0, stringBuilder.length());
//正45°
for (int i = -4; i <= 4; i++) {
int Newrow = row + i;
int Newcol = col - i;
if ((Newrow<0 ||Newrow >= LINE_COUNT||Newcol<0 ||Newcol >= LINE_COUNT)) {
continue;
}
if(i==0){
stringBuilder.append(current_colorpointer);
}else{
stringBuilder.append(chessItems[Newrow][Newcol]);
}
}
tempmax=0;
for(int i=0;i<array.length;i++){
String string=array[i];
if(stringBuilder.indexOf(string)>=0){
tempmax=score[i];
break;
}
}
if(max<tempmax){
max=tempmax;
}
if(max==100){
return max;
}
return max;
}
});
} /**
* 调用public void paintComponent(Graphics arg0){};方法画图
*/
public void paintComponent(Graphics g) {
// 系统调用
super.paintComponent(g);
// g.setColor(Color.yellow);
// g.fillRect(0, 0, jPanel.width(),jPanel.height());
/**
* 画横线,起始位置在窗口左上定点(GRID_WIDTh/2,GRID_WIDTh/2)
*/
for (int i = 0; i < LINE_COUNT; i++) {
int x1 = GRID_WIDTh / 2;
int y1 = GRID_WIDTh / 2 + i * GRID_WIDTh;
int x2 = x1 + (LINE_COUNT - 1) * GRID_WIDTh;
int y2 = y1;
// 画线
g.drawLine(x1, y1, x2, y2);
}
/**
* 画竖线
*/
for (int i = 0; i < LINE_COUNT; i++) {
int x1 = GRID_WIDTh / 2 + i * GRID_WIDTh;
int y1 = GRID_WIDTh / 2;
int x2 = x1;
int y2 = y1 + (LINE_COUNT - 1) * GRID_WIDTh;
// 画线
g.drawLine(x1, y1, x2, y2);
}
/**
* 遍历这个数组
*/
for (int row = 0; row < LINE_COUNT; row++) {
for (int col = 0; col < LINE_COUNT; col++) {
// 判断数组当前值,来画棋子
switch (chessItems[row][col]) {
case WHITE:
chessItem(row, col, Color.WHITE, g);
//每次画完计算机下完白棋之后,在白棋上面画一个方框
chessface(lastpoint,Color.RED, g);
break;
case BLACK:
chessItem(row, col, Color.BLACK, g);
break;
}
repaint();
}
}
}; /**
* 清空数组,便于下次下棋
*/
private void clear() {
for (int row = 0; row < LINE_COUNT; row++) {
for (int col = 0; col < LINE_COUNT; col++) {
// 全部置为0
chessItems[row][col] = 0;
}
}
// 重画一遍棋盘
repaint();
} /**
* 用于判断是否已经取胜
*
* @param row
* @param col
* @return
*/
private boolean checkImage(int row, int col) {
/**
* 判断横行是否win
*/
StringBuilder stringBuilder = new StringBuilder();
// 记录当前存在字符串中的数据个数
int count = 0;
for (int i = -4; i <= 4; i++) {
int Newcol = col + i;
if (Newcol >= 0 && Newcol < LINE_COUNT) {
count++;
stringBuilder.append(chessItems[row][Newcol]);
}
}
if (stringBuilder.indexOf("11111") >= 0
|| stringBuilder.indexOf("22222") >= 0) {
return true;
} else {
// 如果当前不能赢,则清空字符串
stringBuilder.delete(0, count);
count = 0;
}
/**
* 判断竖行是否win
*/
for (int i = -4; i <= 4; i++) {
int Newrow = row + i;
if (Newrow >= 0 && Newrow < LINE_COUNT) {
count++;
stringBuilder.append(chessItems[Newrow][col]);
}
}
if (stringBuilder.indexOf("11111") >= 0
|| stringBuilder.indexOf("22222") >= 0) {
return true;
} else {
stringBuilder.delete(0, count);
count = 0;
}
/**
* 判断负45°是否win
*/
for (int i = -4; i <= 4; i++) {
int Newcol = col + i;
int Newrow = row + i;
if (Newcol >= 0 && Newcol < LINE_COUNT && Newrow >= 0
&& Newrow < LINE_COUNT) {
count++;
stringBuilder.append(chessItems[Newrow][Newcol]);
}
}
if (stringBuilder.indexOf("11111") >= 0
|| stringBuilder.indexOf("22222") >= 0) {
return true;
} else {
stringBuilder.delete(0, count);
count = 0;
}
/**
* 判断正45°是否win
*/
for (int i = -4; i <= 4; i++) {
int Newcol = col + i;
int Newrow = row - i;
if (Newcol >= 0 && Newcol < LINE_COUNT && Newrow >= 0
&& Newrow < LINE_COUNT) {
count++;
stringBuilder.append(chessItems[Newrow][Newcol]);
}
}
if (stringBuilder.indexOf("11111") >= 0
|| stringBuilder.indexOf("22222") >= 0) {
return true;
} else {
stringBuilder.delete(0, count);
count = 0;
}
return false;
} // 画棋子
public void chessItem(int row, int col, Color color, Graphics graphics) {
// x与y分别代表在面板上的位置
int x = col * GRID_WIDTh;
int y = row * GRID_WIDTh;
//判断是白棋还是黑棋
Image image=Color.BLACK.equals(color)?blackImage:whiImage;
graphics.drawImage(image, x, y, GRID_WIDTh, GRID_WIDTh, this);
// graphics.setColor(color);
// // 画圆
// graphics.fillOval(x, y, GRID_WIDTh, GRID_WIDTh);
}
/**
* 为计算机画白棋定义一个方法,用于在计算机下白棋的棋子上画一个方框,表示是当前的棋子
* @param point
* @param color
* @param graphics
*/
public void chessface(Point point, Color color, Graphics graphics ){
int x = point.y * GRID_WIDTh;
int y = point.x * GRID_WIDTh;
graphics.setColor(color);
graphics.drawRect(x+GRID_WIDTh/4, y+GRID_WIDTh/4, GRID_WIDTh/2, GRID_WIDTh/2);
}
} public static void main(String[] args) {
/**
* 使用一个java类来创建一个主类为wuziqijiemianDemo,其中的窗口与棋盘为该主类的内部类
*/
// 使用类部类的方式创建一个窗口引用对象(方式为 外部类名.内部类名 变量名=new 外部类名().new 内部类名();)
wuziqijiemianDemo.Myjframe myjframe = new wuziqijiemianDemo().new Myjframe();
// 设置窗口可见
myjframe.setVisible(true);
} }

实践周java基础软件开发app之五子棋的更多相关文章

  1. Java基础-配置开发环境-安装JDK

    Java基础-配置开发环境-安装JDK 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.计算机基础知识 1>.计算机的组成 计算机有硬件与软件组成. 2>.硬件: 硬 ...

  2. 学java编程软件开发,非计算机专业是否能学

    近几年互联网的发展越来越好,在国外,java程序员已经成为高薪以及稳定职业的代表,虽然国内的有些程序员很苦逼,但是那只是少数,按照国外的大方向来看,程序员还是一个很吃香的职业.根据编程语言的流行程度, ...

  3. java基础-Eclipse开发工具介绍

    java基础-Eclipse开发工具介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 所谓工欲善其事必先利其器,即将身为一名Java开发工程师怎么能没有一款好使的IDE呢?今天就 ...

  4. java基础-Idea开发工具介绍

    java基础-Idea开发工具介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 之前给大家介绍过一款Java的IDE叫eclipse,有些功能用起来不是很得心应手,尤其是在导报的 ...

  5. Java基础之开发工具Eclipse的使用

    Eclipse简介 Eclipse是由IBM公司投资4000万美元开发的集成开发工具.它是目前最流行的Java集成开发工具之一,基于Java语言编写,并且是开放源代码的.可扩展的(Integrated ...

  6. 安装eclipse(tomcat配置maven搭建){Java基础之开发工具}

    安装eclipse 1.下载eclipse-jee-neon-3-win32-x86_64 zip 百度云盘 解压 2. 下载JDK 官网 JDK 8 JDK电脑上环境变量配置 Path路径    % ...

  7. java基础之开发环境搭建

    我们这里后续的所有课程都使用eclipse 来开发java代码,下面我们来搭建开发环境: 1.首先去java.sun.com去下载jdk,可以下载1.6 的版本2.安装JDK,最好安装在某个盘的跟目录 ...

  8. [学习笔记]java基础Java8SE开发环境搭建、第一个Java Hello World、Java程序的编译与执行

    本文作者:sushengmiyan 本文地址:http://blog.csdn.net/sushengmiyan/article/details/25745945 内容简介: ------------ ...

  9. java基础之开发环境配置

    一. 环境变量配置的原理 一.  配置环境变量path 如果我们按照上面的来编译和运行的话未免太过于麻烦了,那么在这里我们可以配置环境变量PATH 1.配置环境变量的步骤 这时可以直接来看效果 如果d ...

随机推荐

  1. TensorFlow线性回归

    目录 数据可视化 梯度下降 结果可视化 数据可视化 import numpy as np import tensorflow as tf import matplotlib.pyplot as plt ...

  2. SpringBoot中application.yml基本配置详情

    把原有的application.properties删掉.然后 maven -X clean install,或者通过Maven Project双击clean和install(1)端口服务配置 #端口 ...

  3. vue指令之v-cloak

    vue指令之v-cloak 一起学 vue指令 v-cloak  指令可看作标签属性 某些情况下可能由于机器性能故障或者网络原因,导致传输有问题,那么浏览器无法成功解析数据,此时浏览器输出的内容就是纯 ...

  4. BuiltIn库

    简介 作为一门表格语言,为了保持简单的结构,RF没有像别的高级语言那样提供类似ifelsewhile等内置关键字来实现各种逻辑功能(注1),而是提供给了用户BuiltIn库.如果用户想在测试用例中实现 ...

  5. 9. 获得图片路径,构造出训练集和验证集,同时构造出相同人脸和不同人脸的测试集,将结果存储为.csv格式 1.random.shuffle(数据清洗) 2.random.sample(从数据集中随机选取2个数据) 3. random.choice(从数据集中抽取一个数据) 4.pickle.dump(将数据集写成.pkl数据)

    1. random.shuffle(dataset) 对数据进行清洗操作 参数说明:dataset表示输入的数据 2.random.sample(dataset, 2) 从dataset数据集中选取2 ...

  6. golang网络通信超时设置

    网络通信中,为了防止长时间无响应的情况,经常会用到网络连接超时.读写超时的设置. 本文结合例子简介golang的连接超时和读写超时设置. 1.超时设置 1.1 连接超时 func DialTimeou ...

  7. AndroidStudio 插件 之 Findbugs 安装与简单使用教程

    http://blog.csdn.net/u013132758/article/details/70187846 http://blog.csdn.net/jdsjlzx/article/detail ...

  8. Java学习笔记之ArrayList基本用法

    原文地址,转载请注明出处:https://blog.csdn.net/GongchuangSu/article/details/51514389 ArrayList简介 ArrayList是一个其容量 ...

  9. 阶段3 2.Spring_01.Spring框架简介_03.spring概述

  10. 非GUI运行Jmeter,jtl文件没有响应数据的解决办法

    一.问题 Jmeter官方一直强调要在非GUI模式下运行Jmeter:Run your JMeter test in command-line non-GUI mode. 但在非GUI模式下运行生成的 ...