五子棋人机对战实践项目

总的任务和目标

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

第一部分 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. 后盾网lavarel视频项目---5、淘宝镜像cnpm的原理及如何使用

    后盾网lavarel视频项目---5.淘宝镜像cnpm的原理及如何使用 一.总结 一句话总结: 原理:把npm上面的所有软件copy过来 使用:npm install -g cnpm --regist ...

  2. P1533可怜的狗狗

    困死了,完全做不下去题 就当是对莫队最最基本的思想的一个复习叭(只有最最基本的思想,没有莫队) 传送 我们可以很容易的想到这题要用线段树. 60pts 此题要求某个区间里第K小的数,可以暴力的考虑对每 ...

  3. Android 编程下Touch 事件的分发和消费机制和OnTouchListener,OnClickListener和OnLongClickListener的关系

    1.事件分发:public boolean dispatchTouchEvent(MotionEvent ev) Touch 事件发生时 Activity 的 dispatchTouchEvent(M ...

  4. CSS - 架构

    MaintainableCSS 原子类几乎只有比行内样式少写几个字符这一个优点,缺点倒是一堆,最好别用 一味追求 "永远不要重复同样的事情两次" 会导致过度思考和过度设计,最终出现 ...

  5. failed to create cublas handle: CUBLAS_STATUS_ALLOC_FAILED 错误解决方法

    解决: config = tf.ConfigProto() config.gpu_options.allow_growth = True session = tf.Session(config=con ...

  6. flutter 添加全局环境变量

    flutter安装好了之后 要添加全局环境变量才可以在终端通过flutter命令来操作 安装flutter环境变量 vim ~/.bash_profile (不存在就创建,添加下面一行命令) expo ...

  7. 嵌套的JsonObject与JSONArray的取值---JSON中嵌套JSONArray

    在复杂的JSON数据的格式中,往往会对JSON数据进行嵌套,这样取值会比之前的取值稍微复杂一点,但是只要思路清晰,其实取法还是一样的.就跟if else语句一样,如果if中套if,if中再套if,写的 ...

  8. HTML笔记(一) 基础标签的介绍

    一个最基本的html文件,必须包含<html>, <head> 和<body> 三个标签 以及<!doctype>声明 1. <!DOCTYPE& ...

  9. excel常用公式--关联匹配类

    index: 根据位置返回单元格的值. match: 根据单元格的值返回位置. index+match替代vlookup rank:返回一列数字的数字排位.数字的排位是其相对于列表中其他值的大小.

  10. kubernetes集群node加入不了master错误处理

    #如果node加入不了master或者加入成功但是,在master中显示不出来.排查错误:1. 运行,kubelet, 查看日志,一般是kubelet的运行和docker启动方式不匹配.调整:vim  ...