java實現掃雷+AI自動掃雷策略及實現

最近打算入門一下java,寫個小程序練下手,由於平時沒事喜歡玩幾把掃雷,就寫個AI玩玩吧。。

java實現掃雷遊戲網上代碼比較多,這裏不多說了,主要記錄一下自己實現的一個自動掃雷策略。

根據掃雷的規則:一個數字x意味着其所在格子旁邊的8個格子中有x個雷。那麼我一共爲電腦設了3步策略;

第一步:存在局部解的情況,即一個數字x,周圍的空格子數y,周圍已經確定是雷的格子數z,x,y,z的數字關係滿足一定條件可以推出旁邊的空格子是雷還是空。

第二步:如果第一步無解,則考慮第二步。如果找不到局部解,我們就根據多個數字之間的關係來確定空格子是雷還是空,想讓這些數字建立起關係的方式就是根據每個數字,將其周圍的8個格子分別設一個未知數,如果是雷我們讓解爲1,如果是空解就爲0,這樣可以連立出一個線性方程組,那麼只要解出這個線性方程組,高斯消元一下,就可以做出決策。注意這裏出現多解是很有可能的事,這裏有一個不可忽略的條件,任意未知數只能爲0或1。

第三步:如果第二步無解,則考慮第三步。隨便點一個。。。

當然,在做第三步決策之前,完全可以根據解的概率分佈(相對隨機來說)大概率的做出一個正確解,而不是完全隨機點一個。但是水平有限,高級的話複雜度可能有點高,時間有限,就沒細想了。

做了1000局的實驗,初級勝率81%(1000/810),中級勝率81.2%(1000/812),高級23.8%(1000/238)。


附上所有class的代碼。


class boomInitialization:


package HBoom;

import java.util.Random;
import HBoom.Station;

public class boomInitialization {
	
	protected Station[][] Array;
	protected int[] blockX;
	protected int[] blockY;
	protected static int blockNum;
	protected static int currentBlockNum;
	private static int blockAround;
	private static int newX;
	private static int newY;
	public boomInitialization(int X, int Y, int N) {
		blockNum = 0;
		currentBlockNum = 0;
		Array = new Station[X + 1][Y + 1];
		blockX = new int[N];
		blockY = new int[N];
		blockNum = N;
		
		for(int i = 1; i <= X; ++i) {
			for(int j = 1; j <= Y; ++j) {
				Array[i][j] = Station.zero;
			}
		}
		
		Random blockCreator = new Random();
		while(currentBlockNum < blockNum) {
			newX = blockCreator.nextInt(X) + 1;
			newY = blockCreator.nextInt(Y) + 1;
            if(Judge(newX, newY)){
            	Array[newX][newY] = Station.block;
            	blockX[currentBlockNum] = newX;
            	blockY[currentBlockNum] = newY;
            	currentBlockNum++;
            }
		}
		//counting numbers
		for(int i = 1; i <= X; ++i) {
			for(int j = 1; j <= Y; ++j) {
				if(Array[i][j] != Station.block) {
					blockAround = 0;
					if(i - 1 >= 1 && j - 1 >= 1) {
						if(Array[i - 1][j - 1] == Station.block) {
							blockAround++;
						}
					}
					if(i - 1 >= 1) {
						if(Array[i - 1][j] == Station.block) {
							blockAround++;
						}
					}
					if(i - 1 >= 1 && j + 1 <= Y) {
						if(Array[i - 1][j + 1] == Station.block) {
							blockAround++;
						}
					}
					if(j - 1 >= 1) {
						if(Array[i][j - 1] == Station.block) {
							blockAround++;
						}
					}
					if(j + 1 <= Y) {
						if(Array[i][j + 1] == Station.block) {
							blockAround++;
						}
					}
					if(i + 1 <= X && j - 1 >= 1) {
						if(Array[i + 1][j - 1] == Station.block) {
							blockAround++;
						}
					}
					if(i + 1 <= X) {
						if(Array[i + 1][j] == Station.block) {
							blockAround++;
						}
					}
					if(i + 1 <= X && j + 1 <= Y) {
						if(Array[i + 1][j + 1] == Station.block) {
							blockAround++;
						}
					}
					switch (blockAround) {
					case 0:
						Array[i][j] = Station.zero;
						break;
					case 1:
						Array[i][j] = Station.one;
						break;
					case 2:
						Array[i][j] = Station.two;
						break;
					case 3:
						Array[i][j] = Station.three;
						break;
					case 4:
						Array[i][j] = Station.four;
						break;
					case 5:
						Array[i][j] = Station.five;
						break;
					case 6:
						Array[i][j] = Station.six;
						break;
					case 7:
						Array[i][j] = Station.seven;
						break;
					}
				}
			}
		}
	}
	private boolean Judge(int X, int Y) {
		if(Array[X][Y] == Station.block) {
			return false;
		}
		return true;
	}
}


