第一个项目:五子棋


 1,自定义容器:MyContainer

       在这个项目中,我并没有使用JDK自带的ArrayList容器,而是自己定义了一个容器,个人认为这样有助于加深对代码的理解与认知。

       MyContainer容器包含以下功能:在末尾添加棋子,删除末尾棋子,删除所有棋子,得到指定下标的棋子,获取容器大小。

      package 五子棋完整版; 
/*
 * 
 * 自定义容器 
 * 
 */
public class MyContainer {
//建立一个数组保存棋子
Chess [] srcArray = new Chess[0];


//在末尾添加棋子的方法
public void add(Chess e)
{
//创建新数组 长度比srcarray大1
Chess []newArray = new Chess[srcArray.length+1];
//将srcArray数组中的元素拷贝到newArray数组中
for(int i=0;i<srcArray.length;i++)
{
newArray[i]=srcArray[i];
}
newArray[srcArray.length]=e;
//数组交换
srcArray=newArray;
}

//删除末尾棋子
public void delete()
{

Chess[] newArray = new Chess[srcArray.length-1];//创建一个新数组,长度比srcArray小1
for(int i=0;i<srcArray.length-1;i++)
{
newArray[i]=srcArray[i];
}
srcArray = newArray;

}


//获取指定下标的棋子
public Chess get(int index)
{
return srcArray[index];
}

//获取容器大小的方法
public int getLength()
{
return srcArray.length;
}



//删除所有元素
public void clear_all()
{
Chess []newArray = new Chess[0];
srcArray = newArray;
}
}

2,封装棋子类:Chess

     由于每个棋子都具有某些共同的特征:棋子的颜色,坐标等;为了优化代码,使之更为简洁,我对棋子进行类的封装,并在类中声明了draw方法(画棋子)。

以下是代码部分:

   package 五子棋完整版;


import java.awt.Color;
import java.awt.Graphics;


/*
 * 棋子类 封装坐标 颜色 画棋子的方法
 */
public class Chess {
int x1,y1;//坐标
Color color;//颜色
public Chess(int x1,int y1,Color color)//构造方法
{
this.x1 = x1;
this.y1 = y1;
this.color = color;
}

public void draw(Graphics g)//画棋子
{
g.setColor(color);
g.fillOval(x1-15, y1-15, 30, 30);
}
}

   

3,面板的使用:

      在刚开始写五子棋的时候,我并没有使用面板,由此导致出现了界面显示效果的问题:按钮无法显示,或者不能自动完全显示出来,界面也不够美观等等;在之后意识到这个问题,便加入了面板,紧接着又出现了一系列的问题,棋盘线条完全对不上,棋子也下不对地方,经过很久的琢磨以及请教老师,最终还是把问题解决了。现在发现,原来是坐标的设置不正确。

// 创建2个面板对象
// 棋盘面板
JPanel board_panel = new JPanel() {
public void paint(Graphics g) {
super.paint(g);// 画窗体本身


// 创建一个图片对象
ImageIcon image = new ImageIcon("image/1-120912095107.jpg");// 插入一张图片
// 把图片画到面板上
g.drawImage(image.getImage(), 0, 0, null);
// 设置线条粗细
Graphics2D g2 = (Graphics2D)g;
BasicStroke bs = new BasicStroke(2);
g2.setStroke(bs);
// 画直线
for (int i = 0; i < 11; i++) {
g2.drawLine(20, 20 + i * 50, 520, 20 + i * 50);
}
for (int i = 0; i < 11; i++) {
g2.drawLine(20 + i * 50, 20, 20 + i * 50, 520);
}
// 取出容器中所有的点,重新绘制
for (int i = 0; i < mc.getLength(); i++) {
mc.get(i).draw(g);
}
}
};
JPanel function_panel = new JPanel(){
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
ImageIcon fun_image = new ImageIcon("image/tu5396_6.jpg");
       g.drawImage(fun_image.getImage(),0,0,null);
}
};
// 设置面板的背景颜色
board_panel.setBackground(Color.green);
function_panel.setBackground(Color.yellow);
function_panel.setLayout(new FlowLayout(1, 10, 40));
board_panel.setPreferredSize(new Dimension(550, 600));
function_panel.setPreferredSize(new Dimension(120, 600));
// 将面板添加到界面上
this.add(board_panel);
this.add(function_panel);

以下是主要代码部分:

package 五子棋完整版;


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;


import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;


public class FiveChess extends JFrame {
// 画笔
Graphics g = null;
// 变量 控制黑白交替
int flag_color = 1;// 如果是1下黑棋 -1下白棋
// 变量 控制开始下棋
boolean flag_begin = false;
// 创建一个二维数组,保存棋子信息
int[][] chesses = new int[15][15];
// 颜色变量
Color color;
// 创建一个容器对象,保存棋子对象
MyContainer mc = new MyContainer();
// 遍历二维数组
public void printArray() {
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
System.out.print(chesses[i][j] + " ");
}
System.out.println();// 换行
}
}
// 显示游戏界面
public void showUI() {
// 设置界面属性
this.setTitle("五子棋游戏");
this.setSize(700, 600);
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
this.setLayout(new FlowLayout());
// 创建2个面板对象
// 棋盘面板
JPanel board_panel = new JPanel() {
public void paint(Graphics g) {
super.paint(g);// 画窗体本身


// 创建一个图片对象
ImageIcon image = new ImageIcon("image/1-120912095107.jpg");// 插入一张图片
// 把图片画到面板上
g.drawImage(image.getImage(), 0, 0, null);
// 设置线条粗细
Graphics2D g2 = (Graphics2D)g;
BasicStroke bs = new BasicStroke(2);
g2.setStroke(bs);
// 画直线
for (int i = 0; i < 11; i++) {
g2.drawLine(20, 20 + i * 50, 520, 20 + i * 50);
}
for (int i = 0; i < 11; i++) {
g2.drawLine(20 + i * 50, 20, 20 + i * 50, 520);
}
// 取出容器中所有的点,重新绘制
for (int i = 0; i < mc.getLength(); i++) {
mc.get(i).draw(g);
}
}
};
JPanel function_panel = new JPanel(){
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
ImageIcon fun_image = new ImageIcon("image/tu5396_6.jpg");
       g.drawImage(fun_image.getImage(),0,0,null);
}
};
// 设置面板的背景颜色
board_panel.setBackground(Color.green);
function_panel.setBackground(Color.yellow);
function_panel.setLayout(new FlowLayout(1, 10, 40));
board_panel.setPreferredSize(new Dimension(550, 600));
function_panel.setPreferredSize(new Dimension(120, 600));
// 将面板添加到界面上
this.add(board_panel);
this.add(function_panel);
// 创建功能按钮
JButton begin = new JButton();
begin.setText("开始");
begin.setBounds(570, 50, 100, 50);
JButton replay = new JButton("重玩");
replay.setBounds(570, 120, 100, 50);
JButton renren = new JButton();
renren.setText("人人");
renren.setBounds(570, 190, 100, 50);
JButton renji = new JButton();
renji.setText("人机");
renji.setBounds(570, 260, 100, 50);
JButton regret = new JButton();
regret.setText("悔棋");
regret.setBounds(570, 330, 100, 50);
JButton about = new JButton();
about.setText("关于");
about.setBounds(570, 400, 100, 50);
//ImageIcon icon = new ImageIcon("image/m_1259220222826.jpg");
//begin.setIcon(icon);
function_panel.add(begin);// 将功能按钮添加到界面上
function_panel.add(replay);
function_panel.add(renren);
function_panel.add(renji);
function_panel.add(regret);
function_panel.add(about);
// 创建监听器对象
ActionListener begin_listener = new ActionListener() {
// 监控方法
public void actionPerformed(ActionEvent e) {
flag_begin = true;// 改变标识
}
};
// 监控开始按钮
begin.addActionListener(begin_listener);
// 重新开始
ActionListener replay_listener = new ActionListener() {
// 监控方法
public void actionPerformed(ActionEvent e) {
mc.clear_all();
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
chesses[i][j] = 0;
}
}
flag_color = 1;
flag_begin = true;
board_panel.repaint();
}
};
// 监控重玩按钮
replay.addActionListener(replay_listener);
ActionListener regret_listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
Chess chess = (Chess) mc.get(mc.getLength() - 1);
// 实现悔棋功能
mc.delete();
// 刷新棋盘 重新绘制
board_panel.repaint();
// 将二位数组中对应位置的元素改成0
chesses[(chess.y1 - 20) / 50][(chess.x1 - 20) / 50] = 0;
if (flag_color == 1) {
flag_color = -1;
} else if (flag_color == -1) {
flag_color = 1;
}
}
};
// 给悔棋按钮装上监听器
regret.addActionListener(regret_listener);
// 可见
this.setVisible(true);
// 获取棋盘面板的画布对象
g = board_panel.getGraphics();// 此处需注意
// 创建鼠标监听器对象
MouseListener mouse_listener = new MouseListener() {
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
// 获取鼠标释放时的坐标
int x = e.getX();
int y = e.getY();
// 用户选择了开始
if (flag_begin) {
// 让棋子出现在交叉点(离x,y最近的交叉点)
// 通过两个for循环 来迭代出所有的交叉点坐标
for (int i = 0; i < 11; i++) {
// 外循环执行一次,找出的是第一列上的所有交叉点
for (int j = 0; j < 11; j++) {
// 内循环执行一次,找出的是第一列上的一个交叉点
int x0 = 20 + 50 * j;
int y0 = 20 + 50 * i;
// 判断当前鼠标坐标与所有交叉点坐标的误差值
if (x > x0 - 50 / 3 && x < x0 + 50 / 3 && y > y0 - 50 / 3 && y < y0 + 50 / 3) {
// 判断是否有棋子
if (chesses[i][j] == 0) {
// 判断下棋的颜色
if (flag_color == 1)// 黑棋
{
chesses[i][j] = 1;
color = Color.black;
flag_color = -1;
} else if (flag_color == -1)// 白棋
{
chesses[i][j] = 2;
color = Color.white;
flag_color = 1;
}
// 创建棋子对象
Chess chess = new Chess(x0, y0, color);
// 将棋子保存到容器中
mc.add(chess);
// 画棋子
chess.draw(g);
renji(i, j);
// 判断输赢
win(i, j);
printArray();
System.out.println();// 换行
}
}
}
}
} else {
// 提示用户
JOptionPane.showMessageDialog(null, "亲,请点击开始按钮!");
}
}
};
// 给面板添加鼠标监听器
board_panel.addMouseListener(mouse_listener); // 此处需注意
}
// 在最有利的位置下棋
public void renji(int hang, int lie) {


}
// 判断输赢
public void win(int hang, int lie) {
// 计数器
int count = 1;// 统计相同棋子的个数
int m = 1;// 控制列值的改变
int n = 1;// 控制行值的改变
// 水平向左
while (lie - m >= 0 && chesses[hang][lie] == chesses[hang][lie - m]) {
m++;
count++;
}
m = 1;
// 水平向右
while (lie + m < 11 && chesses[hang][lie] == chesses[hang][lie + m]) {
m++;
count++;
}
m = 1;
if (chesses[hang][lie] == 1 && count >= 5)// 黑棋胜利
{
// 提示用户
JOptionPane.showMessageDialog(null, "黑棋胜利");
}
if (chesses[hang][lie] == 2 && count >= 5) {
// 提示用户
JOptionPane.showMessageDialog(null, "白棋胜利");
}
count = 1;
// 垂直向上
while (hang - n >= 0 && chesses[hang][lie] == chesses[hang - n][lie]) {
n++;
count++;
}
n = 1;
while (hang + n < 11 && chesses[hang][lie] == chesses[hang + n][lie]) {
n++;
count++;
}
n = 1;
if (chesses[hang][lie] == 1 && count >= 5)// 黑棋胜利
{
// 提示用户
JOptionPane.showMessageDialog(null, "黑棋胜利");
}
if (chesses[hang][lie] == 2 && count >= 5) {
// 提示用户
JOptionPane.showMessageDialog(null, "白棋胜利");
}
count = 1;
// 左斜上
while (hang - n >= 0 && lie - m >= 0 && chesses[hang][lie] == chesses[hang - n][lie - m]) {
m++;
n++;
count++;
}
m = 1;
n = 1;
// 右斜下
while (hang + n < 11 && lie + m < 11 && chesses[hang][lie] == chesses[hang + n][lie + m]) {
m++;
n++;
count++;
}
m = 1;
n = 1;
if (chesses[hang][lie] == 1 && count >= 5)// 黑棋胜利
{
// 提示用户
JOptionPane.showMessageDialog(null, "黑棋胜利");
}
if (chesses[hang][lie] == 2 && count >= 5) {
// 提示用户
JOptionPane.showMessageDialog(null, "白棋胜利");
}
count = 1;
// 左斜下
while (hang + n < 11 && lie - m >= 0 && chesses[hang][lie] == chesses[hang + n][lie - m]) {
n++;
m++;
count++;
}
m = 1;
n = 1;
// 右斜上
while (hang - n >= 0 && lie + m < 11 && chesses[hang][lie] == chesses[hang - n][lie + m]) {
m++;
n++;
count++;
}
if (chesses[hang][lie] == 1 && count >= 5)// 黑棋胜利
{
// 提示用户
JOptionPane.showMessageDialog(null, "黑棋胜利");
}
if (chesses[hang][lie] == 2 && count >= 5) {
// 提示用户
JOptionPane.showMessageDialog(null, "白棋胜利");
}
count = 1;
}
// 主函数,固定写法
public static void main(String[] args) {
// 创建本类对象
FiveChess fc = new FiveChess();
// 执行方法
fc.showUI();
}
}


  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值