百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

java学习-五子棋代码应用 java五子棋完整代码

lipiwang 2024-10-29 15:55 7 浏览 0 评论

第一个文件:

import javax.swing.*;

import java.awt.event.*;

import java.awt.*;

/*

五子棋-主框架类, 程序启动类

*/

public class StartChessJFrame extends JFrame {

private ChessBoard chessBoard;//对战面板

private JPanel toolbar;//工具条面板

private JButton startButton, backButton, exitButton;

//重新开始按钮,悔棋按钮,和退出按钮

private JMenuBar menuBar;//菜单栏

private JMenu sysMenu;//系统菜单

private JMenuItem startMenuItem, exitMenuItem, backMenuItem;

//重新开始,退出,和悔棋菜单项

public StartChessJFrame() {

setTitle("单机版五子棋");//设置标题

chessBoard = new ChessBoard();//初始化面板对象

// 创建和添加菜单

menuBar = new JMenuBar();//初始化菜单栏

sysMenu = new JMenu("系统");//初始化菜单

startMenuItem = new JMenuItem("重新开始");

exitMenuItem = new JMenuItem("退出");

backMenuItem = new JMenuItem("悔棋");//初始化菜单项

sysMenu.add(startMenuItem);//将三个菜单项添加到菜单上

sysMenu.add(backMenuItem);

sysMenu.add(exitMenuItem);

MyItemListener lis = new MyItemListener();//初始化按钮事件监听器内部类

this.startMenuItem.addActionListener(lis);//将三个菜单项注册到事件监听器上

backMenuItem.addActionListener(lis);

exitMenuItem.addActionListener(lis);

menuBar.add(sysMenu);//将系统菜单添加到菜单栏上

setJMenuBar(menuBar);// 将menuBar设置为菜单栏

toolbar = new JPanel();//工具面板栏实例化

startButton = new JButton("重新开始");//三个按钮初始化

backButton = new JButton("悔棋");

exitButton = new JButton("退出");

toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));//将工具面板按钮用FlowLayout布局

toolbar.add(startButton);//将三个按钮添加到工具面板上

toolbar.add(backButton);

toolbar.add(exitButton);

startButton.addActionListener(lis);//将三个按钮注册监听事件

backButton.addActionListener(lis);

exitButton.addActionListener(lis);

add(toolbar, BorderLayout.SOUTH);//将工具面板布局到界面"南"方也就是下面

add(chessBoard);//将面板对象添加到窗体上

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置界面关闭事件

//setSize(800,800);

pack(); // 自适应大小

}

private class MyItemListener implements ActionListener {//事件监听器内部类

public void actionPerformed(ActionEvent e) {

Object obj = e.getSource(); // 取得事件源

if (obj == StartChessJFrame.this.startMenuItem || obj == startButton) {

// 重新开始

// JFiveFrame.this内部类引用外部类

System.out.println("重新开始...");

chessBoard.restartGame();

} else if (obj == exitMenuItem || obj == exitButton) {

System.exit(0); // 结束应用程序

} else if (obj == backMenuItem || obj == backButton) { // 悔棋

System.out.println("悔棋...");

chessBoard.goback();

}

}

}

public static void main(String[] args) {

StartChessJFrame f = new StartChessJFrame(); // 创建主框架

f.setVisible(true); // 显示主框架

}

}

第二个文件:

import java.awt.Color;

/*五子棋的棋子设计。

*/

public class Point {

private int x; // 棋盘中的x索引

private int y; // 棋盘中的y索引

private Color color;//颜色

public static final int DIAMETER = 30;//直径

public Point(int x, int y, Color color) {

this.x = x;

this.y = y;

this.color = color;

}

public int getX() {// 拿到棋盘中的x索引

return x;

}

public int getY() {// 拿到棋盘中的Y索引

return y;

}

public Color getColor() {//得到颜色

return color;

}

}

第三个文件:

import javax.swing.*;

import java.awt.*;

import java.awt.event.MouseListener;

import java.awt.event.MouseMotionListener;

import java.awt.event.MouseEvent;

/*

五子棋-棋盘类

*/

