Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coordinate trainer adjustements #1041

Merged
merged 6 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,22 @@ class CoordinateTrainingController extends _$CoordinateTrainingController {
void _finishTraining() {
// TODO save score in local storage here (and display high score and/or average score in UI)

stopTraining();
_updateTimer?.cancel();
state = CoordinateTrainingState(
lastGuess: state.lastGuess,
lastScore: state.score,
);
}

void stopTraining() {
_updateTimer?.cancel();
state = const CoordinateTrainingState();
}

void newTraining() {
state = const CoordinateTrainingState();
}

/// Generate a random square that is not the same as the [previous] square
Square _randomCoord({Square? previous}) {
while (true) {
Expand Down Expand Up @@ -100,6 +108,7 @@ class CoordinateTrainingState with _$CoordinateTrainingState {
@Default(null) Duration? timeLimit,
@Default(null) Duration? elapsed,
@Default(null) Guess? lastGuess,
@Default(null) int? lastScore,
}) = _CoordinateTrainingState;

bool get trainingActive => elapsed != null;
Expand Down
202 changes: 124 additions & 78 deletions lib/src/view/coordinate_training/coordinate_training_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,31 @@ class _Body extends ConsumerStatefulWidget {
class _BodyState extends ConsumerState<_Body> {
late Side orientation;

late bool computeRandomOrientation;
julien4215 marked this conversation as resolved.
Show resolved Hide resolved

Square? highlightLastGuess;

Timer? highlightTimer;

Side _randomSide() => Side.values[Random().nextInt(Side.values.length)];

void _setOrientation(SideChoice choice) {
setState(() {
orientation = switch (choice) {
SideChoice.white => Side.white,
SideChoice.black => Side.black,
SideChoice.random => Side.values[Random().nextInt(Side.values.length)],
SideChoice.random => _randomSide(),
};
computeRandomOrientation = false;
});
}

void _maybeSetOrientation() {
setState(() {
if (computeRandomOrientation) {
orientation = _randomSide();
}
computeRandomOrientation = true;
});
}

Expand Down Expand Up @@ -148,37 +162,32 @@ class _BodyState extends ConsumerState<_Body> {
],
),
if (trainingState.trainingActive)
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_Score(
score: trainingState.score,
size: boardSize / 8,
color: trainingState.lastGuess == Guess.incorrect
? context.lichessColors.error
: context.lichessColors.good,
),
FatButton(
semanticsLabel: 'Abort Training',
onPressed: ref
.read(
coordinateTrainingControllerProvider
.notifier,
)
.stopTraining,
child: const Text(
'Abort Training',
style: Styles.bold,
),
),
],
),
_ScoreAndTrainingButton(
scoreSize: boardSize / 8,
score: trainingState.score,
onPressed: ref
.read(
coordinateTrainingControllerProvider.notifier,
)
.stopTraining,
label: 'Abort Training',
)
else if (trainingState.lastScore != null)
_ScoreAndTrainingButton(
scoreSize: boardSize / 8,
score: trainingState.lastScore!,
onPressed: ref
.read(
coordinateTrainingControllerProvider.notifier,
)
.newTraining,
label: 'New Training',
)
else
Expanded(
child: _Settings(
onSideChoiceSelected: _setOrientation,
maybeSetOrientation: _maybeSetOrientation,
),
),
],
Expand Down Expand Up @@ -241,7 +250,7 @@ class _TimeBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.center,
alignment: Alignment.centerLeft,
child: SizedBox(
width: maxWidth * (timeFractionElapsed ?? 0.0),
height: 15.0,
Expand Down Expand Up @@ -290,6 +299,48 @@ class _CoordinateTrainingMenu extends ConsumerWidget {
}
}

