You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android Studio中为Tic Tac Toe创建SQLite数据库并实现玩家计分?

嘿,这个需求其实很清晰,我来一步步带你实现Android Studio里用SQLite存储井字棋玩家的姓名和分数,并且在获胜时自动加分的功能~

1. 先写核心的SQLite数据库管理类(SQLiteOpenHelper子类)

首先你需要一个继承自SQLiteOpenHelper的类,用来创建数据库、管理表结构,这是操作SQLite的标准方式。

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class ScoreDBHelper extends SQLiteOpenHelper {
    // 数据库名和版本号
    private static final String DATABASE_NAME = "TicTacToeScores.db";
    private static final int DATABASE_VERSION = 1;

    // 玩家表的结构
    private static final String TABLE_PLAYERS = "players";
    private static final String COLUMN_ID = "_id";
    private static final String COLUMN_NAME = "name";
    private static final String COLUMN_SCORE = "score";

    // 创建表的SQL语句
    private static final String CREATE_TABLE_PLAYERS = "CREATE TABLE " + TABLE_PLAYERS + " ("
            + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
            + COLUMN_NAME + " TEXT UNIQUE NOT NULL, "
            + COLUMN_SCORE + " INTEGER DEFAULT 0)";

    public ScoreDBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // 创建玩家表
        db.execSQL(CREATE_TABLE_PLAYERS);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // 如果数据库版本更新,这里可以处理表结构变更(简单场景下直接删除旧表重建)
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_PLAYERS);
        onCreate(db);
    }
}

这里我把name设为UNIQUE,确保每个玩家姓名唯一,避免重复存储。

2. 封装数据库的增、查、改操作方法

接下来在ScoreDBHelper里添加具体的操作方法,方便主Activity调用:

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

// 继续在ScoreDBHelper类里添加以下方法:

// 添加新玩家(如果玩家已存在则不做操作)
public void addPlayer(String playerName) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(COLUMN_NAME, playerName);
    // insertWithOnConflict避免重复插入,当name重复时忽略
    db.insertWithOnConflict(TABLE_PLAYERS, null, values, SQLiteDatabase.CONFLICT_IGNORE);
    db.close();
}

// 根据玩家姓名获取当前分数
public int getPlayerScore(String playerName) {
    int score = 0;
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.query(TABLE_PLAYERS, new String[]{COLUMN_SCORE},
            COLUMN_NAME + "=?", new String[]{playerName},
            null, null, null);
    if (cursor != null && cursor.moveToFirst()) {
        score = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_SCORE));
        cursor.close();
    }
    db.close();
    return score;
}

// 更新玩家分数(获胜时加1)
public void updatePlayerScore(String playerName) {
    // 先获取当前分数,再加1
    int currentScore = getPlayerScore(playerName);
    int newScore = currentScore + 1;

    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(COLUMN_SCORE, newScore);
    // 根据姓名更新分数
    db.update(TABLE_PLAYERS, values, COLUMN_NAME + "=?", new String[]{playerName});
    db.close();
}
3. 在主Activity中关联数据库并处理获胜逻辑

现在回到你的主Activity,比如MainActivity,我们需要初始化数据库助手,然后在游戏检测到玩家获胜时调用分数更新方法。

第一步:初始化数据库助手

在Activity里声明全局变量:

private ScoreDBHelper dbHelper;

然后在onCreate方法里初始化:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    // 初始化数据库助手
    dbHelper = new ScoreDBHelper(this);
    
    // 假设你已经有玩家姓名的输入或选择逻辑,比如默认玩家叫"Player1"
    // 先确保玩家存在于数据库中
    dbHelper.addPlayer("Player1");
}

第二步:处理游戏获胜的逻辑

假设你已经有了判断玩家获胜的方法,比如checkWin(),当这个方法返回true时,调用我们的分数更新方法:

// 示例:当检测到玩家获胜时调用这个方法
private void onPlayerWin(String winningPlayerName) {
    // 注意:数据库操作不能在主线程执行,否则会触发ANR,这里用Coroutines处理(需要添加Coroutines依赖)
    CoroutineScope(Dispatchers.IO).launch {
        // 更新数据库分数
        dbHelper.updatePlayerScore(winningPlayerName);
        // 更新UI要切回主线程
        withContext(Dispatchers.Main) {
            // 比如更新界面上的分数显示
            int newScore = dbHelper.getPlayerScore(winningPlayerName);
            scoreTextView.setText("分数:" + newScore);
            Toast.makeText(MainActivity.this, winningPlayerName + "获胜!分数+1", Toast.LENGTH_SHORT).show();
        }
    }
}

如果你的项目还没用到Coroutines,也可以用AsyncTask(虽然官方不推荐,但简单场景下能用):

private class UpdateScoreTask extends AsyncTask<String, Void, Integer> {
    @Override
    protected Integer doInBackground(String... params) {
        String playerName = params[0];
        dbHelper.updatePlayerScore(playerName);
        return dbHelper.getPlayerScore(playerName);
    }

    @Override
    protected void onPostExecute(Integer newScore) {
        super.onPostExecute(newScore);
        scoreTextView.setText("分数:" + newScore);
        Toast.makeText(MainActivity.this, "获胜!分数+1", Toast.LENGTH_SHORT).show();
    }
}

// 调用方式:
new UpdateScoreTask().execute(winningPlayerName);
一些注意事项
  • 记得在Activity的onDestroy方法里关闭数据库助手,避免资源泄漏:
@Override
protected void onDestroy() {
    super.onDestroy();
    if (dbHelper != null) {
        dbHelper.close();
    }
}
  • 如果玩家姓名是动态输入的,要先调用addPlayer确保玩家存在,否则updatePlayerScore会因为找不到记录而无效。
  • 数据库操作一定要放在子线程,这是Android的规范,避免阻塞主线程导致界面卡顿或ANR。

这样整个流程就通了:玩家获胜→触发分数更新→数据库里的分数加1→界面同步显示新分数。

内容的提问来源于stack exchange,提问作者Lil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:28:54