Java五子棋(人机版),昨天买的棋子今天就用不上了,2024年最新java高级程序员面试题及答案

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

import javax.swing.JFrame;

import javax.swing.JPanel;

/*

  • 画布类

*/

public class GamePanel extends JPanel {

private static final long serialVersionUID = 1L;

GamePanel gamePanel=this;

private JFrame mainFrame=null;

//构造里面初始化相关参数

public GamePanel(JFrame frame){

this.setLayout(null);

this.setOpaque(false);

mainFrame = frame;

mainFrame.requestFocus();

mainFrame.setVisible(true);

}

}

再创建一个Main类,来启动这个窗口。

public class Main {

//主类

public static void main(String[] args) {

GameFrame frame = new GameFrame();

GamePanel gamePanel = new GamePanel(frame);

frame.add(gamePanel);

frame.setVisible(true);//设定显示

}

}

右键执行这个Main类,窗口建出来了

在这里插入图片描述

创建菜单及菜单选项


创建菜单

private void initMenu(){

// 创建菜单及菜单选项

jmb = new JMenuBar();

JMenu jm1 = new JMenu(“游戏”);

jm1.setFont(new Font(“思源宋体”, Font.BOLD, 18));// 设置菜单显示的字体

JMenu jm2 = new JMenu(“帮助”);

jm2.setFont(new Font(“思源宋体”, Font.BOLD, 18));// 设置菜单显示的字体

JMenuItem jmi1 = new JMenuItem(“开始新游戏”);

JMenuItem jmi2 = new JMenuItem(“退出”);

jmi1.setFont(new Font(“思源宋体”, Font.BOLD, 18));

jmi2.setFont(new Font(“思源宋体”, Font.BOLD, 18));

JMenuItem jmi3 = new JMenuItem(“操作说明”);

jmi3.setFont(new Font(“思源宋体”, Font.BOLD, 18));

JMenuItem jmi4 = new JMenuItem(“成功/失败判定”);

jmi4.setFont(new Font(“思源宋体”, Font.BOLD, 18));

jm1.add(jmi1);

jm1.add(jmi2);

jm2.add(jmi3);

jm2.add(jmi4);

jmb.add(jm1);

jmb.add(jm2);

mainFrame.setJMenuBar(jmb);// 菜单Bar放到JFrame上

jmi1.addActionListener(this);

jmi1.setActionCommand(“Restart”);

jmi2.addActionListener(this);

jmi2.setActionCommand(“Exit”);

jmi3.addActionListener(this);

jmi3.setActionCommand(“help”);

jmi4.addActionListener(this);

jmi4.setActionCommand(“lost”);

}

实现ActionListener并重写方法actionPerformed

在这里插入图片描述

此时GamePanel是报错的,重写actionPerformed方法。

actionPerformed方法的实现

@Override

public void actionPerformed(ActionEvent e) {

String command = e.getActionCommand();

System.out.println(command);

UIManager.put(“OptionPane.buttonFont”, new FontUIResource(new Font(“思源宋体”, Font.ITALIC, 18)));

UIManager.put(“OptionPane.messageFont”, new FontUIResource(new Font(“思源宋体”, Font.ITALIC, 18)));

if (“Exit”.equals(command)) {

Object[] options = { “确定”, “取消” };

int response = JOptionPane.showOptionDialog(this, “您确认要退出吗”, “”,

JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,

options, options[0]);

if (response == 0) {

System.exit(0);

}

}else if(“Restart”.equals(command)){

if(!“end”.equals(gamePanel.gameFlag)){

JOptionPane.showMessageDialog(null, “正在游戏中无法重新开始!”,

“提示!”, JOptionPane.INFORMATION_MESSAGE);

}else{

if(gamePanel!=null) {

gamePanel.restart();

}

}

}else if(“help”.equals(command)){

JOptionPane.showMessageDialog(null, “鼠标在指示器位置点下,则落子!”,

“提示!”, JOptionPane.INFORMATION_MESSAGE);

}else if(“lost”.equals(command)){

JOptionPane.showMessageDialog(null, “五子连珠方获得胜利!”,

“提示!”, JOptionPane.INFORMATION_MESSAGE);

}

}

此时的GamePanel代码如下:

package main;

import java.awt.Font;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JFrame;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

