Merge pull request #1840 from abarth/rm_examples
Remove address_book and mine_digger
This commit is contained in:
commit
f3b0136aa6
@ -1,12 +0,0 @@
|
|||||||
name: address_book
|
|
||||||
version: 0.0.2
|
|
||||||
material-design-icons:
|
|
||||||
- name: av/volume_up
|
|
||||||
- name: communication/email
|
|
||||||
- name: communication/phone
|
|
||||||
- name: content/add
|
|
||||||
- name: image/photo_camera
|
|
||||||
- name: maps/place
|
|
||||||
- name: navigation/check
|
|
||||||
- name: navigation/arrow_back
|
|
||||||
- name: social/person
|
|
@ -1,60 +0,0 @@
|
|||||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
final GlobalKey _kNameKey = new GlobalKey(debugLabel: 'name field');
|
|
||||||
final GlobalKey _kPhoneKey = new GlobalKey(debugLabel: 'phone field');
|
|
||||||
final GlobalKey _kEmailKey = new GlobalKey(debugLabel: 'email field');
|
|
||||||
final GlobalKey _kAddressKey = new GlobalKey(debugLabel: 'address field');
|
|
||||||
final GlobalKey _kRingtoneKey = new GlobalKey(debugLabel: 'ringtone field');
|
|
||||||
final GlobalKey _kNoteKey = new GlobalKey(debugLabel: 'note field');
|
|
||||||
|
|
||||||
class AddressBookHome extends StatelessComponent {
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return new Scaffold(
|
|
||||||
toolBar: new ToolBar(
|
|
||||||
center: new Text('Edit contact'),
|
|
||||||
right: <Widget>[
|
|
||||||
new IconButton(icon: 'navigation/check')
|
|
||||||
]
|
|
||||||
),
|
|
||||||
body: new Block(
|
|
||||||
children: <Widget>[
|
|
||||||
new AspectRatio(
|
|
||||||
aspectRatio: 16.0 / 9.0,
|
|
||||||
child: new Container(
|
|
||||||
decoration: new BoxDecoration(backgroundColor: Colors.purple[300])
|
|
||||||
)
|
|
||||||
),
|
|
||||||
new Input(key: _kNameKey, icon: 'social/person', labelText: 'Name', style: Typography.black.display1),
|
|
||||||
new Input(key: _kPhoneKey, icon: 'communication/phone', hintText: 'Phone'),
|
|
||||||
new Input(key: _kEmailKey, icon: 'communication/email', hintText: 'Email'),
|
|
||||||
new Input(key: _kAddressKey, icon: 'maps/place', hintText: 'Address'),
|
|
||||||
new Input(key: _kRingtoneKey, icon: 'av/volume_up', hintText: 'Ringtone'),
|
|
||||||
new Input(key: _kNoteKey, icon: 'content/add', hintText: 'Add note'),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
floatingActionButton: new FloatingActionButton(
|
|
||||||
child: new Icon(icon: 'image/photo_camera')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final ThemeData theme = new ThemeData(
|
|
||||||
brightness: ThemeBrightness.light,
|
|
||||||
primarySwatch: Colors.teal,
|
|
||||||
accentColor: Colors.pinkAccent[100]
|
|
||||||
);
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
runApp(new MaterialApp(
|
|
||||||
title: 'Address Book',
|
|
||||||
theme: theme,
|
|
||||||
routes: <String, RouteBuilder>{
|
|
||||||
'/': (RouteArguments args) => new AddressBookHome()
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
name: address_book
|
|
||||||
dependencies:
|
|
||||||
flutter:
|
|
||||||
path: ../../packages/flutter
|
|
@ -1,334 +0,0 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
|
|
||||||
// Classic minesweeper-inspired game. The mouse controls are standard
|
|
||||||
// except for left + right combo which is not implemented. For touch,
|
|
||||||
// the duration of the pointer determines probing versus flagging.
|
|
||||||
//
|
|
||||||
// There are only 3 classes to understand. MineDiggerApp, which is
|
|
||||||
// contains all the logic and two classes that describe the mines:
|
|
||||||
// CoveredMineNode and ExposedMineNode, none of them holding state.
|
|
||||||
|
|
||||||
// Colors for each mine count (0-8):
|
|
||||||
const List<Color> textColors = const <Color>[
|
|
||||||
const Color(0xFF555555),
|
|
||||||
const Color(0xFF0094FF), // blue
|
|
||||||
const Color(0xFF13A023), // green
|
|
||||||
const Color(0xFFDA1414), // red
|
|
||||||
const Color(0xFF1E2347), // black
|
|
||||||
const Color(0xFF7F0037), // dark red
|
|
||||||
const Color(0xFF000000),
|
|
||||||
const Color(0xFF000000),
|
|
||||||
const Color(0xFF000000),
|
|
||||||
];
|
|
||||||
|
|
||||||
final List<TextStyle> textStyles = textColors.map((Color color) {
|
|
||||||
return new TextStyle(color: color, fontWeight: FontWeight.bold, textAlign: TextAlign.center);
|
|
||||||
}).toList();
|
|
||||||
|
|
||||||
enum CellState { covered, exploded, cleared, flagged, shown }
|
|
||||||
|
|
||||||
class MineDigger extends StatefulComponent {
|
|
||||||
MineDiggerState createState() => new MineDiggerState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class MineDiggerState extends State<MineDigger> {
|
|
||||||
static const int rows = 9;
|
|
||||||
static const int cols = 9;
|
|
||||||
static const int totalMineCount = 11;
|
|
||||||
|
|
||||||
bool alive;
|
|
||||||
bool hasWon;
|
|
||||||
int detectedCount;
|
|
||||||
|
|
||||||
// |cells| keeps track of the positions of the mines.
|
|
||||||
List<List<bool>> cells;
|
|
||||||
// |uiState| keeps track of the visible player progess.
|
|
||||||
List<List<CellState>> uiState;
|
|
||||||
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
resetGame();
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetGame() {
|
|
||||||
alive = true;
|
|
||||||
hasWon = false;
|
|
||||||
detectedCount = 0;
|
|
||||||
// Initialize matrices.
|
|
||||||
cells = new List<List<bool>>.generate(rows, (int row) {
|
|
||||||
return new List<bool>.filled(cols, false);
|
|
||||||
});
|
|
||||||
uiState = new List<List<CellState>>.generate(rows, (int row) {
|
|
||||||
return new List<CellState>.filled(cols, CellState.covered);
|
|
||||||
});
|
|
||||||
// Place the mines.
|
|
||||||
Random random = new Random();
|
|
||||||
int minesRemaining = totalMineCount;
|
|
||||||
while (minesRemaining > 0) {
|
|
||||||
int pos = random.nextInt(rows * cols);
|
|
||||||
int row = pos ~/ rows;
|
|
||||||
int col = pos % cols;
|
|
||||||
if (!cells[row][col]) {
|
|
||||||
cells[row][col] = true;
|
|
||||||
minesRemaining--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PointerDownEventListener _pointerDownHandlerFor(int posX, int posY) {
|
|
||||||
return (PointerDownEvent event) {
|
|
||||||
if (event.buttons == 1) {
|
|
||||||
probe(posX, posY);
|
|
||||||
} else if (event.buttons == 2) {
|
|
||||||
flag(posX, posY);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildBoard() {
|
|
||||||
bool hasCoveredCell = false;
|
|
||||||
List<Row> flexRows = <Row>[];
|
|
||||||
for (int iy = 0; iy < rows; iy++) {
|
|
||||||
List<Widget> row = <Widget>[];
|
|
||||||
for (int ix = 0; ix < cols; ix++) {
|
|
||||||
CellState state = uiState[iy][ix];
|
|
||||||
int count = mineCount(ix, iy);
|
|
||||||
if (!alive) {
|
|
||||||
if (state != CellState.exploded)
|
|
||||||
state = cells[iy][ix] ? CellState.shown : state;
|
|
||||||
}
|
|
||||||
if (state == CellState.covered || state == CellState.flagged) {
|
|
||||||
row.add(new GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
if (state == CellState.covered)
|
|
||||||
probe(ix, iy);
|
|
||||||
},
|
|
||||||
onLongPress: () {
|
|
||||||
userFeedback.performHapticFeedback(HapticFeedbackType.longPress);
|
|
||||||
flag(ix, iy);
|
|
||||||
},
|
|
||||||
child: new Listener(
|
|
||||||
onPointerDown: _pointerDownHandlerFor(ix, iy),
|
|
||||||
child: new CoveredMineNode(
|
|
||||||
flagged: state == CellState.flagged,
|
|
||||||
posX: ix,
|
|
||||||
posY: iy
|
|
||||||
)
|
|
||||||
)
|
|
||||||
));
|
|
||||||
if (state == CellState.covered) {
|
|
||||||
// Mutating |hasCoveredCell| here is hacky, but convenient, same
|
|
||||||
// goes for mutating |hasWon| below.
|
|
||||||
hasCoveredCell = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
row.add(new ExposedMineNode(
|
|
||||||
state: state,
|
|
||||||
count: count
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flexRows.add(
|
|
||||||
new Row(
|
|
||||||
children: row,
|
|
||||||
justifyContent: FlexJustifyContent.center,
|
|
||||||
key: new ValueKey<int>(iy)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasCoveredCell) {
|
|
||||||
// all cells uncovered. Are all mines flagged?
|
|
||||||
if ((detectedCount == totalMineCount) && alive) {
|
|
||||||
hasWon = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Container(
|
|
||||||
padding: new EdgeDims.all(10.0),
|
|
||||||
margin: new EdgeDims.all(10.0),
|
|
||||||
decoration: new BoxDecoration(backgroundColor: const Color(0xFF6B6B6B)),
|
|
||||||
child: new Column(children: flexRows)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildToolBar(BuildContext context) {
|
|
||||||
String toolbarCaption = hasWon ?
|
|
||||||
'Awesome!!' : alive ?
|
|
||||||
'Mine Digger [$detectedCount-$totalMineCount]': 'Kaboom! [press here]';
|
|
||||||
|
|
||||||
return new ToolBar(
|
|
||||||
// FIXME: Strange to have the toolbar be tapable.
|
|
||||||
center: new Listener(
|
|
||||||
onPointerDown: handleToolbarPointerDown,
|
|
||||||
child: new Text(toolbarCaption, style: Theme.of(context).text.title)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
// We build the board before we build the toolbar because we compute the win state during build step.
|
|
||||||
Widget board = buildBoard();
|
|
||||||
return new Title(
|
|
||||||
title: 'Mine Digger',
|
|
||||||
child: new Scaffold(
|
|
||||||
toolBar: buildToolBar(context),
|
|
||||||
body: new Container(
|
|
||||||
child: new Center(child: board),
|
|
||||||
decoration: new BoxDecoration(backgroundColor: Colors.grey[50])
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleToolbarPointerDown(PointerDownEvent event) {
|
|
||||||
setState(() {
|
|
||||||
resetGame();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// User action. The user uncovers the cell which can cause losing the game.
|
|
||||||
void probe(int x, int y) {
|
|
||||||
if (!alive)
|
|
||||||
return;
|
|
||||||
if (uiState[y][x] == CellState.flagged)
|
|
||||||
return;
|
|
||||||
setState(() {
|
|
||||||
// Allowed to probe.
|
|
||||||
if (cells[y][x]) {
|
|
||||||
// Probed on a mine --> dead!!
|
|
||||||
uiState[y][x] = CellState.exploded;
|
|
||||||
alive = false;
|
|
||||||
} else {
|
|
||||||
// No mine, uncover nearby if possible.
|
|
||||||
cull(x, y);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// User action. The user is sure a mine is at this location.
|
|
||||||
void flag(int x, int y) {
|
|
||||||
setState(() {
|
|
||||||
if (uiState[y][x] == CellState.flagged) {
|
|
||||||
uiState[y][x] = CellState.covered;
|
|
||||||
--detectedCount;
|
|
||||||
} else {
|
|
||||||
uiState[y][x] = CellState.flagged;
|
|
||||||
++detectedCount;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recursively uncovers cells whose totalMineCount is zero.
|
|
||||||
void cull(int x, int y) {
|
|
||||||
if (!inBoard(x, y))
|
|
||||||
return;
|
|
||||||
if (uiState[y][x] == CellState.cleared)
|
|
||||||
return;
|
|
||||||
uiState[y][x] = CellState.cleared;
|
|
||||||
|
|
||||||
if (mineCount(x, y) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cull(x - 1, y);
|
|
||||||
cull(x + 1, y);
|
|
||||||
cull(x, y - 1);
|
|
||||||
cull(x, y + 1 );
|
|
||||||
cull(x - 1, y - 1);
|
|
||||||
cull(x + 1, y + 1);
|
|
||||||
cull(x + 1, y - 1);
|
|
||||||
cull(x - 1, y + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int mineCount(int x, int y) {
|
|
||||||
int count = 0;
|
|
||||||
count += bombs(x - 1, y);
|
|
||||||
count += bombs(x + 1, y);
|
|
||||||
count += bombs(x, y - 1);
|
|
||||||
count += bombs(x, y + 1 );
|
|
||||||
count += bombs(x - 1, y - 1);
|
|
||||||
count += bombs(x + 1, y + 1);
|
|
||||||
count += bombs(x + 1, y - 1);
|
|
||||||
count += bombs(x - 1, y + 1);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bombs(int x, int y) => inBoard(x, y) && cells[y][x] ? 1 : 0;
|
|
||||||
|
|
||||||
bool inBoard(int x, int y) => x >= 0 && x < cols && y >= 0 && y < rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildCell(Widget child) {
|
|
||||||
return new Container(
|
|
||||||
padding: new EdgeDims.all(1.0),
|
|
||||||
height: 27.0, width: 27.0,
|
|
||||||
decoration: new BoxDecoration(backgroundColor: const Color(0xFFC0C0C0)),
|
|
||||||
margin: new EdgeDims.all(2.0),
|
|
||||||
child: child
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildInnerCell(Widget child) {
|
|
||||||
return new Container(
|
|
||||||
padding: new EdgeDims.all(1.0),
|
|
||||||
margin: new EdgeDims.all(3.0),
|
|
||||||
height: 17.0, width: 17.0,
|
|
||||||
child: child
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class CoveredMineNode extends StatelessComponent {
|
|
||||||
|
|
||||||
CoveredMineNode({ this.flagged, this.posX, this.posY });
|
|
||||||
|
|
||||||
final bool flagged;
|
|
||||||
final int posX;
|
|
||||||
final int posY;
|
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
Widget text;
|
|
||||||
if (flagged)
|
|
||||||
text = buildInnerCell(new StyledText(elements : [textStyles[5], '\u2691']));
|
|
||||||
|
|
||||||
Container inner = new Container(
|
|
||||||
margin: new EdgeDims.all(2.0),
|
|
||||||
height: 17.0, width: 17.0,
|
|
||||||
decoration: new BoxDecoration(backgroundColor: const Color(0xFFD9D9D9)),
|
|
||||||
child: text
|
|
||||||
);
|
|
||||||
|
|
||||||
return buildCell(inner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ExposedMineNode extends StatelessComponent {
|
|
||||||
|
|
||||||
ExposedMineNode({ this.state, this.count });
|
|
||||||
|
|
||||||
final CellState state;
|
|
||||||
final int count;
|
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
StyledText text;
|
|
||||||
if (state == CellState.cleared) {
|
|
||||||
// Uncovered cell with nearby mine count.
|
|
||||||
if (count != 0)
|
|
||||||
text = new StyledText(elements : [textStyles[count], '$count']);
|
|
||||||
} else {
|
|
||||||
// Exploded mine or shown mine for 'game over'.
|
|
||||||
int color = state == CellState.exploded ? 3 : 0;
|
|
||||||
text = new StyledText(elements : [textStyles[color], '\u2600']);
|
|
||||||
}
|
|
||||||
return buildCell(buildInnerCell(text));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
runApp(new MineDigger());
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
name: mine_digger
|
|
||||||
dependencies:
|
|
||||||
flutter:
|
|
||||||
path: ../../packages/flutter
|
|
Loading…
x
Reference in New Issue
Block a user