67 lines
1.6 KiB
Dart
67 lines
1.6 KiB
Dart
|
|
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();
|
||
|
|
}
|