java实现简单的五子棋游戏

网友投稿 215 2022-10-10

java实现简单的五子棋游戏

目录一、主要界面二、功能概况三、代码部分四、部分效果展示

本文实例为大家分享了java实现简单五子棋游戏的具体代码,供大家参考,具体内容如下

一、主要界面

1、登录界面;2、游戏选择界面;3、五子棋下棋界面

它们间的逻辑关系为先通过登录界面登录跳转到游戏选择界面,再通过游戏选择界面进入到五子棋下棋界面。

二、功能概况

1、登录界面:

a、设置一定的布局和添加一些组件;b、通过点击登录按钮判断账号和密码是否正确,正确则成功登录,反之则弹出一个提示账号或密码输入错误的窗口;c、在窗口中添加一个按钮,在点击此按钮后关闭当前窗口,并在第三次输入错误后弹出提示并关闭登录界面

2、游戏选择界面:a、添加背景图片;b、在背景面板上添加游戏选择的按钮;c、通过游戏选择按钮跳转到相应的游戏。

3、五子棋下棋界面:

(1)画出一个16*16的棋盘

(2)黑白棋实现轮流落子,落子位置在交叉点上,并且同一位置只能落一子

(3)黑白落子计数器

(4)重绘功能,在拖动改变窗体大小时保留之前的棋盘棋子及计数显示

(5)按钮:开始游戏,重新开始,悔棋,棋局回放,存档,读档,退出游戏等功能

(6)判断输赢,当且仅当五颗同色的棋子连在一起时得胜,当出现六颗及以上同色棋子相连时不算得胜

三、代码部分

1.GoBangUI类:

import javax.swing.*; //导入swing包的所有类和接口

import java.awt.*; //导入awt包的所有类和接口

//登录密码:123 账号:123

public class GoBangUI extends JFrame implements GoBangConfig {

private static final Image bgimg = new ImageIcon("C:\\Users\\zyx\\Pictures\\Camera Roll\\17.jpeg").getImage();

Font f=new Font("楷体", Font.PLAIN, 30);//楷体,常规,30号字体

//主函数入口

public static void main(String[]args) {

Login cx=new Login();

cx.UI();

}

int[][] Array=new int[16][16];//实例化一个二维数组的对象来存储棋子信息,0表示无棋,1表示黑棋,2表示白棋;在我们未给定初值的情况下,会默认初值为0

public void initGobangUI(){

this.setTitle("五子棋");

this.setSize(1200,850);// 设置窗体的大小,单位为像素

this.setLocationRelativeTo(null);//设置窗体相对于组件的居中位置,null表示窗体相对于屏幕的中央位置

this.setDefaultCloseOperation(3); // 设置窗体的关闭操作

Dimension dm1=new Dimension(200,0);//设置JPanel的大小

Dimension dm2=new Dimension(140,50);//设置JButton的大小

Dimension dm3=new Dimension(170,110);//设置JLabel的大小

JPanel jp=new JPanel();

jp.setBackground(Color.lightGray);//设置面板JPanel的背景色

jp.setPreferredSize(dm1);

this.add(jp,BorderLayout.EAST);//通过边框布局将面板添加到窗体的右边

JLabel jl=new JLabel(" ");

jl.setPreferredSize(dm3);

jp.add(jl);

String[] name= {"开始游戏","重新开始","悔棋","棋局回放","存档","读档","退出游戏"};

JButton[] button=new JButton[7];

//依次把五个按钮组件加上去

for(int i=0;i

button[i]=new JButton(name[i]);

button[i].setPreferredSize(dm2);

jp.add(button[i]);

}

//设置窗体的背景颜色

Container con=this.getContentPane();

con.setBackground(Color.darkGray) ;

this.setVisible(true);

// 从当前窗体获取画笔并通过构造方法传入监听类对象中

Graphics gr=this.getGraphics();

GoBangListener goBangListener = new GoBangListener(gr);

//给按钮组件添加动作监听方法

for(int i=0;i

button[i].addActionListener(goBangListener);

}

// 给窗体添加鼠标监听方法

this.addMouseListener(goBangListener);

goBangListener.go=this;

}

@Override

public void paint(Graphics g) {

// 先调用父类绘制窗体的方法

super.paint(g);

//绘制背景图片

g.drawImage(bgimg,X,Y,columns*SIZE,rows*SIZE,null);

// 绘制棋盘

for (int i = 0; i <= rows; i++) {

g.drawLine(X,Y+i*SIZE,X+columns*SIZE,Y+i*SIZE);//画横线

}

for(int j=0;j<=columns;j++) {

g.drawLine(X+j*SIZE,Y,X+j*SIZE,Y+rows*SIZE);//画竖线

}

//黑白棋的落子数

g.setColor(Color.darkGray);

g.fillRect( X*2+columns*SIZE, Y*11/4,SIZE*5/2, 3*SIZE);

g.setColor(Color.ORANGE);

g.setFont(f);

g.drawString("黑棋:"+GoBangListener.m, 2*X+columns*SIZE, Y*10/3);

g.drawString("白棋:"+GoBangListener.n, 2*X+columns*SIZE,Y*13/3);

g.setFont(f);//设置字体

//遍历二维数组,画出已赋值的对应位置的黑白棋

for(int j=0;j<=columns;j++) {

for(int i=0;i<=rows;i++) {

if(Array[i][j]==1) {

g.setColor(Color.BLACK);

g.fillOval(j*SIZE+X-SIZE/2, i*SIZE+Y-SIZE/2, SIZE, SIZE);

}else if(Array[i][j]==2){

g.setColor(Color.WHITE);

g.fillOval(j*SIZE+X-SIZE/2, i*SIZE+Y-SIZE/2, SIZE, SIZE);

}

}

}

}

}

2.GoBangListener类:

import java.awt.*;

import java.awt.event.ActionEvent;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.awt.event.ActionListener;

import javax.swing.*;

public class GoBangListener implements ActionListener,MouseListener,GoBangConfig {

int chessX; //列索引

int chessY; //行索引

int flag=0; //黑白棋轮流标记

int count=0; //记录落子顺序

int ct,flag1,m1,n1,q,w; //用作存档操作

GoBangUI go;

String name;

String name1=""; //用于开始游戏操作

JTextField jt;

JPasswordField jp;

JFrame jf;

JFrame j = new JFrame();

JFrame j1 = new JFrame();

int i=3; //允许登录失败的次数

static int m=0,n=0; //记录黑白各自的落子数

private Graphics g;

public GoBangListener() {}

GoBangListener(Graphics g) {

this.g=g;

}

GBstore[] gbs=new GBstore[16*16]; //储存棋子的落子顺序和位置信息

public void actionPerformed(ActionEvent e) {

name=e.getActionCommand();

if(e.getActionCommand().equals("退出游戏")) {

j.dispose(); j1.dispose(); go.dispose();

}

if(e.getActionCommand().equals("开始游戏")) {

name1=e.getActionCommand();

}else {

if(e.getActionCommand().equals("重新开始")|e.getActionCommand().equals("再来一局")) {

w=count;

count=0;

m=0;

n=0;

flag=0;

for(i=0;i

go.Array[gbs[count+i].chessy][gbs[count+i].chessx]=0;

}

j.dispose();

j1.dispose();

go.repaint();

}

if(e.getActionCommand().equals("悔棋")) {

if(count!=0) {

if(flag==0) {

go.Array[gbs[count-1].chessy][gbs[count-1].chessx]=0;

n--;

go.repaint();

count--;

flag++;

}else if(flag==1) {

go.Array[gbs[count-1].chessy][gbs[count-1].chessx]=0;

go.repaint();

m--;

count--;

flag--;

}

}}

if(e.getActionCommand().equals("棋局回放")) {

if(gbs[count]!=null) {

if(flag==0) {

go.Array[gbs[count].chessy][gbs[count].chessx]=1;

m++;

go.repaint();

count++;

flag++;

}else if(flag==1) {

go.Array[gbs[count].chessy][gbs[count].chessx]=2;

go.repaint();

n++;

count++;

flag--;

}

}}

if(e.getActionCommand().equals("存档")) {

flag1=flag;

ct=count;

m1=m;

n1=n;

}

if(e.getActionCommand().equals("读档")) {

q=count-ct;

count=ct;

m=m1;

n=n1;

if(flag!=0) {

flag=0;

}

for(int i=0;i

if(flag==0) {

go.Array[gbs[i].chessy][gbs[i].chessx]=1;

flag++;

}else if(flag==1) {

go.Array[gbs[i].chessy][gbs[i].chessx]=2;

flag--;

}}

for(i=0;i

go.Array[gbs[count+i].chessy][gbs[count+i].chessx]=0;

}

flag=flag1;

go.repaint();

}

}

if(name.equals("登录")) {

if(jt.getText().equals("123")&&jp.getText().equals("123")) {

GameselectUI ui=new GameselectUI();

ui.selectUI();

jf.dispose();

} else if(i>1) {

JFrame lg1 = new JFrame();

lg1.setSize(400,200);

lg1.setDefaultCloseOperation(3);

lg1.setLocationRelativeTo(null);

JPanel jp1 = new JPanel();

JPanel jp2 = new JPanel();

JPanel jp3 = new JPanel();

Dimension dm = new Dimension(0,50);

JLabel jl = new JLabel(cvkalOvvW"账号或密码输入错误,您还有"+(i-1)+"次机会");

jl.setFont(new Font("华文仿宋",Font.BOLD,18)); //华文仿宋,加粗,18号字体

jp2.add(jl);

jp1.setPreferredSize(dm);

lg1.add(jp1,BorderLayout.NORTH);

lg1.add(jp2,BorderLayout.CENTER);

lg1.add(jp3,BorderLayout.SOUTH);

JButton jb = new JButton("确定");

jp3.add(jb);

lg1.add(jp3,BorderLayout.SOUTH);

jb.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {lg1.dispose();}});

lg1.setVisible(true);

}else if(i==1) {

JFrame lg1 = new JFrame();

lg1.setSize(400,200);

lg1.setDefaultCloseOperation(3);

lg1.setLocationRelativeTo(null);

JPanel jp1 = new JPanel();

JPanel jp2 = new JPanel();

JPanel jp3 = new JPanel();

Dimension dm = new Dimension(0,50);

JLabel jl = new JLabel("账号已锁定");

jl.setFont(new Font("华文仿宋",Font.BOLD,18)); //华文仿宋,加粗,18号字体

jp1.setPreferredSize(dm);

jp2.add(jl);

lg1.add(jp1,BorderLayout.NORTH);

lg1.add(jp2,BorderLayout.CENTER);

lg1.add(jp3,BorderLayout.SOUTH);

JButton jb = new JButton("确定");

jp3.add(jb);

lg1.add(jp3,BorderLayout.SOUTH);

lg1.setVisible(true);

jb.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {lg1.dispose();jf.dispose(); }});