class HBoom:


package HBoom;

import java.util.Random;

public class HBoom {
	public static void main(String[] args) {
		mainWin HB = mainWin.getInstance();	
	}
}


class mainJPanel:


package HBoom;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;

import javax.swing.*;

import HBoom.boomInitialization;
import HBoom.Station;

public class mainJPanel extends JPanel{
	private JPanel[][] m_panel;
	private JLabel[][] m_label;
	private JButton[][] m_button;
	private JLabel[][] m_flag;
	private JLabel[][] m_correctFlag;
	private int X;
	private int Y;
	private int blockNum;
	private boolean play;
	private Station[][] Array;
	private Station[][] currentArray;
	private static boolean result;
	
	public mainJPanel(Station[][] Array, int X, int Y,  int N) {
		this.X = X;
		this.Y = Y;
		this.Array = Array;
		this.blockNum = N;
		this.currentArray = new Station[X + 1][Y + 1];
		this.play = true;
		
		for(int i = 1; i <= X; ++i) {
			for(int j = 1; j <= Y; ++j) {
				this.currentArray[i][j] = Station.unknown;
			}
		}
		this.setLayout(new GridLayout(X, Y, 0, 0));
		m_panel = new JPanel[X + 1][Y + 1];
		m_label = new JLabel[X + 1][Y + 1];
		m_button = new JButton[X + 1][Y + 1];
		m_flag = new JLabel[X + 1][Y + 1];
		m_correctFlag = new JLabel[X + 1][Y + 1];
		
		for(int i = 1; i <= X; ++i) {
			for(int j = 1; j <= Y; ++j) {
				m_panel[i][j] = new JPanel();
				m_panel[i][j].setLayout(new CardLayout());
				m_button[i][j] = new JButton();
				m_button[i][j].setBorder(BorderFactory.createRaisedBevelBorder());
				m_panel[i][j].add(m_button[i][j], "card1");
				
				m_button[i][j].addMouseListener(new MouseListener() {
					@Override
					public void mouseClicked(MouseEvent e) {
						for(int i = 1; i <= X; ++i) {
							for(int j = 1; j <= Y; ++j) {
								if(e.getSource() == m_button[i][j]) {
									if(e.getButton() == MouseEvent.BUTTON1) {
										solveLeftButtonEvents(i, j);
									}
									if(e.getButton() == MouseEvent.BUTTON3) {
										solveRightButtonEvents(i, j);
									}
								}
							}
						}
					}
					@Override
					public void mouseEntered(MouseEvent e) {}
					@Override
					public void mouseExited(MouseEvent e) {}
					@Override
					public void mousePressed(MouseEvent e) {}
					@Override
					public void mouseReleased(MouseEvent arg0) {}
				});
				
				m_label[i][j] = new JLabel();
				m_label[i][j].setBorder(BorderFactory.createLoweredBevelBorder());//設置JLabel顯示爲凹下去,便於美觀
				m_label[i][j].setFont(new java.awt.Font("微軟雅黑", 1, 14));
				
				
				m_flag[i][j] = new JLabel();
				m_flag[i][j].setBorder(BorderFactory.createLoweredBevelBorder());
				ImageIcon img = new ImageIcon("./src/img/flag.jpg");
				m_flag[i][j].setIcon(img);
				
				m_correctFlag[i][j] = new JLabel();
				m_correctFlag[i][j].setBorder(BorderFactory.createLoweredBevelBorder());
				img = new ImageIcon("./src/img/flag2.jpg");
				m_correctFlag[i][j].setIcon(img);
				
				m_flag[i][j].addMouseListener(new MouseListener() {
					@Override
					public void mouseClicked(MouseEvent e) {
						for(int i = 1; i <= X; ++i) {
							for(int j = 1; j <= Y; ++j) {
								if(e.getSource() == m_flag[i][j]) {
									if(e.getButton() == MouseEvent.BUTTON3) {
										solveRightButtonEvents(i, j);
									}
								}
							}
						}	
					}
					@Override
					public void mouseEntered(MouseEvent e) {}
					@Override
					public void mouseExited(MouseEvent e) {}
					@Override
					public void mousePressed(MouseEvent e) {}
					@Override
					public void mouseReleased(MouseEvent e) {}
				});
				if(Array[i][j] == Station.block){
					img = new ImageIcon("./src/img/boom.jpg");
					m_label[i][j].setIcon(img);
                }//若爲雷則顯示地雷圖片
                else if(Array[i][j] == Station.zero){
                	m_label[i][j].setText("");
                }
                else{
                	switch(Array[i][j]) {
                	default:
                		System.out.println("Error");
                		break;
                	case one:
                		m_label[i][j].setForeground(Color.BLUE);
                		m_label[i][j].setText("1");
                		break;
                	case two:
                		m_label[i][j].setForeground(Color.ORANGE);
                		m_label[i][j].setText("2");
                		break;
                	case three:
                		m_label[i][j].setForeground(Color.RED);
                		m_label[i][j].setText("3");
                		break;
                	case four:
                		m_label[i][j].setForeground(Color.cyan);
                		m_label[i][j].setText("4");
                		break;
                	case five:
                		m_label[i][j].setForeground(Color.BLACK);
                		m_label[i][j].setText("5");
                		break;
                	case six:
                		m_label[i][j].setForeground(Color.MAGENTA);
                		m_label[i][j].setText("6");
                		break;
                	case seven:
                		m_label[i][j].setForeground(Color.DARK_GRAY);
                		m_label[i][j].setText("7");
                		break;
                	}
                }//若爲周圍雷的個數則設置每個數字的顏色不同
				m_panel[i][j].add(m_label[i][j], "card2");
				m_panel[i][j].add(m_flag[i][j], "card3");
				m_panel[i][j].add(m_correctFlag[i][j], "card4");
                this.add(m_panel[i][j]);
			}
		}		
	}
	
