fork download
  1. #include <iostream>
  2. #include <functional>
  3. #include <string>
  4. #include <random>
  5. using namespace std;
  6.  
  7.  
  8. template<typename T>
  9. class Attemptor{
  10. public:
  11. struct Actions{
  12. function<T()> in;
  13. function<bool(T)> onCheck;
  14. function<void(T)> onSuccess;
  15. function<void(T)> onPartialFailure;
  16. function<void(T)> onTotalFailure;
  17. function<void()> onNoMoreAttemptsLeft;
  18. };
  19.  
  20. Attemptor(Actions actions, size_t maxFailures)
  21. : _actions(actions), _maxFailures(maxFailures), _failures(0){}
  22.  
  23. bool canAttempt() const{
  24. return !_success && _maxFailures > _failures;
  25. }
  26.  
  27. bool isDone() const{
  28. return _done;
  29. }
  30.  
  31. bool success() const{
  32. return _success;
  33. }
  34.  
  35. bool attempt(){
  36. if(!canAttempt()){
  37. _actions.onNoMoreAttemptsLeft();
  38. return false;
  39. };
  40. T in_result = _actions.in();
  41. if(_actions.onCheck(in_result)){
  42. _actions.onSuccess(in_result);
  43. return finishWithSuccessEq(true);
  44. }
  45. _failures += 1;
  46. if(canAttempt()) _actions.onPartialFailure(in_result);
  47. else {
  48. _actions.onTotalFailure(in_result);
  49. return finishWithSuccessEq(false);
  50. }
  51.  
  52. }
  53. private:
  54. bool finishWithSuccessEq(bool val){
  55. _done = true;
  56. return _success = val;
  57. }
  58. bool _done = false;
  59. bool _success = false;
  60. const Actions _actions;
  61. const size_t _maxFailures;
  62. size_t _failures;
  63. };
  64.  
  65. template<typename T>
  66. auto read(istream &in = cin){
  67. T var;
  68. in >> var;
  69. return var;
  70. }
  71.  
  72. int main() {
  73. size_t min = 1, max = 100, attempts = 10;
  74.  
  75. default_random_engine gen(0xCafeBabe);
  76. uniform_int_distribution<> dist(min, max);
  77.  
  78. auto number = dist(gen);
  79.  
  80. using attemptor_type = Attemptor<int>;
  81. using actions_type = typename attemptor_type::Actions;
  82.  
  83. auto attemptor = attemptor_type(
  84. actions_type{
  85. []{ return read<int>(); },
  86. [number](int in){ return in == number; },
  87. [](int res){cout << "Success with " << res << "!" << endl;},
  88. [number](int res){cout << (res<number? "<":">") << endl;},
  89. [](int res){cout << "Total failure with " << res << "!" << endl;},
  90. []{cout << "No more attempts left!" << endl;}
  91. }, attempts
  92. );
  93.  
  94. while(!attemptor.attempt());
  95. return 0;
  96. }
Success #stdin #stdout 0s 3284KB
stdin
1
100
10
90
20
80
30
70
40
60
50
stdout
<
>
<
>
Success with 20!