From 2ad028f8a75d6673772c6512dc7fffcfb929a93e Mon Sep 17 00:00:00 2001 From: Marco Date: Sun, 18 Dec 2022 01:04:08 +0100 Subject: [PATCH] Many many changes. --- lib/chess_bloc/chess_bloc.dart | 63 +++++++------- lib/chess_bloc/chess_events.dart | 12 +-- lib/chessapp/chess_app.dart | 106 +++++++++++------------ lib/chessapp/chess_board.dart | 4 +- lib/chessapp/chess_square.dart | 11 +-- lib/chessapp/turn_indicator_widget.dart | 19 ++++ lib/connection/ws_connection.dart | 37 ++++---- lib/utils/widgets/server_log_widget.dart | 29 +++++++ 8 files changed, 160 insertions(+), 121 deletions(-) create mode 100644 lib/chessapp/turn_indicator_widget.dart create mode 100644 lib/utils/widgets/server_log_widget.dart diff --git a/lib/chess_bloc/chess_bloc.dart b/lib/chess_bloc/chess_bloc.dart index 12e6d99..9fd421c 100644 --- a/lib/chess_bloc/chess_bloc.dart +++ b/lib/chess_bloc/chess_bloc.dart @@ -1,19 +1,16 @@ -import 'dart:async'; - import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:mchess/chess_bloc/chess_events.dart'; import 'package:mchess/chessapp/chess_utils.dart'; -import 'package:mchess/connection/ws_connection.dart'; import 'dart:developer'; -int message_index = 0; - class ChessBloc extends Bloc { static final ChessBloc _instance = ChessBloc._internal(); + late ChessColor? myColor; ChessBloc._internal() : super(ChessBoardState.init()) { + on(initBoard); + on(flipBoard); on(moveHandler); - on(flipBoard); } factory ChessBloc.getInstance() { @@ -24,52 +21,52 @@ class ChessBloc extends Bloc { return _instance; } - FutureOr moveHandler(PieceMoved event, Emitter emit) { + void initBoard(InitBoard event, Emitter emit) { + emit(ChessBoardState.init()); + } + + void flipBoard(ColorDetermined event, Emitter emit) { + emit(ChessBoardState(event.myColor, state.newTurnColor, state.position)); + } + + void moveHandler(PieceMoved event, Emitter emit) { Map newPosition = state.position; newPosition[event.endSquare] = state.position[event.startSquare]!; newPosition[event.startSquare] = const ChessPiece.none(); + var newTurnColor = state.newTurnColor == ChessColor.white + ? ChessColor.black + : ChessColor.white; + log('emitting new state with position $newPosition'); - emit(ChessBoardState( - state.flipped, - ChessColor.black, - newPosition, - )); - } - - bool preCheckHandler( - PreCheckMove event, - ) { - ServerConnection.getInstance().send( - '${message_index++} pc ${event.move.startSquare.toString()} ${event.move.endSquare.toString()}'); - - log('Pretending to check a move before you drop a piece'); - return true; - } - - void flipBoard(BoardFlippedEvent event, Emitter emit) { - emit(ChessBoardState(!state.flipped, state.turnColor, state.position)); + emit( + ChessBoardState( + state.bottomColor, + newTurnColor, + newPosition, + ), + ); } } class ChessBoardState { - late bool flipped; - final ChessColor turnColor; + late ChessColor bottomColor; + final ChessColor newTurnColor; final Map position; - ChessBoardState._(this.flipped, this.turnColor, this.position); + ChessBoardState._(this.bottomColor, this.newTurnColor, this.position); factory ChessBoardState( - bool flipped, + ChessColor bottomColor, ChessColor turnColor, Map position, ) { - return ChessBoardState._(flipped, turnColor, position); + return ChessBoardState._(bottomColor, turnColor, position); } factory ChessBoardState.init() { - bool flipped = false; + ChessColor bottomColor = ChessColor.white; ChessColor turnColor = ChessColor.white; Map position = {}; @@ -114,6 +111,6 @@ class ChessBoardState { position[ChessCoordinate(8, 1)] = ChessPiece(ChessPieceName.whiteRook, ChessColor.black); - return ChessBoardState._(flipped, turnColor, position); + return ChessBoardState._(bottomColor, turnColor, position); } } diff --git a/lib/chess_bloc/chess_events.dart b/lib/chess_bloc/chess_events.dart index 6500a79..355a04f 100644 --- a/lib/chess_bloc/chess_events.dart +++ b/lib/chess_bloc/chess_events.dart @@ -9,10 +9,12 @@ class PieceMoved extends ChessEvent { PieceMoved({required this.startSquare, required this.endSquare}); } -class PreCheckMove extends ChessEvent { - final ChessMove move; - - PreCheckMove({required this.move}); +class InitBoard extends ChessEvent { + InitBoard(); } -class BoardFlippedEvent extends ChessEvent {} +class ColorDetermined extends ChessEvent { + final ChessColor myColor; + + ColorDetermined({required this.myColor}); +} diff --git a/lib/chessapp/chess_app.dart b/lib/chessapp/chess_app.dart index d4ee9f8..8b81ee8 100644 --- a/lib/chessapp/chess_app.dart +++ b/lib/chessapp/chess_app.dart @@ -1,13 +1,14 @@ -import 'dart:developer'; - import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:mchess/chess_bloc/chess_bloc.dart'; -import 'package:mchess/connection/ws_connection.dart'; import 'package:mchess/chessapp/chess_board.dart'; +import 'package:mchess/chessapp/turn_indicator_widget.dart'; import 'package:mchess/connection_cubit/connection_cubit.dart'; +import '../connection/ws_connection.dart'; +import '../utils/widgets/server_log_widget.dart'; + class ChessApp extends StatelessWidget { const ChessApp({super.key}); @@ -15,61 +16,58 @@ class ChessApp extends StatelessWidget { Widget build(BuildContext context) { return BlocProvider( create: (_) => ConnectionCubit.getInstance(), - child: MaterialApp( - title: 'mChess', - home: Scaffold( - body: Container( - decoration: const BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Color.fromARGB(255, 20, 20, 20), - Color.fromARGB(255, 30, 30, 30), - Color.fromARGB(255, 40, 40, 40), - ], - ), - ), - child: Center( - child: FittedBox( - fit: BoxFit.contain, - child: Column( - children: [ - Container( - margin: const EdgeInsets.all(20), - child: BlocProvider( - create: (_) => ChessBloc.getInstance(), - child: BlocBuilder( - builder: (context, state) { - return ChessBoard( - bState: state, - ); - }, - ), - ), - ), - BlocBuilder( - builder: (context, state) { - return StreamBuilder( - stream: ServerConnection.getInstance().broadcast, - builder: (context, snapshot) { - return Text( - style: const TextStyle(color: Colors.white), - snapshot.data.toString()); - }, - ); - }, - ) + child: BlocProvider( + create: (_) => ChessBloc.getInstance(), + child: MaterialApp( + title: 'mChess', + home: Scaffold( + body: Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Color.fromARGB(255, 20, 20, 20), + Color.fromARGB(255, 30, 30, 30), + Color.fromARGB(255, 40, 40, 40), ], ), ), + child: Center( + child: FittedBox( + fit: BoxFit.contain, + child: Row( + children: [ + StreamBuilder( + stream: ServerConnection.getInstance().broadcast, + builder: (context, snapshot) { + return ServerLogWidget( + snapshot.data ?? "", + textColor: Colors.white, + ); + }, + ), + Container( + margin: const EdgeInsets.all(20), + child: BlocBuilder( + builder: (context, state) { + return ChessBoard( + bState: state, + ); + }, + ), + ), + const TurnIndicator(), + ], + ), + )), + ), + floatingActionButton: FloatingActionButton( + onPressed: () { + ConnectionCubit.getInstance().reconnect(); + }, + child: const Icon(Icons.network_wifi), ), - ), - floatingActionButton: FloatingActionButton( - onPressed: () { - ConnectionCubit.getInstance().reconnect(); - }, - child: const Icon(Icons.network_wifi), ), ), ), diff --git a/lib/chessapp/chess_board.dart b/lib/chessapp/chess_board.dart index aa6f920..9f80353 100644 --- a/lib/chessapp/chess_board.dart +++ b/lib/chessapp/chess_board.dart @@ -34,7 +34,9 @@ class ChessBoard extends StatelessWidget { @override Widget build(BuildContext context) { log("ChessBoard's build()"); - return Column(children: _buildBoard(bState.flipped)); + + return Column( + children: _buildBoard(bState.bottomColor == ChessColor.black)); } Row _buildChessRow(int rowNo, bool flipped) { diff --git a/lib/chessapp/chess_square.dart b/lib/chessapp/chess_square.dart index dcd748e..f10fb06 100644 --- a/lib/chessapp/chess_square.dart +++ b/lib/chessapp/chess_square.dart @@ -1,5 +1,3 @@ -import 'dart:developer'; - import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -9,6 +7,8 @@ import 'package:mchess/chess_bloc/chess_bloc.dart'; import '../connection/ws_connection.dart'; import 'chess_utils.dart'; +int message_index = 0; + class ChessSquare extends StatelessWidget { final ChessCoordinate coordinate; final ChessPiece? containedPiece; @@ -85,13 +85,6 @@ class ChessSquare extends StatelessWidget { ), ); }, - // onWillAccept: (move) { - // move!.endSquare = coordinate; - // final legalMove = - // context.read().preCheckHandler(PreCheckMove(move: move)); - // log('onWillAccept returns $legalMove'); - // return legalMove; - // }, onAccept: (move) { move.endSquare = coordinate; diff --git a/lib/chessapp/turn_indicator_widget.dart b/lib/chessapp/turn_indicator_widget.dart new file mode 100644 index 0000000..3e7e691 --- /dev/null +++ b/lib/chessapp/turn_indicator_widget.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:mchess/chess_bloc/chess_bloc.dart'; + +import 'chess_utils.dart'; + +class TurnIndicator extends StatelessWidget { + const TurnIndicator({super.key}); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) => Text( + state.newTurnColor == ChessColor.white ? "white" : "black", + style: const TextStyle(color: Colors.white), + ), + ); + } +} diff --git a/lib/connection/ws_connection.dart b/lib/connection/ws_connection.dart index 6126df8..85e9186 100644 --- a/lib/connection/ws_connection.dart +++ b/lib/connection/ws_connection.dart @@ -6,7 +6,7 @@ import 'package:mchess/chessapp/chess_utils.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; class ServerConnection { - late WebSocketChannel _channel; + late WebSocketChannel channel; late bool wasConnected = false; late int counter = 0; late Stream broadcast; @@ -27,45 +27,44 @@ class ServerConnection { } void send(String message) { - _channel.sink.add(message); + channel.sink.add(message); counter++; } void connect() { - if (wasConnected) _channel.sink.close(); - _channel = WebSocketChannel.connect(Uri.parse('ws://localhost:8080')); + if (wasConnected) channel.sink.close(); + channel = WebSocketChannel.connect(Uri.parse('ws://localhost:8080')); wasConnected = true; - broadcast = _channel.stream.asBroadcastStream(); + broadcast = channel.stream.asBroadcastStream(); broadcast.listen((data) { log("Data received:"); log(data); var receivedString = data.toString(); + var splitString = receivedString.split(' '); - if (receivedString == "fb") { - ChessBloc.getInstance().add(BoardFlippedEvent()); + if (splitString[0] == "cl") { + ChessColor onBottom = + splitString[1] == "white" ? ChessColor.white : ChessColor.black; + ChessBloc.getInstance().add(ColorDetermined(myColor: onBottom)); return; } - var moveStringList = receivedString.split(' '); - if (moveStringList[1] == ('mv')) { - var startSquare = ChessCoordinate.fromString(moveStringList[2]); - var endSquare = ChessCoordinate.fromString(moveStringList[3]); + if (splitString[0] == "bd") { + if (splitString[1] == "init") ChessBloc.getInstance().add(InitBoard()); + } - log('Move received : ${moveStringList[2]}:${moveStringList[3]}'); + if (splitString[1] == ('mv')) { + var startSquare = ChessCoordinate.fromString(splitString[2]); + var endSquare = ChessCoordinate.fromString(splitString[3]); + + log('Move received : ${splitString[2]}:${splitString[3]}'); ChessBloc.getInstance() .add(PieceMoved(startSquare: startSquare, endSquare: endSquare)); } }); - - sendPassword(); - } - - void sendPassword() { - send( - 'pw NC4EjHvRcsltY3ibWuYDH9OXbKgDXppfnHNCi1K4jktMspoeZjBnOPExxCpDms7zmxijoKCSaSlZ1fWclfWr7Q32DJnv2k87Z5uM'); } } diff --git a/lib/utils/widgets/server_log_widget.dart b/lib/utils/widgets/server_log_widget.dart new file mode 100644 index 0000000..c97e926 --- /dev/null +++ b/lib/utils/widgets/server_log_widget.dart @@ -0,0 +1,29 @@ +import 'package:flutter/widgets.dart'; + +class ServerLogWidget extends StatefulWidget { + final Color textColor; + final String addString; + + const ServerLogWidget(this.addString, {required this.textColor, super.key}); + + @override + State createState() => ServerLogWidgetState(); +} + +class ServerLogWidgetState extends State { + List log = []; + + ServerLogWidgetState(); + + @override + Widget build(BuildContext context) { + log.add(widget.addString); + + return Column( + children: [ + for (int i = 0; i < log.length; i++) + Text(style: TextStyle(color: widget.textColor, fontSize: 20), log[i]) + ], + ); + } +}