	public void solveLeftButtonEvents(int x, int y) {
		if(Array[x][y] == Station.block) {
			System.out.println("you lose");
			result = false;
			gameOver();
			return;
		}
		else if(Array[x][y] == Station.zero){
			CardLayout clayout = (CardLayout) m_panel[x][y].getLayout();
			clayout.show(m_panel[x][y], "card2");
			dfsForAutoClick(x, y);
		}
		else {
			CardLayout clayout = (CardLayout) m_panel[x][y].getLayout();
			clayout.show(m_panel[x][y], "card2");
			currentArray[x][y] = Array[x][y];
		}
		check();
	}
	
	public int check() {
		int currentVisited = 0;
		for(int i = 1; i <= X; ++i) {
			for(int j = 1; j <= Y; ++j) {
				if(currentArray[i][j] != Station.unknown && currentArray[i][j] != Station.block) {
					currentVisited++;
				}
			}
		}
		if(currentVisited == X * Y - blockNum) {
			System.out.println("you win");
			result = true;
			this.play = false;
		}
		return currentVisited;
	}
	
	public void solveDFSpoint(int x, int y) {
		if(currentArray[x][y] != Station.unknown) {
			return;
		}
		if(Array[x][y] == Station.zero) {
			CardLayout clayout = (CardLayout) m_panel[x][y].getLayout();
			clayout.show(m_panel[x][y], "card2");
			dfsForAutoClick(x, y);
		}
		else {
			CardLayout clayout = (CardLayout) m_panel[x][y].getLayout();
			clayout.show(m_panel[x][y], "card2");
			currentArray[x][y] = Array[x][y];
		}
	}
	
	public void dfsForAutoClick(int x, int y) {
		currentArray[x][y] = Array[x][y];
		if(x - 1 >= 1 && y - 1 >= 1) {
			solveDFSpoint(x - 1, y - 1);
		}
		if(x - 1 >= 1) {
			solveDFSpoint(x - 1, y);
		}
		if(x - 1 >= 1 && y + 1 <= Y) {
			solveDFSpoint(x - 1, y + 1);
		}
		if(y - 1 >= 1) {
			solveDFSpoint(x, y - 1);
		}
		if(y + 1 <= Y) {
			solveDFSpoint(x, y + 1);
		}
		if(x + 1 <= X && y - 1 >= 1) {
			solveDFSpoint(x + 1, y - 1);
		}
		if(x + 1 <= X) {
			solveDFSpoint(x + 1, y);
		}
		if(x + 1 <= X && y + 1 <= Y) {
			solveDFSpoint(x + 1, y + 1);
		}
	}
	
	public void solveRightButtonEvents(int x, int y) {
		CardLayout clayout = (CardLayout) m_panel[x][y].getLayout();
		if(currentArray[x][y] == Station.block) {
			currentArray[x][y] = Station.unknown;
			clayout.show(m_panel[x][y], "card1");
		}
		else {
			currentArray[x][y] = Station.block;
			clayout.show(m_panel[x][y], "card3");
		}
	}

	public void gameOver() {
		this.play = false;
		for(int i = 1; i <= X; ++i) {
			for(int j = 1; j <= Y; ++j) {
				if(Array[i][j] == Station.block && currentArray[i][j] == Station.block) {
					CardLayout clayout = (CardLayout) m_panel[i][j].getLayout();
					clayout.show(m_panel[i][j], "card4");
				}
				if(Array[i][j] == Station.block && currentArray[i][j] != Station.block){
					CardLayout clayout = (CardLayout) m_panel[i][j].getLayout();
					clayout.show(m_panel[i][j], "card2");
				}
				m_button[i][j].setEnabled(false);
			}
		}
	}
	public boolean isPlaying() {
		return this.play;
	}
	public Station[][] getCurrentArray(){
		return currentArray;
	}
	public void setcurrentArray(int x, int y, Station cur) {
		currentArray[x][y] = cur;
	}
	public void first(int X, int Y) {
		for(int i = 1; i <= X; ++i) {
			for(int j = 1; j <= Y; ++j) {
				CardLayout clayout = (CardLayout) m_panel[i][j].getLayout();
				clayout.first(m_panel[i][j]);
			}
		}
	}
	public boolean getResult() {
		return this.result;
	}
	public void clear() {
		for(int i = 1; i <= X; ++i) {
			for(int j = 1; j <= Y; ++j) {
				m_panel[i][j].remove(m_button[i][j]);
				m_panel[i][j].remove(m_flag[i][j]);
				m_panel[i][j].remove(m_label[i][j]);
				this.remove(m_panel[i][j]);
			}
		}
	}
}



class mainWin:


package HBoom;

import javax.swing.*;


import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class mainWin extends JFrame{
	private static mainWin m_instance;
	private static int X = 16;//8 * 8 10, 16 * 16 40, 30 * 16 99.
	private static int Y = 30;
	private static int N = 99;
	private static boolean result;
	private static int steps;
	
	JButton button_restart;
	JPanel panel_mainWin;
	JPanel panel_north;
	mainJPanel panel_block;
	boomInitialization block;
	JLabel label_station;
	JPanel panel_station;
	JButton button_robot;
	
	public static mainWin getInstance() {
		if(m_instance == null) {
			m_instance = new mainWin();
		}
		return m_instance;
	}
	public mainJPanel getPanel_block() {
		return this.panel_block;
	}
	public void setArrayX(int X) {
		this.X = X;
		restart();
	}
	public void setArrayY(int Y) {
		this.Y = Y;
		restart();
	}
	public void setBlockN(int N) {
		this.N = N;
		restart();
	}
	public int getArrayX() {
		return this.X;
	}
	public int getArrayY() {
		return this.Y;
	}
	public int getN(){
		return this.N;
	}
	private mainWin() {
		String UI = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
        try {
            UIManager.setLookAndFeel(UI);
        } catch(Exception e){
            e.printStackTrace();
        }//設置整個面板顯示格式
        block = new boomInitialization(X, Y, N);
        button_restart = new JButton("Restart");
        button_robot = new JButton("robot Go!!!");
        
        panel_block = new mainJPanel(block.Array, X, Y, N);
        panel_mainWin = new JPanel();
        panel_north = new JPanel();
        panel_north.setLayout(new GridLayout());
        panel_mainWin.setLayout(new BorderLayout());
        
        label_station = new JLabel();
        ImageIcon img = new ImageIcon("./src/img/lose.jpg");
		label_station.setIcon(img);
		label_station.setBorder(BorderFactory.createLoweredBevelBorder());
		
		panel_station = new JPanel();
		panel_station.setLayout(new CardLayout());
		panel_station.add(label_station, "card1");
		
        button_restart.addActionListener(new ActionListener() {
        	@Override
        	public void actionPerformed(ActionEvent e) {
        		if(e.getSource() == button_restart) {
        			restart();
        		}
        	}
        });
        
        button_robot.addActionListener(new ActionListener() {
			@Override
        	public void actionPerformed(ActionEvent e) {
        		if(e.getSource() == button_robot) {
        			Robotplayer hmc = new Robotplayer(X, Y);
        			m_instance.steps = hmc.getSteps();
        		}
        	}
        });
        
        panel_north.add(button_restart);
        panel_north.add(button_robot);
        panel_mainWin.add(panel_block, BorderLayout.CENTER);
        panel_mainWin.add(panel_north ,BorderLayout.NORTH);
        this.add(panel_mainWin);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle("hmc");
        this.setBounds(100, 100, 600, 360);
        this.setResizable(false);
        this.setVisible(true);
	}
	public void restart() {
		panel_block.clear();
        panel_mainWin.remove(panel_block);
        block = new boomInitialization(X, Y, N);
        panel_block = new mainJPanel(block.Array, X, Y, N);
        panel_block.first(X, Y);
        panel_mainWin.add(panel_block, BorderLayout.CENTER);
        panel_mainWin.revalidate();//刷新整個面板
	}
	public void robotgo() {
		Robotplayer hmc = new Robotplayer(X, Y);
		result = hmc.getResult();
		this.steps = hmc.getSteps();
	}
	public boolean getResult() {
		return this.result;
	}
	public int getSteps() {
		return this.steps;
	}
}


class Robotplayer:


package HBoom;

import java.util.Random;

public class Robotplayer {
	private Station[][] currentArray;
	private static int X;
	private static int Y;
	private static int tot;
	private boolean play = true;
	private int blockAround;   
	private int blankAreaAround;
	private int totalAreaAround;
	private int blockFoundAround;
	private double[][] Matrix;
	private static int currentRow;
	private static int currentCol;
	private static double eps = 1e-10;
	private static boolean result;
	private static int steps;
	