jf.dispose();

}

i--;

}else if(name.equals("注册")) {

JFrame lg1 = new JFrame();

lg1.setSize(400,200);

lg1.setDefaultCloseOperation(3);

lg1.setLocationRelativeTo(null);

JPanel jp1 = new JPanel();

JPanel jp2 = new JPanel();

JPanel jp3 = new JPanel();

Dimension dm = new Dimension(0,50);

JLabel jl = new JLabel("注册功能暂未开放...");

jl.setFont(new Font("华文仿宋",Font.BOLD,18)); //华文仿宋,加粗,18号字体

jp1.setPreferredSize(dm);

jp2.add(jl);

lg1.add(jp1,BorderLayout.NORTH);

lg1.add(jp2,BorderLayout.CENTER);

lg1.add(jp3,BorderLayout.SOUTH);

JButton jb = new JButton("确定");

jp3.add(jb);

lg1.add(jp3,BorderLayout.SOUTH);

lg1.setVisible(true);

jb.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {lg1.dispose(); }});

}

}

@Override

public void mouseClicked(MouseEvent e) {

if(name1.equals("开始游戏")) {

int x=e.getX();

int y=e.getY();

Font f=new Font("楷体", Font.PLAIN, 30); //楷体,常规,30号

// 限制下棋的范围

if((x>=X&&x< X+columns*SIZE)&&(y>Y&&y

// 赋值坐标

chessX = (x-X+SIZE/2)/SIZE; //列索引

chessY = (y-Y+SIZE/2)/SIZE; //行索引

if(go.Array[chessY][chessX]!=0) { //Array[][] arr=new Array[一维数组的个数(行数)][一维数组中元素的个数(列数)]

System.out.println("此处已有棋子");

}else {

//轮到黑方下棋

if(flag==0) {

m++;

g.setColor(Color.BLACK);

g.fillOval(chessX*SIZE+X-SIZE/2, chessY*SIZE+Y-SIZE/2, SIZE, SIZE);

flag++;

//实现黑子计数

g.setColor(Color.darkGray);

g.fillRect( X*2+columns*SIZE, Y*11/4, SIZE*5/2, SIZE);

g.setColor(Color.ORANGE);

g.setFont(f);

g.drawString("黑棋:"+m, 2*X+columns*SIZE, Y*10/3);

go.Array[chessY][chessX]=1;

GBstore gb=new GBstore(chessX,chessY);

gbs[count]=gb;//传递相应顺序对应的行列索引值

count++;

//判断输赢

if(Judge.blackjudge(go.Array,chessY, chessX)){

j1.setSize(400,200);

j1.setDefaultCloseOperation(3);

j1.setLocationRelativeTo(null);

JPanel jp1 = new JPanel();

JPanel jp2 = new JPanel();

JPanel jp3 = new JPanel();

Dimension dm = new Dimension(0,50);

JLabel jl = new JLabel("恭喜黑棋获胜");

jl.setFont(new Font("华文仿宋",Font.BOLD,18)); //华文仿宋,加粗,18号字体

jp2.add(jl);

jp1.setPreferredSize(dm);

j1.add(jp1,BorderLayout.NORTH);

j1.add(jp2,BorderLayout.CENTER);

j1.add(jp3,BorderLayout.SOUTH);

JButton jb = new JButton("回顾棋局");

jp3.add(jb);

JButton jb1 = new JButton("再来一局");

jp3.add(jb1);

j1.add(jp3,BorderLayout.SOUTH);

jb.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {j1.dispose();}});

jb1.addActionListener(this);

j1.setResizable(false);

j1.setVisible(true);

}

}else {

//轮到白方下棋

n++;

g.setColor(Color.WHITE);

g.fillOval(chessX*SIZE+X-SIZE/2, chessY*SIZE+Y-SIZE/2, SIZE, SIZE);

flag--;

g.setColor(Color.darkGray);

g.fillRect( 2*X+columns*SIZE, Y*15/4, SIZE*5/2, SIZE);

g.setColor(Color.ORANGE);

g.setFont(f);

g.drawString("白棋:"+n, 2*X+columns*SIZE,Y*13/3);

go.Array[chessY][chessX]=2;

GBstore gb=new GBstore(chessX,chessY);

gbs[count]=gb;

count++;

if(Judge.whitejudge(go.Array,chessY, chessX)){

j.setSize(400,200);

j.setDefaultCloseOperation(3);

j.setLocationRelativeTo(null);

JPanel jp1 = new JPanel();

JPanel jp2 = new JPanel();

JPanel jp3 = new JPanel();

Dimension dm = new Dimension(0,50);

JLabel jl = new JLabel("恭喜白棋获胜");

jl.setFont(new Font("华文仿宋",Font.BOLD,18)); //华文仿宋,加粗,18号字体

jp2.add(jl);

jp1.setPreferredSize(dm);

j.add(jp1,BorderLayout.NORTH);

j.add(jp2,BorderLayout.CENTER);

j.add(jp3,BorderLayout.SOUTH);

JButton jb = new JButton("回顾棋局");

jp3.add(jb);

JButton jb1 = new JButton("再来一局");

jp3.add(jb1);

j.add(jp3,BorderLayout.SOUTH);

jb.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {j.dispose();}});

jb1.addActionListener(this);

j.setResizable(false);

j.setVisible(true);

}

}

}

}

}}

