java双人对弈五子棋源码_java swing 双人五子棋源代码

2023-11-19

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();

}

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java双人对弈五子棋源码_java swing 双人五子棋源代码 的相关文章

随机推荐

  • pat 乙级 1015. 德才论 (25) c++

    http 39 106 25 239 个人网站 欢迎访问 交流 1015 德才论 25 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN Li 宋代史学家司马光在 资
  • AFNetwork 作用和使用方法具体解释

    转自 http www maxiaoguo com clothes 269 html AFNetworking是一个轻量级的iOS网络通信类库 它建立在NSURLConnection和NSOperation等类库的基础上 让非常多网络通信功
  • Android:通用的ListView数据适配器

    在写Android程序时 经常会用到ListView控件进行数据展示 使用时 需要定义一个ListView并创建其Item布局 然后对ListView设置一个适配器adapter 一般继承自BaseAdapter 同时需要定义一个ViewH
  • 如何消除@Autowired报Field injection is not recommended的警告

    对于一些强迫者来说 代码中有一些警告 就看起来很不爽 今天笔者我也遇到了这种问题 在SpringBoot中 使用 Autowired的时候 警告Field injection is not recommended 如下图 Spring Te
  • electron安装过程中遇到的问题

    安装总结 项目本身安装是用的npm 这个在我们这里 不翻墙是大概率用不了的 所以必须修改镜像源或者用cnpm 一开始的尝试是用 cnpm 但是到后面安装脚手架的时候 脚手架里封装的方法是npm 这时候 脚手架的安装就会有问题 综上 还是需要
  • STM32 USART通信协议详细讲解—小白入门

    文章目录 一 串口通信协议简介 二 物理层 2 1 电平标准 2 2 RS 232 信号线 三 协议层 3 1 波特率 3 2 通讯的起始和停止信号 3 3 有效数据 3 4 有效检验 四 STM32 的 USART 简介 4 1 USAR
  • SQL语句关键字大全

    SQL语句的整理以及总结 目录 SQL语句的整理以及总结 目录 SQL语句的基本类型 S Q L 语
  • 【智慧医疗】Springboot+Vue+Element-UI前后端分离的医疗管理平台

    目录 需求分析 系统概要 技术选型 功能模块 后端逻辑 需求分析 随着第五代移动通信技术 5G 高速发展 推动新一代信息技术与各个行业的融合发展 各行各业都在积极融合智能现代化概念 努力把互联网技术运用到其中 在我国目前人口基数大 对医疗服
  • 【C++笔记】NULL、0、nullptr区别分析

    一 C的NULL 在C语言中 我们一般使NULL表示空指针 即 int i NULL foo t f NULL 但是 实际上在C语言中 NULL通常被定义为 define NULL void 0 也就是说NULL实际上是一个void 的指针
  • C++中的友元分析

    友元函数 class stu public friend int ret stu my stu int a 10 this gt a a private int a int b int ret stu my return my a 定义友元
  • c#的dllimport使用方法详解

    DllImport是System Runtime InteropServices命名空间下的一个属性类 其功能是提供从非托管DLL 托管 非托管是微软的 net framework中特有的概念 其中 非托管代码也叫本地 native 代码
  • 手机游戏软件开发的前景 The future of development of game software on mobiles

    一 课题名称 手机游戏软件开发的前景 The future of development of game software on mobiles 二 课题分析 计算机领域的方向很多 我对手机游戏的开发比较感兴趣 而且3G手机的时代即将到来
  • 编写一个Book类,该类至少有name和price两个属性。该类要实现Comparable接口,在接口的compareTo()方法中规定两个Book类实例的大小关系为二者的price属性的大小关系。在

    编写一个Book类 该类至少有name和price两个属性 该类要实现Comparable接口 在接口的compareTo 方法中规定两个Book类实例的大小关系为二者的price属性的大小关系 在主函数中 选择合适的集合类型存放Book类
  • pc 后台管理系统总结

    人力资源后台管理系统 hrsaas 1 项目介绍 hrsaas是一款对公司员工管理的后台管理系统 主要实现功能 公司组织架构的增删改查 公司角色的增删改查以及公司信息内容展示 员工信息的查阅 员工在公司的工作状态 是否转正 离职 调岗 担任
  • Java基础之String类型详解

    目录 1 简介 2 字符串的比较 3 String的实例化方式 1 直接赋值方式 2 构造方法实例化 4 String对象 常量 池 5 字符串修改 6 String类常用方法 1 字符串查找 2 字符串替换 3 字符串拆分 4 字符串截取
  • 【ReactiveX】Observable 对象(译)

    更多内容 欢迎关注作者博客 http www china10s com blog p 475 Observable 对象 在 ReactiveX 中 一个观察者向 Observable 对象订阅消息 然后这个观察者将会响应 Observab
  • 区块链学习笔记4——BTC实现

    区块链学习笔记4 BTC实现 学习视频 北京大学肖臻老师 区块链技术与应用 笔记参考 北京大学肖臻老师 区块链技术与应用 公开课系列笔记 目录导航页 UTXO 区块链是一个去中心化的账本 比特币采用了基于交易的账本模式 然而 系统中并没有记
  • IPv4、IPv6、UDP、TCP数据报首部格式分析

    一 IPv4首部格式 图片来源 图解TCP IP 通过wireshark抓QQ的数据报 IPV4的数据报格式和上面的一致 现在进行分析 相对重要的会红色标记 1 版本 version 由4比特构成 表示标识IP首部的版本号 如上是版本号为4
  • 面试专题:Linux运维精华面试题

    下面是一名资深Linux运维求职数十家公司总结的Linux运维面试精华 助力大家跳槽找个高薪好工作 1 什么是运维 什么是游戏运维 1 运维是指大型组织已经建立好的网络软硬件的维护 就是要保证业务的上线与运作的正常 在他运转的过程中 对他进
  • java双人对弈五子棋源码_java swing 双人五子棋源代码

    import java awt Color import java awt Font import java awt Graphics import java awt Toolkit import java awt event MouseE