Android五子连珠

绘制棋盘面板:

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

时间: 2024-10-25 19:35:25

Android五子连珠的相关文章

Cocos2d-x 小试牛刀五子连珠游戏

Cocos2d-x 小试牛刀五子连珠游戏 声明:本文游戏使用的是cocos2d-x-3.13的代码 游戏介绍 本文将介绍有Cocos编写经典游戏,五子连珠.游戏规则,有一个10*10的棋盘,里面有六种颜色的珠子,点击棋盘的珠子可以移动到任意有开放路径的位置,如果横.竖.斜.反斜可以连接相同颜色珠子数大于等于5个,就可以消除.如果移动珠子后没有消除珠子,则会增3个珠子,如果棋盘被所有珠子填满则游戏结束. 游戏界面如下: 游戏代码 游戏代码下载地址:https://pan.baidu.com/s/1

Android五种布局方式——LinearLayout、RelativeLayout、TableLayout....(四)

Android五种布局方式--LinearLayout.RelativeLayout .TableLayout.... Android使用XML声明界面布局 将程序的表现层和控制层分离 修改用户界面时,无需更改程序的源代码 可视化工具设计用户界面 Android五种布局方式 LinearLayout线性布局 AbsoluteLayout坐标布局 RelativeLayout相对布局 FrameLayout帧布局 TableLayout表格布局 GridLayout 1.LinearLayout线

HTML5+JS 《五子飞》游戏实现(一)规则

很久没写文章了,这个游戏其实已经写了有段时间了,一直没有完善,赶在新年之际,分享给大家. 该<五子飞>游戏,不是平常大家所说的<五子棋>,这个玩法简单,是我们老家儿时常玩的一种益智游戏,我们先来看看棋盘布局: 规则如下: 一.黑白双方(对方黑,我方白)各执五子,分别摆放在双方的边线上: 二.棋子只能走直线(斜的直线也是),不能转弯: 三.只要前面没有棋子(任何一方的)就可以跳格走: 四.可以夹死对方一个或可以挑对方两个棋子(以1表示黑子,0表示白子,-表示空白): 夹一个:任何一条

《BI那点儿事》三国数据分析系列——蜀汉五虎上将与魏五子良将武力分析,绝对的经典分析

献给广大的三国爱好者们,希望喜欢三国的朋友一起讨论,加深对传奇三国时代的了解 数据分析基础概念:集中趋势分析是指在大量测评数据分布中,测评数据向某点集中的情况.总体(population)是指客观存在的,并在同一性质的基础上结合起来的许多个别单位的整体,即具有某一特性的一类事物的全体,又叫母体或全域.简单地说,总体也就是我们所研究的性质相同个体的总和,用符号N表示.样本(sample),是指从总体中抽出的一部分个体.样本中所包含个体数目称样本容量或含量,用符号n表示.标准差与方差的区别:从公式上

HTML5+JS 《五子飞》游戏实现(五)移动棋子

上一章 我们知道了怎么处理两个重要的吃棋动作,想要吃对方的棋子,首先得移动自己的棋子.现在里沃特跟大家分享分享,怎么移动棋子. 想要移动棋子,在页面上,首先要点击一下要移动的棋子,然后再点击一下目标位置,如果可以移动,则把棋子移动的目标位置,原来的位置就要清空. 上面这句话,我们要分两步来处理:1.判断目标是否可移动:2.可以移动则移动棋子. 1.判断目标是否可移动. 首先移动时只能按直线,其次目标位置与原始位置之间不能有其他棋子: // 是否可移动 this.canMove = functio

HTML5+JS 《五子飞》游戏实现(二)路线分析和资源准备

上一节 里沃特与我们分享了<五子飞>的下棋规则,可能有些伙伴看得不清楚,像我们码农还是看到代码比较靠谱.下面就把可以走棋的路线跟大家说一下. 假设从左上角开始,以0开始编号,往右数(没看第一节棋盘的先去看一下)(因为路线比较简单,就直接写固定的数据了): 1.横着走有5条直线: var lines_h = [ [ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19], [20, 21, 22,

HTML5+JS 《五子飞》游戏实现(八)人机对战

要想实现人机对战,就必须让电脑自动下棋,而且要知道自动去查找对方的棋子,看看有没有可以挑一对的,有没有可以夹一个的,这样下起来才有意思. 当电脑用户下完棋后,电脑应立即搜索用户的棋子,然后如果没有被吃的,就再随机走一个棋子(要想让电脑成为下棋高手就不能随机下棋,要考虑下棋后会不会再被对方吃掉等等,这里只简单做随机下子了). 完整<五子飞>游戏人机对战:http://www.lyout.com/projects/Fiveflychess/FiveflyChess8.htm // 查找是否有可挑的

Android五种布局说明

AbsoluteLayout---->是一个按照绝对坐标定义的布局,由于使用绝对坐标去定位控件,因此要实现自适应界面时,应尽少使用 AbsoluteLayout . RelativeLayout---->最好在界面设计时 做好布局,尽少程序运行时 做控件布局的更改,因为 RelativeLayout布局里面的属性之间,很容易冲突 FrameLayout---->顾名思义跟帧有关,布局里所有的控件都被放到布局的左上角,并且一层覆盖一层. TableLayout + TableRow----

HTML5+JS 《五子飞》游戏实现(六)鼠标响应与多重选择

上一章我们提到了如果有多条线上的棋子可以被吃掉,那么游戏需要提示用户,让用户选择吃哪条线上的.另外因为是网页游戏,所以一定要实现鼠标单击棋子可以进行操作. 当鼠标移动棋子上面后,切换鼠标指针为手形,移开棋子后再切换回默认的状态: el.mousemove(function (e) { var o = el.offset(); var p = { x: e.clientX - o.left, y: e.clientY - o.top }; el.css("cursor", "d