@Override

public void mouseEntered(MouseEvent e) {

}

@Override

public void mouseExited(MouseEvent e) {

}

@Override

public void mousePressed(MouseEvent e) {

}

@Override

public void mouseReleased(MouseEvent e) {

}

}

3.GoBangConfig类:

public interface GoBangConfig {

/**

* 间距|尺寸

*/

int SIZE=50;

/**

* 棋盘左上角 X坐 标

*/

int X=40;

/**

* 棋盘左上角 Y 坐 标

*/

int Y=65;

/**

* 棋盘的行列值

*/

int rows=15;

int columns=15;

}

4.GBstore类:

/*

* 储存棋子的位置信息

*/

public class GBstore {

int chessx,chessy;

GBstore(int chessx,int chessy){

this.chessx=chessx;

this.chessy=chessy;

}

}

5.GameselectUI类:

import javax.swing.*;

import java.awt.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

public class GameselectUI extends JFrame {

public void selectUI(){

JFrame j=this; //绑定当前窗体

this.setTitle("Game selection UI");//设置标题

j.setSize(370,400);

ImageIcon img=new ImageIcon("C:\\Users\\zyx\\Pictures\\Camera Roll\\2.jpg");

BackgroundPanel bgp=new BackgroundPanel(img.getImage());

bgp.setSize(370,400);

this.setDefaultCloseOperation(3);

this.setLocationRelativeTo(null);

Dimension d = new Dimension(370,190); //通过设置标签调整按钮位置,JPanel面板默认使用流式布局

Dimension dim = new Dimension(100,60);//设置按钮的大小

this.add(bgp);//给当前窗体添加背景面板

JLabel jl=new JLabel();

jl.setPreferredSize(d);

bgp.add(jl);

JButton gbbt1 = new JButton("五子棋");

Font f=new Font("华文仿宋",Font.BOLD,18);//字体:华文仿宋;字形:加粗;字号:18

gbbt1.setFont(f);

gbbt1.setPreferredSize(dim);

bgp.add(gbbt1); //添加按钮到面板上

JLabel jla=new JLabel("");

jla.setPreferredSize(new Dimension(100,60));

bgp.add(jla);

JButton drbt2 = new JButton("待定");

drbt2.setFont(f);

drbt2.setPreferredSize(dim);

bgp.add(drbt2);

//设置入口

ActionListener al=new ActionListener() {public void actionPerformed(ActionEvent e) {

if(e.getActionCommand().equals("五子棋")) {

GoBangUI gb=new GoBangUI();

gb.initGobangUI();

j.dispose();

}else if(e.getActionCommand().equals("待定")) {

}

}};//添加监听方法

gbbt1.addActionListener(al);

drbt2.addActionListener(al);

this.setResizable(false);

//设置不可调整窗体大小

GameselectUI.this.setVisible(true); //设置窗体可见

}

}

