Skip to content

Instantly share code, notes, and snippets.

@lesnitsky
Created July 12, 2023 13:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lesnitsky/75a55659638bf2875f2a0a20fe5fd322 to your computer and use it in GitHub Desktop.
Save lesnitsky/75a55659638bf2875f2a0a20fe5fd322 to your computer and use it in GitHub Desktop.
Recursive guessing game with patterns
import 'dart:io';
import 'dart:math';
final rng = Random();
sealed class State {
const State();
}
class UninitializedState extends State {
const UninitializedState();
}
sealed class Context {
const Context();
}
class Output extends State {
Output(String message) {
print(message);
}
}
class Input extends State {
final String? input = stdin.readLineSync();
}
class MaybeGuess {
MaybeGuess();
static State from(String string) {
try {
final num = int.parse(string);
return Guess(num);
} catch (e) {
return const InvalidInput();
}
}
}
class Guess extends State {
final int number;
Guess(this.number);
}
class InvalidInput extends State {
const InvalidInput();
}
class Gte extends State {
const Gte();
}
class Lte extends State {
const Lte();
}
class Success extends State {
const Success();
}
extension on int? {
State toState() => this == null ? InvalidInput() : Guess(this!);
}
State program(
int number, [
State state = const UninitializedState(),
]) {
try {
final State newState = switch (state) {
UninitializedState() => Output('Guess a number (h for help)'),
Output() => Input(),
Input(input: null) => Output('Enter a number'),
Input(input: '') => Output('Enter a number'),
Input(input: 'h') => Output('Guess a number between 0 and 100'),
Input(input: final String input) => int.tryParse(input).toState(),
InvalidInput() => Output('Enter a valid number'),
Guess(number: final g) when g > number => Gte(),
Guess(number: final g) when g < number => Lte(),
Guess(number: final g) when g == number => Success(),
Guess() => throw Exception('Why is this needed?'),
Gte() => Output('Too high'),
Lte() => Output('Too low'),
Success() => throw Success(),
};
return program(number, newState);
} on Success {
print('You guessed it!');
exit(0);
} catch (e) {
stderr.writeln(e.toString());
exit(1);
}
}
void main() {
program(rng.nextInt(100));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment