围住神经猫源码(慕课)

package com.example.kisoo.craycat;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Toast;

import java.util.HashMap;
import java.util.Vector;

/**
 * Created by KiSoo on 2015/12/2.
 */
public class PlayGround extends SurfaceView implements View.OnTouchListener {
    private static int weight = 90;//每个元素的像素

    private static final int width = 10;
    private static final int height = 10;
    /*路障*/
    private static final int blocks = 10;//默认设置的路障数量
    private static final int LEFT = 1;
    private static final int LEFT_TOP = 2;
    private static final int RIGHT_TOP = 3;
    private static final int RIGHT = 4;
    private static final int RIGHT_BOTTOM = 5;
    private static final int LEFT_BOTTOM = 6;
    private Dot matrix[][];
    private Dot cat;


    public PlayGround(Context context) {
        super(context);
        Toast.makeText(getContext(),"点击下方空白处初始化游戏,重要的事情只说一遍",Toast.LENGTH_LONG).show();
        getHolder().addCallback(callback2);
        matrix = new Dot[width][height];
        for (int i = 0; i < width; i++) {//行数
            for (int j = 0; j < height; j++) {//列数
                matrix[i][j] = new Dot(j, i);
            }
        }
        setOnTouchListener(this);
        initGame();
    }


    private void reDraw() {
        Canvas c = getHolder().lockCanvas();

        Paint paint = new Paint();
//        WindowManager windowManager= (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
//        DisplayMetrics metrics= new DisplayMetrics();
//        windowManager.getDefaultDisplay().getMetrics(metrics);
//        float m =  metrics.widthPixels;
//        float n = metrics.heightPixels;
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background);
        c.drawBitmap(bitmap, 0, 0, paint);
        /*取消对canvas的锁定*/
        for (int i = 0; i < width; i++) {
            int offset = 0;
            if (i % 2 != 0) {
                offset = weight / 2;
            }
            for (int j = 0; j < height; j++) {
                Dot one = getDot(j, i);
                switch (one.getStatus()) {
                    case Dot.STATUS_ON:
                        Log.v("路障坐标为", i + "," + j);
                        paint.setColor(Color.RED);
                        break;
                    case Dot.STATUS_off:
                        Log.v("未走过的区域", i + "," + j);
                        paint.setColor(Color.WHITE);
                        break;
                    case Dot.STATUS_in:
                        Log.v("神经猫的位置", i + "," + j);
                        paint.setColor(Color.BLUE);
                        break;
                    default:
                        break;
                }
                c.drawOval(new RectF(one.getX() * weight + offset, one.getY() * weight,
                        (one.getX() + 1) * weight + offset, (one.getY() + 1) * weight), paint);
            }
        }
        getHolder().unlockCanvasAndPost(c);

    }

    SurfaceHolder.Callback2 callback2 = new SurfaceHolder.Callback2() {
        @Override
        public void surfaceRedrawNeeded(SurfaceHolder holder) {

        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            reDraw();
        }

        @Override
        public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
            weight = arg2 * 2 / (width * 2 + 1);
            reDraw();
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {

        }
    };

    private void initGame() {
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                matrix[i][j].setStatus(Dot.STATUS_off);//全部设置为status_off
            }
        }
        cat = new Dot(4, 5);
        getDot(4, 5).setStatus(Dot.STATUS_in);
        for (int i = 0; i < blocks; ) {
            int x = (int) ((Math.random() * 1000) % height);
            int y = (int) ((Math.random() * 1000) % width);
            if (getDot(x, y).getStatus() == Dot.STATUS_off) {
                getDot(x, y).setStatus(Dot.STATUS_ON);
                i++;
                Log.v("--->", "Block的数量为" + i);
                Log.v("block的位置为", x + "," + y);
            }
        }
    }

    private Dot getDot(int x, int y) {
        return matrix[y][x];
    }

    private boolean isAtEdge(Dot d) {
        if (d.getX() * d.getY() == 0 || d.getX() + 1 == width || d.getY() + 1 == height) {
            return true;
        }
        return false;
    }

    private Dot getNeighbor(Dot one, int dir) {//点 ,判断点的方向
        switch (dir) {
            case LEFT:
                //正左方向
                return getDot(one.getX() - 1, one.getY());

            case LEFT_TOP:
                //左上
                if (one.getY() % 2 == 0) {
                    //偶数行
                    return getDot(one.getX() - 1, one.getY() - 1);
                } else {
                    //奇数行
                    return getDot(one.getX(), one.getY() - 1);
                }

            case RIGHT_TOP:
                //右上
                if (one.getY() % 2 == 0) {
                    //偶数行
                    return getDot(one.getX(), one.getY() - 1);
                } else {
                    //奇数行
                    return getDot(one.getX() + 1, one.getY() - 1);
                }
            case RIGHT:
                //正右方向
                return getDot(one.getX() + 1, one.getY());

            case RIGHT_BOTTOM:
                //右下
                if (one.getY() % 2 == 0) {
                    //偶数行
                    return getDot(one.getX(), one.getY() + 1);
                } else {
                    //奇数行
                    return getDot(one.getX() + 1, one.getY() + 1);
                }
            case LEFT_BOTTOM:
                if (one.getY() % 2 == 0) {
                    //偶数行
                    return getDot(one.getX() - 1, one.getY() + 1);
                } else {
                    //奇数行
                    return getDot(one.getX(), one.getY() + 1);
                }
            default:
                break;
        }
        return null;
    }

    private int getDistance(Dot one, int dir) {
        int distance = 0;
        if (isAtEdge(one)){
            return 1;
        }
        Dot ori = one, next;
        while (true) {
            next = getNeighbor(ori, dir);
            if (next.getStatus() == Dot.STATUS_ON) {
                return distance * -1;
            }
            if (isAtEdge(next)) {
                //下一个是边界
                distance = distance + 1;
                return distance;
            }
            distance++;
            ori = next;
        }
    }

    private void MoveTo(Dot one) {
        one.setStatus(Dot.STATUS_in);
        getDot(cat.getX(), cat.getY()).setStatus(Dot.STATUS_off);
        cat.setXY(one.getX(), one.getY());

    }

    private void move() {
        if (isAtEdge(cat)) {
            lose();
            return;
        }
        Vector<Dot> avail = new Vector<>();
        Vector<Dot> positive = new Vector<>();
        HashMap<Dot, Integer> al = new HashMap<Dot, Integer>();

        for (int i = 1; i < 7; i++) {
            Dot n = getNeighbor(cat, i);
            if (n.getStatus() == Dot.STATUS_off) {
                avail.add(n);
                al.put(n, i);
                if (getDistance(n, i) > 0) {
                    positive.add(n);
                }
            }
        }
        if (avail.size() == 0) {
            win();
        } else if (avail.size() == 1) {
            MoveTo(avail.get(0));
        }  else {
            Dot best = null;
            if (positive.size() != 0) {
                int min = 99999;
                for (int i = 0; i < positive.size(); i++) {
                    int distance = getDistance(positive.get(i), al.get(positive.get(i)));
                    if (distance < min) {
                        min = distance;
                        best = positive.get(i);
                        Log.e("----->","向前进");
                    }
                }
            } else {//所有方向都存在路障
                int max = 0;
                for (int i = 0; i < avail.size(); i++) {
                    int k = getDistance(avail.get(i), al.get(avail.get(i)));
                    if (k < max) {
                        max = k;
                        best = avail.get(i);
                        Log.e("----->","躲路障");
                    }
                }
            }
            MoveTo(best);
        }
    }


    private void lose() {
        Toast.makeText(getContext(), "你失败了,菜狗,哇哈哈哈哈", Toast.LENGTH_LONG).show();
    }

    private void win() {
        Toast.makeText(getContext(), "你竟然赢了,我不服!", Toast.LENGTH_LONG).show();

    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
//            Toast.makeText(getContext(),event.getX()+":"+ event.getY(),Toast.LENGTH_SHORT).show();
            int x, y;
            y = (int) (event.getY() / weight);
            if (y % 2 == 0) {
                x = (int) ((event.getX() / weight));
                Log.e("当前为偶数行", y + "" + x + "");

            } else {
                x = (int) ((event.getX() * 2 / weight - 1) / 2);
                Log.e("当前为奇数行", y + "" + x + "");
            }
            if (x + 1 > height || y + 1 > width) {
                initGame();
            } else {
                if (getDot(x, y).getStatus() == Dot.STATUS_off) {
                    getDot(x, y).setStatus(Dot.STATUS_ON);
                    move();
                }
            /*被点以后就被设置为路障模式*/
            }
            reDraw();

        }
        return true;

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值