import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage; import javax.swing.JFrame;
import javax.swing.JOptionPane; public class FiveChessFrame extends JFrame implements Runnable,MouseListener{
/**
*
*/
private static final long serialVersionUID = 1L;
//游戏界面大小
int width=Toolkit.getDefaultToolkit().getScreenSize().width;
int height=Toolkit.getDefaultToolkit().getScreenSize().height; int x,y; //鼠标坐标
int[][]allChess=new int[15][15]; //保存棋盘,0表示无子,1表示黑子,2表示白字
Boolean isblack=true; //当前下子是黑子还是白字,true代表黑子,false代表白子
Boolean canPlay=true; //标始当前游戏是否结束
String message="黑方先行";
String blackMessage="无限制";
String whiteMessage="无限制"; //保存棋谱,记录双方每一步落子的位置
int[]chessX=new int[255];
int[]chessY=new int[255];
int countX,countY; //默认设置无时间限制
int maxTime=0; //保存最大时间
int blackTime=0;
int whiteTime=0; //保存黑白方所剩余的时间 Thread timer=new Thread(this); public FiveChessFrame(){
this.setTitle("五子棋游戏");
this.setSize(500, 500);
this.setLocation((width - 500) / 2, (height - 500) / 2);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.repaint();
this.addMouseListener(this); timer.start(); //开启计时线程
timer.suspend();
} //画棋盘界面
public void paint(Graphics g){
//双缓冲技术
BufferedImage buf=new BufferedImage(500,500,BufferedImage.TYPE_INT_RGB);
Graphics g1=buf.createGraphics(); //创建画笔
g1.setColor(new Color(0,169,158)); //设置画笔颜色
g1.fill3DRect(43,60,375,375,true); for(int i=0;i<=15;i++){
g1.setColor(Color.WHITE);
g1.drawLine(43,60+i*25,375+43,60+i*25);//画棋盘横线
g1.drawLine(43+i*25,60,43+i*25,375+60); //画棋盘竖线
} g1.setFont(new Font("黑体",Font.BOLD,20));
g1.drawString("游戏信息: "+message,50,50); g1.drawRect(30,440,180,40);
g1.drawRect(250,440,180,40); //画黑方时间与白方时间字符串的边框
g1.setFont(new Font("宋体",0,12)); g1.drawString("黑方时间: "+blackMessage,40,465);
g1.drawString("白方时间: "+whiteMessage,260,465); g1.drawRect(428,66,54,20);
g1.drawString("重新开始",432,80); //重新开始按钮 g1.drawRect(428,106,54,20);
g1.drawString("游戏设置",432,120); //游戏设置按钮 g1.drawRect(428, 146, 54, 20);
g1.drawString("游戏说明", 432, 160); // 游戏说明按钮 g1.drawRect(428, 186, 54, 20);
g1.drawString("退出游戏", 432, 200); // 退出游戏按钮 g1.drawRect(428, 246, 54, 20);
g1.drawString("悔棋", 442, 260); // 悔棋 g1.drawRect(428, 286, 54, 20);
g1.drawString("认输", 442, 300); // 认输 for(int i=0;i<15;i++){
for(int j=0;j<15;j++){
//画实心黑子
if(allChess[i][j]==1){
int tempX=i*25+47;
int tempY=j*25+64;
g1.setColor(Color.BLACK);
g1.fillOval(tempX,tempY,16,16);
g1.setColor(Color.BLACK);
g1.drawOval(tempX,tempY,16,16);
} //画实心白子
if(allChess[i][j]==2){
int tempX=i*25+47;
int tempY=j*25+64;
g1.setColor(Color.WHITE);
g1.fillOval(tempX, tempY, 16, 16);
g1.setColor(Color.BLACK);
g1.drawOval(tempX, tempY, 16, 16);
}
}
}
g.drawImage(buf, 0, 0,this);
} @Override
public void mousePressed(MouseEvent e){
if(canPlay){
x=e.getX();
y=e.getY(); //获得鼠标坐标 if(x>=55 && x<=405 && y>=72 && y<=420){
//使x,y在0-15的范围
if((x-55)%25>12){
x=(x-55)/25+1;
}
else{
x=(x-55)/25;
}
if((y-72)%25>12){
y=(y-72)/25+1;
}
else{
y=(y-72)/25;
} //落子
if(allChess[x][y]==0){
chessX[countX++]=x;
chessY[countY++]=y; if(isblack){
allChess[x][y]=1;
isblack=false;
message="白方下子";
}
else{
allChess[x][y]=2;
isblack=true;
message="黑方下子";
}
this.repaint(); if(this.isWin()){
if(allChess[x][y]==1){
JOptionPane.showMessageDialog(this, "游戏结束,黑方胜利");
}else{
JOptionPane.showMessageDialog(this, "游戏结束,白方胜利");
}
this.canPlay=false; //标识游戏结束
}
}
}
} //重新开始游戏
if(e.getX()>=428 && e.getY()<=(428+54) && e.getY()>=66 && e.getY()<=(66+20)){
int result=JOptionPane.showConfirmDialog(this,"是否重新开始游戏?"); //0表示重新开始
if(result==0){
restartGame();
}
} //游戏倒计时设置
if (e.getX()>=428 && e.getX()<=(428+54) && e.getY()>= 106 && e.getY()<=(106+20)) {
String time=JOptionPane.showInputDialog("请输入游戏的最大时间(单位:分钟),如果输入0,表示没有时间限制:");
maxTime=Integer.parseInt(time)*60; //将分钟转换为秒,以便后面计算
if(maxTime<0){
JOptionPane.showMessageDialog(this,"输入的游戏时间有误,请重新设置!");
}
else if(maxTime==0){
int result=JOptionPane.showConfirmDialog(this,"游戏时间设置成功,是否重新开始游戏?");
//重新开始
if(result==0){
restartGame();
timer.suspend(); //挂起线程,以便之后重新启动
}
}
else if(maxTime>0){
int result = JOptionPane.showConfirmDialog(this,"游戏时间设置成功,是否重新开始游戏?");
if(result==0){
for(int i=0;i<15;i++){
for(int j=0;j<15;j++){
allChess[i][j]=0;
}
}
for(int i=0;i<15;i++){
chessX[i]=-1;
chessY[i]=-1;
}
countX=0;
countY=0;
message="黑方先行";
isblack=true; blackMessage=maxTime/3600+":"+(maxTime/60-maxTime/3600*60)+":"+(maxTime-maxTime/60*60);
whiteMessage = maxTime/3600 + ":" + (maxTime/60-maxTime/3600*60) + ":"+ (maxTime-maxTime/60*60); blackTime=maxTime;
whiteTime=maxTime;
timer.resume();
this.canPlay=true;
this.repaint();
}
} } //游戏说明
if(e.getX()>=428 && e.getY()<=(428+54) && e.getY()>=146 && e.getY()<=(146+20)){
JOptionPane.showMessageDialog(this,"规则:横竖斜先连成五子者获胜!");
} //退出游戏
if(e.getX()>=428 && e.getX()<=(428+54) && e.getY()>=186 && e.getY()<=(186+20)) {
int result=JOptionPane.showConfirmDialog(this,"是否退出游戏?");
if(result==0){
System.exit(0);
}
} //悔棋
if(e.getX()>=428 && e.getX()<=(428+54) && e.getY()>=246 && e.getY()<=(246+20)){
int result=JOptionPane.showConfirmDialog(this,(isblack==true?"白方悔棋,黑方是否同意?" : "黑方悔棋,白方是否同意?"));
//result=0为悔棋
if(result==0){
allChess[chessX[--countX]][chessY[--countY]]=0;
if(isblack==true){
isblack=false;
}
else{
isblack=true;
} this.repaint(); //重绘棋盘
}
} //认输
if(e.getX()>=428 && e.getX()<=(428+54) && e.getY()>=286 && e.getY()<=(286+20)){
int result=JOptionPane.showConfirmDialog(this, "是否认输?");
if(result==0){
JOptionPane.showMessageDialog(this,"游戏结束,"+(isblack==true ? "黑方认输,白方获胜!" : "白方认输,黑方获胜!"));
}
} } //计时
@Override
public void run() {
if(this.maxTime>0){
while(true){
if(isblack){
blackTime--;
if(blackTime==0){
JOptionPane.showMessageDialog(this,"黑方超时,游戏结束");
restartGame();
timer.suspend();
}
}
else{
whiteTime--;
if(whiteTime==0){
JOptionPane.showMessageDialog(this,"白方超时,游戏结束");
restartGame();
timer.suspend();
}
}
blackMessage=blackTime/3600+":"+(blackTime/60-blackTime/3600*60)+":"+(blackTime-blackTime/60*60);
whiteMessage=whiteTime/3600+":"+(whiteTime/60-whiteTime/3600*60)+":"+(whiteTime-whiteTime/60*60);
this.repaint();
try {
Thread.sleep(1000); //设置与时钟同步,1秒钟记一次
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} } @Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub } @Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub } @Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub } @Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub } public void restartGame(){
for(int i=0;i<15;i++){
for(int j=0;j<15;j++){
allChess[i][j]=0; //清空棋盘的棋子
}
}
//清空下棋棋子坐标(x,y)的记录
for(int i=0;i<15;i++){
chessX[i]=0;
chessY[i]=0;
} countX=0;
countY=0;
message="黑方先行";
blackMessage="无限制";
whiteMessage="无限制";
blackTime=maxTime;
whiteTime=maxTime;
isblack=true;
canPlay=true;
this.repaint();
} public boolean isWin(){
boolean flag=false; //定义一标志位
int count=1; //保存共有相同颜色多少棋子相连,初始值为1
int color=allChess[x][y]; //color=1(黑子).color=2(白子) //判断横向是否有5个棋子相连,特点:纵坐标是相同,即allChess[x][y]中y值是相同
count=this.checkCount(1,0,color);
if(count>=5){
flag=true;
}
else{
//判断纵向
count=this.checkCount(0, 1, color);
if(count>=5){
flag=true;
}
else{
//判断右上,左下
count=this.checkCount(1,-1, color);
if(count>=5){
flag=true;
}
else{
//判断右下,左上
count=this.checkCount(1,1,color);
if(count>=5){
flag=true;
}
}
}
}
return flag; } public int checkCount(int xChange,int yChange,int color){
int count=1;
int tempX=xChange;
int tempY=yChange; //保存初始值 //全局变量x,y最初为鼠标点击的坐标,经下棋方法已经将x,y的范围变成0-15(遍历整个棋盘,寻找相同颜色的棋子)
while(x+xChange>=0 && x+xChange<15 && y+yChange>=0 && y+yChange<15 && color==allChess[x+xChange][y+yChange]){
count++;
if(xChange!=0) xChange++;
if(yChange!=0){
if(yChange!=0){
if(yChange>0) yChange++;
else {
yChange--;
}
}
}
}
xChange=tempX;
yChange=tempY;
while(x-xChange>=0 && x-xChange<15 && y-yChange>=0 && y-yChange<15 && color==allChess[x-xChange][y-yChange]){
count++;
if(xChange!=0){
xChange++;
}
if(yChange!=0){
if(yChange>0) yChange++;
else{
yChange--;
}
}
}
return count;
} public static void main(String[] args) {
new FiveChessFrame();
} }

java swing 双人五子棋源代码的更多相关文章

  1. 师兄写的一个JAVA播放器的源代码(转)

    师兄写的一个JAVA播放器的源代码 MediaPlayer.java------------------------------------------------------------------ ...

  2. Java课程设计 ————五子棋 (个人博客)

    JAVA课程设计 五子棋(博客个人版) •团队课程设计博客链接 http://www.cnblogs.com/mz201521044152/p/7065575.html •个人负责模块或任务说明 1. ...

  3. Java 推荐读物与源代码阅读

    Java 推荐读物与源代码阅读                                                     江苏无锡  缪小东 1. Java语言基础     谈到Java ...

  4. 基于mysql和Java Swing的简单课程设计

    摘要 现代化的酒店组织庞大.服务项目多.信息量大.要想提高效率.降低成本.提高服务质量和管理水平,进而促进经济效益,必须利用电脑网络技术处理宾馆酒店经营数据,实现酒店现代化的信息管理.本次课程设计运用 ...

  5. 「艺蜂酒店管理系统」 · Java Swing + mysql 开发 学生毕业设计项目

    Java  Swing在社会上基本用不到,但是任有学校拿来当做结课设计,只是博主在校期间的一个项目.如果在部署过程中有问题可以加我qq68872185. 码云仓库地址:https://gitee.co ...

  6. Java Swing interview

    http://www.careerride.com/Swing-AWT-Interview-Questions.aspx   Swing interview questions and answers ...

  7. Java Swing 第03记 布局管理器

    几种Swing常用的布局管理器 BorderLaout 它将容器分为5个部分,即东.南.西.北.中,每一个区域可以容纳一个组件,使用的时候也是通过BorderLayout中5个方位常量来确定组件所在的 ...

  8. Java Swing 第01记 Hello Word

    首先来一个Java Swing的HelloWord程序. package cn.java.swing.chapter03; import javax.swing.JButton; import jav ...

  9. Java swing项目-图书管理系统(swing+mysql+jdbc) 总结

    (一)java Swing的学习. (1)学习如何安装windowbuilder插件的安装. <1>在eclipse中点击help <2>在help的下拉选中选择install ...