	public Robotplayer(int X, int Y) {
		this.X = X;
		this.Y = Y;
		steps = 0;
		currentArray = new Station[X + 1][Y + 1];
		for(int i = 1; i <= X; ++i) {
			for(int j = 1; j <= Y; ++j) {
				currentArray[i][j] = Station.unknown;
			}
		}
		while(play == true) {
			robotplay();
			steps++;
		}
		this.result = mainWin.getInstance().panel_block.getResult();
	}
	public void robotplay() {
		play = mainWin.getInstance().panel_block.isPlaying();
		if(play == false) {
			return;
		}
		currentArray = mainWin.getInstance().panel_block.getCurrentArray();
		if(bruteForce() == false) {
			if(GaussLiner() == false) {
				randomPick();
		//		System.out.println("xixi");
			}
		}
	}
	private boolean GaussLiner() {
		tot = X * Y;
		Matrix = new double[tot + 1][tot + 2];
		for(int i = 1; i <= tot; ++i) {
			for(int j = 1; j <= tot + 1; ++j) {
				Matrix[i][j] = 0.0;
			}
		}
		for(int i = 1; i <= X; ++i) {
			for(int j = 1; j <= Y; ++j) {
				if(currentArray[i][j] == Station.block || currentArray[i][j] == Station.unknown || currentArray[i][j] == Station.zero) {
					continue;
				}
				currentRow = (i - 1) * Y + j;
				getBlockAround(i, j);
				if(i > 1 && j > 1) {
					if(currentArray[i - 1][j - 1] == Station.unknown) {
						currentCol = (i - 2) * Y + j - 1;
						Matrix[currentRow][currentCol] = 1.0;
					}
					if(currentArray[i - 1][j - 1] == Station.block) {
						blockAround--;
					}
				}
				if(i > 1) {
					if(currentArray[i - 1][j] == Station.unknown) {
						currentCol = (i - 2) * Y + j;
						Matrix[currentRow][currentCol] = 1.0;
					}
					if(currentArray[i - 1][j] == Station.block) {
						blockAround--;
					}
				}
				if(i > 1 && j < Y) {
					if(currentArray[i - 1][j + 1] == Station.unknown) {
						currentCol = (i - 2) * Y + j + 1;
						Matrix[currentRow][currentCol] = 1.0;
					}
					if(currentArray[i - 1][j + 1] == Station.block) {
						blockAround--;
					}
				}
				if(j > 1) {
					if(currentArray[i][j - 1] == Station.unknown) {
						currentCol = (i - 1) * Y + j - 1;
						Matrix[currentRow][currentCol] = 1.0;
					}
					if(currentArray[i][j - 1] == Station.block) {
						blockAround--;
					}
				}
				if(j < Y) {
					if(currentArray[i][j + 1] == Station.unknown) {
						currentCol = (i - 1) * Y + j + 1;
						Matrix[currentRow][currentCol] = 1.0;
					}
					if(currentArray[i][j + 1] == Station.block) {
						blockAround--;
					}
				}
				if(i < X && j > 1) {
					if(currentArray[i + 1][j - 1] == Station.unknown) {
						currentCol = i * Y + j - 1;
						Matrix[currentRow][currentCol] = 1.0;
					}
					if(currentArray[i + 1][j - 1] == Station.block) {
						blockAround--;
					}
				}
				if(i < X) {
					if(currentArray[i + 1][j] == Station.unknown) {
						currentCol = i * Y + j;
						Matrix[currentRow][currentCol] = 1.0;
					}
					if(currentArray[i + 1][j] == Station.block) {
						blockAround--;
					}
				}
				if(i < X && j < Y) {
					if(currentArray[i + 1][j + 1] == Station.unknown) {
						currentCol = i * Y + j + 1;
						Matrix[currentRow][currentCol] = 1.0;
					}
					if(currentArray[i + 1][j + 1] == Station.block) {
						blockAround--;
					}
				}
				Matrix[currentRow][tot + 1] = (double)blockAround;
			}
		}
		int cur, pos = 1;
		for(int i = 1; i <= tot; ++i) {
			for(int j = pos; j <= tot; ++j) {
				if(Math.abs(Matrix[j][i]) > eps) {
					for(int k = i; k <= tot + 1; ++k) {
						double tmp = Matrix[j][k];
						Matrix[j][k] = Matrix[pos][k];
						Matrix[pos][k] = tmp;
					}
					break;
				}
			}
			if(Math.abs(Matrix[pos][i]) < eps) {
		//		pos++;
				continue;
			}
			for(int j = 1; j <= tot; ++j) {
				if(j != pos && Math.abs(Matrix[j][i]) > eps) {
					double tmp = Matrix[j][i] / Matrix[pos][i];
					for(int k = i; k <= tot + 1; ++k) {
						Matrix[j][k] -= tmp * Matrix[pos][k];
					}
				}
			}
			pos++;
		}
		for(int i = 1; i <= tot; ++i) {
			cur = 0;
			for(int j = 1; j <= tot; ++j) {
				if(Math.abs(Matrix[i][j]) > eps) {
					cur++;
					pos = j;
				}
			}
			//find an answer
//			if(cur == 1) {	
//				System.out.println("find");
//				currentRow = pos / Y + 1;
//				currentCol = pos % Y;
//				if(currentCol == 0) {
//					currentRow--;
//					currentCol = Y;
//				}
//				if(Math.abs(Matrix[i][tot + 1] - Matrix[i][pos]) < eps) {
//					mainWin.getInstance().panel_block.solveRightButtonEvents(currentRow, currentCol);
//					return true;
//				}
//				else if(Math.abs(Matrix[i][tot + 1]) < eps){
//					mainWin.getInstance().panel_block.solveLeftButtonEvents(currentRow, currentCol);
//					return true;
//				}
//			}
			
			//That answer should be either 0 or 1 can be used to find answer
			double positiveN = 0;
			double negativeN = 0;
			for(int j = 1; j <= tot; ++j) { 
				if(Matrix[i][j] > eps) {
					positiveN += Matrix[i][j];
				}
				if(Matrix[i][j] < -eps) {
					negativeN += Matrix[i][j];
				}
			}
			for(int j = 1; j <= tot; ++j) {
				currentRow = j / Y + 1;
				currentCol = j % Y;
				if(currentCol == 0) {
					currentRow--;
					currentCol = Y;
				}
				if(Matrix[i][j] > eps) {
					// let it be 0, find it can not be 0, so it must be 1
					if(positiveN - Matrix[i][j] - Matrix[i][tot + 1] < -eps) { 
						mainWin.getInstance().panel_block.solveRightButtonEvents(currentRow, currentCol);
					//	System.out.println(positiveN + " " + negativeN + " " + Matrix[i][tot + 1] + " find1");
						return true;
					}
					// let it be 1, find it can not be 1, so it must be 0
					if(Matrix[i][j] + negativeN - Matrix[i][tot + 1] > eps) { 
						mainWin.getInstance().panel_block.solveLeftButtonEvents(currentRow, currentCol);
					//	System.out.println(positiveN + " " + negativeN + " " + Matrix[i][tot + 1] + " find2");
						return true;
					}
				}
				if(Matrix[i][j] < -eps) {
					// let it be 0, find it can not be 0, so it must be 1
					if(negativeN - Matrix[i][j] - Matrix[i][tot + 1] > eps) {
						mainWin.getInstance().panel_block.solveRightButtonEvents(currentRow, currentCol);
					//	System.out.println(positiveN + " " + negativeN + " " + Matrix[i][tot + 1] + " find3");
						return true;
					}
					// let it be 1, find it can not be 1, so it must be 0
					if(Matrix[i][j] + positiveN - Matrix[i][tot + 1] < -eps) {
						mainWin.getInstance().panel_block.solveLeftButtonEvents(currentRow, currentCol);
					//	System.out.println(positiveN + " " + negativeN + " " + Matrix[i][tot + 1] + " find4");
						return true;
					}
				}
			}
		}
		return false;
	}
	private void randomPick() {
		Random blockCreator = new Random();
		int newX, newY;
		while(true) {
			newX = blockCreator.nextInt(X) + 1;
			newY = blockCreator.nextInt(Y) + 1;
			if(currentArray[newX][newY] == Station.unknown) {
				Leftsolution(newX, newY);
				break;
			}
		}	
	}
	private boolean bruteForce() {
		for(int i = 1; i <= X; ++i) {
			for(int j = 1; j <= Y; ++j) {
				if(currentArray[i][j] == Station.unknown || currentArray[i][j] == Station.block || currentArray[i][j] == Station.zero) {
					continue;
				}
				if(tryClick(i, j)) {
					return true;
				}
			}
		}
		return false;
	}
	private boolean tryClick(int x, int y) {
		getBlockAround(x, y);
		totalAreaAround = 0;
		blankAreaAround = 0;
		blockFoundAround = 0;
		if(x - 1 >= 1 && y - 1 >= 1) {
			query(x - 1, y - 1);
		}
		if(x - 1 >= 1) {
			query(x - 1, y);
		}
		if(x - 1 >= 1 && y + 1 <= Y) {
			query(x - 1, y + 1);
		}
		if(y - 1 >= 1) {
			query(x, y - 1);
		}
		if(y + 1 <= Y) {
			query(x, y + 1);
		}
		if(x + 1 <= X && y - 1 >= 1) {
			query(x + 1, y - 1);
		}
		if(x + 1 <= X) {
			query(x + 1, y);
		}
		if(x + 1 <= X && y + 1 <= Y) {
			query(x + 1, y + 1);
		}
		if(blankAreaAround == 0) {
			return false;
		}
		if(blankAreaAround == blockAround - blockFoundAround) {
			if(canClick(x - 1, y - 1)) {
				Rightsolution(x - 1, y - 1);
				return true;
			}
			if(canClick(x - 1, y)) {
				Rightsolution(x - 1, y);
				return true;
			}
			if(canClick(x - 1, y + 1)) {
				Rightsolution(x - 1, y + 1);
				return true;
			}
			if(canClick(x, y - 1)) {
				Rightsolution(x, y - 1);
				return true;
			}
			if(canClick(x, y + 1)) {
				Rightsolution(x, y + 1);
				return true;
			}
			if(canClick(x + 1, y - 1)) {
				Rightsolution(x + 1, y - 1);
				return true;
			}
			if(canClick(x + 1, y)) {
				Rightsolution(x + 1, y);
				return true;
			}
			if(canClick(x + 1, y + 1)) {
				Rightsolution(x + 1, y + 1);
				return true;
			}
		}
		if(blockAround == blockFoundAround) {
			if(canClick(x - 1, y - 1)) {
				Leftsolution(x - 1, y - 1);
				return true;
			}
			if(canClick(x - 1, y)) {
				Leftsolution(x - 1, y);
				return true;
			}
			if(canClick(x - 1, y + 1)) {
				Leftsolution(x - 1, y + 1);
				return true;
			}
			if(canClick(x, y - 1)) {
				Leftsolution(x, y - 1);
				return true;
			}
			if(canClick(x, y + 1)) {
				Leftsolution(x, y + 1);
				return true;
			}
			if(canClick(x + 1, y - 1)) {
				Leftsolution(x + 1, y - 1);
				return true;
			}
			if(canClick(x + 1, y)) {
				Leftsolution(x + 1, y);
				return true;
			}
			if(canClick(x + 1, y + 1)) {
				Leftsolution(x + 1, y + 1);
				return true;
			}
		}
		return false;
	}
	public int getSteps() {
		return this.steps;
	}
	private boolean canClick(int x, int y) {
		if(x >= 1 && y >= 1 && x <= X && y <= Y) {
			if(currentArray[x][y] == Station.unknown) {
				return true;
			}
		}
		return false;
	}
	private void query(int x, int y) {
		totalAreaAround++;
		if(currentArray[x][y] == Station.unknown) {
			blankAreaAround++;
		}
		if(currentArray[x][y] == Station.block) {
			blockFoundAround++;
		}
	}	
	private void Leftsolution(int x, int y) {
		mainWin.getInstance().panel_block.solveLeftButtonEvents(x, y);
	}
	private void Rightsolution(int x, int y) {
		mainWin.getInstance().panel_block.solveRightButtonEvents(x, y);
	}
	private void getBlockAround(int x, int y) {
		switch(currentArray[x][y]) {
		case one:
			blockAround = 1;
			break;
		case two:
			blockAround = 2;
			break;
		case three:
			blockAround = 3;
			break;
		case four:
			blockAround = 4;
			break;
		case five:
			blockAround = 5;
			break;
		case six:
			blockAround = 6;
			break;
		case seven:
			blockAround = 7;
			break;
		default:
			System.out.println("Error");
			break;				
		}
	}
	public boolean getResult() {
		return this.result;
	}
}


enum Station:


package HBoom;

public enum Station {
	zero,
	one,
	two,
	three,
	four,
	five,
	six,
	seven,
	block,
	unknown;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章