小小五子棋小游戏
小小五子棋游戏
1.项目简介
功能描述:使用几十个字简单描述系统所完成的功能(每个同学自己总结,不能相同)。有无参考他人代码。
本项目完成了一个简单的五子棋单机小游戏,棋盘采用15横线*15竖线,组成交叉的每个点都可以放置棋子,进行五子棋黑白两方的对抗游戏。该游戏的规则黑棋先行,黑方行棋结束由白棋开始,若有一方存在五颗棋子连成横竖或斜线则该方获胜,另一方失败,游戏结束。在本系统中还增加了悔棋功能(撤销上一步棋子)和重新开始新一局游戏的功能。在本次课程设计中,我在博客园,csdn等软件中进行了搜索,对一些博客中的代码进行了一定的借鉴。
2.功能架构图
3.个人任务简述
1. 完成的任务与功能:
序号 | 完成功能与任务 | 描述 |
---|---|---|
1 | 界面设计 | 使用GUI技术实现了对整个五子棋小游戏的界面呈现。 |
2 | 棋盘棋子设计 | 棋子摆放,打印和棋盘的设计的页面管理 |
3 | 自动判定赢棋 | 当棋子连成五个时自动判定赢棋 |
4 | 棋子摆放 | 可按照各个方位判断棋子的连成情况 |
2.Git提交记录截图
4.本人负责功能详解
在本次课程设计中,我本身想选择学生管理系统,运用学习数据库和javaweb的相关知识,但是在实际操作中耗时长,对我而言难点多,故而半途放弃。后选择五子棋小游戏,因时间不够以及技术问题而放弃了联网作战功能和界面的进一步优化等。
1.面向对象设计
2.Chess
对棋子的颜色坐标大小和所在棋盘进行设计。
代码:
package impl;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RadialGradientPaint;
import java.awt.RenderingHints;
public class Chess {
Chessboard cp; //棋盘
int row; //横坐标
int col; //纵坐标
Color color; //棋子颜色
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public static final int RADIUS = 18;
public Chess(Chessboard cp, int col, int row, Color color) {
this.cp = cp;
this.col = col;
this.row = row;
this.color = color;
}
//画棋子
public void draw(Graphics g) {
int xPos = col * 20 + 15;//定义棋子圆心
int yPos = row * 20 + 15;
Graphics2D g2d = (Graphics2D) g;
RadialGradientPaint paint = null;
Color[] c = { Color.WHITE, Color.BLACK };
float[] f = { 0f, 1f };
int x = xPos + 3;
int y = yPos - 3;
if (color == Color.WHITE) {
paint = new RadialGradientPaint(x, y, RADIUS * 3, f, c);
}
else {
paint = new RadialGradientPaint(x, y, RADIUS, f, c);
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(paint);
g2d.fillOval(xPos - RADIUS / 2, yPos - RADIUS / 2, RADIUS, RADIUS);
}
}
3.Chess
实现了对棋盘的属性如长度,宽度,格子大小,棋盘颜色等进行设计,完成了开始游戏,重新开始,悔棋,判断谁胜谁负等功能。
代码:
package impl;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class Chessboard extends JPanel {
public static final int MARGIN = 15;//边缘值
public static final int SPAN = 20;//跨度
public static final int ROWS = 19;
public static final int COLS = 19;
Chess[] chessList = new Chess[19 * 19];
int chessCount = 0;
boolean isWhite = false;
boolean isBlack = true;
String message = "黑棋先下";
public Chessboard() {
this.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
if (isWhite) {
return;
}
int col, row;
col = (e.getX() - 15 + 10) / 20;
row = (e.getY() - 15 + 10) / 20;
if (col > 19 || col < 0 || row > 19 || row < 0) {//超过棋盘大小
return;
}
else {
if (haschess(col, row)) {
return;
}
else {
Color c = Color.BLACK;//设置棋子颜色
if (isBlack) {
c = Color.BLACK;
message = "轮到白棋";
}
else {
c = Color.WHITE;
message = "轮到黑棋";
}
Chess cc = new Chess(Chessboard.this, col, row, c);
chessList[chessCount++] = cc;
repaint();
if (isWin(col, row)) {
if (c == Color.BLACK) {
JOptionPane.showMessageDialog(Chessboard.this, "黑棋获胜!");
}
else if (c == Color.WHITE) {
JOptionPane.showMessageDialog(Chessboard.this, "白旗获胜!");
}
isWhite = true;
return;
}
isBlack = !isBlack;
}
}
}
});
}
@Override
public void paint(Graphics e) {
e.setColor(Color.PINK);
e.fillRect(0, 0, 410, 460);
e.setColor(Color.black);
for (int i = 0; i < 20; i++) {
e.drawLine(MARGIN, MARGIN + SPAN * i, MARGIN + 19 * 20, MARGIN + 20 * i);
}
for (int i = 0; i < 20; i++) {
e.drawLine(15 + SPAN * i, 15, 15 + SPAN * i, 15 + 19 * 20);
}
e.fillRect(15 + 3 * 20 - 2, 15 + 3 * 20 - 2, 5, 5);
e.fillRect(15 + 9 * 20 - 2, 15 + 3 * 20 - 2, 5, 5);
e.fillRect(15 + 15 * 20 - 2, 15 + 3 * 20 - 2, 5, 5);
e.fillRect(15 + 3 * 20 - 2, 15 + 9 * 20 - 2, 5, 5);
e.fillRect(15 + 9 * 20 - 2, 15 + 9 * 20 - 2, 5, 5);
e.fillRect(15 + 15 * 20 - 2, 15 + 9 * 20 - 2, 5, 5);
e.fillRect(15 + 3 * 20 - 2, 15 + 15 * 20 - 2, 5, 5);
e.fillRect(15 + 9 * 20 - 2, 15 + 15 * 20 - 2, 5, 5);
e.fillRect(15 + 15 * 20 - 2, 15 + 15 * 20 - 2, 5, 5);
Graphics2D e2 = (Graphics2D) e;
e2.setStroke(new BasicStroke(3f));
e2.drawLine(10, 10, 10, 400);
e2.drawLine(10, 10, 400, 10);
e2.drawLine(400, 10, 400, 400);
e2.drawLine(10, 400, 400, 400);
for (int i = 0; i < chessCount; i++) {
chessList[i].draw(e);
}
e.setFont(new Font("黑体", Font.BOLD, 15));
e.drawString("游戏提示:" + message, 20, 420);
}
private boolean haschess(int col, int row) {
boolean result = false;
for (int i = 0; i < chessCount; i++) {
Chess cc = chessList[i];
if (cc != null && cc.getCol() == col && cc.getRow() == row) {
return true;
}
}
return result;
}
private boolean haschess(int col, int row, Color c) {
Boolean result = false;
for (int i = 0; i < chessCount; i++) {
Chess ch = chessList[i];
if (ch != null && ch.getCol() == col && ch.getRow() == row && ch.getColor() == c) {
result = true;
}
}
return result;
}
private boolean isWin(int col, int row) {
boolean result = false;
int CountCh = 1;
Color c = null;
if (isBlack) {
c = Color.BLACK;
}
else {
c = Color.WHITE;
}
// 水平向左
for (int x = col - 1; x >= 0; x--) {
if (haschess(x, row, c)) {
CountCh++;
}
else
break;
}
// 水平向右
for (int x = col + 1; x <= 19; x++) {
if (haschess(x, row, c)) {
CountCh++;
}
else
break;
}
// 水平取胜
if (CountCh >= 5) {
result = true;
message = "游戏结束";
}
else {
result = false;
CountCh = 1;
}
// 竖直向上
for (int y = row - 1; y >= 0; y--) {
if (haschess(col, y, c)) {
CountCh++;
}
else {
break;
}
}
// 竖直向下
for (int y = row + 1; y <= 19; y++) {
if (haschess(col, y, c)) {
CountCh++;
}
else {
break;
}
}
// 竖直取胜
if (CountCh >= 5) {
result = true;
message = "游戏结束";
}
else {
result = false;
CountCh = 1;
}
// 斜向右上
for (int x = col + 1, y = row - 1; x <= 19 && y >= 0; x++, y--) {
if (haschess(x, y, c)) {
CountCh++;
}
else {
break;
}
}
// 斜向左下
for (int x = col - 1, y = row + 1; x >= 0 && y <= 19; x--, y++) {
if (haschess(x, y, c)) {
CountCh++;
}
else {
break;
}
}
// 斜向取胜
if (CountCh >= 5) {
result = true;
message = "游戏结束";
}
else {
result = false;
CountCh = 1;
}
// 斜向左上
for (int x = col - 1, y = row - 1; x >= 0 && y >= 0; x--, y--) {
if (haschess(x, y, c)) {
CountCh++;
}
else {
break;
}
}
// 斜向右下
for (int x = col + 1, y = row + 1; x <= 19 && y <= 19; x--, y--) {
if (haschess(x, y, c)) {
CountCh++;
}
else {
break;
}
}
// 斜向取胜
if (CountCh >= 5) {
result = true;
message = "游戏结束";
}
else {
result = false;
CountCh = 1;
}
return result;
}
public void againGame() {
for (int i = 0; i < chessList.length; i++) {
chessList[i] = null;
}
chessCount = 0;
isWhite = false;
message = "开局黑棋先手";
repaint();
}
public void regret() {
if (isWhite) {
return;
}
chessList[chessCount - 1] = null;
chessCount--;
if (isBlack) {
message = "白棋悔棋";
}
else {
message = "黑棋悔棋";
}
isBlack = !isBlack;
repaint();
}
}
4.GameMain
对游戏主界面进行设计,监听各个事件
代码:
package impl;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class GameMain extends JFrame {
Chessboard borad;
public GameMain() {
borad = new Chessboard();
// 创建菜单栏
JMenuBar menubar = new JMenuBar();
JMenu menu = new JMenu("小小五子棋");//创建菜单
JMenuItem item1 = new JMenuItem("新游戏");//创建菜单项
JMenuItem item2 = new JMenuItem("退出");
menu.add(item1);
menu.addSeparator();//在菜单中添加分隔符
menu.add(item2);
menubar.add(menu);
// 按钮
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(10, 1));
Button button1 = new Button("重新开始");
Button button2 = new Button("悔棋");
panel.add(button1);
panel.add(button2);
// 窗口设置
BorderLayout bl = new BorderLayout();
this.setTitle("五子棋小游戏");
this.setSize(480, 490);
this.setLocationRelativeTo(null);//设置窗口相对于指定组件的位置(为null,所以在正中央)
this.setVisible(true);
this.setResizable(false);
this.add(menubar, bl.NORTH);
this.add(borad, bl.CENTER);
this.add(panel, bl.EAST);
// 按钮事件
button1.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
borad.againGame();
}
});
//悔棋
button2.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
borad.regret();
}
});
// 新游戏
item1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
borad.againGame();
}
});
// 退出
item2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.exit(0);
}
});
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new GameMain();
}
}
5.最终实现
主界面
结束界面:
黑棋获胜:
白棋获胜:
悔棋:
6.课程设计感想
在课程设计的过程中我实在是遇到了很多困难,在最初想要选择学生管理系统是因为整个项目之前已经进行了很久,但是看到课程设计的相关要求时发现该项目的难度达不到需要的要求,于是在后面的时间里进行了一些数据库和javaweb的学习,由于操作的不熟练,数据库与教程视频的版本不同等问题,我最终选择放弃该选题,选择了五子棋小游戏。同样面临的也是界面设计,棋子的摆放和检验是否相连等问题。通过这次课程设计我明白了技术才是硬道理,只有掌握了过硬的技术,孜孜不倦的学习,才能更上一层,同时学会与朋友相互合作也是十分重要的。
7.展望
本次课程设计实现的五子棋项目其实还有很多不足,比如可以实现联网功能进行两人作战,可以添加检测功能,得到摆放棋子的最优解,从而提供一个参考,以及可以增加聊天对话框,方便联网用户之间的联系,也可以在最开始建立一个用户登陆系统,甚至可以出售不同样式的棋子棋盘实现利润收益等。当然,这些想法都需要我的进一步学习努力才有可能完成其中一些皮毛。