Created
July 12, 2023 13:53
-
-
Save lesnitsky/75a55659638bf2875f2a0a20fe5fd322 to your computer and use it in GitHub Desktop.
Recursive guessing game with patterns
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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