- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:id="@+id/grid_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnWidth="40dp"
android:gravity="center"
android:numColumns="15"
android:stretchMode="columnWidth" />
<Button
android:id="@+id/btn_reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="重新开始"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp"/>
</RelativeLayout>
2.item_grid_view.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/btn_piece"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="1dp"
android:background="@color/colorWhite"
android:gravity="center"
android:textColor="@color/colorBlack"
android:textSize="18sp" />
3.MainActivity.java
import android.graphics.Point;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.GridView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private GridView mGridView;
private ChessboardAdapter mAdapter;
private List<Point> mPiecesList; // 当前棋盘上的所有棋子
private boolean mIsWhiteTurn = true; // 是否轮到白方下棋
private boolean mIsGameOver = false; // 游戏是否结束
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPiecesList = new ArrayList<>();
mGridView = findViewById(R.id.grid_view);
mAdapter = new ChessboardAdapter(this, mPiecesList);
mGridView.setAdapter(mAdapter);
Button btnReset = findViewById(R.id.btn_reset);
btnReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
resetGame();
}
});
mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
if (mIsGameOver) {
Toast.makeText(MainActivity.this, "游戏已结束,请重新开始!", Toast.LENGTH_SHORT).show();
return;
}
Point p = new Point(position / 15, position % 15);
if (mPiecesList.contains(p)) {
Toast.makeText(MainActivity.this, "该位置已经有棋子了!", Toast.LENGTH_SHORT).show();
return;
}
addPiece(p);
checkGameOver();
mIsWhiteTurn = !mIsWhiteTurn; // 切换下一回合
}
});
}
/**
* 在指定位置添加一枚棋子
*/
private void addPiece(Point p) {
int imageResId = mIsWhiteTurn ? R.drawable.white_piece : R.drawable.black_piece;
Piece piece = new Piece(p.x, p.y, imageResId);
mPiecesList.add(piece);
mAdapter.notifyDataSetChanged();
}
/**
* 重置游戏
*/
private void resetGame() {
mPiecesList.clear();
mAdapter.notifyDataSetChanged();
mIsWhiteTurn = true;
mIsGameOver = false;
}
/**
* 检查游戏是否结束
*/
private void checkGameOver() {
int[][] board = new int[15][15];
for (Point p : mPiecesList) {
board[p.x][p.y] = mPiecesList.indexOf(p) % 2 == 0 ? 1 : 2; // 1: 白子,2: 黑子
}
int result = ChessboardUtils.checkFiveInLine(board);
if (result == 1) {
Toast.makeText(this, "白方胜利!", Toast.LENGTH_SHORT).show();
mIsGameOver = true;
} else if (result == 2) {
Toast.makeText(this, "黑方胜利!", Toast.LENGTH_SHORT).show();
mIsGameOver = true;
}
}
}
4.ChessboardAdapter.java
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import java.util.List;
public class ChessboardAdapter extends BaseAdapter {
private Context mContext;
private List<Point> mPiecesList;
public ChessboardAdapter(Context context, List<Point> piecesList) {
mContext = context;
mPiecesList = piecesList;
}
@Override
public int getCount() {
return 15 * 15;
}
@Override
public Object getItem(int position) {
return mPiecesList.contains(new Point(position / 15, position % 15));
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Button btnPiece;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_grid_view, null);
btnPiece = convertView.findViewById(R.id.btn_piece);
convertView.setTag(btnPiece);
} else {
btnPiece = (Button) convertView.getTag();
}
Point p = new Point(position / 15, position % 15);
if (mPiecesList.contains(p)) {
int imageResId = mPiecesList.indexOf(p) % 2 == 0 ? R.drawable.white_piece : R.drawable.black_piece;
btnPiece.setBackgroundResource(imageResId);
} else {
btnPiece.setBackgroundResource(0);
}
btnPiece.setEnabled(!mPiecesList.contains(p)); // 已经有棋子的位置不能再下了
btnPiece.setBackgroundColor((p.x + p.y) % 2 == 0 ? Color.LTGRAY : Color.WHITE); // 棋盘格子颜色交替
return convertView;
}
}
5.ChessboardUtils.java
public class ChessboardUtils {
/**
* 判断是否有五子连线,返回胜方: 1 (白方) 或者 2 (黑方),如果没有返回 0。
*/
public static int checkFiveInLine(int[][] board) {
int rows = board.length;
int cols = board[0].length;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (board[i][j] == 0) continue;
// 水平方向
if (j < cols - 4 &&
board[i][j] == board[i][j + 1] &&
board[i][j] == board[i][j + 2] &&
board[i][j] == board[i][j + 3] &&
board[i][j] == board[i][j + 4]) {
return board[i][j];
}
// 竖直方向
if (i < rows - 4 &&
board[i][j] == board[i + 1][j] &&
board[i][j] == board[i + 2][j] &&
board[i][j] == board[i + 3][j] &&
board[i][j] == board[i + 4][j]) {
return board[i][j];
}
// 正斜线方向
if (i < rows - 4 && j < cols - 4 &&
board[i][j] == board[i + 1][j + 1] &&
board[i][j] == board[i + 2][j + 2] &&
board[i][j] == board[i + 3][j + 3] &&
board[i][j] == board[i + 4][j + 4]) {
return board[i][j];
}
// 反斜线方向
if (i >= 4 && j < cols - 4 &&
board[i][j] == board[i - 1][j + 1] &&
board[i][j] == board[i - 2][j + 2] &&
board[i][j] == board[i - 3][j + 3] &&
board[i][j] == board[i - 4][j + 4]) {
return board[i][j];
}
}
}
return 0; // 没有五子连线
}
}