public class ChessBoard extends JPanel implements MouseListener {

public static final int MARGIN = 30; // 边距

public static final int GRID_SPAN = 35; // 网格间距

public static final int ROWS = 15;//棋盘行数

public static final int COLS = 15;//棋盘列数

Point[] chessList = new Point[(ROWS + 1) * (COLS + 1)]; // 初始每个数组元素为null

boolean isBlack = true;//默然开始是黑棋先下

boolean gameOver = false;// 游戏是否结束

int chessCount; // 当前棋盘的棋子个数

int xIndex, yIndex; // 当前刚下的棋子的索引

public ChessBoard() {

setBackground(Color.ORANGE);//设置背景颜色为橘黄色

addMouseListener(this);// 添加监听器

addMouseMotionListener(new MouseMotionListener() { // 匿名内部类

public void mouseDragged(MouseEvent e) {

}

public void mouseMoved(MouseEvent e) {

int x1 = (e.getX() - MARGIN + GRID_SPAN / 2) / GRID_SPAN;

// 将鼠标点击的坐标位置转换成网格索引。

int y1 = (e.getY() - MARGIN + GRID_SPAN / 2) / GRID_SPAN;

// 游戏已经结束,不能下

// 落在棋盘外,不能下

// x,y位置已经有棋子存在,不能下

if (x1 < 0 || x1 > ROWS || y1 < 0 || y1 > COLS || gameOver

|| findChess(x1, y1))

setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); // 设置成默认形状

else

setCursor(new Cursor(Cursor.HAND_CURSOR)); // 设置成手型

}

});

}

// 绘制

public void paintComponent(Graphics g) {

super.paintComponent(g);

// 画棋盘

for (int i = 0; i <= ROWS; i++) { // 画横线

g.drawLine(MARGIN, MARGIN + i * GRID_SPAN, MARGIN + COLS

* GRID_SPAN, MARGIN + i * GRID_SPAN);

}

for (int i = 0; i <= COLS; i++) {// 画直线

g.drawLine(MARGIN + i * GRID_SPAN, MARGIN, MARGIN + i * GRID_SPAN,

MARGIN + ROWS * GRID_SPAN);

}

// 画棋子

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

int xPos = chessList[i].getX() * GRID_SPAN + MARGIN; // 网格交叉点的x坐标

int yPos = chessList[i].getY() * GRID_SPAN + MARGIN;// 网格交叉点的y坐标

g.setColor(chessList[i].getColor()); // 设置颜色

g.fillOval(xPos - Point.DIAMETER / 2, yPos - Point.DIAMETER / 2,

Point.DIAMETER, Point.DIAMETER);

// 标记最后一个棋子的红矩形框

if (i == chessCount - 1) { // 最后一个棋子

g.setColor(Color.red);

g.drawRect(xPos - Point.DIAMETER / 2,

yPos - Point.DIAMETER / 2, Point.DIAMETER,

Point.DIAMETER);

}

}

}

public void mousePressed(MouseEvent e) {// 鼠标按键在组件上按下时调用。

// 游戏已经结束,不能下

if (gameOver)

return;

String colorName = isBlack ? "黑棋" : "白棋";

xIndex = (e.getX() - MARGIN + GRID_SPAN / 2) / GRID_SPAN; // 将鼠标点击的坐标位置转换成网格索引。

yIndex = (e.getY() - MARGIN + GRID_SPAN / 2) / GRID_SPAN;

// 落在棋盘外,不能下

if (xIndex < 0 || xIndex > ROWS || yIndex < 0 || yIndex > COLS)

return;

// x,y位置已经有棋子存在,不能下

if (findChess(xIndex, yIndex))

return;

Point ch = new Point(xIndex, yIndex, isBlack ? Color.black: Color.white);

chessList[chessCount++] = ch;

repaint(); // 通知系统重新绘制

if (isWin()) {

// 给出胜利信息,不能再继续下棋

String msg = String.format("恭喜,%s赢了!", colorName);

JOptionPane.showMessageDialog(this, msg);

gameOver = true;

}

isBlack = !isBlack;

}

// 覆盖MouseListener的方法

