mirror of
https://forgejo.allbyte.fr/nono/flutter_wordle
synced 2026-03-14 21:15:45 +01:00
217 lines
6 KiB
Dart
217 lines
6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:wordle/db/duel_game.dart';
|
|
import 'package:wordle/db/duel_game_provider.dart';
|
|
import 'package:wordle/word_loader.dart';
|
|
|
|
import 'db/board.dart';
|
|
import 'game_screen.dart';
|
|
|
|
class DuelGameScreen extends StatefulWidget {
|
|
final int numberOfTurns;
|
|
|
|
const DuelGameScreen({super.key, required this.numberOfTurns});
|
|
|
|
@override
|
|
_DuelGameScreenState createState() => _DuelGameScreenState();
|
|
}
|
|
|
|
class _DuelGameScreenState extends State<DuelGameScreen> {
|
|
final _wordController = TextEditingController();
|
|
String? _errorMessage;
|
|
int _currentPlayer = 1;
|
|
final List<String> _playerWords = [];
|
|
int _player1Score = 0;
|
|
int _player2Score = 0;
|
|
int _turnsLeft;
|
|
bool _isGameStarted = false;
|
|
String _currentCorrectWord = "";
|
|
final List<DbBoard> _player1Games = [];
|
|
final List<DbBoard> _player2Games = [];
|
|
|
|
_DuelGameScreenState() : _turnsLeft = 0;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_turnsLeft = widget.numberOfTurns;
|
|
}
|
|
|
|
void _submitWord() async {
|
|
String enteredWord = _wordController.text.trim().toUpperCase();
|
|
bool validWord = await WordLoader.isValidWord(enteredWord);
|
|
if (validWord) {
|
|
setState(() {
|
|
_playerWords.add(enteredWord);
|
|
_wordController.clear();
|
|
_errorMessage = null;
|
|
if (_playerWords.length == 2) {
|
|
_currentPlayer = 1;
|
|
_startGame();
|
|
} else {
|
|
_currentPlayer = 2;
|
|
}
|
|
});
|
|
} else {
|
|
setState(() {
|
|
_errorMessage = "Invalid word. Please enter a valid word.";
|
|
});
|
|
}
|
|
}
|
|
|
|
void _startGame() {
|
|
setState(() {
|
|
_isGameStarted = true;
|
|
_turnsLeft--;
|
|
_playTurn();
|
|
});
|
|
}
|
|
|
|
void _playTurn() {
|
|
setState(() {
|
|
_currentCorrectWord =
|
|
_currentPlayer == 1 ? _playerWords[1] : _playerWords[0];
|
|
});
|
|
}
|
|
|
|
void _onGuessSubmitted(GameData data) async {
|
|
DbBoard currentBoard = DbBoard(
|
|
correctWord: data.correctWord,
|
|
maxGuesses: data.maxGuesses,
|
|
guesses: data.guesses,
|
|
hasWon: data.hasWon,
|
|
);
|
|
|
|
if (_currentPlayer == 1) {
|
|
_player1Games.add(currentBoard);
|
|
} else {
|
|
_player2Games.add(currentBoard);
|
|
}
|
|
|
|
await _showTurnEndDialog(data.hasWon);
|
|
setState(() {
|
|
if (_currentPlayer == 1) {
|
|
if (data.hasWon) _player1Score += _playerWords[0].length;
|
|
_currentPlayer = 2;
|
|
_playTurn();
|
|
} else {
|
|
if (data.hasWon) _player2Score += _playerWords[1].length;
|
|
_currentPlayer = 1;
|
|
|
|
if (_turnsLeft > 0) {
|
|
_turnsLeft--;
|
|
_playerWords.clear();
|
|
_isGameStarted = false;
|
|
} else {
|
|
_saveGameHistory();
|
|
_showEndGameDialog();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
void _saveGameHistory() async {
|
|
final duelGame = DbDuelGame(
|
|
date: DateTime.now(),
|
|
winner: _player1Score > _player2Score ? 0 : 1,
|
|
numberOfTurns: widget.numberOfTurns,
|
|
player1score: _player1Score,
|
|
player2score: _player2Score,
|
|
player1games: _player1Games,
|
|
player2games: _player2Games,
|
|
);
|
|
final provider = Provider.of<DbDuelGameProvider>(context, listen: false);
|
|
await provider.insert(duelGame);
|
|
}
|
|
|
|
Future<void> _showTurnEndDialog(bool hasWon) async {
|
|
String message = hasWon
|
|
? "Congratulations, Player $_currentPlayer! You guessed the correct word."
|
|
: "Player $_currentPlayer, you did not guess the correct word.";
|
|
|
|
await showDialog(
|
|
context: context,
|
|
barrierDismissible: false,
|
|
builder: (BuildContext context) {
|
|
return AlertDialog(
|
|
title: const Text('Turn Over'),
|
|
content: Text(message),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
},
|
|
child: const Text("OK"),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
Future<void> _showEndGameDialog() async {
|
|
await showDialog(
|
|
context: context,
|
|
barrierDismissible: false,
|
|
builder: (BuildContext context) {
|
|
return AlertDialog(
|
|
title: const Text('Game Over'),
|
|
content: Text(
|
|
'The duel has ended. Player 1 score: $_player1Score, Player 2 score: $_player2Score. Thanks for playing!'),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
Navigator.of(context).pop();
|
|
},
|
|
child: const Text("Return to Main Menu"),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: Text('Player $_currentPlayer - Enter a Word'),
|
|
),
|
|
body: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: !_isGameStarted
|
|
? Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Text(
|
|
'Player $_currentPlayer, enter the word you want the other player to guess:',
|
|
style: const TextStyle(fontSize: 18),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
const SizedBox(height: 20),
|
|
TextField(
|
|
controller: _wordController,
|
|
decoration: InputDecoration(
|
|
labelText: 'Enter a word',
|
|
border: const OutlineInputBorder(),
|
|
errorText: _errorMessage,
|
|
),
|
|
),
|
|
const SizedBox(height: 20),
|
|
ElevatedButton(
|
|
onPressed: _submitWord,
|
|
child: const Text('Submit Word'),
|
|
),
|
|
],
|
|
)
|
|
: GameScreen(
|
|
maxGuesses: 6,
|
|
correctWord: _currentCorrectWord,
|
|
readOnly: false,
|
|
onGameEnd: _onGuessSubmitted,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|