扫雷

来源:互联网 发布:红圈通是什么样的软件 编辑:程序博客网 时间:2024/06/01 20:52
//要导包import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.graphics.Color;import android.opengl.Visibility;import android.os.Bundle;import android.util.Log;import android.view.Gravity;import android.view.View;import android.view.View.OnClickListener;import android.view.View.OnLongClickListener;import android.widget.Button;import android.widget.FrameLayout;import android.widget.LinearLayout;import android.widget.RelativeLayout;import android.widget.TextView;public class MainActivity extends Activity implements OnClickListener,OnLongClickListener {    public static final int NUMBER = 10;    LinearLayout.LayoutParams viewParams;    private int[][] map = new int[NUMBER][NUMBER];    List<TextView> tvList = new ArrayList<>();    List<Button> btnList = new ArrayList<Button>();    int[] boomColor = { Color.BLUE, Color.GREEN, Color.RED, Color.BLACK,Color.GRAY, Color.LTGRAY, Color.MAGENTA };    public static final String FLAG = "✈";    private TextView tvBoom;    private TextView tvTime;    private int boomNumber;    private LinearLayout layout;    Timer timer;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        initView();        initData();    }    private void initData() {        // 初始化NUMBER个地雷        boomNumber = NUMBER;        tvBoom.setText("地雷:" + boomNumber);        // 为NUMBER个地雷周围设置好数字        // 用-1来代替地雷        // 初始化地雷        for (int i = 0; i < NUMBER * NUMBER; i++) {            map[i / NUMBER][i % NUMBER] = 0;        }        if (timer != null)            timer.cancel();        timer = null;        tvTime.setText("时间:0");        // 1.随机10个地雷        HashSet<Integer> sets = new HashSet<Integer>();        while (sets.size() != boomNumber) {            sets.add((int) (Math.random() * NUMBER * NUMBER));        }        // 2.将地雷添加到map数组        for (Integer integer : sets) {// 33 9            map[integer / NUMBER][integer % NUMBER] = -1;// 1-->2        }        // 3.将每个格子的地雷数算好        for (int i = 0; i < NUMBER; i++) {            for (int j = 0; j < NUMBER; j++) {                // 如果当前的map中不是地雷,就要算周围的地雷数                if (map[i][j] != -1) {                    int num = calcMine(i, j);                    map[i][j] = num;                }            }        }        // 4. 将所有的map对应到 TextView上去        for (int i = 0; i < NUMBER; i++) {            for (int j = 0; j < NUMBER; j++) {                TextView tv = tvList.get(i * NUMBER + j);                if (map[i][j] == -1) {                    tv.setText("۞");                } else if (map[i][j] != 0) {                    int num = map[i][j];                    tv.setText(num + "");                    tv.setTextColor(boomColor[num - 1]);                }            }        }        // 5. 为所有的button设置点击事件        // 在创建的时候 添加的    }    private int calcMine(int i, int j) {        int number = 0;        for (int m = i - 1; m <= i + 1; m++) {            for (int n = j - 1; n <= j + 1; n++) {                if (m == i && n == j)                    continue;                try {                    if (map[m][n] == -1)                        number++;                } catch (Exception e) {                    continue;                }            }        }        return number;    }    // 最外层的框架    private void initView() {        layout = new LinearLayout(this);        layout.setOrientation(LinearLayout.VERTICAL);        // 添加了 顶部的相对布局        layout.addView(getBoomTime());        // 添加了 主要的框架        layout.addView(mainFrame());        layout.setPadding(50, 50, 50, 50);        setContentView(layout);    }    private FrameLayout mainFrame() {        // 10*10的视图        // int width = getWindowManager().getDefaultDisplay().getWidth();        int width = (getResources().getDisplayMetrics().widthPixels - 100)                / NUMBER;        viewParams = new LinearLayout.LayoutParams(width, width);        // 主要视图部分        FrameLayout layout = new FrameLayout(this);        // 添加了底层的TextView        layout.addView(getTextViews());        // 添加了上层的Button        layout.addView(getButtons());        return layout;    }    private RelativeLayout getBoomTime() {        RelativeLayout layout = new RelativeLayout(this);        tvTime = new TextView(this);        tvTime.setText("时间:0");        tvTime.setPadding(20, 20, 20, 20);        tvBoom = new TextView(this);        tvBoom.setText("地雷:" + NUMBER + "");        tvBoom.setPadding(20, 20, 20, 20);        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(                RelativeLayout.LayoutParams.WRAP_CONTENT,                RelativeLayout.LayoutParams.WRAP_CONTENT);        params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);        tvBoom.setLayoutParams(params);        layout.addView(tvTime);        layout.addView(tvBoom);        return layout;    }    // 创建一个100个TextView的布局    private LinearLayout getTextViews() {        tvList.clear();        LinearLayout layout = new LinearLayout(this);        layout.setBackgroundResource(R.drawable.store);        layout.setPadding(1, 1, 1, 1);        layout.setOrientation(LinearLayout.VERTICAL);        for (int i = 0; i < NUMBER; i++) {            // 每一行都是一个水平线性布局            LinearLayout hLayout = new LinearLayout(this);            hLayout.setOrientation(LinearLayout.HORIZONTAL);            for (int j = 0; j < NUMBER; j++) {                // 内层水平布局,添加TextView10个                TextView tv = new TextView(this);                tv.setGravity(Gravity.CENTER);                tv.setTextSize(18);                tv.setBackgroundResource(R.drawable.store);                tv.setLayoutParams(viewParams);                hLayout.addView(tv);                // 将所有TextView添加到集合                tvList.add(tv);            }            // 外层垂直布局添加内层水平布局10个            layout.addView(hLayout);        }        return layout;    }    // 创建一个100个Button的布局    private LinearLayout getButtons() {        btnList.clear();        LinearLayout layout = new LinearLayout(this);        layout.setOrientation(LinearLayout.VERTICAL);        for (int i = 0; i < NUMBER; i++) {            LinearLayout hLayout = new LinearLayout(this);            hLayout.setOrientation(LinearLayout.HORIZONTAL);            for (int j = 0; j < NUMBER; j++) {                Button btn = new Button(this);                btn.setBackgroundResource(R.drawable.btn_bg);                btn.setLayoutParams(viewParams);                btn.setTag(i * NUMBER + j);                btn.setOnClickListener(this);                btn.setOnLongClickListener(this);                hLayout.addView(btn);                btnList.add(btn);            }            layout.addView(hLayout);        }        return layout;    }    @Override    public void onClick(View v) {        // 判断是否是第一次点击按钮,点击就开始计时        if (timer == null) {            startTimer();        }        // v==button        // 需要知道当前button的坐标        // 每个view都可以设置一个别名(tag) 这个tag是一个object对象,可以存放任意的对象。        // 根据设置的Tag来知道当前是哪一个button被点击了        int i = Integer.parseInt(v.getTag().toString()) / NUMBER;        int j = Integer.parseInt(v.getTag().toString()) % NUMBER;        // 插旗子不允许点击        Button btn = (Button) v;        if (btn.getText().toString().equals(FLAG))            return;        Log.e("TAG", "-------------" + i + "  " + j + "   " + map[i][j]);        // 1.只要点击,肯定需要将当前的坐标 的Button 隐藏        v.setVisibility(View.INVISIBLE);        if (map[i][j] == -1) {            gameOver();        } else if (map[i][j] == 0) {            // 展开周围8个方向            // 如果碰到继续是0            // 继续递归展开这个0的8个方向            expansionButton(i, j);        }    }    int downTime;    private void startTimer() {        downTime = 100;        // 倒计时100秒开始        timer = new Timer();        timer.schedule(new TimerTask() {            @Override            public void run() {                // android 不允许在 子线程中 修改UI视图                // 在Activity中可以使用runonUiThread方法来 将线程转换到主线程                downTime--;                runOnUiThread(new Runnable() {                    @Override                    public void run() {                        // runOnUiThread的run方法 是在主线程中的, UI线程就是主线程                        tvTime.setText("时间:" + downTime);                        if (downTime == 0) {                            gameOver();                        }                    }                });            }        }, 0, 1000);    }    private void expansionButton(int i, int j) {        for (int m = i - 1; m <= i + 1; m++) {            for (int n = j - 1; n <= j + 1; n++) {                if (m == i && n == j)                    continue;                else {                    try {                        Button button = btnList.get(m * NUMBER + n);                        if (button.getVisibility() == View.VISIBLE                                && !button.getText().toString().equals(FLAG)) {                            if (map[m][n] == 0) {                                button.setVisibility(View.INVISIBLE);                                expansionButton(m, n);                            } else {                                button.setVisibility(View.INVISIBLE);                            }                        }                    } catch (Exception e) {                    }                }            }        }    }    private void gameWin() {        showGame("GameWin\n点击重新开始");    }    private void gameOver() {        showGame("GameOver\n点击重新开始");    }    private void showGame(String msg) {        if (timer != null) {            timer.cancel();            timer = null;        }        TextView tv = new TextView(this);        tv.setText(msg);        tv.setGravity(Gravity.CENTER);        tv.setTextColor(Color.RED);        tv.setTextSize(48);        layout.addView(tv);        tv.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                initView();                initData();            }        });    }    @Override    public boolean onLongClick(View v) {        if (timer == null) {            startTimer();        }        // 长按一个Button 判断上面有没有旗子,有的话呢,就取消        Button btn = (Button) v;        if (btn.getText().toString().equals(FLAG)) {            btn.setText("");            boomNumber++;        } else {            btn.setText(FLAG);            boomNumber--;        }        tvBoom.setText("地雷:" + boomNumber);        // 如果旗子用完了,就要计算输赢        if (boomNumber == 0) {            isGameOver();        }        return true;    }    private void isGameOver() {        for (int i = 0; i < NUMBER; i++) {            for (int j = 0; j < NUMBER; j++) {                Button btn = btnList.get(i * NUMBER + j);                // 在map中找到所有的地雷,这些地雷上面,一定要插上旗子                if (map[i][j] == -1) {                    if (!btn.getText().equals(FLAG)) {                        gameOver();                        return;                    }                }            }        }        gameWin();    }}
原创粉丝点击