import javax.swing.JMenuItem;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.UIManager;

import javax.swing.plaf.FontUIResource;

/*

  • 画布类

*/

public class GamePanel extends JPanel implements ActionListener{

private static final long serialVersionUID = 1L;

GamePanel gamePanel=this;

private JFrame mainFrame=null;

JMenuBar jmb=null;

public String gameFlag=“”;

//构造里面初始化相关参数

public GamePanel(JFrame frame){

this.setLayout(null);

this.setOpaque(false);

mainFrame = frame;

//创建按钮

initMenu();

mainFrame.requestFocus();

mainFrame.setVisible(true);

}

private void initMenu(){

// 创建菜单及菜单选项

jmb = new JMenuBar();

JMenu jm1 = new JMenu(“游戏”);

jm1.setFont(new Font(“思源宋体”, Font.BOLD, 18));// 设置菜单显示的字体

JMenu jm2 = new JMenu(“帮助”);

jm2.setFont(new Font(“思源宋体”, Font.BOLD, 18));// 设置菜单显示的字体

JMenuItem jmi1 = new JMenuItem(“开始新游戏”);

JMenuItem jmi2 = new JMenuItem(“退出”);

jmi1.setFont(new Font(“思源宋体”, Font.BOLD, 18));

jmi2.setFont(new Font(“思源宋体”, Font.BOLD, 18));

JMenuItem jmi3 = new JMenuItem(“操作说明”);

jmi3.setFont(new Font(“思源宋体”, Font.BOLD, 18));

JMenuItem jmi4 = new JMenuItem(“成功/失败判定”);

jmi4.setFont(new Font(“思源宋体”, Font.BOLD, 18));

jm1.add(jmi1);

jm1.add(jmi2);

jm2.add(jmi3);

jm2.add(jmi4);

jmb.add(jm1);

jmb.add(jm2);

mainFrame.setJMenuBar(jmb);// 菜单Bar放到JFrame上

jmi1.addActionListener(this);

jmi1.setActionCommand(“Restart”);

jmi2.addActionListener(this);

jmi2.setActionCommand(“Exit”);

jmi3.addActionListener(this);

jmi3.setActionCommand(“help”);

jmi4.addActionListener(this);

jmi4.setActionCommand(“lost”);

}

//重新开始

public void restart() {

//游戏开始标记

gameFlag=“start”;

}

@Override

public void actionPerformed(ActionEvent e) {

String command = e.getActionCommand();

System.out.println(command);

UIManager.put(“OptionPane.buttonFont”, new FontUIResource(new Font(“思源宋体”, Font.ITALIC, 18)));

UIManager.put(“OptionPane.messageFont”, new FontUIResource(new Font(“思源宋体”, Font.ITALIC, 18)));

if (“Exit”.equals(command)) {

Object[] options = { “确定”, “取消” };

int response = JOptionPane.showOptionDialog(this, “您确认要退出吗”, “”,

JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,

options, options[0]);

if (response == 0) {

System.exit(0);

}

}else if(“Restart”.equals(command)){

if(!“end”.equals(gamePanel.gameFlag)){

JOptionPane.showMessageDialog(null, “正在游戏中无法重新开始!”,

“提示!”, JOptionPane.INFORMATION_MESSAGE);

}else{

if(gamePanel!=null) {

gamePanel.restart();

}

}

}else if(“help”.equals(command)){

JOptionPane.showMessageDialog(null, “鼠标在指示器位置点下,则落子!”,

“提示!”, JOptionPane.INFORMATION_MESSAGE);

}else if(“lost”.equals(command)){

JOptionPane.showMessageDialog(null, “五子连珠方获得胜利!”,

“提示!”, JOptionPane.INFORMATION_MESSAGE);

}

}

}

运行一下

在这里插入图片描述

绘制棋盘


重写paint方法

@Override

public void paint(java.awt.Graphics g) {

super.paint(g);

}

绘制横竖相交接的线

定义15行、15列

public static final int ROWS=15;

public static final int COLS=15;

绘制网格

//绘制网格

private void drawGrid(Graphics g) {

Graphics2D g_2d=(Graphics2D)g;

int start=26;

int x1=start;

int y1=20;

int x2=586;

int y2=20;

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

y1 = start + 40*i;

y2 = y1;

g_2d.drawLine(x1, y1, x2, y2);

}

