java课程期末设计-五子棋
创始人
2024-03-31 13:04:11
0

1.设计内容

  1. 设计一个15*15的五子棋小游戏,可以两个玩家进行对战
  2. 游戏开始后可以点击游戏说明了解游戏规则
  3. 能判断鼠标执行的操作
  4. 默认黑棋先下棋,并且玩家1和玩家2可以轮流下棋
  5. 可以从任意方向判断黑棋白棋是否五个连成一线
  6. 支持认输功能
  7. 在对方玩家同意的情况下,当前玩家可以悔棋重新下
  8. 可直接退出游戏
  1. 导包

import javax.swing.JFrame;

import javax.swing.JOptionPane;

import java.awt.*;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.awt.image.BufferedImage;

  1. 定义全局变量

int w = f.getToolkit().getScreenSize().width;//宽度

// int h = f.getToolkit().getScreenSize().height;//高度

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 whileTime = 0;   //保存黑白方所剩余的时间

  1. Main主函数:将FiveGame类实例化对象f。代码如下:

public class FivegameDemo {

public static void main(String[] args) {

FiveGame f=new FiveGame();

}

}

  1. FiveGame类的构造函数FiveGame()创建窗口容器,设置大小,标题,添加鼠标监听器处理事件。代码如下:

public FiveGame(){

//设置标题

this.setTitle("五子棋单机版");

//设置大小

this.setSize(500,500);

this.setLocation((width - 500) / 2 , (height - 500) / 2 );

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.setResizable(false);  //设置窗口不可改变,固定窗口大小

this.setVisible(true);

this.repaint();  //java里repaint()是重绘component的方法;

this.addMouseListener(this);

}

  1. 画棋盘的函数paint(Graphics g):创建一个不带透明色的对象buf作为画布,背景颜色设置为黑色,用buf.createGraphics()创建画笔,fill3DRect()画棋盘,颜色是绿色,从坐标(43,60)开始每隔25个单位用黄色画一条水平直线,一条垂直线,构成棋盘,用循环语句实现。画线函数drawLine()的参数为线的起点和终点坐标,注意要计算正确。函数setColor()可以设置颜色,用drawRect()画边框,drawString()写文字,注意坐标。代码如下:
public void paint(Graphics g){//双缓冲技术//创建一个不带透明色的对象BufferedImage buf = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);Graphics g1 =  buf.createGraphics();  // 创建画笔g1.setColor(new Color(0,200,150));g1.fill3DRect(43, 60, 375, 375,true);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(430,66,55,20);g1.drawString("重新开始",432,80); //重新开始按钮g1.drawRect(430,106,55,20);g1.drawString("游戏设置",432,120); //游戏设置按钮g1.drawRect(430,146, 55, 20);g1.drawString("游戏说明", 432, 160); // 游戏说明按钮g1.drawRect(430, 186, 55, 20);g1.drawString("退出游戏", 432, 200);  // 退出游戏按钮g1.drawRect(430, 246, 55, 20);g1.drawString("悔棋", 442, 260);  // 悔棋g1.drawRect(430, 286, 55, 20);g1.drawString("认输", 442, 300);  // 认输for (int i = 0; i <= 15; i++) {g1.setColor(Color.YELLOW);//设置线的颜色g1.drawLine(43, 60+i*25, 375+43, 60+i*25);  //画棋盘横线g1.drawLine(43+i*25, 60, 43+i*25, 375+60);  //画棋盘竖线}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);/*fillOval(int x,int y ,int width ,int  height)显而易见,前 两个X 和 Y是矩形框的左上角的坐标,width和height是宽和高。*/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.WHITE);g1.drawOval(tempX, tempY, 16, 16);}}}g.drawImage(buf, 0, 0,this);}
  1. 设置鼠标监听器mousePressed:
  1. 让鼠标在棋盘范围内。
  2. 完成落子操作。
  3. 调用isWin()方法进行判断,如果allChess[x][y] == 1输出“游戏结束,黑方胜利”,否则输出“游戏结束,白方胜利”。
  4. 点击重新开始游戏,调用restarGame()方法。
  5. 点击游戏说明,显示游戏规则。
  6. 点击退出游戏,关闭程序。
  7. 点击悔棋,玩家重新下。
  8. 点击认输,游戏结束,输出胜利赢家。

代码如下:

public void mousePressed(MouseEvent e){if(canPlay){x=e.getX();y=e.getY();  // 用来获取鼠标坐标System.out.println(x+"---"+y);if(x>55 && x<= 405  && y>=72 && y<=420){System.out.println();//让鼠标在棋盘范围内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;  //表示游戏结束}}else{JOptionPane.showMessageDialog(this, "已经有棋子,请重新下");}}}//点击按钮//重新开始游戏//e.getX()获得鼠标的位置if(e.getX() >=430 && e.getY() <= (428+55)  && e.getY() >= 66&& e.getY() <= (66+20) ){int result = JOptionPane.showConfirmDialog(this, "是否重新开始游戏?");if(result == 0){restarGame();}}//        游戏说明if(e.getX() >= 430 && e.getY() <= (430+55)  && e.getY() >=146&& e.getY() <= (146+20) ){JOptionPane.showMessageDialog(this, "规则:横竖斜先连成五子者获胜!");}//退出游戏if(e.getX() >=430 && e.getX() <= (430+55)  && e.getY() >=186&&  e.getY() <= (186+20)){int result = JOptionPane.showConfirmDialog(this, "是否退出游戏?");if(result == 0){System.exit(0);}}//悔棋if(e.getX() >= 430 && e.getX() <= (430+55) && 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()>=430 && e.getX()<=(428+55) && e.getY()>=286&& e.getY()<=(286+20)){int result=JOptionPane.showConfirmDialog(this, "是否认输?");if(result==0){JOptionPane.showMessageDialog(this,"游戏结束,"+(isblack==true ? "黑方认输,白方获胜!" : "白方认输,黑方获胜!"));}}}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}
  1. 重新开始游戏方法restarGame():清空棋盘的棋子,用循环实现,将存放棋盘的数组每个元素allChess[i][j] 变成 0。 将isblack重新赋值为true,表示黑棋先下,canPlay 重新赋值为true,表示重新开始;用repaint()刷新重画。代码如下;

public void restarGame(){

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] = 0;

chessY[i] = 0;

}

countX =0;

countY =0;

message = "黑方先行";

blackMessage = "无限制";

whiteMessage = "无限制";

blackTime = maxTime;

whileTime = maxTime;

isblack = true;

canPlay = true;

this.repaint();

}

  1. 判断输赢的函数方法 isWin():返回值类型为boolean,flag 作为标记,令flag起始值为false;count表示五子棋的个数,分别向上、下、左、右、左上、左下、右上、右下八个方向判断count是否大于5, 将flag变为true,游戏结束,输出是哪一方胜利。代码如下:

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 {

//判断纵向,x轴相同

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;

}

  1. 判断五子棋是否连成五子checkCount(): checkCount(int xChange , int yChenge ,int color)中,参数xChange ,  yChenge , color表示行走的坐标量。Color为1代表黑棋,2代表白棋,根据每次落子的位置,分别向上、下、左、右、左上、左下、右上、右下八个方向判断是否有相同颜色的棋子连成五子,如果成立,游戏就结束,并显示提示信息(如:黑方获胜),否则继续落子。代码如下
public int checkCount(int xChange , int yChenge ,int color){int count = 1;int tempX = xChange;int tempy = yChenge;  //临时变量i,保存初始值//全局变量x,y最初为鼠标点击的坐标,//经下棋方法已经将x,y的范围变成0-15(遍历整个棋盘,寻找相同颜色的棋子)//正方向while(x + xChange >=0 && x+xChange <15  && y+yChenge >=0 &&y+yChenge < 15 && color == allChess[x+xChange][y+yChenge]){count++;if(xChange != 0)xChange++;if(yChenge != 0 ){if(yChenge != 0){if(yChenge > 0) {yChenge++;}else {yChenge--;}}}}//反方向xChange = tempX;yChenge = tempy;   // 恢复初始值while(x-xChange >=0 && x-xChange <15 && y-yChenge >=0 &&y-yChenge <15 && color == allChess[x-xChange][y-yChenge]){count++;if(xChange != 0){xChange++;}if(yChenge != 0){if (yChenge > 0) {yChenge++;}else {yChenge--;}}}return count;}
  1. 图形功能函数:以下函数都在graphics中。
  1. setcolor(int color): 把当前画线颜色设置为color 所指定的颜色。
  2. drawLine:两个点画一条直线
  3. fillOval(int x,int y ,int width ,int  height):前 两个X 和 Y是矩形框的左上角的坐标,width和height是宽和高。画出实心椭圆
  4. drawString:写文字
  5. drawRect();画方框

repaint():具有刷新页面效果的方法,如果你要页面进行重画就可以调用.

相关内容

热门资讯

新华社快讯:韩国检方对尹锡悦、... 新华社快讯:负责调查韩国前第一夫人金建希案件的特检组29日发布最终调查结果,对包括前总统尹锡悦、金建...
巩固国家通用语言文字法律地位 本报记者 朱宁宁 我国第一部有关语言文字的专门法律——国家通用语言文字法完成首次大修。 2025年1...
甘肃“十五五”规划建议:加快构... 中共甘肃省委关于制定国民经济和社会发展第十五个五年规划的建议发布,其中提到,加快构建 房地产发展新模...
部署六大重点工作 2026年积... 来源:经济参考报 12月27日至28日在京召开的全国财政工作会议为2026年的财政工作划定了重点。会...
权威抚养权律师推荐:家理(深圳... 在抚养权纠纷中,当事人急需专业且靠谱的律师来维护自身权益。那么,资深抚养权律师哪个好,经验丰富的抚养...
四川拓宽法律援助范围 今年办理... “终于胜诉了!要是按以前的规定,我这种情况属于合同纠纷,不符合法律援助申请条件。”近日,来自自贡市的...
汽车早报|零跑汽车发布首款MP... 重庆追加汽车置换、汽车报废更新补贴 据重庆日报,重庆市商务委消息,为贯彻落实国家部委相关要求,扎实...
自贸试验区昆明片区发布一批区域... 12月26日,中国(云南)自贸试验区昆明片区举行制度创新专题新闻发布会,联合昆明综合保税区发布一批改...
原创 存... “钱存银行,50万以内绝对安全”。 这句话你一定听过,但很多人只知其一,不知其二。 2015年《存款...
美银CEO判断:特朗普关税政策... 智通财经获悉,美国银行首席执行官Brian Moynihan表示,尽管2025年的关税措施曾冲击美国...