Java棋类游戏实践之单机版五子棋

本文实例讲述了java实现的五子棋游戏代码,分享给大家供大家参考,具体代码如下

一、实践目标
       1.掌握JavaGUI界面设计
       2.掌握鼠标事件的监听(MouseListener,MouseMotionListener)
二、实践内容
      设计一个简单的五子棋程序,能够实现五子棋下棋过程。如下图所示

1.五子棋棋盘类

package cn.edu.ouc.fiveChess; 

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RadialGradientPaint;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Ellipse2D; 

import javax.swing.*;
/**
 * 五子棋--棋盘类
 */ 

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;//当前刚下棋子的索引 

 Image img;
 Image shadows;
 Color colortemp;
 public ChessBoard(){ 

  // setBackground(Color.blue);//设置背景色为橘黄色
  img=Toolkit.getDefaultToolkit().getImage("board.jpg");
  shadows=Toolkit.getDefaultToolkit().getImage("shadows.jpg");
  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);//画棋盘 

  int imgWidth= img.getWidth(this);
  int imgHeight=img.getHeight(this);//获得图片的宽度与高度
  int FWidth=getWidth();
  int FHeight=getHeight();//获得窗口的宽度与高度
  int x=(FWidth-imgWidth)/2;
  int y=(FHeight-imgHeight)/2;
  g.drawImage(img, x, y, null); 

  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++){
   //网格交叉点x,y坐标
   int xPos=chessList[i].getX()*GRID_SPAN+MARGIN;
   int yPos=chessList[i].getY()*GRID_SPAN+MARGIN;
   g.setColor(chessList[i].getColor());//设置颜色
   // g.fillOval(xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2,
       //Point.DIAMETER, Point.DIAMETER);
   //g.drawImage(shadows, xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2, Point.DIAMETER, Point.DIAMETER, null);
   colortemp=chessList[i].getColor();
   if(colortemp==Color.black){
    RadialGradientPaint paint = new RadialGradientPaint(xPos-Point.DIAMETER/2+25, yPos-Point.DIAMETER/2+10, 20, new float[]{0f, 1f}
    , new Color[]{Color.WHITE, Color.BLACK});
    ((Graphics2D) g).setPaint(paint);
    ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT); 

   }
   else if(colortemp==Color.white){
    RadialGradientPaint paint = new RadialGradientPaint(xPos-Point.DIAMETER/2+25, yPos-Point.DIAMETER/2+10, 70, new float[]{0f, 1f}
    , new Color[]{Color.WHITE, Color.BLACK});
    ((Graphics2D) g).setPaint(paint);
    ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT); 

   } 

   Ellipse2D e = new Ellipse2D.Float(xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2, 34, 35);
   ((Graphics2D) g).fill(e);
   //标记最后一个棋子的红矩形框 

   if(i==chessCount-1){//如果是最后一个棋子
    g.setColor(Color.red);
    g.drawRect(xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2,
       34, 35);
   }
  }
 } 

 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<=COLS;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;x>=0&&y<=ROWS;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;x>=0&&y>=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;x<=COLS&&y<=ROWS;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 p:chessList){
   if(p!=null&&p.getX()==xIndex&&p.getY()==yIndex
     &&p.getColor()==color)
    return p;
  }
  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);
 } 

} 

2.棋子类

package cn.edu.ouc.fiveChess; 

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(){
  return y;
 }
 public Color getColor(){//获得棋子的颜色
  return color;
 }
} 

3.五子棋主框架类

package cn.edu.ouc.fiveChess;
import java.awt.event.*;
import java.awt.*; 