y1=start;

y2=586;

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

x1 = start + 40*i;

x2 = x1;

g_2d.drawLine(x1, y1, x2, y2);

}

}

绘制5个圆点

//绘制5个黑点

private void draw5Point(Graphics g) {

//第1个点

g.fillArc(142, 142, 8, 8, 0, 360);

//第2个点

g.fillArc(462, 142, 8, 8, 0, 360);

//第3个点

g.fillArc(142, 462, 8, 8, 0, 360);

//第4个点

g.fillArc(462, 462, 8, 8, 0, 360);

//中心点

g.fillArc(302, 302, 8, 8, 0, 360);

}

在paint方法里面调用以上2个方法

@Override

public void paint(java.awt.Graphics g) {

super.paint(g);

//绘制网格

drawGrid(g);

//绘制5个黑点

draw5Point(g);

}

棋盘已经绘制完成

在这里插入图片描述

实现落子指示器


  1. 创建指示器类

package main;

import java.awt.Color;

import java.awt.Graphics;

//指示器类

public class Pointer {

private int i=0;//二维下标i

private int j=0;//二维下标j

private int x=0;//坐标X

private int y=0;//坐标Y

private GamePanel panel=null;

private Color color=null;

private int h=40;//指示的大小

private boolean isShow=false;//是否展示

private int qizi = 0 ;//棋子类型 0:无 1:白棋 2:黑棋

public Pointer(int x,int y,int i,int j,Color color,GamePanel panel){

this.x=x;

this.y=y;

this.i=i;

this.j=j;

this.panel=panel;

this.color=color;

}

//绘制

void draw(Graphics g){

Color oColor = g.getColor();

if(color!=null){

g.setColor(color);

}

if(isShow){

//绘制指示器

g.drawRect(x-h/2, y-h/2, h, h);

}

if(color!=null){//用完设置回去颜色

g.setColor(oColor);

}

}

//判断鼠标是否在指针范围内

boolean isPoint(int x,int y){

//大于左上角,小于右下角的坐标则肯定在范围内

if(x>this.x-h/2 && y >this.y-h/2

&& x<this.x+h/2 && y <this.y+h/2){

return true;

}

return false;

}

public boolean isShow() {

return isShow;

}

public void setShow(boolean isShow) {

this.isShow = isShow;

}

public int getQizi() {

return qizi;

}

public void setQizi(int qizi) {

this.qizi = qizi;

}

public int getX() {

return x;

}

public void setX(int x) {

this.x = x;

}

public int getY() {

return y;

}

public void setY(int y) {

this.y = y;

}

public int getI() {

return i;

}

public void setI(int i) {

this.i = i;

}

public int getJ() {

return j;

}

public void setJ(int j) {

this.j = j;

}

}

  1. 初始化二维数组

public Pointer points[][] = new Pointer[ROWS][COLS];

  1. 创建指示器实例对象

//创建二维数组

private void createArr() {

int x=0,y=0;

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

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

y = 26 + 40*i;

x = 26 + 40*j;

Pointer pointer = new Pointer(x, y, i,j,new Color(255,0,0), this);

points[i][j] = pointer;

}

}

}

  1. 初始化调用

//初始化相关对象

private void init() {

createArr();

//游戏开始标记

gameFlag=“start”;

}

同时 init方法 在GamePanel 的构造方法调用。

  1. paint方法中遍历二维数组并且绘制。

@Override

public void paint(java.awt.Graphics g) {

super.paint(g);

//绘制网格

drawGrid(g);

//绘制5个黑点

draw5Point(g);

//绘制指示器

Pointer pointer = null;

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

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

pointer = points[i][j] ;

if(pointer!=null){

pointer.draw(g);

}

}

}

}

运行如下

在这里插入图片描述

但是这个指示器方块不是我们想要的,需要改一下

  1. 修改指示器类的绘图代码

在Pointer方法中新增方法,并在指示器绘制的时候调用此方法,而不是之前的drawRect。

