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

163 lines
4.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:aesthetica_wallpaper/models/puzzle_game_interface.dart';
/// 拖拽式拼图块数据模型
class DragPuzzlePiece {
final int id; // 唯一标识
final int correctRow; // 正确的行位置
final int correctCol; // 正确的列位置
final ImageProvider image; // 图片块
bool isPlaced; // 是否已放置到正确位置
int? currentRow; // 当前行位置(如果已放置)
int? currentCol; // 当前列位置(如果已放置)
DragPuzzlePiece({
required this.id,
required this.correctRow,
required this.correctCol,
required this.image,
this.isPlaced = false,
this.currentRow,
this.currentCol,
});
bool get isCorrectlyPlaced =>
isPlaced && currentRow == correctRow && currentCol == correctCol;
DragPuzzlePiece copyWith({
int? id,
int? correctRow,
int? correctCol,
ImageProvider? image,
bool? isPlaced,
int? currentRow,
int? currentCol,
}) {
return DragPuzzlePiece(
id: id ?? this.id,
correctRow: correctRow ?? this.correctRow,
correctCol: correctCol ?? this.correctCol,
image: image ?? this.image,
isPlaced: isPlaced ?? this.isPlaced,
currentRow: currentRow ?? this.currentRow,
currentCol: currentCol ?? this.currentCol,
);
}
}
/// 拖拽式拼图游戏状态
class DragPuzzleGame implements IPuzzleGame {
final List<DragPuzzlePiece> pieces; // 所有拼图块
final int gridRows; // 网格行数
final int gridCols; // 网格列数
final Duration elapsedTime; // 已用时间
final int moves; // 移动次数
final bool isComplete; // 是否完成
final String imagePath; // 原图路径
DragPuzzleGame({
required this.pieces,
required this.gridRows,
required this.gridCols,
this.elapsedTime = Duration.zero,
this.moves = 0,
this.isComplete = false,
required this.imagePath,
});
/// 获取未放置的拼图块
List<DragPuzzlePiece> get unplacedPieces =>
pieces.where((piece) => !piece.isPlaced).toList();
/// 获取已放置的拼图块
List<DragPuzzlePiece> get placedPieces =>
pieces.where((piece) => piece.isPlaced).toList();
/// 检查游戏是否完成
bool checkComplete() {
return pieces.every((piece) => piece.isCorrectlyPlaced);
}
/// 获取指定位置的拼图块
DragPuzzlePiece? getPieceAt(int row, int col) {
try {
return pieces.firstWhere(
(piece) =>
piece.isPlaced &&
piece.currentRow == row &&
piece.currentCol == col,
);
} catch (e) {
return null;
}
}
@override
String get difficultyLabel {
return '${gridRows}x$gridCols';
}
/// 获取星级评分
@override
int getStarRating() {
if (!isComplete) return 0;
final totalPieces = gridRows * gridCols;
final optimalMoves = totalPieces; // 理想情况下每个块只移动一次
final optimalTime = Duration(minutes: totalPieces ~/ 4); // 理想时间
int stars = 1;
if (moves <= optimalMoves && elapsedTime <= optimalTime) {
stars = 3;
} else if (moves <= optimalMoves * 1.5 ||
elapsedTime <= optimalTime * 1.5) {
stars = 2;
}
return stars;
}
DragPuzzleGame copyWith({
List<DragPuzzlePiece>? pieces,
int? gridRows,
int? gridCols,
Duration? elapsedTime,
int? moves,
bool? isComplete,
String? imagePath,
}) {
return DragPuzzleGame(
pieces: pieces ?? this.pieces,
gridRows: gridRows ?? this.gridRows,
gridCols: gridCols ?? this.gridCols,
elapsedTime: elapsedTime ?? this.elapsedTime,
moves: moves ?? this.moves,
isComplete: isComplete ?? this.isComplete,
imagePath: imagePath ?? this.imagePath,
);
}
}
/// 拖拽式拼图难度
enum DragPuzzleDifficulty {
beginner(2, 2, 'Beginner', '2x2'),
easy(3, 2, 'Easy', '3x2'),
medium(4, 3, 'Medium', '4x3'),
hard(5, 4, 'Hard', '5x4'),
expert(6, 5, 'Expert', '6x5');
final int rows;
final int cols;
final String label;
final String description;
const DragPuzzleDifficulty(
this.rows,
this.cols,
this.label,
this.description,
);
int get totalPieces => rows * cols;
}