java课程期末设计-五子棋

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():具有刷新页面效果的方法,如果你要页面进行重画就可以调用.

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值