private void drawPointer(Graphics g) {

Graphics2D g2 = (Graphics2D)g; //g是Graphics对象

g2.setStroke(new BasicStroke(2.0f));

/*

  • 1.先计算4个顶点

  • 2.依次从每个顶点绘制横竖两条线

*/

//左上角

int x1 = x-h/2;

int y1 = y-h/2;

//向右画线

int x2 = x1+1*h/4;

int y2 = y1;

g2.drawLine(x1, y1, x2, y2);

//向下画线

x2 = x1;

y2 = y1+1*h/4;

g2.drawLine(x1, y1, x2, y2);

//右上角

x1 = x+h/2;

y1 = y-h/2;

//向左画线

x2 = x1-1*h/4;

y2 = y1;

g2.drawLine(x1, y1, x2, y2);

//向下画线

x2 = x1;

y2 = y1+1*h/4;

g2.drawLine(x1, y1, x2, y2);

//右下角

x1 = x+h/2;

y1 = y+h/2;

//向左画线

x2 = x1-1*h/4;

y2 = y1;

g2.drawLine(x1, y1, x2, y2);

//向上画线

x2 = x1;

y2 = y1-1*h/4;

g2.drawLine(x1, y1, x2, y2);

//左下角

x1 = x-h/2;

y1 = y+h/2;

//向右画线

x2 = x1+1*h/4;

y2 = y1;

g2.drawLine(x1, y1, x2, y2);

//向上画线

x2 = x1;

y2 = y1-1*h/4;

g2.drawLine(x1, y1, x2, y2);

}

再运行

在这里插入图片描述

落子


  1. 创建ImageValue加载类

import java.awt.image.BufferedImage;

import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageValue {

public static BufferedImage whiteQiziImage ;

public static BufferedImage blackQiziImage ;

//路径

public static String ImagePath = “/images/”;

//将图片初始化

public static void init(){

String whitePath = ImagePath +“white.png”;

String blackPath = ImagePath +“black.png”;

try {

whiteQiziImage = ImageIO.read(ImageValue.class.getResource(whitePath));

blackQiziImage = ImageIO.read(ImageValue.class.getResource(blackPath));

} catch (IOException e) {

e.printStackTrace();

}

}

}

  1. 创建落子类

import java.awt.Color;

import java.awt.Graphics;

import common.ImageValue;

public class Qizi {

private int x = 0;

private int y = 0;

private int r = 36;

private GamePanel panel = null;

private Color color = null;

private int type = 1;// 棋子类型 1:白棋 2:黑棋

public Qizi(int x, int y, int type, GamePanel panel) {

this.x = x;

this.y = y;

this.panel = panel;

this.type=type;

}

// 绘制

void draw(Graphics g) {

Color oColor = g.getColor();

if (type == 1) {// 白色

g.drawImage(ImageValue.whiteQiziImage, x - r / 2, y - r / 2,r,r, null);

} else {// 黑色

g.drawImage(ImageValue.blackQiziImage, x - r / 2, y - r / 2,r,r, null);

}

if (color != null) {// 用完设置回去颜色

g.setColor(oColor);

}

}

public int getType() {

return type;

}

public void setType(int type) {

this.type = type;

}

}

  1. 在createMouseListener方法中重写mouseClicked,创建棋子

@Override

public void mouseClicked(MouseEvent e) {

//在合适的位置点击则进行落子操作

if(!“start”.equals(gameFlag)) return ;

int x = e.getX();

int y = e.getY();

Pointer pointer;

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

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

pointer = points[i][j];

if(pointer==null)continue;

//被点击,且没有棋子,则可以落子

if(pointer.isPoint(x, y) && pointer.getQizi()==0){

Qizi qizi = new Qizi(pointer.getX(), pointer.getY(), 2, gamePanel);

pointer.setQizi(2);

qizis.add(qizi);

//重绘画布

repaint();

return ;

}

}

}

}

  1. 在paint 方法中绘制棋子

@Override

public void paint(java.awt.Graphics g) {

super.paint(g);

//绘制网格

drawGrid(g);

//绘制5个黑点

draw5Point(g);

//绘制指示器

Pointer pointer = null;

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

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

pointer = points[i][j] ;

if(pointer!=null){

pointer.draw(g);

}

}

}

//绘制棋子

Qizi qizi=null;

for (int i = 0; i < qizis.size(); i++) {

qizi = (Qizi)qizis.get(i);

qizi.draw(g);

}

}

在这里插入图片描述