public void mouseClicked(MouseEvent e) {

} // 鼠标按键在组件上单击(按下并释放)时调用。

public void mouseEntered(MouseEvent e) {

}// 鼠标进入到组件上时调用。

public void mouseExited(MouseEvent e) {

}// 鼠标离开组件时调用。

public void mouseReleased(MouseEvent e) {

} // 鼠标按钮在组件上释放时调用。

// 在棋子数组中查找是否有索引为x,y的棋子存在

private boolean findChess(int x, int y) {

for (Point c : chessList) {

if (c != null && c.getX() == x && c.getY() == y)

return true;

}

return false;

}

private boolean isWin() {//判断那方赢

int continueCount = 1; // 连续棋子的个数

// 横向向西寻找

for (int x = xIndex - 1; x >= 0; x--) {

Color c = isBlack ? Color.black : Color.white;

if (getChess(x, yIndex, c) != null) {

continueCount++;

} else

break;

}

// 横向向东寻找

for (int x = xIndex + 1; x <= ROWS; x++) {

Color c = isBlack ? Color.black : Color.white;

if (getChess(x, yIndex, c) != null) {

continueCount++;

} else

break;

}

if (continueCount >= 5) {

return true;

} else

continueCount = 1;

// 继续另一种情况的搜索: 纵向

// 纵向向上寻找

for (int y = yIndex - 1; y >= 0; y--) {

Color c = isBlack ? Color.black : Color.white;

if (getChess(xIndex, y, c) != null) {

continueCount++;

} else

break;

}

// 纵向向下寻找

for (int y = yIndex + 1; y <= ROWS; y++) {

Color c = isBlack ? Color.black : Color.white;

if (getChess(xIndex, y, c) != null) {

continueCount++;

} else

break;

}

if (continueCount >= 5) {

return true;

} else

continueCount = 1;

// 继续另一种情况的搜索: 斜向

// 东北寻找

for (int x = xIndex + 1, y = yIndex - 1; y >= 0 && x <= COLS; x++, y--) {

Color c = isBlack ? Color.black : Color.white;

if (getChess(x, y, c) != null) {

continueCount++;

} else

break;

}

// 西南寻找

for (int x = xIndex - 1, y = yIndex + 1; y <= ROWS && x >= 0; x--, y++) {

Color c = isBlack ? Color.black : Color.white;

if (getChess(x, y, c) != null) {

continueCount++;

} else

break;

}

if (continueCount >= 5) {

return true;

} else

continueCount = 1;

// 继续另一种情况的搜索: 斜向

// 西北寻找

for (int x = xIndex - 1, y = yIndex - 1; y >= 0 && x >= 0; x--, y--) {

Color c = isBlack ? Color.black : Color.white;

if (getChess(x, y, c) != null) {

continueCount++;

} else

break;

}

// 西南寻找

for (int x = xIndex + 1, y = yIndex + 1; y <= ROWS && x <= COLS; x++, y++) {

Color c = isBlack ? Color.black : Color.white;

if (getChess(x, y, c) != null) {

continueCount++;

} else

break;

}

if (continueCount >= 5) {

return true;

} else

continueCount = 1;

return false;

}

private Point getChess(int xIndex, int yIndex, Color color) {

for (Point c : chessList) {

if (c != null && c.getX() == xIndex && c.getY() == yIndex

&& c.getColor() == color)

return c;

}

return null;

}

public void restartGame() {

// 清除棋子

for (int i = 0; i < chessList.length; i++)

chessList[i] = null;

// 恢复游戏相关的变量值

isBlack = true;

gameOver = false;// 游戏是否结束

chessCount = 0; // 当前棋盘的棋子个数

repaint();

}

// 悔棋

public void goback() {

if (chessCount == 0)

return;

chessList[chessCount - 1] = null;

chessCount--;

if (chessCount > 0) {

xIndex = chessList[chessCount - 1].getX();

yIndex = chessList[chessCount - 1].getY();

}

isBlack = !isBlack;

repaint();

}

// Dimension: 矩形

public Dimension getPreferredSize() {

return new Dimension(MARGIN * 2 + GRID_SPAN * COLS, MARGIN * 2

+ GRID_SPAN * ROWS);

}

}

