Java实现四连环棋游戏
心怡今天也学习 人气:0游戏规则:
(1)双人游戏,有黑红两色棋子,双方各执一色棋子。
(2)空棋局开盘,黑棋先发,从最上面一行开始下,棋子会落到最下行。
(3)黑、红交替下子,每次只能下一子,从最上行开始下。
(4)棋子下在任何位置,都会掉落至该列的最下方的空格处,只有该列已有棋子时,该棋子才落在该列最上面棋子的上一格(就是往上摞棋子),以此类推。
(5)棋子下定后便不可以移动。
(6)不许悔棋,下定即确定。
(7)允许中途认输,则对方获胜。
(8)哪一方最先出现横或竖或斜向四颗同色已落子,则该方获胜。
(9)若棋子填满双方仍未分出胜负则平局
游戏原型:
功能实现:
定义一个居中窗口,用画板画出6x7的格子。添加鼠标监听器,鼠标点击时获取坐标,用数组存储黑红双方棋子位置。给下黑棋赋一个布尔值,黑子下完后改变布尔值,改为下红棋的布尔值,实现黑红棋交替下在棋盘上。通过查找空格的方法,使棋子下在任何位置,都会落在该列格子中最下面的空格子里,如果该列已有棋子,则该棋子落在该列最上面的棋子的上一格空格处。每下一个棋子时就依次横向和纵向做出判断是否连成四子,以四子棋的颜色为判断基础 ,如果横向和纵向都不符合要求,开始进行斜着判断,直到发现四子相同为止,如果都不成立就代表没有连成四子,如果棋盘下满了仍未有任意一方连成同色四子,则为双方平局。设置重新开始、游戏规则、退出游戏、认输选项,用获取到的坐标确定选择的是哪个功能,点击后会弹出居中的消息框,判断是否确定选择。
代码部分如下:
package chess; import java.awt.Color; import java.awt.Graphics; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JOptionPane; public class 四连环棋 extends JFrame implements MouseListener{ /** * 为了在反序列化时,确保类版本的兼容性,最好在每个要序列化的类中加入private static final long serialVersionUID这个属性,具体数值自己定义. */ private static final long serialVersionUID = 7715397504806319506L; int[][] allChess = new int[7][6]; // 用数组来保存棋子,0表示无子,1表示黑子,2表示红子 int[] chessX = new int[42];//保存棋谱,记录双方每一步落子的位置 int[] chessY = new int[42]; int x; // 定义鼠标的坐标 int y; boolean isblack = true; //用来表示黑子还是红子, true表示黑子 false表示红子 boolean canPlay = true; // 用来表示当前游戏是否结束 BufferedImage background; 四连环棋() { setBounds(600, 270, 580, 450);//设置窗口的位置 坐标,距左上角的,窗口的大小 setVisible(true);//显示窗口 setTitle("四连环棋"); setBackground(Color.yellow); addMouseListener(this); setDefaultCloseOperation(EXIT_ON_CLOSE); setResizable(false);//不可改变大小 } //画棋盘界面 public void paint(Graphics g) { //异常处理,找不到背景图片 try { background=ImageIO.read(getClass().getResource("5.png")); }catch(IOException m) { m.printStackTrace(); } g.drawImage(background,0,0,null); for(int i=0; i<7; i++){ for (int j = 0; j < 6; j++) { //画实心黑子 if(allChess[i][j] == 1){ int weizhiX = i*53+50; int weizhiY = j*53+68; g.setColor(Color.BLACK); g.fillOval(weizhiX, weizhiY, 40, 40); g.drawOval(weizhiX, weizhiY, 40, 40); } //画实心白子 if(allChess[i][j] == 2){ int weizhiX = i*53+50; int weizhiY = j*53+68; g.setColor(Color.red); g.fillOval(weizhiX, weizhiY, 40, 40); g.drawOval(weizhiX, weizhiY, 40, 40); } } } } public void mousePressed(MouseEvent e) { x=e.getX(); y=e.getY(); // 用来获取鼠标坐标 //异常处理 if(e.getX()<=30 || e.getX()>= 460+43 || e.getY()<=50 ||e.getY()>=329+60) { try { throw new BeyondBoardException("您所点击位置超出棋盘"); } catch (BeyondBoardException k) { // TODO 自动生成的 catch 块 System.out.println(k); } } if(x>43 && x<= 414 && y>=60 && y<=378){ //让鼠标在棋盘范围内 if((x-69)%53>26){ x=(x-69)/53 + 1; y=findEmptyPosition(x); }else { x = (x-69)/53; y=findEmptyPosition(x); } //落子 if(allChess[x][y] == 0){ if(isblack){ allChess[x][y] = 1; isblack = false; }else { allChess[x][y] = 2; isblack = true; } this.repaint(); if(this.Win()){ if(allChess[x][y] == 1){ JOptionPane.showMessageDialog(this, "游戏结束,黑方胜利"); }else { JOptionPane.showMessageDialog(this, "游戏结束,红方胜利"); } this.canPlay = false; //表示游戏结束 } //判断平局 int sum=0; for(int i=0;i<7;i++) { for(int j=0;j<6;j++) { if(allChess[i][j]!=0) { sum++; if(sum==42) JOptionPane.showMessageDialog(this, "游戏结束,双方平局"); } } } } } //重新开始游戏 if(e.getX() >=430 && e.getX() <= (428+55) && e.getY() >= 66 && e.getY() <= (66+20) ){ int result = JOptionPane.showConfirmDialog(this, "是否重新开始游戏?"); if(result == 0){ restarGame(); } } //游戏规则 if(e.getX() >= 430 && e.getX() <= (430+55) && e.getY() >=106 && e.getY() <= (106+20) ){ JOptionPane.showMessageDialog(this, "规则:(1)双人游戏,有黑红两色棋子,双方各执一色棋子。\r\n" + " (2)空棋局开盘,黑棋先发,从最上面一行开始下,棋子会落到最下行。\r\n" + " (3)黑、红交替下子,每次只能下一子,从最上行开始下。\r\n" + " (4)棋子下在任何位置,都会掉落至该列的最下方的空格处,只有该列已有棋子时,该棋子才落在该列最上面棋子的上一格(就是往上摞棋子),以此类推。\r\n" + " (5)棋子下定后便不可以移动。\r\n" + " (6)不许悔棋,下定即确定。\r\n" + " (7)允许中途认输,则对方获胜。\r\n" + " (8)哪一方最先出现横或竖或斜向四颗同色已落子,则该方获胜。\r\n"+ " (9)若棋盘填满棋子双方仍未分出胜负则平局。"); } //退出游戏 if(e.getX() >=430 && e.getX() <= (430+55) && e.getY() >=146 && e.getY() <= (146+20)){ int result = JOptionPane.showConfirmDialog(this, "是否退出游戏?"); if(result == 0){ System.exit(0); } } //认输 if(e.getX()>=430 && e.getX()<=(428+55) && e.getY()>=186 && e.getY()<=(186+20)){ int result=JOptionPane.showConfirmDialog(this, "是否认输?"); if(result==0){ JOptionPane.showMessageDialog(this, "游戏结束,"+(isblack==true ? "黑方认输,红方获胜!" : "红方认输,黑方获胜!")); } } } public void restarGame(){ for (int i = 0; i < 7; i++) { for (int j = 0; j < 6; j++) { allChess[i][j] = 0; //清空棋盘的棋子 } } //清空下棋棋子坐标的记录 for (int i = 0; i < 7; i++) { chessX[i] = 0; for (int j = 0; j < 6; j++) { chessY[j] = 0; } } isblack = true; canPlay = true; this.repaint(); } // 判断输赢规则 public boolean Win(){ boolean flag = false; int count = 1; //用来保存共有相同颜色多少棋子相连,初始值为1 int color = allChess[x][y]; //color = 1 (黑子) color = 2(白子) //判断横向是否有4个棋子相连,特点:纵坐标是相同,即allChess[x][y] 中y值是相同 count = this.checkCount(1,0,color); if(count >= 4){ flag = true; }else { //判断纵向 count = this.checkCount(0,1,color); if(count >= 4){ flag = true; }else { //判断右上,左下 count = this.checkCount(1,-1,color); if(count >= 4){ flag = true; }else { //判断右下,左上 count = this.checkCount(1,1,color); if(count >= 4){ flag = true; } } } } return flag; } // 检查棋盘中的棋是否连成四子 public int checkCount(int heng , int zong ,int color){ int count = 1; int weizhiX = heng; int weizhiY = zong; //保存初始值 //寻找相同颜色的棋子 while(x + heng >=0 && x+heng <7 && y+zong >=0 && y+zong < 6 && color == allChess[x+heng][y+zong]){ count++; if(heng != 0) heng++; if(zong != 0 ){ if(zong != 0){ if(zong > 0) { zong++; }else { zong--; } } } } heng = weizhiX; zong = weizhiY; // 恢复初始值 while(x-heng >=0 && x-heng <7 && y-zong >=0 && y-zong <6 && color == allChess[x-heng][y-zong]){ count++; if(heng != 0){ heng++; } if(zong != 0){ if (zong > 0) { zong++; }else { zong--; } } } return count; } public int findEmptyPosition(int i) { int j; //找到空的位置 for (j = 5; j >= 0; j--) { if (allChess[i][j]==0) { return j; } } return j; } public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub } public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } public static void main(String[] args)throws BeyondBoardException { new 四连环棋(); } } //点击位置超出棋盘的异常 class BeyondBoardException extends Exception{ private static final long serialVersionUID = 1L; BeyondBoardException(String ErrorMessage){ super(ErrorMessage); } }
背景选用图片名:5.png,与四连环棋.java同在chess包目录下。
图片如下:
运行结果如下:
加载全部内容