五子棋人机对战实践项目

总的任务和目标

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

第一部分 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. MongoDB中的_id和ObjectId

    ObjectId是"_id"的默认类型.它设计成轻量型的,不同的机器都能用全局唯一的同种方法方便地生成它. 这是MongoDB采用ObjectId,而不是其他比较常规的做法(比如自 ...

  2. 为EasyUI的dataGrid单元格增加鼠标移入移出事件

    onLoadSuccess: function (data) { $(".datagrid-row").mouseover(function (e) { var text = $( ...

  3. java JIT

    JVM 即时编译器即时编译器 (Just In Time Compiler) 简称JIT JAVA程序最初是通过解释器 (Interpreter) 进行解释执行的,当 JVM 发现某个方法或代码块运行 ...

  4. gherkin

    语法 The primary keywords are: Feature Rule (as of Gherkin 6) Scenario (or Example) Given, When, Then, ...

  5. 方差分析(python代码实现)

    python机器学习-乳腺癌细胞挖掘(欢迎关注博主主页,学习python视频资源,还有大量免费python经典文章) https://study.163.com/course/introduction ...

  6. linux添加新用户

    使用root用户adduser yj 后面操作有提示 用这种方法新建的用户会在home下生成用户文件夹

  7. [flask]jinjia2处理表单-实现搜索界面

    思路: 通过flask-wtf创建forms表单类 在app.py中创建search_name()视图函数,实例化form表单类,将通过render_template将form传给html模板 创建h ...

  8. Closure - Mimicking block scope

    The basic syntax of an anoymous function used as a block scope (often called a private scope) is as ...

  9. spring5的基本组成(6个模块)

    1:数据访问及集成(Data Access/Integeration):jdbc,orm,oxm,jms,transactions ——由 spring-jdbc.spring-tx.spring-o ...

  10. 第七次学习总结&&第五次实验报告

    一.实验目的 (1)理解抽象类与接口的使用: (2)了解包的作用,掌握包的设计方法. 二.实验要求 (1)掌握使用抽象类的方法. (2)掌握使用系统接口的技术和创建自定义接口的方法. (3)了解 Ja ...