相关推荐

linux实例之设置时区的方式有哪些

linux系统下的时间管理是一个复杂但精细的功能,而时区又是时间管理非常重要的一个辅助功能。时区解决了本地时间和UTC时间的差异,从而确保了linux系统下时间戳和时间的准确性和一致性。比如文件的时间...

Linux set命令用法(linux cp命令的用法)

Linux中的set命令用于设置或显示系统环境变量。1.设置环境变量:-setVAR=value:设置环境变量VAR的值为value。-exportVAR:将已设置的环境变量VAR导出,使其...

python环境怎么搭建?小白看完就会!简简单单

很多小伙伴安装了python不会搭建环境,看完这个你就会了Python可应用于多平台包括Linux和MacOSX。你可以通过终端窗口输入"python"命令来查看本地是否...

Linux环境下如何设置多个交叉编译工具链?

常见的Linux操作系统都可以通过包管理器安装交叉编译工具链,比如Ubuntu环境下使用如下命令安装gcc交叉编译器:sudoapt-getinstallgcc-arm-linux-gnueab...

JMeter环境变量配置技巧与注意事项

通过给JMeter配置环境变量,可以快捷的打开JMeter:打开终端。执行jmeter。配置环境变量的方法如下。Mac和Linux系统在~/.bashrc中加如下内容:export...

C/C++|头文件、源文件分开写的源起及作用

1C/C++编译模式通常,在一个C++程序中,只包含两类文件——.cpp文件和.h文件。其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码;而.h文件则被称...

linux中内部变量,环境变量,用户变量的区别

unixshell的变量分类在Shell中有三种变量:内部变量,环境变量,用户变量。内部变量:系统提供,不用定义,不能修改环境变量:系统提供,不用定义,可以修改,可以利用export将用户变量转为环...

在Linux中输入一行命令后究竟发生了什么?

Linux,这个开源的操作系统巨人,以其强大的命令行界面而闻名。无论你是初学者还是经验丰富的系统管理员,理解在Linux终端输入一条命令并按下回车后发生的事情,都是掌握Linux核心的关键。从表面上看...

Nodejs安装、配置与快速入门(node. js安装)

Nodejs是现代JavaScript语言产生革命性变化的一个主要框架,它使得JavaScript从一门浏览器语言成为可以在服务器端运行、开发各种各样应用的通用语言。在不同的平台下,Nodejs的安装...

Ollama使用指南【超全版】(olaplex使用方法图解)

一、Ollama快速入门Ollama是一个用于在本地运行大型语言模型的工具,下面将介绍如何在不同操作系统上安装和使用Ollama。官网:https://ollama.comGithub:http...

linux移植(linux移植lvgl)

1uboot移植l移植linux之前需要先移植一个bootlader代码,主要用于启动linux内核,lLinux系统包括u-boot、内核、根文件系统(rootfs)l引导程序的主要作用将...

Linux日常小技巧参数优化(linux参数调优)

Linux系统参数优化可以让系统更加稳定、高效、安全,提高系统的性能和使用体验。下面列出一些常见的Linux系统参数优化示例,包括修改默认配置、网络等多方面。1.修改默认配置1.1修改默认编辑器默...

Linux系统编程—条件变量(linux 条件变量开销)

条件变量是用来等待线程而不是上锁的,条件变量通常和互斥锁一起使用。条件变量之所以要和互斥锁一起使用,主要是因为互斥锁的一个明显的特点就是它只有两种状态:锁定和非锁定,而条件变量可以通过允许线程阻塞和等...

面试题-Linux系统优化进阶学习(linux系统的优化)

一.基础必备优化:1.关闭SElinux2.FirewalldCenetOS7Iptables(C6)安全组(阿里云)3.网络管理服务||NetworkManager|network...

嵌入式Linux开发教程:Linux Shell

本章重点介绍Linux的常用操作和命令。在介绍命令之前,先对Linux的Shell进行了简单介绍,然后按照大多数用户的使用习惯,对各种操作和相关命令进行了分类介绍。对相关命令的介绍都力求通俗易懂,都给...

取消回复欢迎 发表评论: