五子棋基础

五子棋课程设计基础

我们小组三人(小白)的成果,参考b站MLDN的五子棋教程

代码如下:

package wuziqi;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 java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
//00点31 57 间隔40
public class FiveChessFrame extends JFrame implements MouseListener, Runnable {BufferedImage bgImage = null;int x = 0;int y = 0;int[][] allChess = new int[15][15];boolean isBlack = true;//表示当前游戏是否继续boolean canPlay = true;//保存显示的提示信息String message="黑方先行";//保存最多拥有的时间int maxTime = 0;//做倒计时的线程类Thread t = new Thread (this);//保存黑方与白方的剩余时间int blackTime = 0;int whiteTime = 0;//保存上方剩余时间的显示信息String blackMessage = "无限制";String whiteMessage = "无限制";public FiveChessFrame(){this.setTitle("五子棋");this.setSize(900,700);this.setResizable(false);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.addMouseListener(this);int width = Toolkit.getDefaultToolkit().getScreenSize().width;int height = Toolkit.getDefaultToolkit().getScreenSize().height;this.setLocation((width-900)/2, (height-700)/2);try {bgImage = ImageIO.read(new File("D:/Pic/background.jpg"));} catch (IOException e) {// TODO 自动生成的 catch 块e.printStackTrace();}this.setVisible(true);t.start();t.suspend();//刷新屏幕}public void paint(Graphics g) {//双缓冲技术防止屏幕闪烁//BufferedImage bi = new BufferedImage(900, 700, BufferedImage.TYPE_INT_ARGB);//Graphics g2 = bi.createGraphics();g.drawImage(bgImage, 0, 30, this);g.setFont(new Font("宋体",Font.BOLD,20));g.drawString("游戏信息:"+message, 50, 50);g.setFont(new Font("宋体",Font.BOLD,16));g.drawString("黑方时间:"+blackMessage, 50, 680);g.drawString("白方时间:"+whiteMessage, 450, 680);g.setFont(new Font("宋体",Font.BOLD,16));g.drawString("开始游戏", 722, 88);g.drawString("游戏设置", 722, 167);g.drawString("认输", 738, 249);//棋盘for(int i=0;i<15;i++) {g.drawLine(31, 57+40*i, 591, 57+40*i);g.drawLine(31+40*i, 57, 31+40*i, 617);}//棋子for(int i=0;i<15;i++)for(int j=0;j<15;j++) {if(allChess[i][j]==1) {int tempX=i*40+31;int tempY=j*40+57;g.fillOval(tempX-15, tempY-15, 30, 30);}if(allChess[i][j]==2) {int tempX=i*40+31;int tempY=j*40+57;g.setColor(Color.WHITE);g.fillOval(tempX-15, tempY-15, 30, 30);g.setColor(Color.BLACK);g.drawOval(tempX-15, tempY-15, 30, 30);}}//g.drawImage(bi, 0, 0, this);}@Overridepublic void mouseClicked(MouseEvent e) {// TODO 自动生成的方法存根}@Overridepublic void mousePressed(MouseEvent e) {// TODO 自动生成的方法存根if(canPlay==true) {x = e.getX();y = e.getY();if(x>=31 && x<=591 && y>=57 && y<=617) {if((x-31)%40>20) {x=(x-31)/40+1;}else {x=(x-31)/40;}if((y-57)%40>20) {y=(y-57)/40+1;}else {y=(y-57)/40;}if(allChess[x][y]==0) {if(isBlack==true) {allChess[x][y]=1;isBlack=false;message = "轮到白方";}else {allChess[x][y]=2;isBlack=true;message="轮到黑方";}//判断输赢,看周围相连是否有五个boolean winFlag = this.checkWin();if(winFlag==true) {JOptionPane.showMessageDialog(this, "Game Over,"+(allChess[x][y]==1?"黑方":"白方")+"获胜!");canPlay=false;}}//判断输赢,看周围相连是否有五个this.repaint();}}System.out.println(e.getX()+"--"+e.getY());if(e.getX() >=678 && e.getX() <=838 && e.getY() >=50 && e.getY() <=115){int result = JOptionPane.showConfirmDialog(this, "是否重新开始游戏?");if(result == 0) {allChess = new int [19][19];isBlack = true;canPlay = true;blackTime = maxTime;whiteTime = maxTime;if(maxTime > 0) {blackMessage = maxTime/3600+":"+(maxTime/60-maxTime/3600*60)+":"+(maxTime-maxTime/60*60);whiteMessage = maxTime/3600+":"+(maxTime/60-maxTime/3600*60)+":"+(maxTime-maxTime/60*60);}else {blackMessage = "无限制";whiteMessage = "无限制";}t.resume();this.repaint();}}if(e.getX() >=678 && e.getX() <=838 && e.getY() >=134 && e.getY() <=194){String input = JOptionPane.showInputDialog("请输入最大游戏时间(分钟),如果输入0则表示没有时间限制:");try {maxTime = Integer.parseInt(input) * 60;if(maxTime < 0) {JOptionPane.showMessageDialog(this, "请输入正确信息,不允许时负数!");}if(maxTime == 0) {int result = JOptionPane.showConfirmDialog(this, "设置完成,是否重新开始游戏?");if(result == 0) {allChess = new int [19][19];isBlack = true;canPlay = true;blackTime = maxTime;whiteTime = maxTime;blackMessage = "无限制";whiteMessage = "无限制";this.repaint();}}if(maxTime > 0) {int result = JOptionPane.showConfirmDialog(this, "设置完成,是否重新开始游戏?");if(result == 0) {allChess = new int [19][19];isBlack = true;canPlay = true;blackTime = maxTime;whiteTime = maxTime;blackMessage = maxTime/3600+":"+(maxTime/60-maxTime/3600*60)+":"+(maxTime-maxTime/60*60);whiteMessage = maxTime/3600+":"+(maxTime/60-maxTime/3600*60)+":"+(maxTime-maxTime/60*60);t.resume();this.repaint();}}}catch(NumberFormatException el) {JOptionPane.showMessageDialog(this, "请输入正确信息!");}}if(e.getX() >=678 && e.getX() <=838 && e.getY() >=215 && e.getY() <=274){int result = JOptionPane.showConfirmDialog(this,"是否确认 认输?" );if(result == 0) {if(isBlack) {JOptionPane.showMessageDialog(this, "黑方已经认输,游戏结束!");canPlay = false;}else{JOptionPane.showMessageDialog(this, "白方已经认输,游戏结束!");canPlay = false;}}				 }}@Overridepublic void mouseReleased(MouseEvent e) {// TODO 自动生成的方法存根}@Overridepublic void mouseEntered(MouseEvent e) {// TODO 自动生成的方法存根}@Overridepublic void mouseExited(MouseEvent e) {// TODO 自动生成的方法存根}public boolean checkWin() {boolean flag=false;// 保存共有相同颜色多少棋子相连int count = 1;int color = allChess[x][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;}private int checkCount(int xChange, int yChange, int color) {int count = 1;int tempX = xChange;int tempY = yChange;while (x + xChange >= 0 && x + xChange <= 14 && y + yChange >= 0&& y + yChange <= 14&& color == allChess[x + xChange][y + yChange]) {count++;if (xChange != 0)xChange++;if (yChange != 0) {if (yChange > 0)yChange++;else {yChange--;}}}xChange = tempX;yChange = tempY;while (x - xChange >= 0 && x - xChange <= 14 && y - yChange >= 0&& y - yChange <= 14&& color == allChess[x - xChange][y - yChange]) {count++;if (xChange != 0)xChange++;if (yChange != 0) {if (yChange > 0)yChange++;else {yChange--;}}}return count;}@Overridepublic void run() {// TODO 自动生成的方法存根//判断是否有时间限制if(maxTime > 0) {while(true) {if(isBlack) {blackTime-- ;if(blackTime == 0) {JOptionPane.showMessageDialog(this, "黑方超时,游戏结束");canPlay = false;t.stop();}}else {whiteTime-- ;if(whiteTime == 0) {JOptionPane.showMessageDialog(this, "白方超时,游戏结束");canPlay = false;t.stop();}}try {Thread.sleep(1000);}catch (InterruptedException e) {e.printStackTrace();}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();System.out.println(blackTime + "--"+whiteTime);}}}
}

我负责的主要部分为各个按钮的实现与控制以及倒计时的设置。

(1)各个按钮的实现与控制

其中的难点在于每个按钮的使用过程中都是有一些联系的,不然会出现意想不到的bug。例如“认输”按钮后面canPlay = false;会影响接下来的使用,会使认输之后再重新开始后不能落子,所以必须在每一个有重新开始功能的按钮下加入canPlay = true;

allChess = new int【19】【19】作用就是清空棋盘。注:【19】【19】应该为【15】【15】否则会出现bug。

 if(e.getX() >=678 && e.getX() <=838 && e.getY() >=50 && e.getY() <=115){int result = JOptionPane.showConfirmDialog(this, "是否重新开始游戏?");if(result == 0) {allChess = new int [19][19];isBlack = true;canPlay = true;blackTime = maxTime;whiteTime = maxTime;if(maxTime > 0) {blackMessage = maxTime/3600+":"+(maxTime/60-maxTime/3600*60)+":"+(maxTime-maxTime/60*60);whiteMessage = maxTime/3600+":"+(maxTime/60-maxTime/3600*60)+":"+(maxTime-maxTime/60*60);}else {blackMessage = "无限制";whiteMessage = "无限制";}t.resume();this.repaint();}}if(e.getX() >=678 && e.getX() <=838 && e.getY() >=134 && e.getY() <=194){String input = JOptionPane.showInputDialog("请输入最大游戏时间(分钟),如果输入0则表示没有时间限制:");try {maxTime = Integer.parseInt(input) * 60;if(maxTime < 0) {JOptionPane.showMessageDialog(this, "请输入正确信息,不允许时负数!");}if(maxTime == 0) {int result = JOptionPane.showConfirmDialog(this, "设置完成,是否重新开始游戏?");if(result == 0) {allChess = new int [19][19];isBlack = true;canPlay = true;blackTime = maxTime;whiteTime = maxTime;blackMessage = "无限制";whiteMessage = "无限制";this.repaint();}}if(maxTime > 0) {int result = JOptionPane.showConfirmDialog(this, "设置完成,是否重新开始游戏?");if(result == 0) {allChess = new int [19][19];isBlack = true;canPlay = true;blackTime = maxTime;whiteTime = maxTime;blackMessage = maxTime/3600+":"+(maxTime/60-maxTime/3600*60)+":"+(maxTime-maxTime/60*60);whiteMessage = maxTime/3600+":"+(maxTime/60-maxTime/3600*60)+":"+(maxTime-maxTime/60*60);t.resume();this.repaint();}}}catch(NumberFormatException el) {JOptionPane.showMessageDialog(this, "请输入正确信息!");}}if(e.getX() >=678 && e.getX() <=838 && e.getY() >=215 && e.getY() <=274){int result = JOptionPane.showConfirmDialog(this,"是否确认 认输?" );if(result == 0) {if(isBlack) {JOptionPane.showMessageDialog(this, "黑方已经认输,游戏结束!");canPlay = false;}else{JOptionPane.showMessageDialog(this, "白方已经认输,游戏结束!");canPlay = false;}}				 }

(2)倒计时的设置

前面的声明定义就不展示了,设计倒计时的重点之一就是,要让倒计时结束时停止计时,要用到t.stop() (当然这类方法已经过时了但是其他的不会用) 并且要在此之前加入canPlay = false;否则计时结束分出胜负后依然能下棋。

if(maxTime > 0) {while(true) {if(isBlack) {blackTime-- ;if(blackTime == 0) {JOptionPane.showMessageDialog(this, "黑方超时,游戏结束");canPlay = false;t.stop();}}else {whiteTime-- ;if(whiteTime == 0) {JOptionPane.showMessageDialog(this, "白方超时,游戏结束");canPlay = false;t.stop();}}try {Thread.sleep(1000);}catch (InterruptedException e) {e.printStackTrace();}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();System.out.println(blackTime + "--"+whiteTime);}}

其他的bug暂时没发现,第一次写程序练手多多包涵! 

 

效果如下:

背景图片为江流儿(网图),各位可以自行设计背景图片。这个程序会出现屏闪问题,目前也不会修复,还请各位大佬指点。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部