class BackgroundPanel extends JPanel{

Image img;

BackgroundPanel(Image img){

this.img=img;

}

//重写paintComponent方法画出背景图

public void paintComponent(Graphics g){

super.paintComponents(g);

System.out.println();

g.drawImage(img,0,0,370,400,this);

}

}

6.Login类:

import javax.swing.*;

import java.awt.*;

public class Login {

public void UI() {

javax.swing.JFrame jf= new javax.swing.JFrame();

jf.setSize(370, 505);

jf.setDefaultCloseOperation(3);

jf.setTitle("登录界面");

jf.setLocationRelativeTo(null);

java.awt.FlowLayout fl= new java.awt.FlowLayout();

jf.setLayout(fl);

Dimension di=new Dimension(360,360);

javax.swing.ImageIcon image= new javax.swing.ImageIcon("D:\\360Downloads\\1.jpg");

javax.swing.JLabel jl=new javax.swing.JLabel(image);

jl.setPreferredSize(di);

jf.add(jl);

javax.swing.JLabel zh=new javax.swing.JLabel("账号");

jf.add(zh);

javax.swing.JTextField jtf=new javax.swing.JTextField();

Dimension dm=new Dimension(300,30);

jtf.setPreferredSize(dm);

jf.add(jtf);

javax.swing.JLabel mm=new javax.swing.JLabel("密码");

jf.add(mm);

java.awt.Dimension d=new java.awt.Dimension(300,30);

JPasswordField wb=new JPasswordField();

wb.setPreferredSize(d);

jf.add(wb);

JButton button=new JButton("登录");

jf.add(button);

javax.swing.JButton zc=new javax.swing.JButton("注册");

jf.add(zc);

jf.setResizable(false);

jf.setVisible(true);

GoBangListener gl=new GoBangListener();

button.addActionListener(gl);

zc.addActionListener(gl);

gl.jt=jtf;

gl.jp=wb;

gl.jf=jf;

}

}