加入电脑AI


  1. 创建AI类

  2. 创建静态方法next(下一步)

  3. 创建静态方法has5(连成5子)

public class AI {

//AI进行下一步

static void next(GamePanel gamePanel){

}

//判断五子连珠

static boolean has5(Pointer pointer1,GamePanel gamePanel){

return false;

}

}

  1. 在你落子后,会先执行has5方法,根据返回来决定走向

  2. has5返回true则表示你获得胜利,否则AI将会走一步棋

在刚才的mouseClicked修改代码

@Override

public void mouseClicked(MouseEvent e) {

//在合适的位置点击则进行落子操作

if(!“start”.equals(gameFlag)) return ;

int x = e.getX();

int y = e.getY();

Pointer pointer;

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

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

pointer = points[i][j];

if(pointer==null)continue;

//被点击,且没有棋子,则可以落子

if(pointer.isPoint(x, y) && pointer.getQizi()==0){

Qizi qizi = new Qizi(pointer.getX(), pointer.getY(), 2, gamePanel);

pointer.setQizi(2);

qizis.add(qizi);

//重绘画布

repaint();

//判断有没有五子连珠的情况

if(AI.has5(pointer, gamePanel)){

gamePanel.gameWin();

}else{

AI.next(gamePanel);

}

return ;

}

}

}

}

  1. 在AI类中随机落子(创建方法)

- 随机获取下标 i 和 j。

- 通过下标从二维数组取到指示器对象。

- 如果此指示器被占用则再次随机(递归),直到正确获取到指示器对象。

- 在此指示器位置,创建棋子对象并更新指示器的棋子信息。

我的面试宝典:一线互联网大厂Java核心面试题库

以下是我个人的一些做法,希望可以给各位提供一些帮助:

整理了很长一段时间,拿来复习面试刷题非常合适,其中包括了Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等,且还会持续的更新…可star一下!

image

283页的Java进阶核心pdf文档

Java部分:Java基础,集合,并发,多线程,JVM,设计模式

数据结构算法:Java算法,数据结构

开源框架部分:Spring,MyBatis,MVC,netty,tomcat

分布式部分:架构设计,Redis缓存,Zookeeper,kafka,RabbitMQ,负载均衡等

微服务部分:SpringBoot,SpringCloud,Dubbo,Docker

image

还有源码相关的阅读学习

image

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

if(!“start”.equals(gameFlag)) return ;

int x = e.getX();

int y = e.getY();

Pointer pointer;

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

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

pointer = points[i][j];

if(pointer==null)continue;

//被点击,且没有棋子,则可以落子

if(pointer.isPoint(x, y) && pointer.getQizi()==0){

Qizi qizi = new Qizi(pointer.getX(), pointer.getY(), 2, gamePanel);

pointer.setQizi(2);

qizis.add(qizi);

//重绘画布

repaint();

//判断有没有五子连珠的情况

if(AI.has5(pointer, gamePanel)){

gamePanel.gameWin();

}else{

AI.next(gamePanel);

}

return ;

}

}

}

}

  1. 在AI类中随机落子(创建方法)

- 随机获取下标 i 和 j。

- 通过下标从二维数组取到指示器对象。

- 如果此指示器被占用则再次随机(递归),直到正确获取到指示器对象。

- 在此指示器位置,创建棋子对象并更新指示器的棋子信息。

我的面试宝典:一线互联网大厂Java核心面试题库

以下是我个人的一些做法,希望可以给各位提供一些帮助:

整理了很长一段时间,拿来复习面试刷题非常合适,其中包括了Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等,且还会持续的更新…可star一下!

[外链图片转存中…(img-R4urCDHl-1713615151979)]

283页的Java进阶核心pdf文档

Java部分:Java基础,集合,并发,多线程,JVM,设计模式

数据结构算法:Java算法,数据结构

开源框架部分:Spring,MyBatis,MVC,netty,tomcat

分布式部分:架构设计,Redis缓存,Zookeeper,kafka,RabbitMQ,负载均衡等

微服务部分:SpringBoot,SpringCloud,Dubbo,Docker

[外链图片转存中…(img-A2XjZya1-1713615151979)]

还有源码相关的阅读学习

[外链图片转存中…(img-AycVn9nH-1713615151980)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-7QEetmPW-1713615151980)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值