Android五子连珠

来源:互联网 发布:帝国cms网址导航模板 编辑:程序博客网 时间:2024/05/06 05:58

绘制棋盘面板:

MainActivity.java
package com.xbmu.wuziqi;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.xbmu.wuziqi.MainActivity">    <com.xbmu.wuziqi.WuziqiPanel        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_centerInParent="true" /></RelativeLayout>
WuziqiPanel.java
package com.xbmu.wuziqi;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.view.View;/** * 五子棋面板 * Created by Administrator on 2016/5/2 0002. */public class WuziqiPanel extends View {    private int mPanelWidth;//棋盘宽度    private float mLineHeight;//棋盘每行行高    private int MAX_LINE = 10;//棋盘最大行数    //创建绘画对象    private Paint mPaint = new Paint();    public WuziqiPanel(Context context, AttributeSet attrs) {        super(context, attrs);        setBackgroundColor(0x44ff0000);        init();    }    /**初始化画笔属性*/    private void init() {        mPaint.setColor(0x88000000);//设置颜色为灰色效果        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setStyle(Paint.Style.STROKE);    }    /**测量一个view的大小*/    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(widthMeasureSpec);        int width = Math.min(widthSize,heightSize);        if(widthMode == MeasureSpec.UNSPECIFIED){            width = heightSize;        }else if(heightMode == MeasureSpec.UNSPECIFIED){            width = widthSize;        }        //设置自身大小        setMeasuredDimension(width,width);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mPanelWidth = w;        mLineHeight = mPanelWidth*1.0f / MAX_LINE;    }    /**Draw画出View的显示内容*/    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        drawBoard(canvas);    }    private void drawBoard(Canvas canvas) {        /**         * 分析:根据棋盘的效果,我们知道棋子是下在边界的交叉点上的。可得棋盘中间有9个完整的lineHeight,         * 上下两边有半个lineHeight,总共10个lineHeight。左右也是。         */        int w = mPanelWidth;        float lineHeight = mLineHeight;        for(int i=0;i<MAX_LINE;i++){            int startX = (int) (lineHeight / 2);//起点坐标            int endX = (int) (w - lineHeight / 2);//终点坐标            int y = (int) ((0.5+i)*lineHeight);            canvas.drawLine(startX,y,endX,y,mPaint);            canvas.drawLine(y,startX,y,endX,mPaint);        }    }}
运行效果:

绘制黑白棋子:

WuziqiPanel.java
package com.xbmu.wuziqi;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Point;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import java.util.ArrayList;import java.util.List;/** * 五子棋面板 * Created by Administrator on 2016/5/2 0002. */public class WuziqiPanel extends View {    private int mPanelWidth;//棋盘宽度    private float mLineHeight;//棋盘每行行高    private int MAX_LINE = 10;//棋盘最大行数    //创建绘画对象    private Paint mPaint = new Paint();    private Bitmap mWhitePiece;//白色棋子    private Bitmap mBlackPiece;//黑色棋子    //比例:棋子的大小是行高的3/4;    private float ratioPieceOfLineHeight = 3*1.0f / 4;    //白棋先手,当前轮到白棋。    private boolean mIsWhite = true;    private List<Point> mWhiteArray = new ArrayList<>();    private List<Point> mBlackArray = new ArrayList<>();    public WuziqiPanel(Context context, AttributeSet attrs) {        super(context, attrs);        setBackgroundColor(0x44ff0000);        init();    }    /**初始化画笔属性*/    private void init() {        mPaint.setColor(0x88000000);//设置颜色为灰色效果        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setStyle(Paint.Style.STROKE);        mWhitePiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_w2);        mBlackPiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_b1);    }    /**测量一个view的大小*/    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(widthMeasureSpec);        int width = Math.min(widthSize,heightSize);        if(widthMode == MeasureSpec.UNSPECIFIED){            width = heightSize;        }else if(heightMode == MeasureSpec.UNSPECIFIED){            width = widthSize;        }        //设置自身大小        setMeasuredDimension(width,width);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mPanelWidth = w;        mLineHeight = mPanelWidth*1.0f / MAX_LINE;        int pieceWidth = (int) (mLineHeight * ratioPieceOfLineHeight);//棋子宽度        mWhitePiece = Bitmap.createScaledBitmap(mWhitePiece,pieceWidth,pieceWidth,false);        mBlackPiece = Bitmap.createScaledBitmap(mBlackPiece,pieceWidth,pieceWidth,false);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        int action = event.getAction();        if(action == MotionEvent.ACTION_DOWN){            int x = (int) event.getX();            int y = (int) event.getY();            Point p = getValidPoint(x,y);            if(mWhiteArray.contains(p) || mBlackArray.contains(p)){                return false;            }            if(mIsWhite){                mWhiteArray.add(p);            }else{                mBlackArray.add(p);            }            invalidate();//请求重绘            mIsWhite = !mIsWhite;            return true;        }        return super.onTouchEvent(event);    }    private Point getValidPoint(int x, int y) {        return new Point((int)(x/mLineHeight) ,(int)(y/mLineHeight));    }    /**Draw画出View的显示内容*/    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //绘制棋盘        drawBoard(canvas);        //绘制棋子        drawPieces(canvas);    }    private void drawPieces(Canvas canvas) {        for(int i=0,n = mWhiteArray.size(); i< n ;i++){            Point whitePoint = mWhiteArray.get(i);            canvas.drawBitmap(mWhitePiece,                    (whitePoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (whitePoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }        for(int i=0,n = mBlackArray.size(); i< n ;i++){            Point blackPoint = mBlackArray.get(i);            canvas.drawBitmap(mBlackPiece,                    (blackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (blackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }    }    private void drawBoard(Canvas canvas) {        /**         * 分析:根据棋盘的效果,我们知道棋子是下在边界的交叉点上的。可得棋盘中间有9个完整的lineHeight,         * 上下两边有半个lineHeight,总共10个lineHeight。左右也是。         */        int w = mPanelWidth;        float lineHeight = mLineHeight;        for(int i=0;i<MAX_LINE;i++){            int startX = (int) (lineHeight / 2);//起点坐标            int endX = (int) (w - lineHeight / 2);//终点坐标            int y = (int) ((0.5+i)*lineHeight);            canvas.drawLine(startX,y,endX,y,mPaint);            canvas.drawLine(y,startX,y,endX,mPaint);        }    }}
运行效果:

五子棋业务逻辑判断:

WuziqiPanel.java
package com.xbmu.wuziqi;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Point;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.Toast;import java.util.ArrayList;import java.util.List;/** * 五子棋面板 * Created by Administrator on 2016/5/2 0002. */public class WuziqiPanel extends View {    private int mPanelWidth;//棋盘宽度    private float mLineHeight;//棋盘每行行高    private int MAX_LINE = 10;//棋盘最大行数    //创建绘画对象    private Paint mPaint = new Paint();    private Bitmap mWhitePiece;//白色棋子    private Bitmap mBlackPiece;//黑色棋子    //比例:棋子的大小是行高的3/4;    private float ratioPieceOfLineHeight = 3*1.0f / 4;    //白棋先手,当前轮到白棋。    private boolean mIsWhite = true;    private List<Point> mWhiteArray = new ArrayList<>();    private List<Point> mBlackArray = new ArrayList<>();    private boolean mIsGameOver;    private boolean mIsWhiteWinner;    private int MAX_COUNT_IN_LINE = 5;    public WuziqiPanel(Context context, AttributeSet attrs) {        super(context, attrs);        setBackgroundColor(0x44ff0000);        init();    }    /**初始化画笔属性*/    private void init() {        mPaint.setColor(0x88000000);//设置颜色为灰色效果        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setStyle(Paint.Style.STROKE);        mWhitePiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_w2);        mBlackPiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_b1);    }    /**测量一个view的大小*/    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(widthMeasureSpec);        int width = Math.min(widthSize,heightSize);        if(widthMode == MeasureSpec.UNSPECIFIED){            width = heightSize;        }else if(heightMode == MeasureSpec.UNSPECIFIED){            width = widthSize;        }        //设置自身大小        setMeasuredDimension(width,width);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mPanelWidth = w;        mLineHeight = mPanelWidth*1.0f / MAX_LINE;        int pieceWidth = (int) (mLineHeight * ratioPieceOfLineHeight);//棋子宽度        mWhitePiece = Bitmap.createScaledBitmap(mWhitePiece,pieceWidth,pieceWidth,false);        mBlackPiece = Bitmap.createScaledBitmap(mBlackPiece,pieceWidth,pieceWidth,false);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        int action = event.getAction();        if(action == MotionEvent.ACTION_DOWN){            int x = (int) event.getX();            int y = (int) event.getY();            Point p = getValidPoint(x,y);            if(mWhiteArray.contains(p) || mBlackArray.contains(p)){                return false;            }            if(mIsWhite){                mWhiteArray.add(p);            }else{                mBlackArray.add(p);            }            invalidate();//请求重绘            mIsWhite = !mIsWhite;            return true;        }        return super.onTouchEvent(event);    }    private Point getValidPoint(int x, int y) {        return new Point((int)(x/mLineHeight) ,(int)(y/mLineHeight));    }    /**Draw画出View的显示内容*/    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //绘制棋盘        drawBoard(canvas);        //绘制棋子        drawPieces(canvas);        //检查游戏结束        checkGameOver();    }    private void checkGameOver() {        boolean whiteWin = checkFiveInLine(mWhiteArray);        boolean blackWin = checkFiveInLine(mBlackArray);        if(whiteWin || blackWin){            mIsGameOver = true;            mIsWhiteWinner = whiteWin;            String text = mIsWhiteWinner ? "白棋胜利":"黑棋胜利";            Toast.makeText(getContext(),text,Toast.LENGTH_LONG).show();        }    }    private boolean checkFiveInLine(List<Point> points) {        for (Point p : points){            int x = p.x;            int y = p.y;            boolean win = checkHorizontal(x,y,points);            if(win) return true;            win = checkVertical(x,y,points);            if(win) return true;            win =checkLeftDiagonal(x,y,points);            if(win) return true;            win = checkRightDiagonal(x,y,points);            if(win) return true;        }        return false;    }    /**     * 判断x,y位置的棋子,是否横向有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkHorizontal(int x, int y, List<Point> points) {        int count = 1;        //左        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否纵向有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkVertical(int x, int y, List<Point> points) {        int count = 1;        //上        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x,y-i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x,y+i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否左斜有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkLeftDiagonal(int x, int y, List<Point> points) {        int count = 1;        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y+i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y-i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否右斜有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkRightDiagonal(int x, int y, List<Point> points) {        int count = 1;        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y-i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y+i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    private void drawPieces(Canvas canvas) {        for(int i=0,n = mWhiteArray.size(); i< n ;i++){            Point whitePoint = mWhiteArray.get(i);            canvas.drawBitmap(mWhitePiece,                    (whitePoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (whitePoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }        for(int i=0,n = mBlackArray.size(); i< n ;i++){            Point blackPoint = mBlackArray.get(i);            canvas.drawBitmap(mBlackPiece,                    (blackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (blackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }    }    private void drawBoard(Canvas canvas) {        /**         * 分析:根据棋盘的效果,我们知道棋子是下在边界的交叉点上的。可得棋盘中间有9个完整的lineHeight,         * 上下两边有半个lineHeight,总共10个lineHeight。左右也是。         */        int w = mPanelWidth;        float lineHeight = mLineHeight;        for(int i=0;i<MAX_LINE;i++){            int startX = (int) (lineHeight / 2);//起点坐标            int endX = (int) (w - lineHeight / 2);//终点坐标            int y = (int) ((0.5+i)*lineHeight);            canvas.drawLine(startX,y,endX,y,mPaint);            canvas.drawLine(y,startX,y,endX,mPaint);        }    }}

View的存储与恢复:

WuziqiPanel.java
package com.xbmu.wuziqi;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Point;import android.os.Bundle;import android.os.Parcelable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.Toast;import java.util.ArrayList;import java.util.List;/** * 五子棋面板 * Created by Administrator on 2016/5/2 0002. */public class WuziqiPanel extends View {    private int mPanelWidth;//棋盘宽度    private float mLineHeight;//棋盘每行行高    private int MAX_LINE = 10;//棋盘最大行数    //创建绘画对象    private Paint mPaint = new Paint();    private Bitmap mWhitePiece;//白色棋子    private Bitmap mBlackPiece;//黑色棋子    //比例:棋子的大小是行高的3/4;    private float ratioPieceOfLineHeight = 3*1.0f / 4;    //白棋先手,当前轮到白棋。    private boolean mIsWhite = true;    private ArrayList<Point> mWhiteArray = new ArrayList<>();    private ArrayList<Point> mBlackArray = new ArrayList<>();    private boolean mIsGameOver;    private boolean mIsWhiteWinner;    private int MAX_COUNT_IN_LINE = 5;    public WuziqiPanel(Context context, AttributeSet attrs) {        super(context, attrs);        setBackgroundColor(0x44ff0000);        init();    }    /**初始化画笔属性*/    private void init() {        mPaint.setColor(0x88000000);//设置颜色为灰色效果        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setStyle(Paint.Style.STROKE);        mWhitePiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_w2);        mBlackPiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_b1);    }    /**测量一个view的大小*/    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(widthMeasureSpec);        int width = Math.min(widthSize,heightSize);        if(widthMode == MeasureSpec.UNSPECIFIED){            width = heightSize;        }else if(heightMode == MeasureSpec.UNSPECIFIED){            width = widthSize;        }        //设置自身大小        setMeasuredDimension(width,width);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mPanelWidth = w;        mLineHeight = mPanelWidth*1.0f / MAX_LINE;        int pieceWidth = (int) (mLineHeight * ratioPieceOfLineHeight);//棋子宽度        mWhitePiece = Bitmap.createScaledBitmap(mWhitePiece,pieceWidth,pieceWidth,false);        mBlackPiece = Bitmap.createScaledBitmap(mBlackPiece,pieceWidth,pieceWidth,false);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        int action = event.getAction();        if(action == MotionEvent.ACTION_DOWN){            int x = (int) event.getX();            int y = (int) event.getY();            Point p = getValidPoint(x,y);            if(mWhiteArray.contains(p) || mBlackArray.contains(p)){                return false;            }            if(mIsWhite){                mWhiteArray.add(p);            }else{                mBlackArray.add(p);            }            invalidate();//请求重绘            mIsWhite = !mIsWhite;            return true;        }        return super.onTouchEvent(event);    }    private Point getValidPoint(int x, int y) {        return new Point((int)(x/mLineHeight) ,(int)(y/mLineHeight));    }    /**Draw画出View的显示内容*/    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //绘制棋盘        drawBoard(canvas);        //绘制棋子        drawPieces(canvas);        //检查游戏结束        checkGameOver();    }    private void checkGameOver() {        boolean whiteWin = checkFiveInLine(mWhiteArray);        boolean blackWin = checkFiveInLine(mBlackArray);        if(whiteWin || blackWin){            mIsGameOver = true;            mIsWhiteWinner = whiteWin;            String text = mIsWhiteWinner ? "白棋胜利":"黑棋胜利";            Toast.makeText(getContext(),text,Toast.LENGTH_LONG).show();        }    }    private boolean checkFiveInLine(List<Point> points) {        for (Point p : points){            int x = p.x;            int y = p.y;            boolean win = checkHorizontal(x,y,points);            if(win) return true;            win = checkVertical(x,y,points);            if(win) return true;            win =checkLeftDiagonal(x,y,points);            if(win) return true;            win = checkRightDiagonal(x,y,points);            if(win) return true;        }        return false;    }    /**     * 判断x,y位置的棋子,是否横向有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkHorizontal(int x, int y, List<Point> points) {        int count = 1;        //左        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否纵向有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkVertical(int x, int y, List<Point> points) {        int count = 1;        //上        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x,y-i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x,y+i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否左斜有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkLeftDiagonal(int x, int y, List<Point> points) {        int count = 1;        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y+i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y-i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否右斜有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkRightDiagonal(int x, int y, List<Point> points) {        int count = 1;        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y-i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y+i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    private void drawPieces(Canvas canvas) {        for(int i=0,n = mWhiteArray.size(); i< n ;i++){            Point whitePoint = mWhiteArray.get(i);            canvas.drawBitmap(mWhitePiece,                    (whitePoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (whitePoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }        for(int i=0,n = mBlackArray.size(); i< n ;i++){            Point blackPoint = mBlackArray.get(i);            canvas.drawBitmap(mBlackPiece,                    (blackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (blackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }    }    private void drawBoard(Canvas canvas) {        /**         * 分析:根据棋盘的效果,我们知道棋子是下在边界的交叉点上的。可得棋盘中间有9个完整的lineHeight,         * 上下两边有半个lineHeight,总共10个lineHeight。左右也是。         */        int w = mPanelWidth;        float lineHeight = mLineHeight;        for(int i=0;i<MAX_LINE;i++){            int startX = (int) (lineHeight / 2);//起点坐标            int endX = (int) (w - lineHeight / 2);//终点坐标            int y = (int) ((0.5+i)*lineHeight);            canvas.drawLine(startX,y,endX,y,mPaint);            canvas.drawLine(y,startX,y,endX,mPaint);        }    }    private static final String INSTANCE = "instance";    private static final String INSTANCE_GAME_OVER = "instance_game_over";    private static final String INSTANCE_WHITE_ARRAY = "instance_white_array";    private static final String INSTANCE_BLACK_ARRAY = "instance_black_array";    @Override    protected Parcelable onSaveInstanceState() {        Bundle bundle = new Bundle();        bundle.putParcelable(INSTANCE,super.onSaveInstanceState());        bundle.putBoolean(INSTANCE_GAME_OVER,mIsGameOver);        bundle.putParcelableArrayList(INSTANCE_WHITE_ARRAY,mWhiteArray);        bundle.putParcelableArrayList(INSTANCE_BLACK_ARRAY,mBlackArray);        return bundle;    }    @Override    protected void onRestoreInstanceState(Parcelable state) {        if(state instanceof Bundle){            Bundle bundle = (Bundle) state;            mIsGameOver = bundle.getBoolean(INSTANCE_GAME_OVER);            mWhiteArray = bundle.getParcelableArrayList(INSTANCE_WHITE_ARRAY);            mBlackArray = bundle.getParcelableArrayList(INSTANCE_BLACK_ARRAY);            super.onRestoreInstanceState(bundle.getParcelable(INSTANCE));            return ;        }        super.onRestoreInstanceState(state);    }}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@drawable/bg"    tools:context="com.xbmu.wuziqi.MainActivity">    <com.xbmu.wuziqi.WuziqiPanel        android:id="@+id/id_wuziqi"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_centerInParent="true" /></RelativeLayout>
运行效果:

再来一局&我要悔棋

Wuziqi.java
package com.xbmu.wuziqi;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Point;import android.os.Bundle;import android.os.Parcelable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.Toast;import java.util.ArrayList;import java.util.List;/** * 五子棋面板 * Created by Administrator on 2016/5/2 0002. */public class WuziqiPanel extends View {    private int mPanelWidth;//棋盘宽度    private float mLineHeight;//棋盘每行行高    private int MAX_LINE = 10;//棋盘最大行数    //创建绘画对象    private Paint mPaint = new Paint();    private Bitmap mWhitePiece;//白色棋子    private Bitmap mBlackPiece;//黑色棋子    //比例:棋子的大小是行高的3/4;    private float ratioPieceOfLineHeight = 3*1.0f / 4;    //白棋先手,当前轮到白棋。    private boolean mIsWhite = true;    private ArrayList<Point> mWhiteArray = new ArrayList<>();    private ArrayList<Point> mBlackArray = new ArrayList<>();    private boolean mIsGameOver;    private boolean mIsWhiteWinner;    private int MAX_COUNT_IN_LINE = 5;    public WuziqiPanel(Context context, AttributeSet attrs) {        super(context, attrs);        setBackgroundColor(0x44ff0000);        init();    }    /**初始化画笔属性*/    private void init() {        mPaint.setColor(0x88000000);//设置颜色为灰色效果        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setStyle(Paint.Style.STROKE);        mWhitePiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_w2);        mBlackPiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_b1);    }    /**测量一个view的大小*/    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(widthMeasureSpec);        int width = Math.min(widthSize,heightSize);        if(widthMode == MeasureSpec.UNSPECIFIED){            width = heightSize;        }else if(heightMode == MeasureSpec.UNSPECIFIED){            width = widthSize;        }        //设置自身大小        setMeasuredDimension(width,width);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mPanelWidth = w;        mLineHeight = mPanelWidth*1.0f / MAX_LINE;        int pieceWidth = (int) (mLineHeight * ratioPieceOfLineHeight);//棋子宽度        mWhitePiece = Bitmap.createScaledBitmap(mWhitePiece,pieceWidth,pieceWidth,false);        mBlackPiece = Bitmap.createScaledBitmap(mBlackPiece,pieceWidth,pieceWidth,false);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        int action = event.getAction();        if(action == MotionEvent.ACTION_DOWN){            int x = (int) event.getX();            int y = (int) event.getY();            Point p = getValidPoint(x,y);            if(mWhiteArray.contains(p) || mBlackArray.contains(p)){                return false;            }            if(mIsWhite){                mWhiteArray.add(p);            }else{                mBlackArray.add(p);            }            invalidate();//请求重绘            mIsWhite = !mIsWhite;            return true;        }        return super.onTouchEvent(event);    }    private Point getValidPoint(int x, int y) {        return new Point((int)(x/mLineHeight) ,(int)(y/mLineHeight));    }    private Canvas canvas;    /**Draw画出View的显示内容*/    @Override    protected void onDraw(Canvas canvas) {        this.canvas = canvas;        super.onDraw(canvas);        //绘制棋盘        drawBoard(canvas);        //绘制棋子        drawPieces(canvas);        //检查游戏结束        checkGameOver();    }    private void checkGameOver() {        boolean whiteWin = checkFiveInLine(mWhiteArray);        boolean blackWin = checkFiveInLine(mBlackArray);        if(whiteWin || blackWin){            mIsGameOver = true;            mIsWhiteWinner = whiteWin;            String text = mIsWhiteWinner ? "白棋胜利":"黑棋胜利";            Toast.makeText(getContext(),text,Toast.LENGTH_LONG).show();        }    }    private boolean checkFiveInLine(List<Point> points) {        for (Point p : points){            int x = p.x;            int y = p.y;            boolean win = checkHorizontal(x,y,points);            if(win) return true;            win = checkVertical(x,y,points);            if(win) return true;            win =checkLeftDiagonal(x,y,points);            if(win) return true;            win = checkRightDiagonal(x,y,points);            if(win) return true;        }        return false;    }    /**     * 判断x,y位置的棋子,是否横向有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkHorizontal(int x, int y, List<Point> points) {        int count = 1;        //左        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否纵向有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkVertical(int x, int y, List<Point> points) {        int count = 1;        //上        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x,y-i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x,y+i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否左斜有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkLeftDiagonal(int x, int y, List<Point> points) {        int count = 1;        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y+i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y-i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否右斜有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkRightDiagonal(int x, int y, List<Point> points) {        int count = 1;        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y-i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y+i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    private void drawPieces(Canvas canvas) {        for(int i=0,n = mWhiteArray.size(); i< n ;i++){            Point whitePoint = mWhiteArray.get(i);            canvas.drawBitmap(mWhitePiece,                    (whitePoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (whitePoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }        for(int i=0,n = mBlackArray.size(); i< n ;i++){            Point blackPoint = mBlackArray.get(i);            canvas.drawBitmap(mBlackPiece,                    (blackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (blackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }    }    private void drawPieces(Canvas canvas,int whiteCount,int blackCount) {        for(int i=0,n =whiteCount; i< n ;i++){            Point whitePoint = mWhiteArray.get(i);            canvas.drawBitmap(mWhitePiece,                    (whitePoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (whitePoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }        for(int i=0,n = blackCount; i< n ;i++){            Point blackPoint = mBlackArray.get(i);            canvas.drawBitmap(mBlackPiece,                    (blackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (blackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }    }    private void drawBoard(Canvas canvas) {        /**         * 分析:根据棋盘的效果,我们知道棋子是下在边界的交叉点上的。可得棋盘中间有9个完整的lineHeight,         * 上下两边有半个lineHeight,总共10个lineHeight。左右也是。         */        int w = mPanelWidth;        float lineHeight = mLineHeight;        for(int i=0;i<MAX_LINE;i++){            int startX = (int) (lineHeight / 2);//起点坐标            int endX = (int) (w - lineHeight / 2);//终点坐标            int y = (int) ((0.5+i)*lineHeight);            canvas.drawLine(startX,y,endX,y,mPaint);            canvas.drawLine(y,startX,y,endX,mPaint);        }    }    /**再来一局*/    public void reStart(){        mWhiteArray.clear();        mBlackArray.clear();        mIsGameOver = false;        mIsWhiteWinner = false;        invalidate();    }    //是否悔棋。true悔棋,false不悔棋    private boolean isBlack = true;    //悔棋    public void goRegret(){        //棋盘上无子        if(mWhiteArray.size() == 0 && mBlackArray.size() == 0){            return;        }        //棋盘上有子        if(mIsWhite){//下一步白棋先手            //上一步黑棋可以悔棋            mBlackArray.remove(mBlackArray.size()-1);        }else{//下一步黑棋先手手            //上一步白棋可以悔棋            mWhiteArray.remove(mWhiteArray.size()-1);        }        mIsWhite = !mIsWhite;        mIsGameOver = true;        mIsWhiteWinner = false;        invalidate();        isBlack = !isBlack;    }    private static final String INSTANCE = "instance";    private static final String INSTANCE_GAME_OVER = "instance_game_over";    private static final String INSTANCE_WHITE_ARRAY = "instance_white_array";    private static final String INSTANCE_BLACK_ARRAY = "instance_black_array";    @Override    protected Parcelable onSaveInstanceState() {        Bundle bundle = new Bundle();        bundle.putParcelable(INSTANCE,super.onSaveInstanceState());        bundle.putBoolean(INSTANCE_GAME_OVER,mIsGameOver);        bundle.putParcelableArrayList(INSTANCE_WHITE_ARRAY,mWhiteArray);        bundle.putParcelableArrayList(INSTANCE_BLACK_ARRAY,mBlackArray);        return bundle;    }    @Override    protected void onRestoreInstanceState(Parcelable state) {        if(state instanceof Bundle){            Bundle bundle = (Bundle) state;            mIsGameOver = bundle.getBoolean(INSTANCE_GAME_OVER);            mWhiteArray = bundle.getParcelableArrayList(INSTANCE_WHITE_ARRAY);            mBlackArray = bundle.getParcelableArrayList(INSTANCE_BLACK_ARRAY);            super.onRestoreInstanceState(bundle.getParcelable(INSTANCE));            return ;        }        super.onRestoreInstanceState(state);    }}
MainActivity.java
package com.xbmu.wuziqi;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Button;public class MainActivity extends Activity {    private WuziqiPanel wuziqiPanel;    private Button btnRestart;    private Button btnRegret;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        wuziqiPanel  = (WuziqiPanel) findViewById(R.id.id_wuziqi);        btnRestart  = (Button) findViewById(R.id.btn_restart);        btnRegret = (Button) findViewById(R.id.btn_regret);        //再来一局        btnRestart.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                wuziqiPanel.reStart();            }        });        //我要悔棋        btnRegret.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                wuziqiPanel.goRegret();            }        });    }}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@drawable/bg"    tools:context="com.xbmu.wuziqi.MainActivity">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal"        android:id="@+id/ll_top"        android:gravity="center">        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="再来一局"            android:id="@+id/btn_restart"/>        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/btn_regret"            android:text="我要悔棋"/>    </LinearLayout>    <com.xbmu.wuziqi.WuziqiPanel        android:id="@+id/id_wuziqi"        android:layout_marginTop="10dp"        android:layout_below="@id/ll_top"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_centerHorizontal="true" /></RelativeLayout>
运行效果:


感谢慕课网提供的教学资料,源码下载:http://download.csdn.net/detail/btt2013/9508584
0 0