Introduce api types and some changes.
This commit is contained in:
parent
b0d6f4002c
commit
605743c0d2
32
lib/api/move.dart
Normal file
32
lib/api/move.dart
Normal file
@ -0,0 +1,32 @@
|
||||
class ApiMove {
|
||||
final ApiCoordinate startSquare;
|
||||
final ApiCoordinate endSquare;
|
||||
|
||||
const ApiMove({
|
||||
required this.startSquare,
|
||||
required this.endSquare,
|
||||
});
|
||||
|
||||
factory ApiMove.fromJson(Map<String, dynamic> json) {
|
||||
final startSquare = ApiCoordinate.fromJson(json['startSquare']);
|
||||
final endSquare = ApiCoordinate.fromJson(json['endSquare']);
|
||||
|
||||
return ApiMove(startSquare: startSquare, endSquare: endSquare);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
{'startSquare': startSquare, 'endSquare': endSquare};
|
||||
}
|
||||
|
||||
class ApiCoordinate {
|
||||
final int col;
|
||||
final int row;
|
||||
|
||||
const ApiCoordinate({required this.col, required this.row});
|
||||
|
||||
factory ApiCoordinate.fromJson(Map<String, dynamic> json) {
|
||||
return ApiCoordinate(col: json['col'], row: json['row']);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {'col': col, 'row': row};
|
||||
}
|
30
lib/api/register.dart
Normal file
30
lib/api/register.dart
Normal file
@ -0,0 +1,30 @@
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class ResponseFromRegisteringGame {
|
||||
final UuidValue playerID;
|
||||
final UuidValue lobbyID;
|
||||
|
||||
const ResponseFromRegisteringGame({
|
||||
required this.playerID,
|
||||
required this.lobbyID,
|
||||
});
|
||||
|
||||
factory ResponseFromRegisteringGame.fromJson(Map<String, dynamic> json) {
|
||||
final playerid = UuidValue(json['playerID']);
|
||||
final lobbyid = UuidValue(json['lobbyID']);
|
||||
|
||||
return ResponseFromRegisteringGame(playerID: playerid, lobbyID: lobbyid);
|
||||
}
|
||||
}
|
||||
|
||||
class WebsocketMessageIdentifyPlayer {
|
||||
final String playerID;
|
||||
final String lobbyID;
|
||||
|
||||
const WebsocketMessageIdentifyPlayer({
|
||||
required this.playerID,
|
||||
required this.lobbyID,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() => {'lobbyID': lobbyID, 'playerID': playerID};
|
||||
}
|
@ -1,4 +1,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:mchess/api/move.dart';
|
||||
import 'package:mchess/chess_bloc/chess_events.dart';
|
||||
import 'package:mchess/chess_bloc/chess_position.dart';
|
||||
import 'package:mchess/connection/ws_connection.dart';
|
||||
@ -62,8 +65,13 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
||||
void ownMoveHandler(OwnPieceMoved event, Emitter<ChessBoardState> emit) {
|
||||
ChessPosition.getInstance().recordMove(event.startSquare, event.endSquare);
|
||||
|
||||
ServerConnection.getInstance().send(
|
||||
'mv ${event.startSquare.toString()} ${event.endSquare.toString()}');
|
||||
var start = ApiCoordinate(
|
||||
col: event.startSquare.column, row: event.startSquare.row);
|
||||
var end =
|
||||
ApiCoordinate(col: event.endSquare.column, row: event.endSquare.row);
|
||||
var move = ApiMove(startSquare: start, endSquare: end);
|
||||
|
||||
ServerConnection.getInstance().send(jsonEncode(move));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,10 @@ class ChessPosition {
|
||||
}
|
||||
|
||||
ChessPositionType get currentPosition => position;
|
||||
ChessMove get lastMove => history.last;
|
||||
ChessMove? get lastMove {
|
||||
if (history.isEmpty) return null;
|
||||
return history.last;
|
||||
}
|
||||
|
||||
void recordMove(ChessCoordinate from, ChessCoordinate to) {
|
||||
position[to] = position[from] ?? const ChessPiece.none();
|
||||
|
@ -1,8 +1,11 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mchess/api/move.dart';
|
||||
import 'package:mchess/chess_bloc/chess_bloc.dart';
|
||||
import 'package:mchess/chess_bloc/chess_events.dart';
|
||||
import 'package:mchess/chess_bloc/chess_position.dart';
|
||||
import 'package:mchess/api/register.dart';
|
||||
import 'package:mchess/utils/chess_utils.dart';
|
||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||
|
||||
@ -31,7 +34,7 @@ class ServerConnection {
|
||||
counter++;
|
||||
}
|
||||
|
||||
void connect(String playerID) {
|
||||
void connect(String playerID, lobbyID) {
|
||||
if (wasConnected) channel.sink.close();
|
||||
|
||||
if (kDebugMode) {
|
||||
@ -41,7 +44,8 @@ class ServerConnection {
|
||||
channel =
|
||||
WebSocketChannel.connect(Uri.parse('wss://chess.sw-gross.de:8080'));
|
||||
}
|
||||
send(playerID);
|
||||
send(jsonEncode(WebsocketMessageIdentifyPlayer(
|
||||
playerID: (playerID), lobbyID: (lobbyID))));
|
||||
|
||||
log(channel.closeCode.toString());
|
||||
|
||||
@ -49,39 +53,27 @@ class ServerConnection {
|
||||
|
||||
broadcast = channel.stream.asBroadcastStream();
|
||||
|
||||
broadcast.listen((data) {
|
||||
log("Data received:");
|
||||
log(data);
|
||||
broadcast.listen(handleIncomingData);
|
||||
}
|
||||
|
||||
var receivedString = data.toString();
|
||||
var splitString = receivedString.split(' ');
|
||||
void handleIncomingData(dynamic data) {
|
||||
log("Data received:");
|
||||
log(data);
|
||||
var apiMove = ApiMove.fromJson(jsonDecode(data));
|
||||
|
||||
if (splitString[0] == "cl") {
|
||||
ChessColor onBottom =
|
||||
splitString[1] == "white" ? ChessColor.white : ChessColor.black;
|
||||
ChessBloc.getInstance().add(ColorDetermined(myColor: onBottom));
|
||||
return;
|
||||
}
|
||||
//Todo: Implement status messages
|
||||
// e.g. to tell the client that both players connected, who is playing which color and so on
|
||||
|
||||
if (splitString[0] == "bd") {
|
||||
if (splitString[1] == "init") ChessBloc.getInstance().add(InitBoard());
|
||||
}
|
||||
var move = ChessMove.fromApiMove(apiMove);
|
||||
if (move == ChessPosition.getInstance().lastMove) {
|
||||
//This is our own move that got resent by the server. Do not process.
|
||||
} else {
|
||||
log('lastMove: from: ${ChessPosition.getInstance().lastMove?.from} to: ${ChessPosition.getInstance().lastMove?.to}');
|
||||
log('constructed move: from: ${move.from} to: ${move.to}');
|
||||
log('Move received : ${move.from.toAlphabetical()}->${move.to.toAlphabetical()}');
|
||||
|
||||
if (splitString[0] == ('mv')) {
|
||||
var startSquare = ChessCoordinate.fromString(splitString[1]);
|
||||
var endSquare = ChessCoordinate.fromString(splitString[2]);
|
||||
if (ChessMove(from: startSquare, to: endSquare) ==
|
||||
ChessPosition.getInstance().lastMove) {
|
||||
//This is our own move that got resent by the server. Do not process.
|
||||
} else {
|
||||
log('lastMove: from: ${ChessPosition.getInstance().lastMove.from} to: ${ChessPosition.getInstance().lastMove.to}');
|
||||
log('constructed move: from: $startSquare to: $endSquare)}');
|
||||
log('Move received : ${startSquare.toAlphabetical()}:${endSquare.toAlphabetical()}');
|
||||
|
||||
ChessBloc.getInstance().add(OpponentPieceMoved(
|
||||
startSquare: startSquare, endSquare: endSquare));
|
||||
}
|
||||
}
|
||||
});
|
||||
ChessBloc.getInstance()
|
||||
.add(OpponentPieceMoved(startSquare: move.from, endSquare: move.to));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ class ConnectionCubit extends Cubit<ConnectionCubitState> {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
void connect(String playerID) {
|
||||
ServerConnection.getInstance().connect(playerID);
|
||||
void connect(String playerID, lobbyID) {
|
||||
ServerConnection.getInstance().connect(playerID, lobbyID);
|
||||
emit(ConnectionCubitState(true));
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class ResponseFromRegisteringGame {
|
||||
final UuidValue playerID;
|
||||
|
||||
const ResponseFromRegisteringGame({
|
||||
required this.playerID,
|
||||
});
|
||||
|
||||
factory ResponseFromRegisteringGame.fromJson(Map<String, dynamic> json) {
|
||||
final uuid = UuidValue(json['playerID']);
|
||||
|
||||
return ResponseFromRegisteringGame(
|
||||
playerID: uuid,
|
||||
);
|
||||
}
|
||||
}
|
@ -14,7 +14,8 @@ import 'package:uuid/uuid.dart';
|
||||
|
||||
class ChessGame extends StatefulWidget {
|
||||
final UuidValue playerID;
|
||||
const ChessGame({required this.playerID, super.key});
|
||||
final UuidValue lobbyID;
|
||||
const ChessGame({required this.playerID, required this.lobbyID, super.key});
|
||||
|
||||
@override
|
||||
State<ChessGame> createState() => _ChessGameState();
|
||||
@ -24,7 +25,8 @@ class _ChessGameState extends State<ChessGame> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
ConnectionCubit.getInstance().connect(widget.playerID.uuid);
|
||||
ConnectionCubit.getInstance()
|
||||
.connect(widget.playerID.uuid, widget.lobbyID.uuid);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mchess/models/models.dart';
|
||||
import 'package:mchess/api/register.dart';
|
||||
import 'package:mchess/pages/chess_game.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
@ -18,6 +18,7 @@ class PrepareChessGameWidget extends StatelessWidget {
|
||||
log('future done ${snapshot.data?.playerID}');
|
||||
return ChessGame(
|
||||
playerID: snapshot.data!.playerID,
|
||||
lobbyID: snapshot.data!.lobbyID,
|
||||
);
|
||||
}
|
||||
return const CircularProgressIndicator();
|
||||
@ -26,8 +27,9 @@ class PrepareChessGameWidget extends StatelessWidget {
|
||||
}
|
||||
|
||||
Future<ResponseFromRegisteringGame> registerForRandomGame() async {
|
||||
final response =
|
||||
await http.get(Uri.parse('http://localhost:8080/api/random'));
|
||||
final response = await http.get(
|
||||
Uri.parse('http://localhost:8080/api/random'),
|
||||
headers: {"Accept": "application/json"});
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
log(response.body);
|
||||
@ -35,7 +37,7 @@ class PrepareChessGameWidget extends StatelessWidget {
|
||||
} else {
|
||||
// If the server did not return a 200 OK response,
|
||||
// then throw an exception.
|
||||
throw Exception('Failed to load album');
|
||||
throw Exception('Failed to register for random game');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:mchess/api/move.dart';
|
||||
import 'package:quiver/core.dart';
|
||||
|
||||
enum ChessPieceName {
|
||||
@ -65,6 +66,10 @@ class ChessCoordinate {
|
||||
return ChessCoordinate(column, row);
|
||||
}
|
||||
|
||||
factory ChessCoordinate.fromApiCoordinate(ApiCoordinate apiCoordinate) {
|
||||
return ChessCoordinate(apiCoordinate.col, apiCoordinate.row);
|
||||
}
|
||||
|
||||
ChessCoordinate.copyFrom(ChessCoordinate original)
|
||||
: column = original.column,
|
||||
row = original.row;
|
||||
@ -159,6 +164,13 @@ class ChessMove {
|
||||
|
||||
ChessMove({required this.from, required this.to});
|
||||
|
||||
factory ChessMove.fromApiMove(ApiMove apiMove) {
|
||||
final start = ChessCoordinate.fromApiCoordinate(apiMove.startSquare);
|
||||
final end = ChessCoordinate.fromApiCoordinate(apiMove.endSquare);
|
||||
|
||||
return ChessMove(from: start, to: end);
|
||||
}
|
||||
|
||||
@override
|
||||
operator ==(other) {
|
||||
return other is ChessMove && other.from == from && other.to == to;
|
||||
|
Loading…
Reference in New Issue
Block a user