Skip to content
Snippets Groups Projects
Commit d05ce606 authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Merge branch '9-clean-code' into 'master'

Resolve "Clean code"

Closes #9

See merge request !8
parents fcf5c889 2a06224d
No related branches found
1 merge request!8Resolve "Clean code"
Pipeline #2912 passed
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
app.versionName=0.0.5
app.versionCode=5
app.versionName=0.0.6
app.versionCode=6
Clean code, fix deprecations
Nettoyage de code, correction des deprecations
......@@ -133,8 +133,7 @@ class GameBoard {
// flipped. If so, the method returns true, otherwise false. If [flip] is set
// to true, the pieces are flipped in place to their new colors before the
// method returns.
bool _traversePath(
int x, int y, int dx, int dy, PieceType player, bool flip) {
bool _traversePath(int x, int y, int dx, int dy, PieceType player, bool flip) {
var foundOpponent = false;
var curX = x + dx;
var curY = y + dy;
......
......@@ -39,7 +39,7 @@ class GameModel {
/// returned. If unsuccessful, null is returned.
GameModel updateForMove(int x, int y) {
if (!board.isLegalMove(x, y, player)) {
return null!;
return GameModel(board: board, player: player);
}
final newBoard = board.updateForMove(x, y, player);
......
......@@ -7,7 +7,6 @@ import 'dart:async';
import 'package:async/async.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show SystemChrome, DeviceOrientation;
import 'package:flutter/widgets.dart';
import 'game_board.dart';
import 'game_model.dart';
......@@ -30,7 +29,6 @@ void main() {
class FlutterFlipApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
......@@ -56,10 +54,8 @@ class GameScreen extends StatefulWidget {
/// sent downstream. [GameScreen] uses a [StreamBuilder] wired up to that stream
/// of models to build out its [Widget] tree.
class _GameScreenState extends State<GameScreen> {
final StreamController<GameModel> _userMovesController =
StreamController<GameModel>();
final StreamController<GameModel> _restartController =
StreamController<GameModel>();
final StreamController<GameModel> _userMovesController = StreamController<GameModel>();
final StreamController<GameModel> _restartController = StreamController<GameModel>();
Stream<GameModel>? _modelStream;
_GameScreenState() {
......@@ -129,19 +125,18 @@ class _GameScreenState extends State<GameScreen> {
// turn, this method will attempt to make the move, creating a new GameModel
// in the process.
void _attemptUserMove(GameModel model, int x, int y) {
if (model.player == PieceType.black &&
model.board.isLegalMove(x, y, model.player)) {
if (model.player == PieceType.black && model.board.isLegalMove(x, y, model.player)) {
_userMovesController.add(model.updateForMove(x, y));
}
}
Widget _buildScoreBox(PieceType player, GameModel model) {
var assetImageCode = player == PieceType.black ? 'black' : 'white';
String assetImageName = 'assets/skins/' + model.skin + '_tile_' + assetImageCode + '.png';
String assetImageName =
'assets/skins/' + model.skin + '_tile_' + assetImageCode + '.png';
var scoreText = player == PieceType.black
? '${model.blackScore}'
: '${model.whiteScore}';
var scoreText =
player == PieceType.black ? '${model.blackScore}' : '${model.whiteScore}';
return Container(
padding: const EdgeInsets.symmetric(
......@@ -199,7 +194,11 @@ class _GameScreenState extends State<GameScreen> {
for (var x = 0; x < GameBoard.width; x++) {
PieceType pieceType = model.board.getPieceAtLocation(x, y);
String? assetImageCode = Styling.assetImageCodes[pieceType];
String assetImageName = 'assets/skins/' + model.skin + '_tile_' + (assetImageCode != null ? assetImageCode : 'empty') + '.png';
String assetImageName = 'assets/skins/' +
model.skin +
'_tile_' +
(assetImageCode != null ? assetImageCode : 'empty') +
'.png';
Column cell = Column(
children: [
......@@ -215,7 +214,9 @@ class _GameScreenState extends State<GameScreen> {
child: Image(
image: AssetImage(assetImageName),
fit: BoxFit.fill,
key: ValueKey<int>(pieceType == PieceType.empty ? 0 : (pieceType == PieceType.black ? 1 : 2)),
key: ValueKey<int>(pieceType == PieceType.empty
? 0
: (pieceType == PieceType.black ? 1 : 2)),
),
),
onTap: () {
......@@ -224,7 +225,7 @@ class _GameScreenState extends State<GameScreen> {
),
),
)
]
],
);
cells.add(cell);
......@@ -233,10 +234,7 @@ class _GameScreenState extends State<GameScreen> {
rows.add(TableRow(children: cells));
}
return Table(
defaultColumnWidth: IntrinsicColumnWidth(),
children: rows
);
return Table(defaultColumnWidth: IntrinsicColumnWidth(), children: rows);
}
Widget _buildThinkingIndicator(GameModel model) {
......@@ -262,25 +260,20 @@ class _GameScreenState extends State<GameScreen> {
Widget _buildEndGameWidget(GameModel model) {
Image decorationImage = Image(
image: AssetImage(
model.gameResultString == 'black'
image: AssetImage(model.gameResultString == 'black'
? 'assets/icons/game_win.png'
: 'assets/icons/empty.png'
),
: 'assets/icons/empty.png'),
fit: BoxFit.fill,
);
return Container(
margin: EdgeInsets.all(2),
padding: EdgeInsets.all(2),
child: Table(
defaultColumnWidth: IntrinsicColumnWidth(),
children: [
margin: EdgeInsets.all(2),
padding: EdgeInsets.all(2),
child: Table(defaultColumnWidth: IntrinsicColumnWidth(), children: [
TableRow(
children: [
Column(children: [ decorationImage ]),
Column(children: [ decorationImage ]),
Column(children: [decorationImage]),
Column(children: [decorationImage]),
Column(children: [
GestureDetector(
onTap: () {
......@@ -291,13 +284,11 @@ class _GameScreenState extends State<GameScreen> {
child: _buildRestartGameWidget(),
)
]),
Column(children: [ decorationImage ]),
Column(children: [ decorationImage ]),
Column(children: [decorationImage]),
Column(children: [decorationImage]),
],
),
]
)
);
]));
}
// Builds out the Widget tree using the most recent GameModel from the stream.
......@@ -305,7 +296,7 @@ class _GameScreenState extends State<GameScreen> {
return Scaffold(
appBar: AppBar(
actions: [
FlatButton(
TextButton(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
......@@ -317,7 +308,7 @@ class _GameScreenState extends State<GameScreen> {
margin: EdgeInsets.all(8),
child: Image(
image: AssetImage('assets/icons/button_restart.png'),
fit: BoxFit.fill
fit: BoxFit.fill,
),
),
onPressed: () => _restartController.add(GameModel(board: GameBoard())),
......@@ -325,7 +316,11 @@ class _GameScreenState extends State<GameScreen> {
],
),
body: Container(
padding: EdgeInsets.only(top: 5.0, left: 5.0, right: 5.0),
padding: EdgeInsets.only(
top: 5.0,
left: 5.0,
right: 5.0,
),
decoration: Styling.mainWidgetDecoration,
child: SafeArea(
child: Column(
......
......@@ -10,8 +10,7 @@ import 'game_board.dart';
import 'game_board_scorer.dart';
class MoveSearchArgs {
MoveSearchArgs(
{required this.board, required this.player, required this.numPlies});
MoveSearchArgs({required this.board, required this.player, required this.numPlies});
final GameBoard board;
final PieceType player;
......@@ -29,8 +28,8 @@ class ScoredMove {
// The [compute] function requires a top-level method as its first argument.
// This is that method for [MoveFinder].
Position? _findNextMove(MoveSearchArgs args) {
final bestMove = _performSearchPly(
args.board, args.player, args.player, args.numPlies - 1);
final bestMove =
_performSearchPly(args.board, args.player, args.player, args.numPlies - 1);
return bestMove?.move;
}
......@@ -48,9 +47,8 @@ ScoredMove? _performSearchPly(
return null;
}
var score = (scoringPlayer == player)
? GameBoardScorer.minScore
: GameBoardScorer.maxScore;
var score =
(scoringPlayer == player) ? GameBoardScorer.minScore : GameBoardScorer.maxScore;
ScoredMove? bestMove;
for (var i = 0; i < availableMoves.length; i++) {
......@@ -66,8 +64,7 @@ ScoredMove? _performSearchPly(
pliesRemaining - 1,
)?.score ??
0;
} else if (pliesRemaining > 0 &&
newBoard.getMovesForPlayer(player).isNotEmpty) {
} else if (pliesRemaining > 0 && newBoard.getMovesForPlayer(player).isNotEmpty) {
// Opponent has no moves; player gets another turn.
score = _performSearchPly(
newBoard,
......@@ -84,8 +81,7 @@ ScoredMove? _performSearchPly(
if (bestMove == null ||
(score > bestMove.score && scoringPlayer == player) ||
(score < bestMove.score && scoringPlayer != player)) {
bestMove =
ScoredMove(score, Position(availableMoves[i].x, availableMoves[i].y));
bestMove = ScoredMove(score, Position(availableMoves[i].x, availableMoves[i].y));
}
}
......
......@@ -26,9 +26,8 @@ abstract class Styling {
),
);
static const BoxDecoration mainWidgetDecoration = BoxDecoration(
color: Color(0xffffffff)
);
static const BoxDecoration mainWidgetDecoration =
BoxDecoration(color: Color(0xffffffff));
static const thinkingColor = Color(0xff2196f3);
......
......@@ -26,8 +26,7 @@ class ThinkingIndicator extends ImplicitlyAnimatedWidget {
ImplicitlyAnimatedWidgetState createState() => _ThinkingIndicatorState();
}
class _ThinkingIndicatorState
extends AnimatedWidgetBaseState<ThinkingIndicator> {
class _ThinkingIndicatorState extends AnimatedWidgetBaseState<ThinkingIndicator> {
Tween<double>? _opacityTween;
@override
......@@ -85,16 +84,16 @@ class _AnimatedCirclesState extends State<_AnimatedCircles>
@override
void initState() {
super.initState();
_thinkingController = AnimationController(
duration: const Duration(milliseconds: 500), vsync: this)
..addStatusListener((status) {
// This bit ensures that the animation reverses course rather than
// stopping.
if (status == AnimationStatus.completed) _thinkingController.reverse();
if (status == AnimationStatus.dismissed) _thinkingController.forward();
});
_thinkingAnimation = Tween(begin: 0.0, end: widget.height).animate(
CurvedAnimation(parent: _thinkingController, curve: Curves.easeOut));
_thinkingController =
AnimationController(duration: const Duration(milliseconds: 500), vsync: this)
..addStatusListener((status) {
// This bit ensures that the animation reverses course rather than
// stopping.
if (status == AnimationStatus.completed) _thinkingController.reverse();
if (status == AnimationStatus.dismissed) _thinkingController.forward();
});
_thinkingAnimation = Tween(begin: 0.0, end: widget.height)
.animate(CurvedAnimation(parent: _thinkingController, curve: Curves.easeOut));
_thinkingController.forward();
}
......
......@@ -42,14 +42,14 @@ packages:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
version: "1.16.0"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.3.0"
ffi:
dependency: transitive
description:
......@@ -85,7 +85,7 @@ packages:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
version: "0.6.4"
matcher:
dependency: transitive
description:
......@@ -99,7 +99,7 @@ packages:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
version: "0.1.4"
meta:
dependency: transitive
description:
......@@ -120,7 +120,7 @@ packages:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
version: "1.8.1"
path_provider_linux:
dependency: transitive
description:
......@@ -237,7 +237,7 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
version: "1.8.2"
stack_trace:
dependency: transitive
description:
......@@ -272,21 +272,14 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.8"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
version: "0.4.9"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
version: "2.1.2"
win32:
dependency: transitive
description:
......@@ -302,5 +295,5 @@ packages:
source: hosted
version: "0.2.0+1"
sdks:
dart: ">=2.15.0 <3.0.0"
dart: ">=2.17.0-0 <3.0.0"
flutter: ">=2.8.0"
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:reversi/main.dart';
void main() {
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment