Android program ---- & gt; implementation of android wuziqi, android wuziqi

Source: Internet
Author: User

Android program ----> Implementation of android wuziqi, android wuziqi

I learned the wuziqi course on MOOC online. It feels good. Then I wrote an android program about Wuzi, from which I can still learn a lot. Now let's start the compilation of today's wuziqi program. For the program source code, see the link:

 

Directory navigation

 

Now, let's build a project step by step. The first is the following project structure:

Running:

Some code for preparation

I. Main activity MainActivity, which includes the following functions in the menu:

Public class MainActivity extends AppCompatActivity {private ChessBoardView chessBoardView; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); chessBoardView = (ChessBoardView) findViewById (R. id. boardView) ;}@ Override public boolean onOptionsItemSelected (MenuItem item) {int id = item. getItemId (); // if (id = R. id. action_setting) {chessBoardView. start (); return true;} return super. onOptionsItemSelected (item) ;}@ Override public boolean onCreateOptionsMenu (Menu menu) {getMenuInflater (). inflate (R. menu. menu_main, menu); return true ;}}

 

Ii. Convenient Maintenance and Management of Constants: Constants

Public class Constants {// five sub-links public final static int MAX_COUNT_IN_LINE = 5; // The number of rows on the board final static int MAX_LINE = 15; // check the direction of final static int HORIZONTAL = 0; final static int VERTICAL = 1; final static int LEFT_DIAGONAL = 2; final static int RIGHT_DIAGONAL = 4 ;}

 

3. added the View of the custom board in 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="@mipmap/bg"    tools:context="com.example.linux.mygobang.MainActivity">    <com.example.linux.mygobang.ChessBoardView        android:id="@+id/boardView"        android:layout_centerInParent="true"        android:layout_width="match_parent"        android:layout_height="match_parent" /></RelativeLayout>

 

4. Define the next menu in menu_main.xml:

<? Xml version = "1.0" encoding = "UTF-8"?> <Menu xmlns: tools = "http://schemas.android.com/tools" xmlns: android = "http://schemas.android.com/apk/res/android"> <item android: id = "@ + id/action_setting" android: title = "Next game" android: orderInCategory = "100" android: showAsAction = "never" tools: ignore = "AppCompatResource"/> </menu>

 

View of the custom board

The ChessBoardView class is the core of the entire program.

I. Initialization. the variables used in the program are also included in the following code:

// The width of the Board, which is also the length of private int mViewWidth; // The length of each cell of the Board private float maxLineHeight; private Paint paint = new Paint (); // define Bitmapprivate Bitmap mwhitePiece, mblackPiece; private float ratioPieceOfLineHeight = 3 * 1.0f/4; // determine whether the current falling piece is a white private boolean mIsWhite = true; // record the list of black and white pawns. private ArrayList <Point> mwhiteArray = new ArrayList <> (); private ArrayList <Point> mblackArray = new ArrayList <> (); // whether the game ends. private boolean mIsGameOver; // whether the game ends. Whether the game is a white-side victory. private boolean mIsWhiteWinner; public ChessBoardView (Context context, AttributeSet attrs) {super (context, attrs ); init ();} private void init () {paint. setColor (0x88000000); paint. setAntiAlias (true); paint. setDither (true); paint. setStyle (Paint. style. STROKE); mwhitePiece = BitmapFactory. decodeResource (getResources (), R. mipmap. stone_w2); mblackPiece = BitmapFactory. decodeResource (getResources (), R. mipmap. stone_b1 );}

 

2. The onMeasure method is used to measure the size of the View so that the length and width of the View are consistent.

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    int widthSize = MeasureSpec.getSize(widthMeasureSpec);    int widthModel = MeasureSpec.getMode(widthMeasureSpec);    int heightSize = MeasureSpec.getSize(heightMeasureSpec);    int heightModel = MeasureSpec.getMode(heightMeasureSpec);    int width = Math.min(widthSize, heightSize);    if (widthModel == MeasureSpec.UNSPECIFIED) {        width = heightSize;    } else if (heightModel == MeasureSpec.UNSPECIFIED) {        width = widthSize;    }    setMeasuredDimension(width, width);}

 

3. The onSizeChanged method is in the layout stage. If the View Size changes, this method is called.

@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {    super.onSizeChanged(w, h, oldw, oldh);    mViewWidth = w;    maxLineHeight = mViewWidth * 1.0f / Constants.MAX_LINE;    int pieceWidth = (int) (maxLineHeight * ratioPieceOfLineHeight);    mwhitePiece = Bitmap.createScaledBitmap(mwhitePiece, pieceWidth, pieceWidth, false);    mblackPiece = Bitmap.createScaledBitmap(mblackPiece, pieceWidth, pieceWidth, false);}

 

4. The onTouchEvent method processes the position of the pawns:

@Overridepublic 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 point = getValidPoint(x, y);        if (mwhiteArray.contains(point) || mblackArray.contains(point)) {            return false;        }        if (mIsWhite) {            mwhiteArray.add(point);        } else {            mblackArray.add(point);        }        invalidate();        mIsWhite = !mIsWhite;    }    return true;}

 

5. Draw the board in the onDraw method:

@ Overrideprotected void onDraw (Canvas canvas) {super. onDraw (canvas); // draw the canvas's grid drawBoard (canvas); // draw the canvas's black-and-white pawns drawPieces (canvas); // check whether the game is over checkGameOver ();}

 

6. Next, we will explain the process in detail one by one:

Draw the grid of the Board:

// Draw the private void drawBoard (Canvas canvas) {int w = mViewWidth; float lineHeight = maxLineHeight; for (int I = 0; I <Constants. 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, paint); canvas. drawLine (y, startX, y, endX, paint );}}

Draw the black and white chess pieces of the Board:

// Draw the private void drawPieces (Canvas canvas) {for (int I = 0, n = mwhiteArray. size (); I <n; I ++) {Point whitePoint = mwhiteArray. get (I); float left = (whitePoint. x + (1-ratioPieceOfLineHeight)/2) * maxLineHeight; float top = (whitePoint. y + (1-ratioPieceOfLineHeight)/2) * maxLineHeight; canvas. drawBitmap (mwhitePiece, left, top, null);} for (int I = 0, n = mblackArray. size (); I <n; I ++) {Point blackPoint = mblackArray. get (I); float left = (blackPoint. x + (1-ratioPieceOfLineHeight)/2) * maxLineHeight; float top = (blackPoint. y + (1-ratioPieceOfLineHeight)/2) * maxLineHeight; canvas. drawBitmap (mblackPiece, left, top, null );}}

Check whether the game is over:

// Check whether the game ends private void checkGameOver () {CheckWinner checkWinner = new CheckWinner (); boolean whiteWin = checkWinner. checkFiveInLineWinner (mwhiteArray); boolean blackWin = checkWinner. checkFiveInLineWinner (mblackArray); if (whiteWin | blackWin) {mIsGameOver = true; mIsWhiteWinner = whiteWin; String text = mIsWhiteWinner? "" ":" "; Toast. makeText (getContext (), text, Toast. LENGTH_SHORT). show ();}}

 

Save the mess and restore the Board

1. Save the residual State, for example, when switching the landscape:

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";@Overrideprotected Parcelable onSaveInstanceState() {    Bundle bundle = new Bundle();    bundle.putParcelable(INSTANCE, super.onSaveInstanceState());    bundle.putBoolean(INSTANCE_GAME_OVER, mIsGameOver);    bundle.putParcelableArrayList(INSTANCE_BLACK_ARRAY, mblackArray);    bundle.putParcelableArrayList(INSTANCE_WHITE_ARRAY, mwhiteArray);    return bundle;}

 

2. Restore the game from bundle:

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

 

3. added the logic for the next game:

// Public void start () {mwhiteArray. clear (); mblackArray. clear (); mIsGameOver = false; mIsWhiteWinner = false; invalidate ();}

 

Algorithms used to determine whether a game is over

In CheckWinner, check whether the "meters" font of the pawns in the checker are even five sub-beads:

I. In the check method, make judgments for different directions:

private boolean check(int x, int y, List<Point> points, int checkOri) {    int count = 1;    for (int i = 1; i < Constants.MAX_COUNT_IN_LINE; i++) {        switch (checkOri) {            case Constants.HORIZONTAL:                point1 = new Point(x - i, y);                break;            case Constants.VERTICAL:                point1 = new Point(x, y - i);                break;            case Constants.LEFT_DIAGONAL:                point1 = new Point(x - i, y + i);                break;            case Constants.RIGHT_DIAGONAL:                point1 = new Point(x + i, y + i);                break;        }        if (points.contains(point1)) {            count++;        } else {            break;        }    }    for (int i = 1; i < Constants.MAX_COUNT_IN_LINE; i++) {        switch (checkOri) {            case Constants.HORIZONTAL:                point2 = new Point(x + i, y);                break;            case Constants.VERTICAL:                point2 = new Point(x, y + i);                break;            case Constants.LEFT_DIAGONAL:                point2 = new Point(x + i, y - i);                break;            case Constants.RIGHT_DIAGONAL:                point2 = new Point(x - i, y - i);                break;        }        if (points.contains(point2)) {            count++;        } else {            break;        }    }    if (count == Constants.MAX_COUNT_IN_LINE) {        return true;    }    return false;}

 

2. Perform four direction checks:

// Lateral judgment private boolean checkHorizontal (int x, int y, List <Point> points) {checkModel = Constants. HORIZONTAL; return check (x, y, points, checkModel);} // vertical judgment private boolean checkVertical (int x, int y, List <Point> points) {checkModel = Constants. VERTICAL; return check (x, y, points, checkModel);} // determines the left oblique private boolean checkLeftDiagonal (int x, int y, List <Point> points) {checkModel = Constants. LEFT_DIAGONAL; return check (x, y, points, checkModel);} // right oblique judgment private boolean checkRighttDiagonal (int x, int y, List <Point> points) {checkModel = Constants. RIGHT_DIAGONAL; return check (x, y, points, checkModel );}

 

Iii. Determine whether the game is over:

private Point point1, point2;private int checkModel = -1;public boolean checkFiveInLineWinner(List<Point> points) {    for (Point point : points) {        int x = point.x;        int y = point.y;        if (checkHorizontal(x, y, points)) {            return true;        } else if (checkVertical(x, y, points)) {            return true;        } else if (checkLeftDiagonal(x, y, points)) {            return true;        } else if (checkRighttDiagonal(x, y, points)) {            return true;        }    }    return false;}

 

Links
  • Download wuziqi source code

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.