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.javapackage 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);
}
}
}
运行效果: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);
}
}
}
运行效果: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);
}
}
}
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>运行效果: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.javapackage 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://blog.csdn.net/btt2013/article/details/51298177