安卓開發 五子棋遊戲

SanSanOtaku發表於2020-12-11

五子棋

Chess類

package com.example.gobang5.tools;

public class Chess {
  public enum Color {BLACK, WHITE, NONE}

  public Color color;

  public Chess() {
    this.color = Color.NONE;
  }

  public Color getColor() {
    return color;
  }

  public void setColor(Color color) {
    this.color = color;
  }
}

GameView

package com.example.gobang5.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import com.example.gobang5.tools.Chess;

import java.util.ArrayList;
import java.util.List;

public class GoBangView extends View {
  private List<Point> mEveryPlay;
  private Chess[][] mChessArray;
  private Paint mBgPaint, mLinePaint, mChessPaint;
  private boolean mIsBlack, mIsLock;
  private OnGameListener mListnere;

  private void init() {
    mEveryPlay = new ArrayList<>(255);

    mBgPaint = new Paint();
    mLinePaint = new Paint();
    mChessPaint = new Paint();

    mBgPaint.setAntiAlias(true);
    mLinePaint.setAntiAlias(true);
    mChessPaint.setAntiAlias(true);

    mBgPaint.setColor(Color.GRAY);
    mLinePaint.setColor(Color.BLACK);
    mChessPaint.setColor(Color.WHITE);

    mIsBlack = true;
    mIsLock = false;

    mChessArray = new Chess[15][15];

    for (int i = 0; i < mChessArray.length; i++) {
      for (int j = 0; j < mChessArray.length; j++) {
        mChessArray[i][j] = new Chess();
      }
    }
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int height = MeasureSpec.getSize(heightMeasureSpec);
    int width = MeasureSpec.getSize(widthMeasureSpec);

    int min = width < height ? width : height;

    setMeasuredDimension(min, min);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    int height = getMeasuredHeight();
    int width = getMeasuredWidth();
    int avg = height / 16;

    canvas.drawRect(0, 0, width, height, mBgPaint);
    for (int i = 1; i < 16; i++) {
      for (int j = 1; j < 16; j++) {
        canvas.drawLine(avg * i, avg, avg * i, height - avg, mLinePaint);
        canvas.drawLine(avg, avg * i, height - avg, avg * i, mLinePaint);
      }
    }

    for (int i = 1; i < 16; i++) {
      for (int j = 1; j < 16; j++) {
        switch (mChessArray[i - 1][j - 1].getColor()) {
          case BLACK:
            mChessPaint.setColor(Color.BLACK);
            break;
          case WHITE:
            mChessPaint.setColor(Color.WHITE);
            break;
          case NONE:
            continue;
        }

        canvas.drawCircle(avg * i, avg * j, avg / 2 - 0.5f, mChessPaint);
      }
    }

  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    if (mIsLock) {
      return true;
    }

    if (event.getAction() == MotionEvent.ACTION_DOWN) {
      float y = event.getY();
      float x = event.getX();

      Rect rect = createRect(x, y);
      Point point = queryPoint(rect);

      if (point != null) {
        addChess(point);
        mEveryPlay.add(point);

        if (isOver(point)) {
          Log.d("Over", "onTouchEvent: Over");
          if (mListnere != null) {
            mListnere.gameOver();
          }
        }

        mIsBlack = !mIsBlack;
      }
    }

    return super.onTouchEvent(event);
  }

  private boolean isOver(Point point) {
    int y = point.y;
    int x = point.x;
    Chess.Color color = mChessArray[x][y].getColor();
    return overA(x, y, color) || overB(x, y, color) || overC(x, y, color) || overD(x, y, color);
  }

  private boolean overD(int x, int y, Chess.Color color) {
    int count = 0;

    for (int i = x, j = y; i < mChessArray.length && j >= 0; i++, j--) {
      if (mChessArray[i][j].getColor() == color) {
        count++;
      } else {
        break;
      }
    }

    for (int i = x, j = y; i >= 0 && j < mChessArray[i].length; i--, j++) {
      if (mChessArray[i][j].getColor() == color) {
        count++;
      } else {
        break;
      }
    }


    return count > 5;
  }

  private boolean overC(int x, int y, Chess.Color color) {
    int count = 0;

    for (int i = x, j = y; i < mChessArray.length && j < mChessArray[i].length; i++, j++) {
      if (mChessArray[i][j].getColor() == color) {
        count++;
      } else {
        break;
      }
    }

    for (int i = x, j = y; i >= 0 && j >= 0; i--, j--) {
      if (mChessArray[i][j].getColor() == color) {
        count++;
      } else {
        break;
      }
    }

    return count > 5;
  }

  private boolean overB(int x, int y, Chess.Color color) {
    int count = 0;

    for (int i = x; i < mChessArray.length; i++) {
      if (mChessArray[i][y].getColor() == color) {
        count++;
      } else {
        break;
      }
    }

    for (int i = x; i >= 0; i--) {
      if (mChessArray[i][y].getColor() == color) {
        count++;
      } else {
        break;
      }
    }

    return count > 5;
  }

  private boolean overA(int x, int y, Chess.Color color) {
    int count = 0;

    for (int i = y; i < mChessArray.length; i++) {
      if (mChessArray[x][i].getColor() == color) {
        count++;
      } else {
        break;
      }
    }

    for (int i = y; i >= 0; i--) {
      if (mChessArray[x][i].getColor() == color) {
        count++;
      } else {
        break;
      }
    }

    return count > 5;
  }

  private void addChess(Point point) {
    if (mIsBlack) {
      mChessArray[point.x][point.y].setColor(Chess.Color.BLACK);
    } else {
      mChessArray[point.x][point.y].setColor(Chess.Color.WHITE);
    }
    invalidate();
  }

  private Point queryPoint(Rect rect) {
    int avg = getMeasuredHeight() / 16;

    for (int i = 1; i < 16; i++) {
      for (int j = 1; j < 16; j++) {
        if (rect.contains(i * avg, j * avg)) {
          Point point = new Point(i - 1, j - 1);
          if (mChessArray[i - 1][j - 1].getColor() == Chess.Color.NONE) {
            return point;
          }
        }
      }
    }

    return null;
  }

  private Rect createRect(float x, float y) {
    int slide = getMeasuredHeight() / 16;
    int left = (int) (x - slide / 2);
    int right = (int) (x + slide / 2);
    int top = (int) (y - slide / 2);
    int bottom = (int) (y + slide / 2);
    return new Rect(left, top, right, bottom);
  }


  public void regret() {
    if (mEveryPlay.isEmpty()) {
      return;
    }

    Point point = mEveryPlay.get(mEveryPlay.size() - 1);
    mChessArray[point.x][point.y].setColor(Chess.Color.NONE);
    mEveryPlay.remove(mEveryPlay.size() - 1);
    mIsBlack = !mIsBlack;
    invalidate();
  }

  public void again() {
    for (Chess[] chess : mChessArray) {
      for (Chess chess1 : chess) {
        chess1.setColor(Chess.Color.NONE);
      }
    }

    mEveryPlay.clear();
    mIsBlack = true;
    mIsLock = false;

    invalidate();
  }

  public interface OnGameListener {
    void gameOver();
  }

  public void setOnGameListener(OnGameListener listener) {
    this.mListnere = listener;
  }


  public boolean ismIsLock() {
    return mIsLock;
  }

  public void setmIsLock(boolean mIsLock) {
    this.mIsLock = mIsLock;
  }

  public GoBangView(Context context) {
    this(context, null);
  }

  public GoBangView(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public GoBangView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
  }
}

相關文章