Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 0 additions & 45 deletions examples/fwe/birdle/.gitignore

This file was deleted.

45 changes: 0 additions & 45 deletions examples/fwe/birdle/.metadata

This file was deleted.

5 changes: 3 additions & 2 deletions examples/fwe/birdle/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# birdle
# Birdle app

A new Flutter project.
Code excerpts for the Birdle example app built in
the [Flutter tutorial](https://docs.flutter.dev/learn/pathway/tutorial).
1 change: 0 additions & 1 deletion examples/fwe/birdle/analysis_options.yaml

This file was deleted.

50 changes: 25 additions & 25 deletions examples/fwe/birdle/lib/game.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,28 @@ enum HitType { none, hit, partial, miss, removed }

typedef Letter = ({String char, HitType type});

const legalWords = <String>["aback", "abase", "abate", "abbey", "abbot"];
const legalWords = <String>['aback', 'abase', 'abate', 'abbey', 'abbot'];

/// Legal guesses minus legal wordles
const legalGuesses = <String>[
"aback",
"abase",
"abate",
"abbey",
"abbot",
"abhor",
"abide",
"abled",
"abode",
"abort",
'aback',
'abase',
'abate',
'abbey',
'abbot',
'abhor',
'abide',
'abled',
'abode',
'abort',
];

/// This class holds game state for a single round of Bulls and Cows,
/// and exposes methods that a UI would need to manage the game state.
///
/// On it's own, this class won't manage a game. For example, it won't
/// call [startGame] on it's own. It assumes that a client will use it's
/// methods to progress through a game.
/// On its own, this class won't manage a game.
/// For example, it won't call [resetGame] on its own.
/// It assumes that a client will use its methods to progress through a game.
class Game {
Game({this.numAllowedGuesses = defaultNumGuesses, this.seed}) {
_wordToGuess = seed == null ? Word.random() : Word.fromSeed(seed!);
Expand Down Expand Up @@ -76,7 +76,7 @@ class Game {
bool get didWin {
if (_guesses.first.isEmpty) return false;

for (var letter in previousGuess) {
for (final letter in previousGuess) {
if (letter.type != HitType.hit) return false;
}

Expand All @@ -94,7 +94,7 @@ class Game {
// Doesn't move the game forward, only executes match logic.
Word matchGuessOnly(String guess) {
// The hidden word will be used by subsequent guesses.
var hiddenCopy = Word.fromString(_wordToGuess.toString());
final hiddenCopy = Word.fromString(_wordToGuess.toString());
return Word.fromString(guess).evaluateGuess(hiddenCopy);
}

Expand All @@ -112,16 +112,16 @@ class Word with IterableMixin<Letter> {
}

factory Word.fromString(String guess) {
var list = guess.toLowerCase().split('');
var letters = list
.map((String char) => (char: char, type: HitType.none))
final list = guess.toLowerCase().split('');
final letters = list
.map((char) => (char: char, type: HitType.none))
.toList();
return Word(letters);
}

factory Word.random() {
var rand = Random();
var nextWord = legalWords[rand.nextInt(legalWords.length)];
final rand = Random();
final nextWord = legalWords[rand.nextInt(legalWords.length)];
return Word.fromString(nextWord);
}

Expand All @@ -148,7 +148,7 @@ class Word with IterableMixin<Letter> {

@override
String toString() {
return _letters.map((Letter c) => c.char).join().trim();
return _letters.map((c) => c.char).join().trim();
}

// Used to play game in the CLI implementation
Expand All @@ -168,7 +168,7 @@ extension WordUtils on Word {
}

/// Compares two [Word] objects and returns a new [Word] that
/// has the same letters as the [this], but each [Letter]
/// has the same letters as this word, but each [Letter]
/// has new a [HitType] of either [HitType.hit],
/// [HitType.partial], or [HitType.miss].
Word evaluateGuess(Word other) {
Expand All @@ -188,12 +188,12 @@ extension WordUtils on Word {
for (var i = 0; i < other.length; i++) {
// If a letter in the hidden word is already marked as "removed",
// then it's already an exact match, so skip it
Letter targetLetter = other[i];
final targetLetter = other[i];
if (targetLetter.type != HitType.none) continue;

// loop through the guessed word onces for each letter in the hidden word
for (var j = 0; j < length; j++) {
Letter guessedLetter = this[j];
final guessedLetter = this[j];
// skip letters that have already been marked as exact matches
if (guessedLetter.type != HitType.none) continue;
// If this letter, which must not be in the same position, is the same,
Expand Down
16 changes: 10 additions & 6 deletions examples/fwe/birdle/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';

import 'game.dart';

void main() {
Expand All @@ -14,9 +15,12 @@ class MainApp extends StatelessWidget {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Align(alignment: Alignment.centerLeft, child: Text('Birdle')),
title: const Align(
alignment: Alignment.centerLeft,
child: Text('Birdle'),
),
),
body: Center(child: GamePage()),
body: const Center(child: GamePage()),
),
);
}
Expand All @@ -42,16 +46,16 @@ class _GamePageState extends State<GamePage> {
spacing: 5.0,
mainAxisAlignment: MainAxisAlignment.center,
children: [
for (var guess in _game.guesses)
for (final guess in _game.guesses)
Row(
spacing: 5.0,
mainAxisAlignment: MainAxisAlignment.center,
children: [
for (var letter in guess) Tile(letter.char, letter.type),
for (final letter in guess) Tile(letter.char, letter.type),
],
),
GuessInput(
onSubmitGuess: (String guess) {
onSubmitGuess: (guess) {
setState(() {
_game.guess(guess);
});
Expand Down Expand Up @@ -98,7 +102,7 @@ class GuessInput extends StatelessWidget {
controller: _textEditingController,
autofocus: true,
focusNode: _focusNode,
onSubmitted: (String input) {
onSubmitted: (input) {
_onSubmit();
},
),
Expand Down
1 change: 0 additions & 1 deletion examples/fwe/birdle/lib/step1_main.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// ignore_for_file: unused_import, unused_field, unused_local_variable, avoid_print, prefer_const_constructors_in_immutables, use_key_in_widget_constructors, sized_box_for_whitespace
import 'package:flutter/material.dart';

// #docregion main
Expand Down
4 changes: 3 additions & 1 deletion examples/fwe/birdle/lib/step2_main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// ignore_for_file: unused_import, unused_field, unused_local_variable, avoid_print, prefer_const_constructors_in_immutables, use_key_in_widget_constructors, sized_box_for_whitespace
// ignore_for_file: prefer_const_constructors

import 'package:flutter/material.dart';

import 'game.dart';

void main() {
Expand Down
2 changes: 1 addition & 1 deletion examples/fwe/birdle/lib/step2a_main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ignore_for_file: unused_import, unused_field, unused_local_variable, avoid_print, prefer_const_constructors_in_immutables, use_key_in_widget_constructors, sized_box_for_whitespace
import 'package:flutter/material.dart';

import 'game.dart';

// #docregion Tile
Expand Down
2 changes: 1 addition & 1 deletion examples/fwe/birdle/lib/step2b_main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ignore_for_file: unused_import, unused_field, unused_local_variable, avoid_print, prefer_const_constructors_in_immutables, use_key_in_widget_constructors, sized_box_for_whitespace
import 'package:flutter/material.dart';

import 'game.dart';

// #docregion Tile
Expand Down
4 changes: 3 additions & 1 deletion examples/fwe/birdle/lib/step2c_main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// ignore_for_file: unused_import, unused_field, unused_local_variable, avoid_print, prefer_const_constructors_in_immutables, use_key_in_widget_constructors, sized_box_for_whitespace
// ignore_for_file: sized_box_for_whitespace

import 'package:flutter/material.dart';

import 'game.dart';

// #docregion Tile
Expand Down
2 changes: 1 addition & 1 deletion examples/fwe/birdle/lib/step2d_main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ignore_for_file: unused_import, unused_field, unused_local_variable, avoid_print, prefer_const_constructors_in_immutables, use_key_in_widget_constructors, sized_box_for_whitespace
import 'package:flutter/material.dart';

import 'game.dart';

// #docregion Tile
Expand Down
2 changes: 1 addition & 1 deletion examples/fwe/birdle/lib/step2e_main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ignore_for_file: unused_import, unused_field, unused_local_variable, avoid_print, prefer_const_constructors_in_immutables, use_key_in_widget_constructors, sized_box_for_whitespace
import 'package:flutter/material.dart';

import 'game.dart';

// #docregion Tile
Expand Down
2 changes: 1 addition & 1 deletion examples/fwe/birdle/lib/step2f_main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ignore_for_file: unused_import, unused_field, unused_local_variable, avoid_print, prefer_const_constructors_in_immutables, use_key_in_widget_constructors, sized_box_for_whitespace
import 'package:flutter/material.dart';

import 'game.dart';

// #docregion Tile
Expand Down
14 changes: 7 additions & 7 deletions examples/fwe/birdle/lib/step3_main.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
// ignore_for_file: unused_import, unused_field, unused_local_variable, avoid_print, prefer_const_constructors_in_immutables, use_key_in_widget_constructors, sized_box_for_whitespace
import 'package:flutter/material.dart';

import 'game.dart';
import 'step2_main.dart'
show Tile; // Use Tile from step2 for simplicity, or just define it here.

// But actually the excerpt tool just reads the file, so redefining `Tile` is fine, we just don't tag it.
class Tile extends StatelessWidget {
const Tile(this.letter, this.hitType, {super.key});
final String letter;
Expand All @@ -25,7 +22,10 @@ class MainApp extends StatelessWidget {
home: Scaffold(
// #docregion AppBar
appBar: AppBar(
title: Align(alignment: Alignment.centerLeft, child: Text('Birdle')),
title: const Align(
alignment: Alignment.centerLeft,
child: Text('Birdle'),
),
),
// #enddocregion AppBar
body: Center(child: GamePage()),
Expand All @@ -51,12 +51,12 @@ class GamePage extends StatelessWidget {
spacing: 5.0,
children: [
// #docregion Rows
for (var guess in _game.guesses)
for (final guess in _game.guesses)
Row(
spacing: 5.0,
children: [
// #docregion TileLoop
for (var letter in guess) Tile(letter.char, letter.type),
for (final letter in guess) Tile(letter.char, letter.type),
// #enddocregion TileLoop
],
),
Expand Down
4 changes: 3 additions & 1 deletion examples/fwe/birdle/lib/step3a_main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// ignore_for_file: unused_import, unused_field, unused_local_variable, avoid_print, prefer_const_constructors_in_immutables, use_key_in_widget_constructors, sized_box_for_whitespace
// ignore_for_file: unused_field

import 'package:flutter/material.dart';

import 'game.dart';

// #docregion GamePage
Expand Down
4 changes: 3 additions & 1 deletion examples/fwe/birdle/lib/step3b_main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// ignore_for_file: unused_import, unused_field, unused_local_variable, avoid_print, prefer_const_constructors_in_immutables, use_key_in_widget_constructors, sized_box_for_whitespace
// ignore_for_file: prefer_const_literals_to_create_immutables, unused_field, prefer_const_constructors

import 'package:flutter/material.dart';

import 'game.dart';

// #docregion GamePage
Expand Down
6 changes: 4 additions & 2 deletions examples/fwe/birdle/lib/step3c_main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// ignore_for_file: unused_import, unused_field, unused_local_variable, avoid_print, prefer_const_constructors_in_immutables, use_key_in_widget_constructors, sized_box_for_whitespace
// ignore_for_file: unused_local_variable, prefer_const_literals_to_create_immutables, prefer_const_constructors

import 'package:flutter/material.dart';

import 'game.dart';

// #docregion GamePage
Expand All @@ -15,7 +17,7 @@ class GamePage extends StatelessWidget {
child: Column(
spacing: 5.0,
children: [
for (var guess in _game.guesses)
for (final guess in _game.guesses)
Row(
spacing: 5.0,
children: [
Expand Down
Loading
Loading