五子棋

发到博客纯属为了保存资料,从imooc,所学;

链接:http://www.imooc.com/learn/641

运行效果

素材图片

新建五子棋类WuziqiPanel

package com.example.win10.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.support.annotation.Nullable;
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 win10 on 2017/10/31.
*/

public class WuziqiPanel extends View {

private int MAX_COUNT_IN_LINE=5;
private boolean mIsGameOver;
private boolean ismIsWhiteWinner;
private int mPanelWidth;
private float mLineHeight;
private int MAX_LINE=10;
private Paint mPaint=new Paint();
private Bitmap mWhitePiece;
private Bitmap mBlackPirece;
private float ratioPieceOfLineHeight=3*1.0f/4;
private ArrayList<Point> mWhiteArray=new ArrayList<>();
private ArrayList<Point> mBlackArray=new ArrayList<>();
//白棋先手,当前轮到白棋
private boolean mIsWhite=true;
public WuziqiPanel(Context context, @Nullable 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);
mBlackPirece= BitmapFactory.decodeResource(getResources(),R.drawable.stone_b1);
}
protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int width = Math.min(widthSize, heightSize);
if (widthMode == MeasureSpec.UNSPECIFIED) {
width = heightSize;
} else if (heightMode == MeasureSpec.UNSPECIFIED) {
width = widthSize;
}
setMeasuredDimension(width, width);
}
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);
mBlackPirece=Bitmap.createScaledBitmap(mBlackPirece,pieceWidth,pieceWidth,false);
}
public boolean onTouchEvent(MotionEvent event)
{
if(mIsGameOver)
return false;
int action=event.getAction();
if(action==MotionEvent.ACTION_UP)
{
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;
}

private Point getValidPoint(int x, int y) {
return new Point((int)(x/mLineHeight),(int)(y/mLineHeight));
}

protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
drawBoard(canvas);
drawPiece(canvas);
checkGameOver();
}

private void checkGameOver() {
boolean whiteWin=checkFiveInLine(mWhiteArray);
boolean blackWin=checkFiveInLine(mBlackArray);
String text;
if(whiteWin ||blackWin)
{
mIsGameOver=true;
ismIsWhiteWinner=whiteWin;
if(ismIsWhiteWinner)
{
text="白棋胜利";
}
else {
text= "黑棋胜利";
}
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=checkVetical(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;
}

private boolean checkHorizontal(int x, int y, List<Point> points) {
int count =1;
for(int i=1;i<MAX_COUNT_IN_LINE;i++)
{
if(points.contains(new Point(x-i,y)))
{
count++;
}
else
{
break;
}
}
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;
}
private boolean checkVetical(int x, int y, List<Point> points) {
int count =1;
for(int i=1;i<MAX_COUNT_IN_LINE;i++)
{
if(points.contains(new Point(x,y+i)))
{
count++;
}
else
{
break;
}
}
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;
}
private boolean checkLeftDiagonal(int x, int y, List<Point> points) {
int count =1;
for(int i=1;i<MAX_COUNT_IN_LINE;i++)
{
if(points.contains(new Point(x-i,y+i)))
{
count++;
}
else
{
break;
}
}
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 boolean checkRightDiagonal(int x, int y, List<Point> points) {
int count =1;
for(int i=1;i<MAX_COUNT_IN_LINE;i++)
{
if(points.contains(new Point(x-i,y-i)))
{
count++;
}
else
{
break;
}
}
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 drawPiece(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(mBlackPirece,(blackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,(blackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);
}
}


private void drawBoard(Canvas canvas)
{
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_arry";
private static final String INSTANCE_BLACK_ARRAY="instance_black_arry";


@Nullable
@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);
}

public void start()
{
mWhiteArray.clear();
mBlackArray.clear();
mIsGameOver=false;
mIsWhite=false;
invalidate();
}
}

NainActivity
package com.example.win10.wuziqi;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

private Button btn;
private WuziqiPanel wuziqiPanel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wuziqiPanel=(WuziqiPanel)findViewById(R.id.id_wuzhiqi);
btn=(Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
wuziqiPanel.start();
}
});
}

}
接下来是布局main_Activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg"
>

<com.example.win10.wuziqi.WuziqiPanel
android:id="@+id/id_wuzhiqi"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="150dp"
android:text="再来一局"/>
</RelativeLayout>





package com.example.win10.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.support.annotation.Nullable;
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 win10 on 2017/10/31.
*/

public class WuziqiPanel extends View {

private int MAX_COUNT_IN_LINE=5;
private boolean mIsGameOver;
private boolean ismIsWhiteWinner;
private int mPanelWidth;
private float mLineHeight;
private int MAX_LINE=10;
private Paint mPaint=new Paint();
private Bitmap mWhitePiece;
private Bitmap mBlackPirece;
private float ratioPieceOfLineHeight=3*1.0f/4;
private ArrayList<Point> mWhiteArray=new ArrayList<>();
private ArrayList<Point> mBlackArray=new ArrayList<>();
//白棋先手,当前轮到白棋
private boolean mIsWhite=true;
public WuziqiPanel(Context context, @Nullable 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);
mBlackPirece= BitmapFactory.decodeResource(getResources(),R.drawable.stone_b1);
}
protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int width = Math.min(widthSize, heightSize);
if (widthMode == MeasureSpec.UNSPECIFIED) {
width = heightSize;
} else if (heightMode == MeasureSpec.UNSPECIFIED) {
width = widthSize;
}
setMeasuredDimension(width, width);
}
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);
mBlackPirece=Bitmap.createScaledBitmap(mBlackPirece,pieceWidth,pieceWidth,false);
}
public boolean onTouchEvent(MotionEvent event)
{
if(mIsGameOver)
return false;
int action=event.getAction();
if(action==MotionEvent.ACTION_UP)
{
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;
}

private Point getValidPoint(int x, int y) {
return new Point((int)(x/mLineHeight),(int)(y/mLineHeight));
}

protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
drawBoard(canvas);
drawPiece(canvas);
checkGameOver();
}

private void checkGameOver() {
boolean whiteWin=checkFiveInLine(mWhiteArray);
boolean blackWin=checkFiveInLine(mBlackArray);
String text;
if(whiteWin ||blackWin)
{
mIsGameOver=true;
ismIsWhiteWinner=whiteWin;
if(ismIsWhiteWinner)
{
text="白棋胜利";
}
else {
text= "黑棋胜利";
}
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=checkVetical(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;
}

private boolean checkHorizontal(int x, int y, List<Point> points) {
int count =1;
for(int i=1;i<MAX_COUNT_IN_LINE;i++)
{
if(points.contains(new Point(x-i,y)))
{
count++;
}
else
{
break;
}
}
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;
}
private boolean checkVetical(int x, int y, List<Point> points) {
int count =1;
for(int i=1;i<MAX_COUNT_IN_LINE;i++)
{
if(points.contains(new Point(x,y+i)))
{
count++;
}
else
{
break;
}
}
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;
}
private boolean checkLeftDiagonal(int x, int y, List<Point> points) {
int count =1;
for(int i=1;i<MAX_COUNT_IN_LINE;i++)
{
if(points.contains(new Point(x-i,y+i)))
{
count++;
}
else
{
break;
}
}
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 boolean checkRightDiagonal(int x, int y, List<Point> points) {
int count =1;
for(int i=1;i<MAX_COUNT_IN_LINE;i++)
{
if(points.contains(new Point(x-i,y-i)))
{
count++;
}
else
{
break;
}
}
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 drawPiece(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(mBlackPirece,(blackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,(blackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);
}
}


private void drawBoard(Canvas canvas)
{
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_arry";
private static final String INSTANCE_BLACK_ARRAY="instance_black_arry";


@Nullable
@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);
}

public void start()
{
mWhiteArray.clear();
mBlackArray.clear();
mIsGameOver=false;
mIsWhite=false;
invalidate();
}
}

原文地址:https://www.cnblogs.com/CY-947205926/p/7771692.html