| OLD | NEW | 
|    1 part of pop_pop_win.game; |    1 part of pop_pop_win.game; | 
|    2  |    2  | 
|    3 class Game { |    3 class Game { | 
|    4   final Field field; |    4   final Field field; | 
|    5   final Array2d<SquareState> _states; |    5   final Array2d<SquareState> _states; | 
|    6   final EventHandle<EventArgs> _updatedEvent = new EventHandle<EventArgs>(); |    6   final StreamController _updatedEvent = new StreamController(); | 
|    7   final EventHandle<GameState> _gameStateEvent = new EventHandle<GameState>(); |    7   final StreamController<GameState> _gameStateEvent = | 
 |    8       new StreamController<GameState>(); | 
|    8  |    9  | 
|    9   GameState _state; |   10   GameState _state; | 
|   10   int _bombsLeft; |   11   int _bombsLeft; | 
|   11   int _revealsLeft; |   12   int _revealsLeft; | 
|   12   DateTime _startTime; |   13   DateTime _startTime; | 
|   13   DateTime _endTime; |   14   DateTime _endTime; | 
|   14  |   15  | 
|   15   Game(Field field) : |   16   Game(Field field) | 
|   16     this.field = field, |   17       : this.field = field, | 
|   17     _state = GameState.reset, |   18         _state = GameState.reset, | 
|   18     _states = new Array2d<SquareState>(field.width, field.height, SquareState.hi
     dden) { |   19         _states = new Array2d<SquareState>(field.width, field.height, | 
 |   20           SquareState.hidden) { | 
|   19     assert(field != null); |   21     assert(field != null); | 
|   20     _bombsLeft = field.bombCount; |   22     _bombsLeft = field.bombCount; | 
|   21     _revealsLeft = field.length - field.bombCount; |   23     _revealsLeft = field.length - field.bombCount; | 
|   22   } |   24   } | 
|   23  |   25  | 
|   24   int get bombsLeft => _bombsLeft; |   26   int get bombsLeft => _bombsLeft; | 
|   25  |   27  | 
|   26   int get revealsLeft => _revealsLeft; |   28   int get revealsLeft => _revealsLeft; | 
|   27  |   29  | 
|   28   GameState get state => _state; |   30   GameState get state => _state; | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   71   bool canReveal(int x, int y) { |   73   bool canReveal(int x, int y) { | 
|   72     final currentSS = _states.get(x, y); |   74     final currentSS = _states.get(x, y); | 
|   73     if (currentSS == SquareState.hidden) { |   75     if (currentSS == SquareState.hidden) { | 
|   74       return true; |   76       return true; | 
|   75     } else if (_canChord(x, y)) { |   77     } else if (_canChord(x, y)) { | 
|   76       return true; |   78       return true; | 
|   77     } |   79     } | 
|   78     return false; |   80     return false; | 
|   79   } |   81   } | 
|   80  |   82  | 
|   81   List<Coordinate> reveal(int x, int y) { |   83   List<Point> reveal(int x, int y) { | 
|   82     _ensureStarted(); |   84     _ensureStarted(); | 
|   83     require(canReveal(x, y), "Item cannot be revealed."); |   85     require(canReveal(x, y), "Item cannot be revealed."); | 
|   84     final currentSS = _states.get(x, y); |   86     final currentSS = _states.get(x, y); | 
|   85  |   87  | 
|   86     List<Coordinate> reveals; |   88     List<Point> reveals; | 
|   87  |   89  | 
|   88     // normal reveal |   90     // normal reveal | 
|   89     if (currentSS == SquareState.hidden) { |   91     if (currentSS == SquareState.hidden) { | 
|   90       if (field.get(x, y)) { |   92       if (field.get(x, y)) { | 
|   91         _setLost(); |   93         _setLost(); | 
|   92         reveals = <Coordinate>[]; |   94         reveals = <Point>[]; | 
|   93       } else { |   95       } else { | 
|   94         reveals = _doReveal(x, y); |   96         reveals = _doReveal(x, y); | 
|   95       } |   97       } | 
|   96     } else if (_canChord(x, y)) { |   98     } else if (_canChord(x, y)) { | 
|   97       reveals = _doChord(x, y); |   99       reveals = _doChord(x, y); | 
|   98     } |  100     } | 
|   99     _update(); |  101     _update(); | 
|  100  |  102  | 
|  101     if (_state == GameState.lost) { |  103     if (_state == GameState.lost) { | 
|  102       return null; |  104       return null; | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  165           final adjFlags = _getAdjacentCount(x, y, SquareState.flagged); |  167           final adjFlags = _getAdjacentCount(x, y, SquareState.flagged); | 
|  166           if (adjFlags == adjCount) { |  168           if (adjFlags == adjCount) { | 
|  167             return true; |  169             return true; | 
|  168           } |  170           } | 
|  169         } |  171         } | 
|  170       } |  172       } | 
|  171     } |  173     } | 
|  172     return false; |  174     return false; | 
|  173   } |  175   } | 
|  174  |  176  | 
|  175   List<Coordinate> _doChord(int x, int y) { |  177   List<Point> _doChord(int x, int y) { | 
|  176     // this does not repeat a bunch of validations that have already happened |  178     // this does not repeat a bunch of validations that have already happened | 
|  177     // be careful |  179     // be careful | 
|  178     final currentSS = _states.get(x, y); |  180     final currentSS = _states.get(x, y); | 
|  179     assert(currentSS == SquareState.revealed); |  181     assert(currentSS == SquareState.revealed); | 
|  180  |  182  | 
|  181     final flagged = new List<int>(); |  183     final flagged = new List<int>(); | 
|  182     final hidden = new List<int>(); |  184     final hidden = new List<int>(); | 
|  183     final adjCount = field.getAdjacentCount(x, y); |  185     final adjCount = field.getAdjacentCount(x, y); | 
|  184     assert(adjCount > 0); |  186     assert(adjCount > 0); | 
|  185  |  187  | 
|  186     bool failed = false; |  188     bool failed = false; | 
|  187  |  189  | 
|  188     for (final i in field.getAdjacentIndices(x, y)) { |  190     for (final i in field.getAdjacentIndices(x, y)) { | 
|  189       if (_states[i] == SquareState.hidden) { |  191       if (_states[i] == SquareState.hidden) { | 
|  190         hidden.add(i); |  192         hidden.add(i); | 
|  191         if (field[i]) { |  193         if (field[i]) { | 
|  192           failed = true; |  194           failed = true; | 
|  193         } |  195         } | 
|  194       } else if (_states[i] == SquareState.flagged) { |  196       } else if (_states[i] == SquareState.flagged) { | 
|  195         flagged.add(i); |  197         flagged.add(i); | 
|  196       } |  198       } | 
|  197     } |  199     } | 
|  198  |  200  | 
|  199     // for now we assume counts have been checked |  201     // for now we assume counts have been checked | 
|  200     assert(flagged.length == adjCount); |  202     assert(flagged.length == adjCount); | 
|  201  |  203  | 
|  202     var reveals = <Coordinate>[]; |  204     var reveals = <Point>[]; | 
|  203  |  205  | 
|  204     // if any of the hidden are bombs, we've failed |  206     // if any of the hidden are bombs, we've failed | 
|  205     if (failed) { |  207     if (failed) { | 
|  206       // TODO: assert one of the flags must be wrong, right? |  | 
|  207       _setLost(); |  208       _setLost(); | 
|  208     } else { |  209     } else { | 
|  209       for (final i in hidden) { |  210       for (final i in hidden) { | 
|  210         final c = field.getCoordinate(i); |  211         final c = field.getCoordinate(i); | 
|  211         if (canReveal(c.item1, c.item2)) { |  212         if (canReveal(c.item1, c.item2)) { | 
|  212           reveals.addAll(reveal(c.item1, c.item2)); |  213           reveals.addAll(reveal(c.item1, c.item2)); | 
|  213         } |  214         } | 
|  214       } |  215       } | 
|  215     } |  216     } | 
|  216  |  217  | 
|  217     return reveals; |  218     return reveals; | 
|  218   } |  219   } | 
|  219  |  220  | 
|  220   List<Coordinate> _doReveal(int x, int y) { |  221   List<Point> _doReveal(int x, int y) { | 
|  221     assert(_states.get(x, y) == SquareState.hidden); |  222     assert(_states.get(x, y) == SquareState.hidden); | 
|  222     _states.set(x, y, SquareState.revealed); |  223     _states.set(x, y, SquareState.revealed); | 
|  223     _revealsLeft--; |  224     _revealsLeft--; | 
|  224     assert(_revealsLeft >= 0); |  225     assert(_revealsLeft >= 0); | 
|  225     var reveals = [new Coordinate(x, y)]; |  226     var reveals = [new Point(x, y)]; | 
|  226     if (_revealsLeft == 0) { |  227     if (_revealsLeft == 0) { | 
|  227       _setWon(); |  228       _setWon(); | 
|  228     } else if (field.getAdjacentCount(x, y) == 0) { |  229     } else if (field.getAdjacentCount(x, y) == 0) { | 
|  229       for (final i in field.getAdjacentIndices(x, y)) { |  230       for (final i in field.getAdjacentIndices(x, y)) { | 
|  230         if (_states[i] == SquareState.hidden) { |  231         if (_states[i] == SquareState.hidden) { | 
|  231           final c = field.getCoordinate(i); |  232           final c = field.getCoordinate(i); | 
|  232           reveals.addAll(_doReveal(c.item1, c.item2)); |  233           reveals.addAll(_doReveal(c.item1, c.item2)); | 
|  233           assert(state == GameState.started || state == GameState.won); |  234           assert(state == GameState.started || state == GameState.won); | 
|  234         } |  235         } | 
|  235       } |  236       } | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|  250   void _setLost() { |  251   void _setLost() { | 
|  251     assert(state == GameState.started); |  252     assert(state == GameState.started); | 
|  252     for (int i = 0; i < field.length; i++) { |  253     for (int i = 0; i < field.length; i++) { | 
|  253       if (field[i]) { |  254       if (field[i]) { | 
|  254         _states[i] = SquareState.bomb; |  255         _states[i] = SquareState.bomb; | 
|  255       } |  256       } | 
|  256     } |  257     } | 
|  257     _setState(GameState.lost); |  258     _setState(GameState.lost); | 
|  258   } |  259   } | 
|  259  |  260  | 
|  260   void _update() => _updatedEvent.add(EventArgs.empty); |  261   void _update() => _updatedEvent.add(null); | 
|  261  |  262  | 
|  262   void _setState(GameState value) { |  263   void _setState(GameState value) { | 
|  263     assert(value != null); |  264     assert(value != null); | 
|  264     assert(_state != null); |  265     assert(_state != null); | 
|  265     assert((_state == GameState.reset) == (_startTime == null)); |  266     assert((_state == GameState.reset) == (_startTime == null)); | 
|  266     if (_state != value) { |  267     if (_state != value) { | 
|  267       _state = value; |  268       _state = value; | 
|  268       if (_state == GameState.started) { |  269       if (_state == GameState.started) { | 
|  269         _startTime = new DateTime.now(); |  270         _startTime = new DateTime.now(); | 
|  270       } else if (gameEnded) { |  271       } else if (gameEnded) { | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|  286   int _getAdjacentCount(int x, int y, SquareState state) { |  287   int _getAdjacentCount(int x, int y, SquareState state) { | 
|  287     int val = 0; |  288     int val = 0; | 
|  288     for (final i in field.getAdjacentIndices(x, y)) { |  289     for (final i in field.getAdjacentIndices(x, y)) { | 
|  289       if (_states[i] == state) { |  290       if (_states[i] == state) { | 
|  290         val++; |  291         val++; | 
|  291       } |  292       } | 
|  292     } |  293     } | 
|  293     return val; |  294     return val; | 
|  294   } |  295   } | 
|  295 } |  296 } | 
| OLD | NEW |