Development of Gobang based on android

Development of Gobang based on Android

requirement analysis

1 chessboard and chess drawing
Make the rules of the game according to the rules of Gobang
3 mouse response in the game, you need to click the mouse to play chess
4. Game mode: duel between two players, which is the first and which is the second
5. The form and function of chess pieces are divided into black and white. Each side holds one piece. The chess pieces are matched by black and white
Finish the game of five consecutive beads by playing chess

Flow chart

Basic architecture in android stdio

CheckWinner.java

  package com.example.wuziqi;
   import android.graphics.Point;
    import java.util.List;
/**
 * Created by Linux on 2016/4/8.
 */
public class CheckWinner {
    private Point point1, point2;
    private int checkModel = Constants.HORIZONTAL;
    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;
    }
    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;
    }
    // Horizontal judgement
    private boolean checkHorizontal(int x, int y, List<Point> points) {
        checkModel = Constants.HORIZONTAL;
        return check(x, y, points, checkModel);
    }

    // Vertical judgement
    private boolean checkVertical(int x, int y, List<Point> points) {
        checkModel = Constants.VERTICAL;
        return check(x, y, points, checkModel);
    }

    // Left oblique judgement
    private boolean checkLeftDiagonal(int x, int y, List<Point> points) {
        checkModel = Constants.LEFT_DIAGONAL;
        return check(x, y, points, checkModel);
    }

    // Right skew judgement
    private boolean checkRighttDiagonal(int x, int y, List<Point> points) {
        checkModel = Constants.RIGHT_DIAGONAL;
        return check(x, y, points, checkModel);
    }

}

ChessBoardView.java

package com.example.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.media.MediaPlayer;
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;

public class ChessBoardView extends View {
    // The width and length of the chessboard
    private int mViewWidth;
    // Length of each chessboard
    private float maxLineHeight;
    private Paint paint = new Paint();
    // Define Bitmap of black and white chess pieces
    private Bitmap mwhitePiece, mblackPiece;
    private float ratioPieceOfLineHeight = 3 * 1.0f / 4;

// Judge whether the currently dropped pieces are white
private boolean mIsWhite = true;
// A list to record the location of black and white pieces
private ArrayList<Point> mwhiteArray = new ArrayList<>();
private ArrayList<Point> mblackArray = new ArrayList<>();

// Is the game over
private boolean mIsGameOver;
// The end of the game, whether it is a white square 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);
}

@Override
protected 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);
}
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // Draw the grid of chessboard
    drawBoard(canvas);
    // Black and white pieces for drawing chessboard
    drawPieces(canvas);
    // Check if the game is over
    checkGameOver();
}
// Check if the game is over
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 ? "Victory in white chess" : "Black victory";
        Toast.makeText(getContext(), text, Toast.LENGTH_SHORT).show();
    }
}
// Draw pieces from an array of black and white pieces
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);
    }
}
// Draw the net line of chessboard
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);
    }
}
@Override
protected 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);
}
@Override
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 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;
}
private Point getValidPoint(int x, int y) {
    int validX = (int) (x / maxLineHeight);
    int validY = (int) (y / maxLineHeight);
    return new Point(validX, validY);
}
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_BLACK_ARRAY, mblackArray);
    bundle.putParcelableArrayList(INSTANCE_WHITE_ARRAY, mwhiteArray);
    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);
}
// Another round.
public void start() {
    mwhiteArray.clear();
    mblackArray.clear();
    mIsGameOver = false;
    mIsWhiteWinner = false;
    invalidate();
}

}

Constants.java

 package com.example.wuziqi;

/**
 * Created by Linux on 2016/4/8.
 */
public class Constants {

    // color ball
    public final static int MAX_COUNT_IN_LINE = 5;
    // Lines of chessboard
    final static int MAX_LINE = 25;

    // Direction of inspection
    final static int HORIZONTAL = 0;
    final static int VERTICAL = 1;
    final static int LEFT_DIAGONAL = 2;
    final static int RIGHT_DIAGONAL = 3;
}

MainActivity.java

package com.example.wuziqi;

import android.content.Intent;
import android.os.Bundle;

import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;

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);
}
public void doClick(View v) {
    Intent intent = new Intent(MainActivity.this, MusicServer.class);
    switch (v.getId()) {
        case R.id.button1:
            this.startService(intent);
            break;
        case R.id.button2:
            this.stopService(intent);
            break;
    }
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    // Another round.
    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;
}

}

MusicServers.java

package com.example.wuziqi;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;
public class MusicServer extends Service {
    private MediaPlayer mp;
    public IBinder onBind(Intent intent) {
        Log.e("Service", "onBind Be called");
        mp.start();
        return null;
    }

    public void onCreate() {
        Log.e("Service", "onCreate Be called");
        mp = MediaPlayer.create(this, R.raw.yinyue);
        super.onCreate();
    }

    public void onDestroy() {
        Log.e("Service", "onDestroy Be called");
        mp.stop();
        super.onDestroy();
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("Service", "onStartCommand Be called");
        mp.start();
        return super.onStartCommand(intent, flags, startId);
    }

    public boolean onUnbind(Intent intent) {
        Log.e("Service", "onUnbind Be called");
        mp.stop();
        return super.onUnbind(intent);
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.wuziqi">

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

    </activity>
    <service
        android:name=".MusicServer"
        android:enabled="true"
        android:exported="true"></service>
</application>
</manifest>

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/bg1"
    tools:context="com.example.wuziqi.MainActivity">

    <com.example.wuziqi.ChessBoardView
        android:id="@+id/boardView"
        android:layout_centerInParent="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="16dp"
        android:onClick="doClick"
        android:text="Opening music" />

    <Button
        android:id="@+id/button2"
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button1"
        android:layout_alignStart="@+id/button1"
        android:layout_marginStart="94dp"
        android:layout_marginTop="-48dp"
        android:onClick="doClick"
        android:text="Stop music" />

</RelativeLayout>

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="Another round."
        android:orderInCategory="100"
        android:showAsAction="never"
        tools:ignore="AppCompatResource" />
    <item android:id="@+id/action_setting1"
        android:title="Regret game"
        android:orderInCategory="100"
        android:showAsAction="never"
        tools:ignore="AppCompatResource" />
</menu>

Operation result


Repentance is not realized because there is no time. If there is any problem, I hope you can help to correct it.

Published 5 original articles, won praise 2, visited 165
Private letter follow

Tags: Android Java xml MediaPlayer

Posted on Mon, 03 Feb 2020 08:27:17 -0800 by ramrod737