运用二进制知识写扫雷小游戏

文章介绍了一种利用二进制知识来设计扫雷游戏的方法。通过一个Java类`ClearMineGame`,作者详细阐述了如何用二进制表示雷的位置、周围雷的数量以及游戏状态,并提供了埋雷、打开棋子、插旗等操作的逻辑。代码包括了一个二维数组来存储游戏状态,并有相应的游戏开始和结束条件。
摘要由CSDN通过智能技术生成

运用二进制知识写扫雷小游戏

前言

相信各位同学都玩过扫雷游戏,接下来我们来玩一玩扫雷code。我用的二进制知识表示雷的一些规则。以下是相关注释和代码。在这里插入图片描述

扫雷类代码块

package Demo1;

import java.util.Random;
import java.util.Scanner;


/**
 * 1.使用整形二维数组完成扫雷游戏1.是否为雷		2.周围雷的数量		3.状态:打开 未打开 插旗
 * 	ob0 xxxx xx x  ------
 * 		分成三组:
 * 			第一组:前四位  表示雷的数量 0001 表示一个雷 加一个雷的数量 0b00001000
 * 			第二组:中间两位 表示状态 00 未打开 10 插旗 01 打开
 * 			第三组:最后一位 表示雷 1 雷 0 没有雷
 * 2.埋雷成功
 * 		2.1随机一个点	判断该点是否已经埋雷	
 * 					已埋-》重新随机
 * 					未埋-》修改最后一位从0——》1
 * 					再以当前这个雷为中心,周围的八个点的雷数量+0b1000
 * 0-->0b0 0000 00 0
 * 1-->0b0 0000 00 1
 * 8-->0b0 0001 00 0	-->1
 * 16->0b0 0010 00 0	-->2
 * 17->0b0 0010 00 1
 * 24->0b0 0011 00 0	-->3
 * 32->0b0 0100 00 0
 * 25->0b0 0011 00 1
 * @author 86151
 *
 */


public class ClearMineGame {
int rows;//行长度
int cols;//列长度
int mineCount;//雷的数量
int pointCount;//未打开的棋子数量
int[][]mineBoard;
	//构造函数
	public ClearMineGame() {
		init();//初始化操作
	}
	//初始化操作
	public void init() {
		Scanner sc=new Scanner(System.in);
		int choice=0;
		System.out.println("******************欢迎进入扫雷游戏社区*******************");
		System.out.println("请选择游戏等级:1.初级		2.中级	3.高级");
		choice=sc.nextInt();
		switch (choice) {
		case 2:
			rows=16;
			cols=16;
			mineCount=40;
			break;
		case 3:
			rows=16;
			cols=30;
			mineCount=100;
		default:
			rows=9;
			cols=9;
			mineCount=10;
			break;
		}
		//创建二维数组
		mineBoard=new int[rows][cols];
		pointCount=rows*cols;
		burnMine();
	}
	//开始游戏
	public void startGame() {
		int choice=0;
		boolean flag=false;//标识游戏是否结束
		Scanner sc=new Scanner(System.in);
		showMineBoard2();
		System.out.println("请输入坐标(x,y):");
		int x=sc.nextInt()-1;
		int y=sc.nextInt()-1;
		do {
			System.out.println("请选择:1.打开	2.插旗	3.拔旗");
			choice=sc.nextInt();
			switch (choice) {
			case 1:
				flag=openPoint(x,y);
				break;
			case 2:
				insertFlag(x,y);
				break;
			case 3:
				delFlag(x,y);
				break;
			default:
				System.out.println("输入选项有误,请重新输入!");
				break;
			}
		}while(choice<1||choice>3);
		if(flag==false) {
			startGame();
		}else {
			System.out.println("游戏结束。。。。。");
		}
	}
	public void burnMine() {
		Random rd=new Random();
		for(int i=0;i<mineCount;) {
			int x=rd.nextInt(rows);
			int y=rd.nextInt(cols);
			//判断是否为雷
			if((mineBoard[x][y]&0b1)==1)
			{
				//是 重新循环
				continue;
			}
			//不是 埋雷的操作
			mineBoard[x][y]=mineBoard[x][y]|0b1;
			//以雷为中心,周围8个点雷的数量+1
			//上一行
			if(x-1>=0) {
				//左上角
			if(y-1>=0) {
				mineBoard[x-1][y-1]+=0b1000;
			}
			//右上角
			if(y+1<cols) {
				mineBoard[x-1][y+1]+=0b1000;
			}
			//正上方
			mineBoard[x-1][y]+=0b1000;
		}
			//下一行
			if(x+1<rows) {
				//左下角
				if(y-1>=0) {
					mineBoard[x+1][y-1]+=0b1000;
				}
				//右下角
				if (y+1<cols) {
					mineBoard[x+1][y+1]+=0b1000;
				}
				//正下方
				mineBoard[x+1][y]+=0b1000;
					
				}
			//同一行
			//左边点
			if (y-1>=0) {
				mineBoard[x][y-1]+=0b1000;
			}
			//右边点
			if (y+1<cols) {
				mineBoard[x][y+1]+=0b1000;
			}
			i++;//当埋雷成功再i++
		}
		}

