MoodCanvas/lib/providers/simple_puzzle_provider.dart
fengshengxiong 91b7eebbf2 接入TopON
2026-01-22 16:34:55 +08:00

252 lines
6.6 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:aesthetica_wallpaper/models/puzzle_game.dart';
/// 简化版拼图Provider用于快速测试
class SimplePuzzleProvider extends ChangeNotifier {
PuzzleGame? _currentGame;
Timer? _timer;
List<GameRecord> _records = [];
PuzzleGame? get currentGame => _currentGame;
List<GameRecord> get records => _records;
/// 创建简化版游戏(使用颜色块而不是图片)
void createSimpleGame({
required GameDifficulty difficulty,
GameMode mode = GameMode.classic,
}) {
// 停止之前的计时器
_timer?.cancel();
// 创建颜色块拼图
final pieces = _createColorPieces(difficulty.gridSize);
// 打乱拼图
_shufflePieces(pieces, difficulty.gridSize);
// 创建游戏
_currentGame = PuzzleGame(
pieces: pieces,
difficulty: difficulty,
mode: mode,
emptyPosition: mode == GameMode.classic ? pieces.length - 1 : null,
);
// 开始计时
_startTimer();
notifyListeners();
}
/// 创建颜色块拼图(用于测试)
List<PuzzlePiece> _createColorPieces(int gridSize) {
final pieces = <PuzzlePiece>[];
final colors = [
Colors.red,
Colors.blue,
Colors.green,
Colors.orange,
Colors.purple,
Colors.pink,
Colors.teal,
Colors.amber,
Colors.indigo,
Colors.cyan,
Colors.lime,
Colors.brown,
Colors.grey,
Colors.deepOrange,
Colors.lightBlue,
Colors.lightGreen,
Colors.yellow,
Colors.deepPurple,
Colors.blueGrey,
Colors.redAccent,
Colors.greenAccent,
Colors.blueAccent,
Colors.orangeAccent,
Colors.purpleAccent,
Colors.pinkAccent,
Colors.tealAccent,
Colors.amberAccent,
Colors.indigoAccent,
Colors.cyanAccent,
Colors.limeAccent,
Colors.black87,
Colors.black54,
Colors.black45,
Colors.black38,
Colors.black26,
Colors.black12,
];
for (int i = 0; i < gridSize * gridSize; i++) {
pieces.add(
PuzzlePiece(
id: i,
correctPosition: i,
currentPosition: i,
image: _createColorImage(colors[i % colors.length], i + 1),
),
);
}
return pieces;
}
/// 创建颜色图片
ImageProvider _createColorImage(Color color, int number) {
// 这里返回一个简单的颜色图片
// 实际实现中可以使用Canvas绘制带数字的颜色块
return NetworkImage(
'https://via.placeholder.com/100x100/${color.value.toRadixString(16).substring(2)}/FFFFFF?text=$number',
);
}
/// 打乱拼图
void _shufflePieces(List<PuzzlePiece> pieces, int gridSize) {
final random = math.Random();
// 执行多次随机交换
for (int i = 0; i < pieces.length * 5; i++) {
final index1 = random.nextInt(pieces.length);
final index2 = random.nextInt(pieces.length);
final temp = pieces[index1].currentPosition;
pieces[index1].currentPosition = pieces[index2].currentPosition;
pieces[index2].currentPosition = temp;
}
}
/// 移动拼图块
void movePiece(int pieceIndex) {
if (_currentGame == null || _currentGame!.isComplete) return;
final piece = _currentGame!.pieces[pieceIndex];
final gridSize = _currentGame!.gridSize;
if (_currentGame!.mode == GameMode.classic) {
// 滑动模式:只能移动到空格
if (!_canMoveToEmpty(piece.currentPosition, gridSize)) return;
final emptyPos = _currentGame!.emptyPosition!;
piece.currentPosition = emptyPos;
_currentGame = _currentGame!.copyWith(emptyPosition: pieceIndex);
}
// 增加步数
_currentGame = _currentGame!.copyWith(moves: _currentGame!.moves + 1);
// 检查是否完成
if (_currentGame!.checkComplete()) {
_completeGame();
}
notifyListeners();
}
/// 交换两个拼图块(交换模式)
void swapPieces(int index1, int index2) {
if (_currentGame == null || _currentGame!.isComplete) return;
if (_currentGame!.mode == GameMode.classic) return;
final piece1 = _currentGame!.pieces[index1];
final piece2 = _currentGame!.pieces[index2];
final temp = piece1.currentPosition;
piece1.currentPosition = piece2.currentPosition;
piece2.currentPosition = temp;
_currentGame = _currentGame!.copyWith(moves: _currentGame!.moves + 1);
if (_currentGame!.checkComplete()) {
_completeGame();
}
notifyListeners();
}
/// 检查是否可以移动到空格
bool _canMoveToEmpty(int position, int gridSize) {
final emptyPos = _currentGame!.emptyPosition!;
final row = position ~/ gridSize;
final col = position % gridSize;
final emptyRow = emptyPos ~/ gridSize;
final emptyCol = emptyPos % gridSize;
// 检查是否相邻
return (row == emptyRow && (col - emptyCol).abs() == 1) ||
(col == emptyCol && (row - emptyRow).abs() == 1);
}
/// 开始计时
void _startTimer() {
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
if (_currentGame != null && !_currentGame!.isComplete) {
_currentGame = _currentGame!.copyWith(
elapsedTime: _currentGame!.elapsedTime + const Duration(seconds: 1),
);
notifyListeners();
}
});
}
/// 完成游戏
void _completeGame() {
_timer?.cancel();
_currentGame = _currentGame!.copyWith(isComplete: true);
// 保存记录
final record = GameRecord(
imageId: 'color_test',
difficulty: _currentGame!.difficulty,
time: _currentGame!.elapsedTime,
moves: _currentGame!.moves,
stars: _currentGame!.getStarRating(),
completedAt: DateTime.now(),
);
_records.add(record);
}
/// 重新开始游戏
void restartGame() {
if (_currentGame == null) return;
_timer?.cancel();
_shufflePieces(_currentGame!.pieces, _currentGame!.gridSize);
_currentGame = _currentGame!.copyWith(
moves: 0,
elapsedTime: Duration.zero,
isComplete: false,
);
_startTimer();
notifyListeners();
}
/// 使用提示
void useHint() {
if (_currentGame == null || _currentGame!.isComplete) return;
// 简单提示:找到第一个不在正确位置的块
for (int i = 0; i < _currentGame!.pieces.length; i++) {
final piece = _currentGame!.pieces[i];
if (!piece.isCorrect) {
// 这里可以添加高亮显示逻辑
print('提示:块 ${piece.id} 应该在位置 ${piece.correctPosition}');
break;
}
}
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
}