OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 import 'dart:sky' as sky; | 5 import 'dart:sky' as sky; |
6 import 'dart:math'; | 6 import 'dart:math'; |
7 | 7 |
8 import 'package:sky/rendering/flex.dart'; | 8 import 'package:sky/rendering/flex.dart'; |
9 import 'package:sky/widgets/basic.dart'; | 9 import 'package:sky/widgets/basic.dart'; |
| 10 import 'package:sky/widgets/scaffold.dart'; |
| 11 import 'package:sky/widgets/tool_bar.dart'; |
| 12 import 'package:sky/widgets/theme.dart'; |
| 13 import 'package:sky/theme/colors.dart' as colors; |
10 import 'package:sky/painting/text_style.dart'; | 14 import 'package:sky/painting/text_style.dart'; |
11 | 15 |
12 // Classic minesweeper-inspired game. The mouse controls are standard except | 16 // Classic minesweeper-inspired game. The mouse controls are standard except |
13 // for left + right combo which is not implemented. For touch, the duration of | 17 // for left + right combo which is not implemented. For touch, the duration of |
14 // the pointer determines probing versus flagging. | 18 // the pointer determines probing versus flagging. |
15 // | 19 // |
16 // There are only 3 classes to understand. Game, which is contains all the | 20 // There are only 3 classes to understand. Game, which is contains all the |
17 // logic and two UI classes: CoveredMineNode and ExposedMineNode, none of them | 21 // logic and two UI classes: CoveredMineNode and ExposedMineNode, none of them |
18 // holding state. | 22 // holding state. |
19 | 23 |
20 class Game { | 24 class Game { |
21 static const int rows = 9; | 25 static const int rows = 9; |
22 static const int cols = 9; | 26 static const int cols = 9; |
23 static const int totalMineCount = 11; | 27 static const int totalMineCount = 11; |
24 | 28 |
25 static const int coveredCell = 0; | 29 static const int coveredCell = 0; |
26 static const int explodedCell = 1; | 30 static const int explodedCell = 1; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 int ry = random.nextInt(cols); | 89 int ry = random.nextInt(cols); |
86 if (cells[ry][rx]) { | 90 if (cells[ry][rx]) { |
87 // Mine already there. Try again. | 91 // Mine already there. Try again. |
88 --mc; | 92 --mc; |
89 } else { | 93 } else { |
90 cells[ry][rx] = true; | 94 cells[ry][rx] = true; |
91 } | 95 } |
92 } | 96 } |
93 } | 97 } |
94 | 98 |
95 Widget generateBoard() { | 99 Widget buildBoard() { |
96 bool hasCoveredCell = false; | 100 bool hasCoveredCell = false; |
97 List<Flex> flexRows = new List<Flex>(); | 101 List<Flex> flexRows = new List<Flex>(); |
98 for (int iy = 0; iy != 9; iy++) { | 102 for (int iy = 0; iy != 9; iy++) { |
99 List<Component> row = new List<Component>(); | 103 List<Component> row = new List<Component>(); |
100 for (int ix = 0; ix != 9; ix++) { | 104 for (int ix = 0; ix != 9; ix++) { |
101 int state = uiState[iy][ix]; | 105 int state = uiState[iy][ix]; |
102 int count = mineCount(ix, iy); | 106 int count = mineCount(ix, iy); |
103 | 107 |
104 if (!alive) { | 108 if (!alive) { |
105 if (state != explodedCell) | 109 if (state != explodedCell) |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 key: 'minefield', | 149 key: 'minefield', |
146 padding: new EdgeDims.all(10.0), | 150 padding: new EdgeDims.all(10.0), |
147 margin: new EdgeDims.all(10.0), | 151 margin: new EdgeDims.all(10.0), |
148 decoration: new BoxDecoration(backgroundColor: const Color(0xFF6B6B6B)), | 152 decoration: new BoxDecoration(backgroundColor: const Color(0xFF6B6B6B)), |
149 child: new Flex( | 153 child: new Flex( |
150 flexRows, | 154 flexRows, |
151 direction: FlexDirection.vertical, | 155 direction: FlexDirection.vertical, |
152 key: 'flxv')); | 156 key: 'flxv')); |
153 } | 157 } |
154 | 158 |
155 Widget generateUI() { | 159 Widget buildToolBar() { |
156 Widget board = generateBoard(); | |
157 String banner = hasWon ? | 160 String banner = hasWon ? |
158 'Awesome!!' : alive ? | 161 'Awesome!!' : alive ? |
159 'Mine Digger [$detectedCount-$totalMineCount]': 'Kaboom! [press here]'; | 162 'Mine Digger [$detectedCount-$totalMineCount]': 'Kaboom! [press here]'; |
160 | 163 |
161 return new Flex([ | 164 return new ToolBar( |
162 new Container( | 165 // FIXME: Strange to have the toolbar be tapable. |
163 padding: new EdgeDims.all(10.0), | 166 center: new Listener( |
164 margin: new EdgeDims.all(10.0), | 167 onPointerDown: handleBannerPointerDown, |
165 decoration: new BoxDecoration(backgroundColor: const Color(0xFFC0C0C0)), | 168 child: new Text(banner, style: Theme.of(this.app).text.title) |
166 child: new Listener( | |
167 onPointerDown: handleBannerPointerDown, | |
168 child: new Text(banner))), | |
169 board, | |
170 new Container( | |
171 height: 100.0, width: 100.0, | |
172 decoration: new BoxDecoration(backgroundColor: const Color(0xFFCC1111)) | |
173 ) | 169 ) |
174 ], | 170 ); |
175 direction: FlexDirection.vertical, | 171 } |
176 justifyContent: FlexJustifyContent.spaceAround); | 172 |
| 173 Widget buildUI() { |
| 174 return new Scaffold( |
| 175 toolbar: buildToolBar(), |
| 176 body: new Container( |
| 177 child: new Center(child: buildBoard()), |
| 178 decoration: new BoxDecoration(backgroundColor: colors.Grey[50]) |
| 179 ) |
| 180 ); |
177 } | 181 } |
178 | 182 |
179 void handleBannerPointerDown(sky.PointerEvent event) { | 183 void handleBannerPointerDown(sky.PointerEvent event) { |
180 initialize(); | 184 initialize(); |
181 app.setState((){}); | 185 app.setState((){}); |
182 } | 186 } |
183 | 187 |
184 // User action. The user uncovers the cell which can cause losing the game. | 188 // User action. The user uncovers the cell which can cause losing the game. |
185 void probe(int x, int y) { | 189 void probe(int x, int y) { |
186 if (!alive) | 190 if (!alive) |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 } | 354 } |
351 | 355 |
352 class MineDiggerApp extends App { | 356 class MineDiggerApp extends App { |
353 Game game; | 357 Game game; |
354 | 358 |
355 MineDiggerApp() { | 359 MineDiggerApp() { |
356 game = new Game(this); | 360 game = new Game(this); |
357 } | 361 } |
358 | 362 |
359 Widget build() { | 363 Widget build() { |
360 return game.generateUI(); | 364 return game.buildUI(); |
361 } | 365 } |
362 } | 366 } |
363 | 367 |
364 void main() { | 368 void main() { |
365 runApp(new MineDiggerApp()); | 369 runApp(new MineDiggerApp()); |
366 } | 370 } |
OLD | NEW |