Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Распутываем зависимости #8

Merged
merged 1 commit into from
Jul 24, 2021
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
4 changes: 3 additions & 1 deletion lib/data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import 'package:http/http.dart' as http;
import 'models.dart';

class Api {
static Future<List<Country>> fetchCountries() async {
const Api();

Future<List<Country>> fetchCountries() async {
final rawResponse =
await http.get(Uri.parse('https://restcountries.eu/rest/v2/all'));
final response = jsonDecode(rawResponse.body);
Expand Down
108 changes: 55 additions & 53 deletions lib/game.dart
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import 'dart:math';

import 'package:capitals/data.dart';
import 'package:flutter/material.dart';
import 'package:palette_generator/palette_generator.dart';

import 'data.dart';
import 'models.dart';

const _successGuess = 3;
const _successFake = 1;
const _fail = -1;
class GameLogic extends ChangeNotifier {
static const _successGuess = 3;
static const _successFake = 1;
static const _fail = -1;
static const countryLimit = 30;

const countryLimit = 30;

final _random = Random();

mixin GameMixin<T extends StatefulWidget> on State<T> {
var topScore = 0;
var score = 0;
var current = 0;
Expand All @@ -24,19 +21,18 @@ mixin GameMixin<T extends StatefulWidget> on State<T> {
PaletteGenerator? currentPalette;
PaletteGenerator? nextPalette;

_Colors colors = _Colors(Colors.grey, Colors.grey);
ColorPair colors = ColorPair(Colors.grey, Colors.grey);

bool get isCompleted => current == items.length;
final Random _random;
final Api _api;

Future<void> onInit() async {
await Assets.load();
await _onSetupGame();
await _onUpdatePalette();
}
GameLogic(this._random, this._api);

bool get isCompleted => current == items.length;

Future<void> _onSetupGame() async {
Future<void> onStartGame() async {
try {
var countries = await Api.fetchCountries();
var countries = await _api.fetchCountries();
countries = _countryWithImages(countries);
countries.shuffle(_random);
countries = countries.sublist(0, countryLimit);
Expand All @@ -45,33 +41,19 @@ mixin GameMixin<T extends StatefulWidget> on State<T> {
// TODO handle error
print(e);
}
await _onUpdatePalette();
}

Future<void> _onUpdatePalette() async {
final crt = currentPalette == null
? await PaletteGenerator.fromImageProvider(items[current].image)
: nextPalette;
final next = (current + 1) < items.length
? await PaletteGenerator.fromImageProvider(items[current + 1].image)
: null;
setState(() {
currentPalette = crt;
nextPalette = next;
colors = _buildColors(crt);
});
}

_Colors _buildColors(PaletteGenerator? palette) {
var mainColor = palette?.mutedColor?.color;
var secondColor = palette?.vibrantColor?.color;
final defaultColor =
mainColor ?? secondColor ?? Theme.of(context).backgroundColor;
mainColor = mainColor ?? defaultColor;
secondColor = secondColor ?? defaultColor;
return _Colors(mainColor, secondColor);
Future<void> onReset() async {
_updateCurrent(0);
_updateScore(0);
_updateTopScore(0);
final countries = items.map((e) => e.original).toList();
_updateItems(countries);
}

void onGuess(int index, bool isTrue, bool isActuallyTrue) async {
Future<void> onGuess(int index, bool isTrue) async {
final isActuallyTrue = items[current].fake != null;
var scoreUpdate = 0;
if (isTrue && isActuallyTrue) {
scoreUpdate = _successGuess;
Expand All @@ -88,20 +70,35 @@ mixin GameMixin<T extends StatefulWidget> on State<T> {
await _onUpdatePalette();
}

void reset() {
_updateCurrent(0);
_updateScore(0);
_updateTopScore(0);
final countries = items.map((e) => e.original).toList();
_updateItems(countries);
Future<void> _onUpdatePalette() async {
final crt = currentPalette == null
? await PaletteGenerator.fromImageProvider(items[current].image)
: nextPalette;
final next = (current + 1) < items.length
? await PaletteGenerator.fromImageProvider(items[current + 1].image)
: null;
_setState(() {
currentPalette = crt;
nextPalette = next;
colors = _buildColors(crt);
});
}

void _updateCurrent(int current) => setState(() => this.current = current);
ColorPair _buildColors(PaletteGenerator? palette) {
var mainColor = palette?.mutedColor?.color;
var secondColor = palette?.vibrantColor?.color;
final defaultColor = mainColor ?? secondColor ?? Colors.grey;
mainColor = mainColor ?? defaultColor;
secondColor = secondColor ?? defaultColor;
return ColorPair(mainColor, secondColor);
}

void _updateScore(int score) => setState(() => this.score = score);
void _updateCurrent(int current) => _setState(() => this.current = current);

void _updateScore(int score) => _setState(() => this.score = score);

void _updateTopScore(int topScore) =>
setState(() => this.topScore = topScore);
_setState(() => this.topScore = topScore);

void _updateItems(List<Country> countries) {
final originals = countries.sublist(0, countries.length ~/ 2);
Expand All @@ -115,7 +112,7 @@ mixin GameMixin<T extends StatefulWidget> on State<T> {
list.add(GameItem(fakes[i], fake: fakes[(i + 1) % fakes.length]));
}
list.shuffle(_random);
setState(() {
_setState(() {
items.clear();
items.addAll(list);
});
Expand All @@ -135,11 +132,16 @@ mixin GameMixin<T extends StatefulWidget> on State<T> {
})
.where((element) => element.index != -1)
.toList();

void _setState(VoidCallback callback) {
callback();
notifyListeners();
}
}

class _Colors {
class ColorPair {
final Color main;
final Color second;

const _Colors(this.main, this.second);
const ColorPair(this.main, this.second);
}
38 changes: 33 additions & 5 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import 'dart:math';

import 'package:capitals/models.dart';
import 'package:flutter/material.dart';
import 'package:tcard/tcard.dart';

import 'components.dart';
import 'data.dart';
import 'game.dart';

final _appName = '$countryLimit Capitals';
final _appName = '${GameLogic.countryLimit} Capitals';

void main() => runApp(App());

Expand Down Expand Up @@ -39,15 +41,40 @@ class HomePage extends StatefulWidget {
_HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with GameMixin<HomePage> {
class _HomePageState extends State<HomePage> {
TCardController _cardsController = TCardController();
final GameLogic game = GameLogic(Random(), const Api());

@override
void initState() {
super.initState();
game.addListener(_update);
onInit();
}

Future<void> onInit() async {
await Assets.load();
await game.onStartGame();
}

@override
void dispose() {
game.removeListener(_update);
super.dispose();
}

List<GameItem> get items => game.items;

int get current => game.current;

bool get isCompleted => game.isCompleted;

ColorPair get colors => game.colors;

int get score => game.score;

int get topScore => game.topScore;

@override
Widget build(BuildContext context) {
if (items.isEmpty) {
Expand Down Expand Up @@ -82,7 +109,7 @@ class _HomePageState extends State<HomePage> with GameMixin<HomePage> {
child: CompleteWidget(
score: score,
topScore: topScore,
onTap: reset,
onTap: () => game.onReset(),
),
)
: Center(
Expand Down Expand Up @@ -125,10 +152,9 @@ class _HomePageState extends State<HomePage> with GameMixin<HomePage> {
CapitalCard(key: ValueKey(e), item: e))
.toList(),
onForward: (index, info) {
onGuess(
game.onGuess(
index,
info.direction == SwipDirection.Right,
items[current].fake != null,
);
},
),
Expand All @@ -153,4 +179,6 @@ class _HomePageState extends State<HomePage> with GameMixin<HomePage> {
),
);
}

void _update() => setState(() {});
}