【java】单机版五子棋
程序员文章站
2022-05-25 13:52:56
...
import java.awt.Container;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
//单机版五子棋主框架类
public class MyChess extends JFrame implements ActionListener{
private ChessBoard CB = null;
JPanel jp1 = null;
JMenuBar jmb1 = null;
JButton jb1 = null;
JButton jb2 = null;
JButton jb3 = null;
JButton jb4 = null;
JMenu jm1 = null;
public MyChess(){
CB = new ChessBoard();
Container contentPane=getContentPane();
contentPane.add(CB);
CB.setOpaque(true); //设置控件不透明
jm1 = new JMenu();
jmb1 = new JMenuBar();
Font font=new Font("方正舒体",Font.BOLD,22);//设置按钮所需字体
//定义三个按钮
jb1 = new JButton("开始");
jb1.setFont(font);
jb2 = new JButton("退出");
jb2.setFont(font);
jb3 = new JButton("悔棋");
jb3.setFont(font);
jb4 = new JButton("关于");
jb4.setFont(font);
jp1 = new JPanel();
this.setTitle("单机版五子棋");//设置标题
this.setSize(660, 730);//设置窗体大小
this.setLocationRelativeTo(null);//使窗体显示在屏幕的正中间
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setJMenuBar(jmb1);
jmb1.add(jb1);
jmb1.add(jb2);
jmb1.add(jb3);
jmb1.add(jb4);
//注册监听
jb1.addActionListener(this);
jb1.setActionCommand("开始");
jb2.addActionListener(this);
jb2.setActionCommand("退出");
jb3.addActionListener(this);
jb3.setActionCommand("悔棋");
jb4.addActionListener(this);
jb4.setActionCommand("关于");
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("开始")){
CB.startGame();
}else if(e.getActionCommand().equals("退出")){
if(JOptionPane.showConfirmDialog(null, "确定退出吗?") == JOptionPane.YES_OPTION){
System.exit(0);
}
}else if(e.getActionCommand().equals("悔棋")){
CB.goback();
}else if(e.getActionCommand().equals("关于")){
JOptionPane.showMessageDialog(null, "这是一个用java编写的小游戏\n作者:筱筱\n日期:20170617\n请尊重版权,谢谢!");
}
}
public static void main(String[] args){
MyChess mychess = new MyChess();//创建主框架
mychess.setVisible(true);//显示主框架
}
}
package Mychess02;
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.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 java.util.HashSet;
import java.util.Vector;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import com.sun.prism.j2d.paint.RadialGradientPaint;
import fiveChess01.Point;
//单机版五子棋棋盘类
public class ChessBoard extends JPanel implements MouseListener{
private int margin = 20;//页边距
private int space = 30;//网格间距
private int row = 20;//行数
private int column = 20;//列数
ChessPiece[] chessList = new ChessPiece[(row+1)*(column+1)];//初始每个数组元素为null
boolean isBlack = true;//默认开始是黑棋先
boolean isgameover = false;//游戏是否结束
int chessCount;//当前棋盘棋子的个数
int xIndex,yIndex;//当前刚下棋子的索引
Vector v_info = null;//所有每步走棋的信息
private Color colortemp;
public ChessBoard(){
v_info = new Vector();
addMouseListener(this);
addMouseMotionListener(new MouseMotionListener(){
public void mouseDragged(MouseEvent arg0) {
}
public void mouseMoved(MouseEvent e) {
//将鼠标点击的坐标位置转换成网格索引
int x1 = (e.getX()-margin+space/2)/space;
int y1 = (e.getY()-margin+space/2)/space;
if(x1<0||x1>row||y1<0||y1>column||isgameover||findChess(x1,y1)){
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}else {
setCursor(new Cursor(Cursor.HAND_CURSOR));//鼠标改成手的形状
}
}
});
}
public void paint(Graphics g){
super.paint(g);//画棋盘
g.setColor(Color.black);
//画横线
for(int i=0; i<row+1; i++){
g.drawLine(margin, margin+i*space, margin+space*column, margin+i*space);
}
//画竖线
for(int i=0; i<column+1; i++){
g.drawLine(margin+i*space, margin, margin+i*space, margin+space*row);
}
//画棋子
for(int i=0;i<chessCount;i++){
//网格交叉点x、y坐标
int cross_X = chessList[i].getX()*space+margin;
int cross_Y = chessList[i].getY()*space+margin;
g.setColor(chessList[i].getColor());
colortemp = chessList[i].getColor();
if(colortemp==Color.BLACK){
RadialGradientPaint paint = new RadialGradientPaint(cross_X-ChessPiece.diameter/2+25, cross_Y-ChessPiece.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(cross_X-ChessPiece.diameter/2+25, cross_Y-ChessPiece.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 类描述窗体矩形定义的椭圆。 此类是所有存储 2D 椭圆的对象的惟一抽象超类。坐标的实际存储表示形式由子类决定。
Ellipse2D e = new Ellipse2D.Float(cross_X-ChessPiece.diameter/2, cross_Y-ChessPiece.diameter/2, 29, 30);
((Graphics2D) g).fill(e);
//标记最后一个棋子的红矩形框
if(i==chessCount-1){//如果是最后一个棋子
g.setColor(Color.red);
g.drawRect(cross_X-ChessPiece.diameter/2, cross_Y-ChessPiece.diameter/2, 29, 30);
}
}
}
public void mousePressed(MouseEvent e) {
//游戏结束时,不再能下
if(isgameover) return;
String colorName=isBlack?"黑棋":"白棋";
//将鼠标点击的坐标位置转换成网格索引
xIndex=(e.getX()-margin+space/2)/space;
yIndex=(e.getY()-margin+space/2)/space;
//落在棋盘外不能下
if(xIndex<0||xIndex>row||yIndex<0||yIndex>column) return;
//如果x,y位置已经有棋子存在,不能下
if(findChess(xIndex,yIndex))return;
//可以进行时的处理
ChessPiece ch=new ChessPiece(xIndex,yIndex,isBlack?Color.black:Color.white);
chessList[chessCount++]=ch;
if(chessCount%2==0){
v_info.add(xIndex+"-"+yIndex+Color.white);
}else{
v_info.add(xIndex+"-"+yIndex+Color.black);
}
repaint();//通知系统重新绘制
//如果胜出则给出提示信息,不能继续下棋
if(isWin()){
String msg=String.format("恭喜,%s赢了!", colorName);
JOptionPane.showMessageDialog(this, msg);
isgameover=true;
}
isBlack=!isBlack;
}
private boolean isWin() {
int continueCount = 0;
//判断横向的棋子数量
for(int i=0;i<5;i++){
if(v_info.contains((xIndex+i)+"-"+yIndex+Color.white)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
for(int i=0;i<5;i++){
if(v_info.contains((xIndex-i)+"-"+yIndex+Color.white)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
for(int i=0;i<5;i++){
if(v_info.contains((xIndex+i)+"-"+yIndex+Color.black)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
for(int i=0;i<5;i++){
if(v_info.contains((xIndex-i)+"-"+yIndex+Color.BLACK)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
//判断纵向棋子数量
for(int i=0;i<5;i++){
if(v_info.contains(xIndex+"-"+(yIndex+i)+Color.WHITE)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
for(int i=0;i<5;i++){
if(v_info.contains(xIndex+"-"+(yIndex-i)+Color.WHITE)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
for(int i=0;i<5;i++){
if(v_info.contains(xIndex+"-"+(yIndex+i)+Color.BLACK)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
for(int i=0;i<5;i++){
if(v_info.contains(xIndex+"-"+(yIndex-i)+Color.black)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
//判断135度倾斜方向
for(int i=0;i<5;i++){
if(v_info.contains((xIndex+i)+"-"+(yIndex+i)+Color.WHITE)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
for(int i=0;i<5;i++){
if(v_info.contains((xIndex-i)+"-"+(yIndex-i)+Color.WHITE)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
for(int i=0;i<5;i++){
if(v_info.contains((xIndex+i)+"-"+(yIndex+i)+Color.black)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
for(int i=0;i<5;i++){
if(v_info.contains((xIndex-i)+"-"+(yIndex-i)+Color.BLACK)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
//倾斜45度角判断
for(int i=0;i<5;i++){
if(v_info.contains((xIndex+i)+"-"+(yIndex-i)+Color.WHITE)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
for(int i=0;i<5;i++){
if(v_info.contains((xIndex-i)+"-"+(yIndex+i)+Color.WHITE)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
for(int i=0;i<5;i++){
if(v_info.contains((xIndex+i)+"-"+(yIndex-i)+Color.BLACK)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
for(int i=0;i<5;i++){
if(v_info.contains((xIndex-i)+"-"+(yIndex+i)+Color.BLACK)){
continueCount++;
}else{
break;
}
}
if(continueCount>=5){
return true;
}else{
continueCount = 0;
}
return false;
}
private boolean findChess(int x,int y){
for(ChessPiece c:chessList){
if(c!=null&&c.getX()==x&&c.getY()==y)
return true;
}
return false;
}
//开始游戏
public void startGame(){
//清除棋子
for(int i=0;i<chessList.length;i++){
chessList[i]=null;
v_info.removeAll(v_info);
}
//恢复游戏相关的变量值
isBlack=true;
isgameover=false; //游戏是否结束
chessCount =0; //当前棋盘棋子个数
repaint();
}
//悔棋
public void goback(){
if(chessCount==0)
return ;
chessList[chessCount-1]=null;
chessCount--;
v_info.remove(v_info.size()-1);
if(chessCount>0){
xIndex=chessList[chessCount-1].getX();
yIndex=chessList[chessCount-1].getY();
}
isBlack=!isBlack;
repaint();
}
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
package Mychess02;
import java.awt.Color;
public class ChessPiece {
private int x;//棋盘中x索引
private int y;//棋盘中y索引
private Color color;
public static final int diameter = 30;//直径
public ChessPiece(int x, int y, Color color){
this.x = x;
this.y = y;
this.color = color;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Color getColor(){//获得棋子的颜色
return color;
}
}
上一篇: 制作五子棋小游戏单机/在线联网对弈手把手精致设计含游戏服务器源码2
下一篇: 蒙特卡洛与围棋