如何在Angular开发的井字棋中跟踪会话全局游戏统计数据?
我来帮你搞定这个会话级游戏统计的问题~ 核心思路是把统计数据从每次新建游戏都会重建的TicTacToeBoard对象里抽离出来,放到Angular的单例服务中——因为服务在整个会话生命周期里只会实例化一次,完美符合你「不随新棋盘重置」的需求。
下面是具体的实现步骤和代码示例:
1. 创建全局统计服务
首先新建一个专门管理统计数据的服务,它会负责存储、更新统计信息,并且默认是全局单例:
// tic-tac-toe-stats.service.ts import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' // 标记为全局单例服务 }) export class TicTacToeStatsService { totalGames = 0; xWins = 0; oWins = 0; draws = 0; constructor() { // 可选:页面刷新后保留统计,从localStorage读取 this.loadSavedStats(); } // 更新统计数据 updateStats(result: 'x' | 'o' | 'draw') { this.totalGames++; switch(result) { case 'x': this.xWins++; break; case 'o': this.oWins++; break; case 'draw': this.draws++; break; } // 可选:同步到localStorage this.saveStatsToLocal(); } // 重置统计(按需添加) resetStats() { this.totalGames = 0; this.xWins = 0; this.oWins = 0; this.draws = 0; this.saveStatsToLocal(); } // 从localStorage加载历史统计 private loadSavedStats() { const saved = localStorage.getItem('ticTacToeStats'); if (saved) { const stats = JSON.parse(saved); this.totalGames = stats.totalGames || 0; this.xWins = stats.xWins || 0; this.oWins = stats.oWins || 0; this.draws = stats.draws || 0; } } // 保存统计到localStorage private saveStatsToLocal() { localStorage.setItem('ticTacToeStats', JSON.stringify({ totalGames: this.totalGames, xWins: this.xWins, oWins: this.oWins, draws: this.draws })); } }
2. 修改棋盘类,依赖统计服务
让TicTacToeBoard注入统计服务,在游戏结束时调用服务的更新方法:
// tic-tac-toe-board.ts import { TicTacToeStatsService } from './tic-tac-toe-stats.service'; export class TicTacToeBoard { private currentPlayer: 'x' | 'o' = 'x'; private board: ('x' | 'o' | null)[][] = Array(3).fill(null).map(() => Array(3).fill(null)); // 注入统计服务 constructor(private statsService: TicTacToeStatsService) {} // 你的胜负判断逻辑(示例) private checkGameEnd(): 'x' | 'o' | 'draw' | null { // 这里写你原本的胜负/平局判断逻辑,返回对应的结果或null // 比如:检查行、列、对角线是否有相同符号,或者棋盘已满无胜负则返回'draw' } // 落子方法,结束时更新统计 makeMove(row: number, col: number): void { if (this.board[row][col] !== null || this.checkGameEnd()) return; this.board[row][col] = this.currentPlayer; const gameResult = this.checkGameEnd(); if (gameResult) { // 游戏结束,通知服务更新统计 this.statsService.updateStats(gameResult); // 这里可以加游戏结束的提示逻辑 } else { this.currentPlayer = this.currentPlayer === 'x' ? 'o' : 'x'; } } // 其他棋盘逻辑方法... }
3. 组件中使用服务,展示统计
在TicTacToeComponent中注入统计服务,用来展示数据,并且newGame方法只负责创建新棋盘:
// tic-tac-toe.component.ts import { Component, OnInit } from '@angular/core'; import { TicTacToeBoard } from './tic-tac-toe-board'; import { TicTacToeStatsService } from './tic-tac-toe-stats.service'; @Component({ selector: 'app-tic-tac-toe', templateUrl: './tic-tac-toe.component.html', styleUrls: ['./tic-tac-toe.component.css'] }) export class TicTacToeComponent implements OnInit { currentBoard: TicTacToeBoard; // 注入统计服务,供模板使用 constructor(public statsService: TicTacToeStatsService) {} ngOnInit(): void { this.newGame(); } newGame(): void { // 每次新建棋盘时,传入统计服务实例 this.currentBoard = new TicTacToeBoard(this.statsService); } }
4. 模板中展示统计数据
在组件模板里添加统计展示区域:
<!-- tic-tac-toe.component.html --> <div class="game-stats"> <h3>游戏统计</h3> <p>总游戏数: {{ statsService.totalGames }}</p> <p>X获胜: {{ statsService.xWins }}</p> <p>O获胜: {{ statsService.oWins }}</p> <p>平局: {{ statsService.draws }}</p> <button (click)="statsService.resetStats()">重置统计</button> </div> <!-- 你的棋盘渲染区域 --> <div class="tic-tac-toe-board"> <!-- 这里写你原本的棋盘格子渲染逻辑 --> </div> <button (click)="newGame()">开始新游戏</button>
这样一来,无论你点击多少次「开始新游戏」创建新棋盘,统计数据都会保存在单例服务里不会重置;甚至添加了localStorage逻辑后,页面刷新也能保留历史统计~
内容的提问来源于stack exchange,提问作者mosher912
相关产品推荐
相关产品推荐