	//拔旗
	public void delFlag(int x,int y) {
		if((mineBoard[x][y]&0b00000110)==0b100) {
			mineBoard[x][y]=mineBoard[x][y]&0b01111001;
			return;
		}
		System.out.println("没有插旗,不能进行拔旗操作!!");
		
	}
	//插旗
	public void insertFlag(int x,int y) {
		if((mineBoard[x][y]&0b00000110)==0b10) {
			System.out.println("棋子已打开,不能插旗!!");
			return;
		}
		if((mineBoard[x][y]&0b00000110)==0b100) {
			System.out.println("棋子已插旗,不能重复插旗!!");
			return;
		}
		mineBoard[x][y]=mineBoard[x][y]|0b100;
	}
	//打开棋子
	public boolean openPoint(int x, int y) {
		//1.判断是否为雷,结束游戏
		if((mineBoard[x][y]&0b1)==0b1) {
			//是雷  将所有的棋子打开
			for(int i=0;i<rows;i++) {
				for(int j=0;j<cols;j++) {
					//全部设置为未打开然后再设置为打开
					mineBoard[i][j]=(mineBoard[i][j]&0b01111001)|0b10;
				}
			}
			showMineBoard2();//再次显示所有的棋子
			return true;
		}else {
			//2.不是雷  数字  空白点(将周围的未打开且不是雷的点自动打开)
			openWhitePoint(x,y);
			//判断  剩余未打开的棋子数量==雷的数量 说明胜利 游戏结束
			if(pointCount==mineCount) {
				System.out.println("恭喜你,获胜了!!");
				return true;
			}
		}
		
		return false;
	}
	public void openWhitePoint(int x,int y) {
		int state=mineBoard[x][y];
		//1.是雷 2.已打开 3.插旗 不能去操作该点
		if((state&0b1)==0b1||(state&0b110)==0b010||(state&0b110)==0b100){
			return;
		}
		//设置为打开
		mineBoard[x][y]=mineBoard[x][y]|0b10;
		//未打开的点-1
		pointCount--;
		//判断当前这个点是否为空白点
		if((mineBoard[x][y]>>3)==0) {
			//说明是一个空白点,以空白点为中心,打开周围其他的点
			//上一行
			if(x-1>=0) {
				//左上角
			if(y-1>=0) {
				openWhitePoint(x-1,y-1);
			}
			//右上角
			if(y+1<cols) {
				openWhitePoint(x-1,y+1);
			}
			//正上方
			openWhitePoint(x-1,y);
		}
			//下一行
			if(x+1<rows) {
				//左下角
				if(y-1>=0) {
					openWhitePoint(x+1,y-1);
				}
				//右下角
				if (y+1<cols) {
					openWhitePoint(x+1,y+1);
				}
				//正下方
				openWhitePoint(x+1,y);
					
				}
			//同一行
			//左边点
			if (y-1>=0) {
				openWhitePoint(x,y-1);
			}
			//右边点
			if (y+1<cols) {
				openWhitePoint(x,y+1);
			}
		}
	}
	//显示棋盘,游戏中调用此方法
	public void showMineBoard2() {
		if(null==mineBoard) {
			return;
		}
		showCol();
		showXin();
		//mineBoard[0][0]=0b00010101;
		//mineBoard[0][1]=0b00010010;
		for(int i=0;i<rows;i++) {
			//输出行下标
			System.out.print((i+1)+"*\t");
			for(int j=0;j<cols;j++) {
				//未打开00
				if((mineBoard[i][j]&0b110)==0b0) {
					System.out.print("N\t");
				}
				//插旗
				else if ((mineBoard[i][j]&0b110)==0b100) {
					System.out.print("F\t");
				}else {//打开
				if((mineBoard[i][j]&0b1)==1) {
					System.out.print("M\t");
				}
				else {
					if((mineBoard[i][j]>>3)==0) {
						System.out.print(" \t");
					}
					else {
						System.out.print((mineBoard[i][j]>>3)+"\t");
						}
					}
				}
			}
			System.out.print("*"+(i+1));
			System.out.println();
		}
		showXin();
		showCol();
	}
	//显示列表号
	public void showCol() {
		for(int i=0;i<=cols;i++) {
			if(i==0) {
				System.out.print("\t");
			}else {
				System.out.print(i+"\t");
			}
		}
		System.out.println();
	}
	//显示*
	public void showXin() {
		for(int i=0;i<=cols;i++) {
			if(i==0) {
				System.out.print("\t");
			}else {
				System.out.print("*\t");
			}
		}
		System.out.println();
	}
}

扫雷测试类代码块

package Demo1;

public class ClearMineGameTest {
public static void main(String[] args) {
	ClearMineGame game=new ClearMineGame();
	game.startGame();
}
}

如果有什么疑问或者缺陷不足,还请不吝赐教。谢谢!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值