class _ScoreAndTrainingButton extends ConsumerWidget {
const _ScoreAndTrainingButton({
required this.scoreSize,
required this.score,
required this.onPressed,
required this.label,
});

final double scoreSize;
final int score;
final VoidCallback onPressed;
final String label;

@override
Widget build(BuildContext context, WidgetRef ref) {
final trainingState = ref.watch(coordinateTrainingControllerProvider);

return Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_Score(
score: score,
size: scoreSize,
color: trainingState.lastGuess == Guess.incorrect
? context.lichessColors.error
: context.lichessColors.good,
),
FatButton(
semanticsLabel: label,
onPressed: onPressed,
child: Text(
label,
style: Styles.bold,
),
),
],
),
);
}
}

class _Score extends StatelessWidget {
const _Score({
required this.size,
Expand Down Expand Up @@ -337,9 +388,11 @@ class _Score extends StatelessWidget {
class _Settings extends ConsumerStatefulWidget {
const _Settings({
required this.onSideChoiceSelected,
required this.maybeSetOrientation,
});

final void Function(SideChoice) onSideChoiceSelected;
final VoidCallback maybeSetOrientation;

@override
ConsumerState<_Settings> createState() => _SettingsState();
Expand All @@ -351,61 +404,54 @@ class _SettingsState extends ConsumerState<_Settings> {
final trainingPrefs = ref.watch(coordinateTrainingPreferencesProvider);

return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
PlatformListTile(
title: Text(context.l10n.side),
trailing: Padding(
padding: Styles.horizontalBodyPadding,
child: Wrap(
spacing: 8.0,
children: SideChoice.values.map((choice) {
return ChoiceChip(
label: Text(sideChoiceL10n(context, choice)),
selected: trainingPrefs.sideChoice == choice,
showCheckmark: false,
onSelected: (selected) {
widget.onSideChoiceSelected(choice);
ref
.read(coordinateTrainingPreferencesProvider.notifier)
.setSideChoice(choice);
},
);
}).toList(),
),
),
Wrap(
spacing: 8.0,
children: SideChoice.values.map((choice) {
julien4215 marked this conversation as resolved.
Show resolved Hide resolved
return ChoiceChip(
label: Text(sideChoiceL10n(context, choice)),
selected: trainingPrefs.sideChoice == choice,
showCheckmark: false,
onSelected: (selected) {
widget.onSideChoiceSelected(choice);
ref
.read(coordinateTrainingPreferencesProvider.notifier)
.setSideChoice(choice);
},
);
}).toList(),
),
PlatformListTile(
title: Text(context.l10n.time),
trailing: Padding(
padding: Styles.horizontalBodyPadding,
child: Wrap(
spacing: 8.0,
children: TimeChoice.values.map((choice) {
return ChoiceChip(
label: timeChoiceL10n(context, choice),
selected: trainingPrefs.timeChoice == choice,
showCheckmark: false,
onSelected: (selected) {
if (selected) {
ref
.read(
coordinateTrainingPreferencesProvider.notifier,
)
.setTimeChoice(choice);
}
},
);
}).toList(),
),
),
Wrap(
spacing: 8.0,
children: TimeChoice.values.map((choice) {
return ChoiceChip(
label: timeChoiceL10n(context, choice),
selected: trainingPrefs.timeChoice == choice,
showCheckmark: false,
onSelected: (selected) {
if (selected) {
ref
.read(
coordinateTrainingPreferencesProvider.notifier,
)
.setTimeChoice(choice);
}
},
);
}).toList(),
),
FatButton(
semanticsLabel: 'Start Training',
onPressed: () => ref
.read(coordinateTrainingControllerProvider.notifier)
.startTraining(trainingPrefs.timeChoice.duration),
onPressed: () {
if (trainingPrefs.sideChoice == SideChoice.random) {
widget.maybeSetOrientation();
}
ref
.read(coordinateTrainingControllerProvider.notifier)
.startTraining(trainingPrefs.timeChoice.duration);
},
child: const Text(
// TODO l10n once script works
'Start Training',
Expand Down