扫雷

//要导包
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();
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值