随机推荐

  1. 如何在Node.js中合并两个复杂对象

    通常情况下,在Node.js中我们可以通过underscore的extend或者lodash的merge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢? 例如我有以下两个object: ...

  2. 也许你需要点实用的-Web前端笔试题

    之前发的一篇博客里没有附上答案,现在有空整理了下发出来,希望能帮助到正在找工作的你,还是那句话:技术只有自己真正理解了才是自己的东西,共勉. Web前端笔试题 Html+css 1.对WEB标准以及w ...

  3. 在View and Data API中更改指定元素的颜色

    大家在使用View and Data API开发过程中,经常会用到的就是改变某些元素的颜色已区别显示.比如根据某些属性做不同颜色的专题显示,或者用不同颜色表示施工进度,或者只是简单的以颜色变化来提醒用 ...

  4. Java中使用IO流实现大文件的分裂与合并

    文件分割应该算一个比较实用的功能,举例子说明吧比如说:你有一个3G的文件要从一台电脑Copy到另一台电脑, 但是你的存储设备(比如SD卡)只有1G ,这个时候就可以把这个文件切割成3个1G的文件 ,分 ...

  5. React Native学习笔记

    React 是使用ES6 ,支持JSX语法, 开发组件化web或native的工具. 现阶段使用Babel工具转换成ES5 代码. 组件通过props属性传递不变化的内容,UI通过state属性变动来 ...

  6. Android 自带后退按钮的使用

    一.后退按钮有两种定义,分别是向上按钮和返回按钮:向上按钮:偏向于一种父子关系:返回按钮:反映的是一种前后关系 向上按钮:在清单文件中需要添加后退功能按钮的Activity中添加parentActiv ...

  7. Android中使用GridView和ImageViewSwitcher实现电子相册简单功能

    我们在手机上查看相册时,首先看到的是网格状的图片展示界面,然后我们选择想要欣赏的照片点击进入,这样就可以全屏观看该照片,并且可以通过左右滑动来切换照片.如下图的显示效果: 首先我们先罗列一下本次实现所 ...

  8. SQL Server 2012 新特性:FileTable

    FileTable是基于FILESTREAM的一个特性.有以下一些功能: 一行表示一个文件或者目录. 每行包含以下信息: file_Stream流数据,stream_id标示符(GUID). 用户表示 ...

  9. 优化SQLServer--表和索引的分区(二)

    简介 之前一篇简单的介绍了语法和一些基本的概念,隔了一段时间,觉得有必要细致的通过实例来总结一下这部分内容.如之前所说,分区就是讲大型的对象(表)分成更小的块来管理,基本单位是行.这也就产生了很大优势 ...

  10. Linux下更换默认yum源为网易yum源的操作记录

    废话不多说,下面记录了centos下更换系统默认yum源为网易yum源的操作过程:1)备份原有的默认yum源[root@bastion-IDC ~]# cp /etc/yum.repos.d/Cent ...