Files
flame_flip/lib/game/engine.dart

67 lines
1.6 KiB
Dart
Raw Normal View History

2026-06-10 18:23:39 +08:00
import 'dart:math';
import 'types.dart';
final Random _random = Random();
List<T> shuffleList<T>(List<T> arr) {
final a = List<T>.from(arr);
for (int i = a.length - 1; i > 0; i--) {
final int j = _random.nextInt(i + 1);
final T temp = a[i];
a[i] = a[j];
a[j] = temp;
}
return a;
}
List<CardModel> createDeck({
required int rows,
required int totalCards,
required int poolSize,
required List<String> allFaceIds,
}) {
if (totalCards <= 0) {
throw Exception('totalCards must be > 0');
}
if (totalCards.isOdd) {
throw Exception('totalCards must be even');
}
if (allFaceIds.isEmpty) {
throw Exception('allFaceIds must not be empty');
}
final pairs = totalCards ~/ 2;
final actualPoolSize = poolSize.clamp(1, allFaceIds.length);
final pool = shuffleList(allFaceIds).take(actualPoolSize).toList();
if (pool.isEmpty) {
throw Exception('pool must not be empty');
}
final List<String> picked = [];
if (pool.length >= pairs) {
picked.addAll(shuffleList(pool).take(pairs));
} else {
picked.addAll(pool);
final remain = pairs - pool.length;
for (int i = 0; i < remain; i++) {
picked.add(pool[_random.nextInt(pool.length)]);
}
}
final doubled = picked.expand((e) => [e, e]).toList();
final shuffled = shuffleList(doubled);
return shuffled.asMap().entries.map((entry) {
final idx = entry.key;
final faceId = entry.value;
return CardModel(
id: '$faceId-$idx-${_random.nextInt(1 << 32).toRadixString(16)}',
faceId: faceId,
isFlipped: false,
isMatched: false,
);
}).toList();
}