7.Judge类:

public class Judge {

//黑棋胜负判断

public static boolean blackjudge(int[][] Array,int chessY,int chessX) {

int count1=0,count2=0,count3=0,count4=0;

//横向遍历

for(int i=-15;i<=15;i++) {

if(chessX+i>=0&&chessX+i<=15) { //确定遍历的范围

if(count1<5) {

if(Array[chessY][chessX+i]==1) {

count1++;

}else {

count1=0;

}

}else if(count1==5) {

if(Array[chessY][chessX+i]==1) {

count1++;

}}}}

//纵向遍历

for(int i=-15;i<=15;i++) {

if(chessY+i>=0&&chessY+i<=15) {

if(count2<5) {

if(Array[chessY+i][chessX]==1) {

count2++;

}else {

count2=0;

}

}else if(count2==5) {

if(Array[chessY+i][chessX]==1) {

count2++;

}}}}

//斜下遍历

for(int i=-15;i<=15;i++) {

if(chessY+i>=0&&chessY+i<=15&&chessX+i>=0&&chessX+i<=15) {

if(count3<5) {

if(Array[chessY+i][chessX+i]==1) {

count3++;

}else {

count3=0;

}

}else if(count3==5) {

if(Array[chessY+i][chessX+i]==1) {

count3++;

}}}}

//斜上遍历

for(int i=-15;i<=15;i++) {

if(chessY-i>=0&&chessY-i<=15&&chessX+i>=0&&chessX+i<=15) {

if(count4<5) {

if(Array[chessY-i][chessX+i]==1) {

count4++;

}else {

count4=0;

}

}else if(count4==5) {

if(Array[chessY-i][chessX+i]==1) {

count4++;

}}}}

if(count1==5|count2==5|count3==5|count4==5) {

return true;

}

return false;

}

//白棋胜负判断

public static boolean whitejudge(int[][] Array,int chessY,int chessX) {

int count1=0,count2=0,count3=0,count4=0;

//横向遍历

for(int i=-15;i<=15;i++) {

if(chessX+i>=0&&chessX+i<=15) {

if(count1<5) {

if(Array[chessY][chessX+i]==2) {

count1++;

}else {

count1=0;

}

}else if(count1==5) {

if(Array[chessY][chessX+i]==2) {

count1++;

}}}}

//纵向遍历

for(int i=-15;i<=15;i++) {

if(chessY+i>=0&&chessY+i<=15) {

if(count2<5) {

if(Array[chessY+i][chessX]==2) {

count2++;

}else {

count2=0;

}

}else if(count2==5) {

if(Array[chessY+i][chessX]==2) {

count2++;

}}}}

//斜下遍历

for(int i=-15;i<=15;i++) {

if(chessY+i>=0&&chessY+i<=15&&chessX+i>=0&&chessX+i<=15) {

if(count3<5) {

if(Array[chessY+i][chessX+i]==2) {

count3++;

}else {

count3=0;

}

}else if(count3==5) {

if(Array[chessY+i][chessX+i]==2) {

count3++;

}}}}

//斜上遍历

for(int i=-15;i<=15;i++) {

if(chessY-i>=0&&chessY-i<=15&&chessX+i>=0&&chessX+i<=15) {

if(count4<5) {

if(Array[chessY-i][chessX+i]==2) {

count4++;

}else {

count4=0;

}

}else if(count4==5) {

if(Array[chessY-i][chessX+i]==2) {

count4++;

}}}}

if(count1==5|count2==5|count3==5|count4==5) {

return true;

}

return false;

}

}

四、部分效果展示

注意,代码中图片的路径还需自己更改设置

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:演进实录|不同阶段的企业如何搭建监控体系?
下一篇:@所有人,中国正式提出申请加入《数字经济伙伴关系协定》
相关文章

 发表评论

暂时没有评论,来抢沙发吧~