1. 掃雷演算法
我做了一個掃雷游戲。不過是C#的。如果你覺得有用的話可以給我發郵箱一個信息。我會給把程序給你回過去,包含源碼。不過演算法可能不是很優話
因為都是在大學的時候寫的。你要是覺得有用就發[email protected]
呵呵
2. 掃雷怎麼推理又怎麼計算
1、推理方法:
掃雷中的1,2,3,4代表在這個數字周圍的8個方塊里有地雷的數量,如是一就代表有一個;二就代表有2個。
如:對一條未挖開的方塊組成的邊,如果它旁邊的數字為「232」,則表示這三個數字旁邊的三個方塊都是地雷。
2、通常玩法是先亂點,點出一塊較大的無雷區域,再根據無雷區域邊上的數字判斷地雷的位置測出去,在你確定有地雷的方塊上點右鍵插上紅棋。
把全部的地雷上都正確的插上紅旗就可以贏。
3、計算方法就根據上述規則在游戲中自行嘗試。由於每次開始游戲後的雷的位置不同,所以需要多進行游戲,多摸索,只要掌握游戲方法就可以找出所有雷了。
掃雷口訣
一:基本定式不要忘。
二:滑鼠點擊不要快。
三:就近猜雷把心橫。
四:猜雷猜錯不要悔。
五:碰上好局不要慌。
3. 掃雷的程序
參照以下步驟就行了:
1.啟動「掃雷」小游戲。
2.在鍵盤上輸入「xyzzy」。
3.然後按住」shift「鍵大約一秒鍾。
4.現在雷區里哪個是雷哪個不是雷,一目瞭然,當滑鼠移到雷區的某個方塊時,注意看電腦屏幕的最左上角,如果左上角有一個小亮點顯示,證明不是雷,反之則是雷。
注意:在輸入xyzzy時並沒有提供輸出的窗口什麼的,只要打開掃雷游戲,再直接在鍵盤上輸字母,然後按shift鍵就可以了。
不一定非用那個
也可以點雙鍵
在已掃出的數字上
同時點兩個滑鼠鍵
周圍可能是雷的就出現啦!!
呵呵,只能幫你這么多了!!!!!
多多諒解!!!!!!
請參考
4. 掃雷點到空格時的演算法 跪求
從手工點開的這個空格進行處理,按上右下左或你自己定義的一個順序來判斷相應位置的格式是否是空格且未被點開,如果不是,則跳過,如果是,則將其自動點開,同時把這幾個位置加入隊列後續處理。
簡單的流程圖示意:
當前位置是空白位置?----否--->非空白的處理
|
|是
|
V
加入隊列
|
V
+--->隊列為空?-------->是--->結束
||
||否
||
|V
|第一個元素出隊
||
|V
|點開該元素所指的位置
||
|V
|上左下右的位置如果是空白且未點開則入隊
||
--------+
上面是非遞歸的方案,遞歸方案則更容易了:
偽代碼演算法描述如下:
Click(pos)//點開pos這個位置
{
//IsClicked()判斷是否是已經點開的格子
if(IsClicked(pos))
return;
//IsBlank()判斷是否是空白格子
if(!IsBlank(pos))
{
點開非空白格子的處理
}
//下面是點開空白格子的處理
ClickBlank(pos);
}
ClickBlank(pos)
{
if(!IsBlank(pos))
rerurn;
if(IsClicked(pos))
return;
//下面對四個方向的格子進行自動點開
//你需要計算四向的格子位置,無效的直接返回
ClickBlank(pos上面的格子);
ClickBlank(pos右面的格子);
ClickBlank(pos下面的格子);
ClickBlank(pos左面的格子);
}
5. J2ME掃雷演算法
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/*按扭類*/
class Bomb extends JButton
{
public int num_x,num_y; //第幾號方塊
public int BombRoundCount; //周圍雷數
public boolean isBomb; //是否為雷
public boolean isClicked; //是否被點擊
public int BombFlag; //探雷標記
public boolean isRight; //是否點擊右鍵
public Bomb(int x,int y)
{
BombFlag = 0;
num_x = x;
num_y = y;
BombRoundCount = 0;
isBomb = false;
isClicked = false;
isRight = false;
}
}
/*窗口及演算法實現類*/
class MainBomb extends JFrame implements ActionListener,MouseListener
{
public JTextField text;
public Label nowBomb,setBomb;
public int BlockNum,BombNum; //當前方塊數當前雷數
public Icon icon_bomb = new ImageIcon("Bomb.gif"); //踩雷
public Icon icon_bomb_big = new ImageIcon("bomb_big.gif"); //踩雷標記
public Icon icon_flag = new ImageIcon("flag.gif"); //雷標記
public Icon icon_question = new ImageIcon("question.gif"); //疑惑是否有雷
public JButton start = new JButton(" 開始 ");
public Panel MenuPamel = new Panel();
public Panel mainPanel = new Panel();
public Bomb[][] bombButton;
/*界面設計*/
public MainBomb()
{
super("掃雷 Aaron2004製作 2004.8 ");
BlockNum = 64;
BombNum = 10;
Container c=getContentPane();
c.setBackground(Color.gray);
c.setLayout(new BorderLayout());
text=new JTextField("10 ",3);
nowBomb = new Label("當前雷數"+" "+BombNum+"");
setBomb= new Label("設置地雷數");
start.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
BombNum = Integer.parseInt(text.getText().trim());
if(BombNum >= 10 && BombNum < 50 )
replay();
else
{
JOptionPane msg = new JOptionPane();
JOptionPane.showMessageDialog(null,"您設置的地雷數太多了,請重設!","錯誤",2);
}
}
} );
MenuPamel.add(setBomb);
MenuPamel.add(text);
MenuPamel.add(start);
MenuPamel.add(nowBomb);
c.add(MenuPamel,"North");
mainPanel.setLayout(new GridLayout( (int)Math.sqrt(BlockNum) , (int)Math.sqrt(BlockNum)) );
bombButton=new Bomb[ (int)Math.sqrt(BlockNum) ][];
for(int i = 0 ; i < (int)Math.sqrt(BlockNum) ; i++)
{
bombButton[ i ]=new Bomb[ (int)Math.sqrt(BlockNum) ];
}
for(int i = 0 ; i < (int)Math.sqrt(BlockNum) ; i++ )
for(int j = 0 ; j < (int)Math.sqrt(BlockNum) ; j++ )
{
bombButton[ i ][ j ]=new Bomb(i,j);
bombButton[ i ][ j ].setForeground( Color.gray);
bombButton[ i ][ j ].addActionListener(this);
bombButton[ i ][ j ].addMouseListener(this);
}
for(int i = 0 ; i < (int)Math.sqrt(BlockNum) ; i++ )
for(int j = 0 ; j < (int)Math.sqrt(BlockNum) ; j++ )
mainPanel.add(bombButton[ i ][ j ]);
c.add(mainPanel,"Center");
startBomb();
setSize(400,400);
setLocation(350,200);
setResizable(false);
}
/*布雷*/
public void startBomb()
{
for(int i=0;i<BombNum;i++)
{
int x =(int)(Math.random()*(int)(Math.sqrt(BlockNum)-1));
int y =(int)(Math.random()*(int)(Math.sqrt(BlockNum)-1));
if(bombButton[ x ][ y ].isBomb==true)
i--;
else
bombButton[ x ][ y ].isBomb=true ;
}
}
/*重新開始*/
public void replay()
{
nowBomb.setText("當前雷數"+" "+BombNum+"");
for(int i = 0 ; i < (int)Math.sqrt(BlockNum) ; i++)
for(int j = 0 ; j < (int)Math.sqrt(BlockNum) ; j++)
{
bombButton[ i ][ j ].isBomb=false;
bombButton[ i ][ j ].isClicked=false;
bombButton[ i ][ j ].setEnabled(true);
bombButton[ i ][ j ].setText("");
bombButton[ i ][ j ].setIcon(null);
}
startBomb();
}
/*是否挖完了所有的雷*/
public void isWin()
{
int findBomb=0; //找到的地雷數
for(int i = 0;i < (int)Math.sqrt(BlockNum) ; i++)
for(int j = 0;j < (int)Math.sqrt(BlockNum ); j++)
{
if(bombButton[ i ][ j ].isBomb == true && bombButton[ i ][ j ].isRight == true)
findBomb++;
}
if( findBomb == Integer.parseInt(text.getText().trim()) )
{
JOptionPane msg = new JOptionPane();
JOptionPane.showMessageDialog(this,"您挖完了所有的雷,您勝利了!","您勝利了",2);
}
}
/*計算方塊周圍雷數 */
public void CountRoundBomb()
{
for (int i = 0; i < (int)Math.sqrt(BlockNum); i++) {
for (int j = 0; j < (int)Math.sqrt(BlockNum); j++) {
int count = 0;
//當需要檢測的單元格本身無地雷的情況下,統計周圍的地雷個數
if (bombButton[ i ][ j ].isBomb != true) {
if ( (i - 1 >= 0) && (j - 1 >= 0)) {
if (bombButton[i - 1][j - 1].isBomb == true) {
count += 1; //檢測左上方空格是否是地雷
}
}
if ( (i - 1 >= 0)) {
if (bombButton[i - 1][ j ].isBomb == true) {
count += 1; //檢測上方空格是否為地雷
}
}
if ( (i - 1 >= 0) && (j + 1 <= (int)Math.sqrt(BlockNum)-1)) {
if (bombButton[i - 1][j + 1] .isBomb == true) {
count += 1; //檢測右上方是否為地雷
}
}
if ( (j - 1 >= 0)) {
if (bombButton[ i ][j - 1] .isBomb == true) {
count += 1; //檢測左邊是否為地雷
}
}
if ( (i >= 0) && (j + 1 <= (int)Math.sqrt(BlockNum)-1)) {
if (bombButton[ i ][j + 1].isBomb == true) {
count += 1; //右邊
}
}
if ( (j - 1 >= 0) && (i + 1 <= (int)Math.sqrt(BlockNum)-1)) {
if (bombButton[i + 1][j - 1].isBomb == true) {
count += 1; //左下
}
}
if ( (i + 1 <= (int)Math.sqrt(BlockNum)-1)) {
if (bombButton[i + 1][ j ].isBomb == true) {
count += 1; //下
}
}
if ( (j + 1 <= (int)Math.sqrt(BlockNum)-1) && (i + 1 <= Math.sqrt(BlockNum)-1)) {
if (bombButton[i + 1][j + 1].isBomb == true) {
count += 1; //右下
}
}
bombButton[ i ][ j ].BombRoundCount = count;
}
}
}
}
/**當選中的位置為空,則翻開周圍的地圖**/
public void isNull(Bomb[][] bombButton,Bomb ClickecButton)
{
int i,j;
i=ClickecButton.num_x;
j=ClickecButton.num_y;
if (ClickecButton.isBomb==true) {
}
else {
if ( (i - 1 >= 0) && (j - 1 >= 0)) { //檢測左上方空格是否是空
if (bombButton[i - 1][j - 1].isBomb == false && bombButton[i - 1][j - 1].isClicked == false && bombButton[i - 1][j - 1].isRight == false) {
bombButton[i - 1][j - 1].setText((bombButton[i - 1][j - 1].BombRoundCount)+"");
bombButton[i - 1][j - 1].setEnabled(false);
bombButton[i - 1][j - 1].isClicked=true;
}
}
if ( (i - 1 >= 0)) { //檢測上方空格是否為空
if (bombButton[i - 1][ j ] .isBomb == false && bombButton[i - 1][ j ].isClicked == false && bombButton[i - 1][ j ].isRight == false) {
bombButton[i - 1][ j ].setText((bombButton[i - 1][ j ].BombRoundCount)+"");
bombButton[i - 1][ j ].setEnabled(false);
bombButton[i - 1][ j ].isClicked=true;
}
}
if ( (i - 1 >= 0) && (j + 1 <= ((int)Math.sqrt(BlockNum)-1)) ) { //檢測右上方是否為空
if (bombButton[i - 1][j + 1] .isBomb == false && bombButton[i - 1][j + 1].isClicked == false && bombButton[i - 1][j + 1].isRight == false) {
bombButton[i - 1][j + 1].setText((bombButton[i - 1][j + 1].BombRoundCount)+"");
bombButton[i - 1][j + 1].setEnabled(false);
bombButton[i - 1][j + 1].isClicked=true;
}
}
if ( (j - 1 >= 0)) { //檢測左邊是否為空
if (bombButton[ i ][j - 1].isBomb == false && bombButton[ i ][j - 1].isClicked == false && bombButton[ i ][j - 1].isRight == false) {
bombButton[ i ][j - 1].setText((bombButton[ i ][j - 1].BombRoundCount)+"");
bombButton[ i ][j - 1].setEnabled(false);
bombButton[ i ][j - 1].isClicked=true;
}
}
if ( (i >= 0) && (j + 1 <= ((int)Math.sqrt(BlockNum)-1)) ) { //檢測右邊空格是否是空
if (bombButton[ i ][j + 1].isBomb == false && bombButton[ i ][j + 1].isClicked == false && bombButton[ i ][j + 1].isRight == false) {
bombButton[ i ][j + 1].setText((bombButton[ i ][j + 1].BombRoundCount)+"");
bombButton[ i ][j + 1].setEnabled(false);
bombButton[ i ][j + 1].isClicked=true;
}
}
if ( (j - 1 >= 0) && (i + 1 <= ((int)Math.sqrt(BlockNum)-1)) ) { //檢測左下空格是否是空
if (bombButton[i + 1][j - 1].isBomb == false && bombButton[i + 1][j - 1].isClicked == false && bombButton[i + 1][j - 1].isRight == false) {
bombButton[i + 1][j - 1].setText((bombButton[i + 1][j - 1].BombRoundCount)+"");
bombButton[i + 1][j - 1].setEnabled(false);
bombButton[i + 1][j - 1].isClicked=true;
}
}
if ( (i + 1 <= ((int)Math.sqrt(BlockNum)-1)) ) { //檢測下邊空格是否是空
if (bombButton[i + 1][ j ].isBomb == false && bombButton[i + 1][ j ].isClicked == false && bombButton[i + 1][ j ].isRight == false) {
bombButton[i + 1][ j ].setText((bombButton[i + 1][ j ].BombRoundCount)+"");
bombButton[i + 1][ j ].setEnabled(false);
bombButton[i + 1][ j ].isClicked=true;
}
}
if ( (j + 1 <= ((int)Math.sqrt(BlockNum)-1) ) && (i + 1 <= ((int)Math.sqrt(BlockNum)-1)) ) { //檢測右下邊空格是否是空
if (bombButton[i + 1][j + 1].isBomb == false && bombButton[i + 1][j + 1].isClicked == false && bombButton[i + 1][j + 1].isRight == false) {
bombButton[i + 1][j + 1].setText((bombButton[i + 1][j + 1].BombRoundCount)+"");
bombButton[i + 1][j + 1].setEnabled(false);
bombButton[i + 1][j + 1].isClicked=true;
}
}
if ( (i - 1 >= 0) && (j - 1 >= 0))//檢測左上
isNull(bombButton,bombButton[i - 1][j - 1]);
if ( (i - 1 >= 0))
isNull( bombButton,bombButton[i - 1][ j ]);//檢測上方
if ( (i - 1 >= 0) && (j + 1 <= (int)Math.sqrt(BlockNum)-1))
isNull( bombButton,bombButton[i - 1][j + 1]);//檢測右上
if ( (j - 1 >= 0))
isNull(bombButton,bombButton[i][j - 1]);//檢測左邊
if ( (i >= 0) && (j + 1 <= ((int)Math.sqrt(BlockNum)-1)) )
isNull(bombButton,bombButton[i][j + 1]);//檢測右邊
if ( (j - 1 >= 0) && (i + 1 <= ((int)Math.sqrt(BlockNum)-1)) )
isNull(bombButton,bombButton[i + 1][j - 1]); //檢測左下
if ( (i + 1 <= ((int)Math.sqrt(BlockNum)-1)) ) //檢測下
isNull(bombButton,bombButton[i + 1][ j ]);
if ( (j + 1 <= ((int)Math.sqrt(BlockNum)-1)) && (i + 1 <= ((int)Math.sqrt(BlockNum)-1)) ) //檢測右下
isNull(bombButton,bombButton[i + 1][j + 1]);
}
}
public void actionPerformed(ActionEvent e)
{
CountRoundBomb();
if(((Bomb)e.getSource()).isBomb==false && ((Bomb)e.getSource()).isClicked == false)
{
((Bomb)e.getSource()).setText(( ((Bomb)e.getSource()).BombRoundCount )+"");
((Bomb)e.getSource()).isClicked=true;
((Bomb)e.getSource()).setIcon(null);
((Bomb)e.getSource()).setEnabled(false);
if((((Bomb)e.getSource()).BombRoundCount) == 0)
isNull(bombButton,(Bomb)e.getSource());
isWin();
}
else if(((Bomb)e.getSource()).isBomb == true)
{
for(int i=0;i<(int)Math.sqrt(BlockNum);i++)
for(int j=0;j<(int)Math.sqrt(BlockNum);j++)
{
if(bombButton[ i ][ j ].isBomb == true)
bombButton[ i ][ j ].setIcon(icon_bomb);
}
((Bomb)e.getSource()).setIcon(icon_bomb_big);
JOptionPane msg = new JOptionPane();
JOptionPane.showMessageDialog(this,"你踩到地雷了,按確定重來","你踩到地雷了",2);
replay();
}
}
public void mouseClicked(MouseEvent e)
{
Bomb bombSource = (Bomb)e.getSource();
boolean right = SwingUtilities.isRightMouseButton(e);
if((right == true) && (bombSource.isClicked == false))
{
bombSource.BombFlag = (bombSource.BombFlag + 1)%3;
if(bombSource.BombFlag == 1)
{
if(BombNum > 0 && bombSource.isRight == false ){
bombSource.setIcon(icon_flag);
bombSource.isRight = true;
BombNum--;
}
isWin();
nowBomb.setText("當前雷數"+" "+BombNum+"");
}
else if(bombSource.BombFlag == 2)
{
if( (BombNum !=0 ) ||(BombNum ==0 &&(bombSource.getIcon()==icon_flag)) )
BombNum++;
bombSource.setIcon(icon_question);
nowBomb.setText("當前雷數"+" "+BombNum+"");
}
else if(bombSource.BombFlag == 0)
{
bombSource.setIcon(null);
bombSource.isRight = false;
}
}
}
public void mouseEntered(MouseEvent e)
{}
public void mouseReleased(MouseEvent e)
{}
public void mouseExited(MouseEvent e)
{}
public void mousePressed(MouseEvent e)
{}
}
/*主類*/
public class Main
{
public static void main(String args[])
{
(new MainBomb()).show();
}
}
6. 關於編程,掃雷的演算法問題,求教~~~
點下去空白自動出現可以根據遞歸來算,找每個格子周圍是否有空白,有就遞歸。。。
7. 游戲掃雷有一種演算法能分析出哪個是雷,是怎麼算的
呵呵
這個要自己玩多次後就慢慢會算了比如2就代表旁邊的格子有兩個,誰也不知道在哪,只有依據周圍的數字來定個大概
8. java掃雷遞歸演算法
在掃雷游戲中,如何實現使Field處於打開狀態。如果它是地雷,打開所有Field;如果它不是地雷,並且它四周也沒有地雷,將其四周Field也打開。
//雷的數目如果是0,可以打開當前Field四周的Field
if (getField(x, y).getMineValue() == 0) {
List<Field> arroundList = getAround(x, y);
for (Field field : arroundList) {
//遞歸調用open方法,
open(field.getX(), field.getY());
}
}
Open方法指的就是你指定的打開方法,這里通過0或者數字1來定義是否為雷,如果是1則是
雷。希望能提示到你。主要就是使用到啦增強型for循環
9. 掃雷演算法時間復雜度是多少
演算法復雜度,可分為時間復雜度,以及空間復雜度,
時間復雜度根據執行程序的時間,時間越長復雜度越高,
空間復雜度是根據所佔內存的大小來確定,佔用空間越多,空間復雜度越高
所以你這問題問的太籠統,掃雷演算法又不止一種,有好的演算法,也有不好的
10. 掃雷中佈雷的演算法
首先,你要先定義一個n*n的二維數組,該數組的i-1到i+1,j-1到j+1除去i,j本身。值為周圍有幾個雷。如果該數組的值為10則本身是雷。
接著,你自動生成m個雷,讓這m個雷分布在界面上。被選中的值i,j點的值為10,從i-1到i+1,從j-1到j+1的值都+1;
第三,在界面上想辦法區分出n*n個格子,然後把格子的坐標和二維數組關聯起來