import javax.swing.*;
/*
 五子棋主框架類,程序啟動類
 */
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(); 

  Container contentPane=getContentPane();
  contentPane.add(chessBoard);
  chessBoard.setOpaque(true); 

  //创建和添加菜单
  menuBar =new JMenuBar();//初始化菜单栏
  sysMenu=new JMenu("系统");//初始化菜单
  //初始化菜单项
  startMenuItem=new JMenuItem("重新开始");
  exitMenuItem =new JMenuItem("退出");
  backMenuItem =new JMenuItem("悔棋");
  //将三个菜单项添加到菜单上
  sysMenu.add(startMenuItem);
  sysMenu.add(exitMenuItem);
  sysMenu.add(backMenuItem);
  //初始化按钮事件监听器内部类
  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("重新开始");
  exitButton=new JButton("退出");
  backButton=new JButton("悔棋");
  //将工具面板按钮用FlowLayout布局
  toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));
  //将三个按钮添加到工具面板
  toolbar.add(startButton);
  toolbar.add(exitButton);
  toolbar.add(backButton);
  //将三个按钮注册监听事件
  startButton.addActionListener(lis);
  exitButton.addActionListener(lis);
  backButton.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);//显示主框架 

 }
}

三、总结
1.菜单的设计与实现?
2.鼠标点击棋盘后,如何绘制棋子?如何为刚下的棋子绘制一个红色框?
3.棋谱是如何一个数据结构?

以上就是本文的全部内容,希望对大家学习java程序设计有所帮助。

(0)

