Java GUI 单机版五子棋
前言
刚开始学java时接触到GUI,一时兴起写了个五子棋,五子棋的关键点在于判断输赢,其他的都没什么,现在翻出来整理并记录下来,不足之处还望各位路过的大佬多多指教。
代码实现
代码不多,四百多行,全都在这个类里面,直接运行main函数就可以看到效果,JDK用的是1.7
@SuppressWarnings("ALL")
public class MyFrame extends Frame {
private static int y;// 鼠标点击的X轴
private static int x;// 鼠标点击的Y轴
private int[][] xY = new int[400][2];// 定义二维数组x_y来保存每一个棋子的坐标,用于界面的展示
private int a = 0;//定义一个变量表示已经保存了的坐标数
private static String[][] str = new String[20][20];// 定义一个二维数组str来保存每一个棋子的位置和颜色,用于判断输赢
private boolean isWhite = true;// 棋子的颜色是否为白色
static boolean flagWin = false;// 是否分出输赢
private boolean isClick = false;// 是否点击了鼠标
private int win;// 判断是白棋赢还是黑棋赢,返回0,还没有人赢,返回1,白棋赢,返回2,黑棋赢
private String whoWin = "";//谁赢了
/**
* 初始化str,二维数组str来保存每一个棋子的位置和颜色,用于判断输赢
*/
private static void initStr() {
// 初始化str
for (int i = 0; i < str.length; i++) {
for (int j = 0; j < str[0].length; j++) {
str[i][j] = "*";
}
}
}
/**
* 判断输赢,返回0,还没有人赢,返回1,白棋赢,返回2,黑棋赢
*/
private static int win(String s) {
final int b = 1;
final int h = 2;
int win = 0;
for (int i = 0; i < str.length; i++) {
for (int j = 0; j < str[0].length; j++) {
// 横向的判断
if (j < str[0].length - 4) {
if (s.equals(str[i][j]) && s.equals(str[i][j + 1])
&& s.equals(str[i][j + 2])
&& s.equals(str[i][j + 3])
&& s.equals(str[i][j + 4])) {
// 返回0,还没有人赢,返回1,白棋赢,返回2,黑棋赢
if ("O".equals(s)) {
win = b;
}
if ("@".equals(s)) {
win = h;
}
return win;
}
}
// 横向的判断
if (j > 4) {
if (s.equals(str[i][j - 4])
&& s.equals(str[i][j - 3])
&& s.equals(str[i][j - 2])
&& s.equals(str[i][j - 1])
&& s.equals(str[i][j])) {
// 返回0,还没有人赢,返回1,白棋赢,返回2,黑棋赢
if ("O".equals(s)) {
win = b;
}
if ("@".equals(s)) {
win = h;
}
return win;
}
}
// 纵向的判断
if (i < str.length - 4) {
if (s.equals(str[i][j])
&& s.equals(str[i + 1][j])
&& s.equals(str[i + 2][j])
&& s.equals(str[i + 3][j])
&& s.equals(str[i + 4][j])) {
// 返回0,还没有人赢,返回1,白棋赢,返回2,黑棋赢
if ("O".equals(s)) {
win = b;
}
if ("@".equals(s)) {
win = h;
}
return win;
}
}
// 纵向的判断
if (i > 4) {
if (s.equals(str[i - 4][j])
&& s.equals(str[i - 3][j])
&& s.equals(str[i - 2][j])
&& s.equals(str[i - 1][j])
&& s.equals(str[i][j])) {
// 返回0,还没有人赢,返回1,白棋赢,返回2,黑棋赢
if ("O".equals(s)) {
win = b;
}
if ("@".equals(s)) {
win = h;
}
return win;
}
}
// 捺方向的判断
if (i < str.length - 4 && j < str[0].length - 4) {
if (s.equals(str[i][j])
&& s.equals(str[i + 1][j + 1])
&& s.equals(str[i + 2][j + 2])
&& s.equals(str[i + 3][j + 3])
&& s.equals(str[i + 4][j + 4])) {
// 返回0,还没有人赢,返回1,白棋赢,返回2,黑棋赢
if ("O".equals(s)) {
win = b;
}
if ("@".equals(s)) {
win = h;
}
return win;
}
}
// 捺方向的判断
if (i > 4 && j > 4) {
if (s.equals(str[i - 4][j - 4])
&& s.equals(str[i - 3][j - 3])
&& s.equals(str[i - 2][j - 2])
&& s.equals(str[i - 1][j - 1])
&& s.equals(str[i][j])) {
// 返回0,还没有人赢,返回1,白棋赢,返回2,黑棋赢
if ("O".equals(s)) {
win = b;
}
if ("@".equals(s)) {
win = h;
}
return win;
}
}
// 撇丿方向的判断
if (j >= 4 && i < str.length - 4) {
if (s.equals(str[i][j])
&& s.equals(str[i + 1][j - 1])
&& s.equals(str[i + 2][j - 2])
&& s.equals(str[i + 3][j - 3])
&& s.equals(str[i + 4][j - 4])) {
// 返回0,还没有人赢,返回1,白棋赢,返回2,黑棋赢
if ("O".equals(s)) {
win = b;
}
if ("@".equals(s)) {
win = h;
}
return win;
}
}
// 撇丿方向的判断
if (i >= 4 && j < str[0].length - 4) {
if (s.equals(str[i - 4][j + 4])
&& s.equals(str[i - 3][j + 3])
&& s.equals(str[i - 2][j + 2])
&& s.equals(str[i - 1][j + 1])
&& s.equals(str[i][j])) {
// 返回0,还没有人赢,返回1,白棋赢,返回2,黑棋赢
if ("O".equals(s)) {
win = b;
}
if ("@".equals(s)) {
win = h;
}
return win;
}
}
}
}
// 返回0,还没有人赢,返回1,白棋赢,返回2,黑棋赢
return win;
}
/**
* 判断是否和棋 返回true则棋盘上已经放满了 返回false则表示还没有放满
*/
private static boolean isDraw() {
for (String[] aStr : str) {
for (int j = 0; j < str[0].length; j++) {
if ("*".equals(aStr[j])) {
return false;
}
}
}
return true;
}
/**
* 对落子位置的逻辑判断
*/
private void ifPrint(Graphics g) {
// 如果已经分出胜负
if (!flagWin) {
// 是否为和棋
if (!isDraw()) {
//判断画笔颜色
if (isWhite) {
g.setColor(Color.WHITE);//定义画笔颜色
g.drawString("白棋走棋", 660, 100);
} else {
g.setColor(Color.BLACK);//定义画笔颜色
g.drawString("黑棋走棋", 660, 100);
}
// 往空格添加棋子
if (isClick) {// 是否点击了鼠标
if (x > 50 && x < 650 && y > 50 && y < 650) {// 是否在正确的位置下子
for (int i = 50; i < 650; i += 30) {
for (int j = 50; j < 650; j += 30) {
if (x > i && x < i + 30 && y > j && y < j + 30) {// 判断是在哪一个空格下子
if ("*".equals(str[(j - 50) / 30][(i - 50) / 30])) {// 判断该空格是否已经有子
if (isWhite) {// 判断下的棋子的颜色
g.setColor(Color.WHITE);//定义画笔颜色
str[(j - 50) / 30][(i - 50) / 30] = "O";// 保存棋子的位置和颜色
} else {
g.setColor(Color.BLACK);//定义画笔颜色
str[(j - 50) / 30][(i - 50) / 30] = "@";
}
g.fillOval(i, j, 30, 30);// //画棋子,实心圆
// 保存棋子的坐标
xY[a][0] = i;
xY[a][1] = j;
System.out.println("x:" + x + " y:" + y
+ "a:" + a + " teyp" + isWhite);
a++;
// 重置坐标
x = 0;
y = 0;
isWhite = !isWhite;
for (int i1 = 0; i1 < str.length; i1++) {
for (int j1 = 0; j1 < str[0].length; j1++) {
System.out.print(str[i1][j1] + " ");
}
}
} else {
g.setColor(Color.RED);//定义画笔颜色
g.drawString("该位置已经有子,请从新下!", 660, 120);
System.out.println("该位置已经有子,请从新下!");
}
}
}
}
} else {
g.setColor(Color.RED);//定义画笔颜色
g.drawString("请在正确的位置放子!", 660, 120);
System.out.println("请在正确的位置放子!");
}
isClick = false;
}
if (!isWhite) {// 因为前面下完子之后已经取反了,所以这里取非
win = win("O");// 判断白棋是否赢
} else {
win = win("@");// 判断黑棋是否赢
}
switch (win) {
case 1:
System.out.println("白棋赢了");
flagWin = true;
whoWin = "白棋赢了";
break;
case 2:
System.out.println("黑棋赢了");
flagWin = true;
whoWin = "黑棋赢了";
break;
default:
}
} else {
g.setColor(Color.RED);//定义画笔颜色
g.drawString("和棋!!!", 660, 100);
g.drawString("你们打成了平手!", 660, 120);
}
} else {
g.setColor(Color.RED);//定义画笔颜色
g.drawString(whoWin, 660, 100);
g.drawString("已经分出了胜负啦!", 660, 120);
}
}
/**
* 初始化窗口
*/
private void launchFrame() {
// 设置窗口大小
setSize(800, 700);
// 设置窗口位置
setLocation(50, 50);
// 设置背景颜色
setBackground(Color.PINK);
// 设置窗口可见
setVisible(true);
// 设置标题
setTitle("欢子出品,必属精品");
// 设置窗口大小不可变
setResizable(false);
// 启用线程
new PaintThread().start();
// 添加窗口监听,实现窗口关闭
addWindowListener(new MyWindow());
// 添加鼠标监听
addMouseListener(new MyMouse());
}
/**
* 画窗体里的内容
*/
@Override
public void paint(Graphics g) {
//初始化画笔的颜色
g.setColor(Color.BLACK);
// 画线,画方格
// X轴方向
for (int i = 0, j = 50; i <= 20; i++) {
g.drawLine(50, j, 650, j);
j += 30;
}
// Y轴方向
for (int i = 0, j = 50; i <= 20; i++) {
g.drawLine(j, 50, j, 650);
j += 30;
}
// 画棋子
for (int i = 0; i < a; i++) {
if ("O".equals(str[(xY[i][1] - 50) / 30][(xY[i][0] - 50) / 30])) {
g.setColor(Color.WHITE);//定义画笔颜色
} else if ("@"
.equals(str[(xY[i][1] - 50) / 30][(xY[i][0] - 50) / 30])) {
g.setColor(Color.BLACK);//定义画笔颜色
}
g.fillOval(xY[i][0], xY[i][1], 30, 30);//画棋子,实心圆
}
//对落子位置的逻辑判断
ifPrint(g);
//恢复画笔的颜色
g.setColor(Color.BLACK);
}
/**
* 退出
*/
class MyWindow extends WindowAdapter {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
/**
* 定义一个鼠标监听事件类
*/
class MyMouse implements MouseListener {
/**
* 鼠标释放
*/
@Override
public void mouseReleased(MouseEvent arg0) {
// System.out.println("鼠标释放"+arg0);
}
/**
* 鼠标按下
*/
@Override
public void mousePressed(MouseEvent arg0) {
// System.out.println("鼠标按下"+arg0);
}
/**
* 鼠标离开
*/
@Override
public void mouseExited(MouseEvent arg0) {
// System.out.println("鼠标离开)"+arg0);
}
/**
* 鼠标进入
*/
@Override
public void mouseEntered(MouseEvent arg0) {
// System.out.println("鼠标进入)"+arg0);
}
/**
* 鼠标点击
*/
@Override
public void mouseClicked(MouseEvent arg0) {
x = arg0.getX();
y = arg0.getY();
isClick = true;
}
}
/**
* 定义一个线程重画窗口,是一个内部类
*/
class PaintThread extends Thread {
@Override
public void run() {
while (true) {
repaint();
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* main函数
*/
public static void main(String[] args) {
new MyFrame().launchFrame();
initStr();
}
}
效果
功能有些简陋,提示语不够友好,悔棋、再开一局等功能也都还没有做...。输赢算法分为横、竖、撇、捺四个方向判断
横

竖

撇

捺

总结
五子棋的重点在于判断输赢,其他的一些“小功能”都只是锦上添花,有时间可以用socket搞个多人在线对弈版本,不过这些东西也只有在学校的时候骗骗学弟学妹装装逼,同时可以巩固自己、其他的感觉没什么用,各位大佬觉得呢?
Java GUI 单机版五子棋的更多相关文章
- JAVA课程设计——单机版五子棋
JAVA课程设计--单机版五子棋 1.团队名称.团队成员介绍 团队名称:Gomoku小分队 团队成员: 网络1512 201521123038 游舒婷(组长) 网络1512 201521123043 ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- JAVA GUI
JAVA GUI中的事件处理: 委托事件模型:事件源对象和监听器对象具有绑定关系 一个监听器可以绑定多个事件源 一个事件源也可以绑定多个监听器 监听器有各自监听的事件类型 设置容器的布局管 ...
- paip.java gui swt/jface 最佳实践
paip.java gui swt/jface 最佳实践 1. 工具:Eclipse +jigloo4 1 2. 安装插件: 1 1. IMPORT swt lib 2 2. 新建立窗体 2 3. 运 ...
- 写在学习Java GUI之前
Java GUI就是用Java语言开发桌面应用,而Java又有三个Java GUI库,分别为AWT,Swing和SWT/JFace. 现在要学的是Swing库. 后记:开发桌面应用,不止一种技术,现在 ...
- JAVA GUI 工具
Java GUI图形界面开发工具 上大学那会儿比较主流的Java图形开发插件是:Visual Editor 和 SWT Designer, 不久又出了个Jigloo, 但去官网看了下发现这个东西也 ...
- [置顶] java Gui 键盘监听事件
简单写一个java Gui键盘监听事件,实现的效果就是按下键盘控制台输出你按下的键.比如:按下A控制台就输出A 效果如图: 以下把实现的效果分为几个步骤: 1.新建一个窗体类继承窗体: 2.给这个窗体 ...
- java GUI (课堂笔记)
关于java GUI Swing组件: JFrame 窗口组件 JLabel 标签 JButton 按钮组件 JTextField 单行文本框 系统控件(JDK自带) 自定义控件(模仿系统控件): 继 ...
- java Gui编程 事件监听机制
1. GUI编程引言 以前的学习当中,我们都使用的是命令交互方式: 例如:在DOS命令行中通过javac java命令启动程序. 软件的交互的方式: 1. 命令交互方式 图书管理系统 ...
随机推荐
- c# Winform Invoke 的用法
在Winform中线程更新UI线程 例如:Form中有一个DataGridView,我们使用Thread查询后,更新这个表格,如果在Thread中直接更新会报错. Thread th = new Th ...
- cf 1142 C
忽然觉得这个题很有必要写题解. 移项 y-x^2 = bx+c 那么其实就是找有多少条直线上方没有点 所以就是一个上凸壳有多少条直线/点. 绝妙啊!!!! 太妙了啊!!!! 神乎其技卧槽!!! (我是 ...
- Flutter 文本样式继承
使用inherit来设置是否继承样式 DefaultTextStyle( style: TextStyle(color: Colors.red, fontSize: 22), child: Colum ...
- 找一个数组的最大和的连续子数组(时间复杂度 O(n))
设计思想 一开始的思想是求出全部的情况,再分别比较大小,这种方法适用于有限个数组,不适用于输入数组长度和内容的情况. 但也试着做了 int a[]= {-1,2,6,-10}; int size=4; ...
- swoole+websocket+redis实现一对一聊天
如同web端的QQ和微信一样,这是一个web端的聊天程序. 环境:ubuntu + php + swoole扩展 + redis + mysql Redis 实现每个连接websocket的服务都唯一 ...
- java实现注册的短信验证码
最近在做只能净化器的后台用户管理系统,需要使用手机号进行注册,找了许久才大致了解了手机验证码实现流程,今天在此和大家分享一下. 我们使用的是榛子云短信平台, 官网地址:http://smsow.zhe ...
- 解决Visual Studio 加载符号卡死情况
VS 加载符号 过慢或卡死的情况都可以用这种方法 打开VS的[工具]-[选项]-[调试]-[符号], 如下图所示: 1. 先取消勾选 ”Microsoft符号服务器” 2. 再点击 “清空符号缓存” ...
- 在ASP.NET Core中使用brotli压缩
Brotli是一种全新的数据格式,可以提供比Zopfli高20-26%的压缩比.据谷歌研究,Brotli压缩速度同zlib的Deflate实现大致相同,而在Canterbury语料库上的压缩密度比LZ ...
- 查询结果集转换成HTML存储过程
工作中经常需要用SQLServer发送报警或者业务报表邮件,每次现拼串也不是办法,故写了一个TableResult to HTML的存储过程 USE master; GO -- Description ...
- 【RL-TCPnet网络教程】第37章 RL-TCPnet之FTP客户端
第37章 RL-TCPnet之FTP客户端 本章节为大家讲解RL-TCPnet的FTP客户端应用,学习本章节前,务必要优先学习第35章的FTP基础知识.有了这些基础知识之后,再搞本章节会有事 ...