相关推荐

  • java基于swing实现的五子棋游戏代码

    本文实例讲述了java基于swing实现的五子棋游戏代码.分享给大家供大家参考. 主要功能代码如下: 复制代码 代码如下: import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Main extends JFrame implements ActionListener{         private static final long serialVersionUID = 1L;      

  • java实现五子棋小游戏

    java实现五子棋小游戏 package Gomoku; import java.awt.Toolkit; import javax.swing.JFrame; public class GomokuFrame extends JFrame { //定义一个操作面板 OperatorPane op=null; public GomokuFrame() { //设置名称 this.setTitle("五子棋"); //设置窗口大小 this.setSize(510,510); //设置窗

  • Java棋类游戏实践之中国象棋

    本文实例讲述了java实现的中国象棋游戏代码,分享给大家供大家参考,具体代码如下 一.实践目的: 1.鼠标点击.拖动等事件的应用与区别 2.棋谱文件的保存与读取 3.完善象棋的规则. 二.实践内容: 中国象棋历史悠久,吸引了无数的人研究,现对中国象棋的对战和实现棋谱的制作做如下的设计和说明,供大家参考学习. 1.机机对弈,红方先手.在符合规则的情况下拖动棋子到目的地,松鼠标落子. 人人对弈图 2.制作棋谱,选择制作棋谱菜单后,对弈开始,并记录了下棋过程. 选择"制作棋谱"菜单 棋谱制作

  • Java swing五子棋的实现方法

    今天给大家介绍一下如何用Java swing实现五子棋的开发即用Java开发图形界面程序五子棋,代码由于太多,只贴部分,最下面会附上下载地址,废话不多说,下面我们先看一下运行结果: 接下来我们看代码: 首先是创建主frame框架界面: package org.liky.game.frame; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Toolkit; import

  • java实现单人版五子棋游戏

    本文实例讲述了java实现的五子棋游戏代码,分享给大家供大家参考,具体代码如下 package gyb.exam; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Point; import java.awt.Toolkit; import java.awt.

  • Java棋类游戏实践之单机版五子棋

    本文实例讲述了java实现的五子棋游戏代码,分享给大家供大家参考,具体代码如下 一.实践目标        1.掌握JavaGUI界面设计        2.掌握鼠标事件的监听(MouseListener,MouseMotionListener) 二.实践内容       设计一个简单的五子棋程序,能够实现五子棋下棋过程.如下图所示 1.五子棋棋盘类 package cn.edu.ouc.fiveChess; import java.awt.Color; import java.awt.Curs

  • java实现单机版五子棋小游戏

    简单的java小游戏–单机版五子棋 学了java有一段时间了,今天就来搞一个简单的单机版五子棋游戏. 实现功能:那必须能进行基础的输赢判断.还有重新开始的功能,悔棋的功能,先手设置的功能和退出的功能.在右上角能够显示目前轮到哪个棋种下棋.右下角还有一个记录信息框,记录行为,当信息量过多时,可以清除信息内容. 成果: 初始界面: 游戏(获胜)界面: 附上代码: Chessframe.java package firstgobang; import javax.swing.JFrame; impor

  • Java实现单机版五子棋游戏的示例代码

    目录 前言 主要需求 主要设计 功能截图 代码实现 总结 前言 五子棋是世界智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏,是世界智力运动会竞技项目之一,通常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成5子连线者获胜. 棋具与围棋通用,起源于中国上古时代的传统黑白棋种之一.主要流行于华人和汉字文化圈的国家以及欧美一些地区,是世界上最古老的棋. 容易上手,老少皆宜,而且趣味横生,引人入胜:不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性. 用java语言实现

  • java实现单机版五子棋

    这个小游戏是我和我姐们儿的JAVA课程设计,也是我做的第一个JAVA项目,适合初学者,希望能帮到那些被JAVA课设所困扰的孩纸们~~~ 一.该游戏需要实现 1.设计主框架,界面. 2.利用ActionListener接口实现按钮事件的监听. 3.重新开始功能的实现. 4.悔棋功能的实现. 5.退出功能的实现. 6.棋盘中棋子点类的定义. 7.利用MouseListener接口实现事件监听,并实现接口里的所有方法. 8.当鼠标移动到棋盘上的交点上,且该点上无棋子时能够变成小手形状. 9.点击棋盘时

  • Java基于享元模式实现五子棋游戏功能实例详解

    本文实例讲述了Java基于享元模式实现五子棋游戏功能.分享给大家供大家参考,具体如下: 一.模式定义 享元模式,以共享的方式高效地支持大量的细粒度对象.通过复用内存中已存在的对象,降低系统创建对象实例的性能消耗.享元的英文是Flyweight,表示特别小的对象,即细粒度对象. 二.模式举例 1. 模式分析 我们借用五子棋游戏来说明这一模式. 2. 享元模式静态类图 3. 代码示例 3.1 创建抽象棋子一AbstractChessman package com.demo.flyweight.obj

  • 10个微妙的Java编码最佳实践

    这是一个比Josh Bloch的Effective Java规则更精妙的10条Java编码实践的列表.和Josh Bloch的列表容易学习并且关注日常情况相比,这个列表将包含涉及API/SPI设计中不常见的情况,可能有很大影响. 我在编写和维护jOOQ(Java中内部DSL建模的SQL)时遇到过这些.作为一个内部DSL,jOOQ最大限度的挑战了Java的编译器和泛型,把泛型,可变参数和重载结合在一起,Josh Bloch可能不会推荐的这种太宽泛的API. 让我与你分享10个微妙的Java编码最佳

  • java数独游戏完整版分享

    本文实例为大家分享了java数独游戏的具体代码,供大家参考,具体内容如下 自己写的数独游戏,共9关,代码如下: 1.DoShudu类用于产生数独数组 import java.util.Random; public class DoShudu { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int[][] cells=newshudu(); //ce

  • 简单实现java数独游戏

    本文实例为大家分享了java数独游戏的具体代码,供大家参考,具体内容如下 打算把javaFx需要的组件装好以后直接用javaFx的,但似乎eclipse的版本不对,安装了也不能用... 数独代码是在之前寒假受命写的,学了一个月java的成果,现在看来有些不足但毕竟是第一个程序,就直接放上来,数独终盘的实现直接用了暴力,时间复杂度有点高,懒得改了直接放代码 终盘实现: import java.util.Random; public class SudokuPuzzleGenerator { pri

  • 详解Java异常处理最佳实践及陷阱防范

    前言 不管在我们的工作还是生活中,总会出现各种"错误",各种突发的"异常".无论我们做了多少准备,多少测试,这些异常总会在某个时间点出现,如果处理不当或是不及时,往往还会导致其他新的问题出现.所以我们要时刻注意这些陷阱以及需要一套"最佳实践"来建立起一个完善的异常处理机制. 异常分类 首先,这里我画了一个异常分类的结构图. 在JDK中,Throwable是所有异常的父类,其下分为"Error"和"Exception&

随机推荐