added comments and integration test
parent
f6fa31196e
commit
5ebe14df32
|
@ -8,15 +8,16 @@ void main() {
|
|||
);
|
||||
}
|
||||
|
||||
// Main application widget
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
theme: halloweenTheme,
|
||||
home: const PlayerRegistry(),
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: halloweenTheme, // Apply custom theme
|
||||
home: const PlayerRegistry(), // Set initial screen to PlayerRegistry
|
||||
debugShowCheckedModeBanner: false, // Disable debug banner
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
import 'package:werwolf/models/role.dart';
|
||||
|
||||
import 'player.dart';
|
||||
|
||||
class Game {
|
||||
// List to store player objects
|
||||
List<Player> players = [];
|
||||
|
||||
// List to store player names
|
||||
List playernames = [];
|
||||
|
||||
// Initial number of werewolves
|
||||
int numWolves = 1;
|
||||
|
||||
// Map to store special roles and their activation status
|
||||
Map specialRoles = <Role, bool>{};
|
||||
|
||||
// Constructor to initialize the game with player names
|
||||
Game({required this.playernames}) {
|
||||
// Initialize specialRoles map, setting all special roles to false
|
||||
for (Role role in Role.values) {
|
||||
if (role != Role.dorfbewohner && role != Role.werwolf) {
|
||||
specialRoles[role] = false;
|
||||
|
@ -16,43 +24,64 @@ class Game {
|
|||
}
|
||||
}
|
||||
|
||||
// Method to increment the number of werewolves
|
||||
void incrementWolves() {
|
||||
// Increment only if conditions are met: enough players and balance maintained
|
||||
if (numWolves < playernames.length - 1 &&
|
||||
(playernames.length) >= ((numWolves + 1) * 3)) {
|
||||
numWolves++;
|
||||
}
|
||||
}
|
||||
|
||||
// Method to decrement the number of werewolves
|
||||
void decrementWolves() {
|
||||
// Decrement only if there's more than one werewolf
|
||||
if (numWolves > 1) {
|
||||
numWolves--;
|
||||
}
|
||||
}
|
||||
|
||||
// Method to get the current number of werewolves
|
||||
int getWolves() {
|
||||
return numWolves;
|
||||
}
|
||||
|
||||
// Method to get all players with their assigned roles
|
||||
List<Player> getAllPlayers() {
|
||||
// Clear the players list to start fresh
|
||||
players.clear();
|
||||
|
||||
// List to hold roles randomly assigned to players
|
||||
List<Role> randomRoles = [];
|
||||
|
||||
// Add werewolf roles to the list
|
||||
for (var i = 0; i < numWolves; i++) {
|
||||
randomRoles.add(Role.werwolf);
|
||||
}
|
||||
|
||||
// Add active special roles to the list
|
||||
for (var specialRole in specialRoles.keys) {
|
||||
if (specialRoles[specialRole]) {
|
||||
randomRoles.add(specialRole);
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the remaining roles with dorfbewohner
|
||||
for (var i = randomRoles.length; i < playernames.length; i++) {
|
||||
randomRoles.add(Role.dorfbewohner);
|
||||
}
|
||||
|
||||
// Shuffle the roles to ensure randomness
|
||||
randomRoles.shuffle();
|
||||
|
||||
// Assign roles to players and create Player objects
|
||||
for (var playerName in playernames) {
|
||||
players
|
||||
.add(Player(name: playerName, role: randomRoles.last, isDead: false));
|
||||
randomRoles.removeLast();
|
||||
}
|
||||
|
||||
// Return the list of players with their roles
|
||||
return players;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
import 'package:werwolf/models/role.dart';
|
||||
|
||||
// Define a class named Player
|
||||
class Player {
|
||||
// Declare a string variable to store the player's name
|
||||
String name;
|
||||
// Declare a variable of type Role to store the player's role
|
||||
Role role;
|
||||
// Declare a boolean variable to indicate whether the player is dead
|
||||
bool isDead;
|
||||
|
||||
// Constructor for the Player class with required parameters for name, role, and isDead status
|
||||
Player({required this.name, required this.role, required this.isDead});
|
||||
}
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
// Enum representing different roles in the game
|
||||
enum Role { dorfbewohner, werwolf, joker, seher, doctor }
|
||||
|
||||
// Extension on the Role enum to provide string representations
|
||||
extension RoleExtension on Role {
|
||||
// Getter to convert enum value to its string representation
|
||||
String get stringValue {
|
||||
switch (this) {
|
||||
case Role.dorfbewohner:
|
||||
return 'Dorfbewohner';
|
||||
return 'Dorfbewohner'; // Returns 'Dorfbewohner' for the dorfbewohner role
|
||||
case Role.werwolf:
|
||||
return 'Werwolf';
|
||||
return 'Werwolf'; // Returns 'Werwolf' for the werwolf role
|
||||
case Role.joker:
|
||||
return 'Joker';
|
||||
return 'Joker'; // Returns 'Joker' for the joker role
|
||||
case Role.seher:
|
||||
return 'Seher';
|
||||
return 'Seher'; // Returns 'Seher' for the seher role
|
||||
case Role.doctor:
|
||||
return 'Doctor';
|
||||
return 'Doctor'; // Returns 'Doctor' for the doctor role
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:werwolf/screens/gameboard.dart';
|
|||
import '../models/player.dart';
|
||||
import '../models/role.dart';
|
||||
|
||||
// FlipingCard is a StatefulWidget that takes a list of players as input
|
||||
class FlipingCard extends StatefulWidget {
|
||||
final List<Player> players;
|
||||
const FlipingCard({required this.players, super.key});
|
||||
|
@ -15,17 +16,19 @@ class FlipingCard extends StatefulWidget {
|
|||
State<FlipingCard> createState() => _FlipingCardState();
|
||||
}
|
||||
|
||||
// State class for FlipingCard
|
||||
class _FlipingCardState extends State<FlipingCard> {
|
||||
int index = 0;
|
||||
int index = 0; // Index to keep track of the current player
|
||||
|
||||
late FlipCardController _controller;
|
||||
late FlipCardController _controller; // Controller for the flip card
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = FlipCardController();
|
||||
_controller = FlipCardController(); // Initialize the flip card controller
|
||||
}
|
||||
|
||||
// Method to render the content of the flip card
|
||||
_renderContent(context) {
|
||||
return Card(
|
||||
elevation: 0.0,
|
||||
|
@ -56,7 +59,7 @@ class _FlipingCardState extends State<FlipingCard> {
|
|||
),
|
||||
),
|
||||
const Text(
|
||||
'Klick um deine Rolle zu sehen!',
|
||||
'Click to see your role!',
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
|
@ -124,14 +127,14 @@ class _FlipingCardState extends State<FlipingCard> {
|
|||
onPressed: () {
|
||||
setState(() {
|
||||
if (index > 0 && index <= widget.players.length) {
|
||||
index--;
|
||||
index--; // Go to the previous player
|
||||
if (!_controller.state!.isFront) {
|
||||
_controller.toggleCardWithoutAnimation();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
child: const Text("Zurück"),
|
||||
child: const Text("Back"),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
|
@ -139,11 +142,12 @@ class _FlipingCardState extends State<FlipingCard> {
|
|||
onPressed: () {
|
||||
setState(() {
|
||||
if (index >= 0 && index < widget.players.length - 1) {
|
||||
index++;
|
||||
index++; // Go to the next player
|
||||
if (!_controller.state!.isFront) {
|
||||
_controller.toggleCardWithoutAnimation();
|
||||
}
|
||||
} else if (index == widget.players.length - 1) {
|
||||
// Navigate to the game board if it's the last player
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
|
@ -155,8 +159,8 @@ class _FlipingCardState extends State<FlipingCard> {
|
|||
});
|
||||
},
|
||||
child: Text(index != widget.players.length - 1
|
||||
? "Nächster Spieler"
|
||||
: "Spiel anfangen!"),
|
||||
? "Next Player"
|
||||
: "Start Game!"),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
|||
import '../models/player.dart';
|
||||
import '../models/role.dart';
|
||||
|
||||
// Main widget for displaying the player grid
|
||||
class PlayerGridView extends StatefulWidget {
|
||||
final List<Player> players;
|
||||
|
||||
|
@ -14,7 +15,7 @@ class PlayerGridView extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _PlayerGridViewState extends State<PlayerGridView> {
|
||||
bool isNight = true;
|
||||
bool isNight = true; // Variable to track whether it is night or day
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -35,7 +36,7 @@ class _PlayerGridViewState extends State<PlayerGridView> {
|
|||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
isNight ? 'Nacht' : 'Tag',
|
||||
isNight ? 'Nacht' : 'Tag', // Display whether it is night or day
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -44,21 +45,21 @@ class _PlayerGridViewState extends State<PlayerGridView> {
|
|||
IconButton(
|
||||
icon: const Icon(Icons.info),
|
||||
onPressed: () {
|
||||
_showRolesDialog();
|
||||
_showRolesDialog(); // Show dialog with player roles
|
||||
},
|
||||
),
|
||||
],
|
||||
leading: IconButton(
|
||||
icon: const Icon(FontAwesomeIcons.xmark),
|
||||
onPressed: () {
|
||||
Navigator.popUntil(context, ModalRoute.withName('/'));
|
||||
Navigator.popUntil(context, ModalRoute.withName('/')); // Return to main screen
|
||||
},
|
||||
),
|
||||
),
|
||||
body: Container(
|
||||
color: isNight
|
||||
? const Color(0xff2d2d2d)
|
||||
: const Color.fromARGB(255, 194, 216, 225),
|
||||
: const Color.fromARGB(255, 194, 216, 225), // Set background color based on night/day
|
||||
padding: const EdgeInsets.only(left: 15, right: 15),
|
||||
child: Column(
|
||||
children: [
|
||||
|
@ -66,7 +67,7 @@ class _PlayerGridViewState extends State<PlayerGridView> {
|
|||
child: GridView.builder(
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount:
|
||||
MediaQuery.of(context).size.shortestSide < 600 ? 2 : 4,
|
||||
MediaQuery.of(context).size.shortestSide < 600 ? 2 : 4, // Adjust grid based on screen size
|
||||
mainAxisSpacing: 10,
|
||||
crossAxisSpacing: 10,
|
||||
),
|
||||
|
@ -78,14 +79,14 @@ class _PlayerGridViewState extends State<PlayerGridView> {
|
|||
onTap: () {
|
||||
setState(() {
|
||||
if (!widget.players[index].isDead) {
|
||||
_killPlayer(widget.players[index]);
|
||||
_killPlayer(widget.players[index]); // Mark player as dead
|
||||
}
|
||||
});
|
||||
},
|
||||
child: Card(
|
||||
color: widget.players[index].isDead
|
||||
? Colors.grey
|
||||
: Theme.of(context).colorScheme.primary,
|
||||
: Theme.of(context).colorScheme.primary, // Change card color based on player status
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
|
@ -98,7 +99,7 @@ class _PlayerGridViewState extends State<PlayerGridView> {
|
|||
),
|
||||
if (widget.players[index].isDead)
|
||||
const Icon(Icons.close,
|
||||
color: Colors.red, size: 48),
|
||||
color: Colors.red, size: 48), // Show icon if player is dead
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -113,7 +114,7 @@ class _PlayerGridViewState extends State<PlayerGridView> {
|
|||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 60, top: 10),
|
||||
child: ElevatedButton(
|
||||
onPressed: _changePhase,
|
||||
onPressed: _changePhase, // Change phase between night and day
|
||||
child: Text(isNight ? 'Tag skippen' : 'Nacht skippen'),
|
||||
),
|
||||
),
|
||||
|
@ -127,14 +128,14 @@ class _PlayerGridViewState extends State<PlayerGridView> {
|
|||
if (isNight) {
|
||||
if (player.role != Role.werwolf) {
|
||||
player.isDead = true;
|
||||
_checkWinCondition();
|
||||
_checkWinCondition(); // Check win condition after killing player
|
||||
isNight = false;
|
||||
}
|
||||
} else {
|
||||
player.isDead = true;
|
||||
_checkWinCondition();
|
||||
_checkWinCondition(); // Check win condition after killing player
|
||||
if (player.role == Role.joker) {
|
||||
_showWinDialog('Der Joker hat gewonnen!');
|
||||
_showWinDialog('Der Joker hat gewonnen!'); // Show win dialog for Joker
|
||||
}
|
||||
isNight = true;
|
||||
}
|
||||
|
@ -142,11 +143,7 @@ class _PlayerGridViewState extends State<PlayerGridView> {
|
|||
}
|
||||
|
||||
void _changePhase() {
|
||||
if (isNight) {
|
||||
isNight = false;
|
||||
} else {
|
||||
isNight = true;
|
||||
}
|
||||
isNight = !isNight; // Toggle between night and day
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
|
@ -159,9 +156,9 @@ class _PlayerGridViewState extends State<PlayerGridView> {
|
|||
.length;
|
||||
|
||||
if (countWolves == 0) {
|
||||
_showWinDialog('Die Dorfbewohner haben gewonnen!');
|
||||
_showWinDialog('Die Dorfbewohner haben gewonnen!'); // Show win dialog for villagers
|
||||
} else if (countWolves >= countVillagers) {
|
||||
_showWinDialog('Die Werwölfe haben gewonnen!');
|
||||
_showWinDialog('Die Werwölfe haben gewonnen!'); // Show win dialog for werewolves
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +173,7 @@ class _PlayerGridViewState extends State<PlayerGridView> {
|
|||
TextButton(
|
||||
child: const Text('Spiel beenden'),
|
||||
onPressed: () {
|
||||
Navigator.popUntil(context, ModalRoute.withName('/'));
|
||||
Navigator.popUntil(context, ModalRoute.withName('/')); // Return to main screen
|
||||
},
|
||||
),
|
||||
],
|
||||
|
@ -217,7 +214,7 @@ class _PlayerGridViewState extends State<PlayerGridView> {
|
|||
TextButton(
|
||||
child: const Text('OK'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop(); // Close dialog
|
||||
},
|
||||
),
|
||||
],
|
||||
|
|
|
@ -1,25 +1,28 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:werwolf/screens/settings.dart';
|
||||
|
||||
// Define the PlayerRegistry StatefulWidget
|
||||
class PlayerRegistry extends StatefulWidget {
|
||||
const PlayerRegistry({super.key});
|
||||
|
||||
@override
|
||||
// Create the state for the PlayerRegistry widget
|
||||
// ignore: library_private_types_in_public_api
|
||||
_PlayerRegistryState createState() => _PlayerRegistryState();
|
||||
}
|
||||
|
||||
// Define the state for the PlayerRegistry widget
|
||||
class _PlayerRegistryState extends State<PlayerRegistry> {
|
||||
final TextEditingController _playerController = TextEditingController();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
String _errorMessage = "";
|
||||
List<String> playernames = [];
|
||||
final TextEditingController _playerController = TextEditingController(); // Controller for player name input
|
||||
final _formKey = GlobalKey<FormState>(); // Key for form validation
|
||||
String _errorMessage = ""; // Error message string
|
||||
List<String> playernames = []; // List to store player names
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("Werwolf"),
|
||||
title: const Text("Werwolf"), // App bar title
|
||||
centerTitle: true,
|
||||
),
|
||||
body: Padding(
|
||||
|
@ -32,8 +35,8 @@ class _PlayerRegistryState extends State<PlayerRegistry> {
|
|||
key: _formKey,
|
||||
controller: _playerController,
|
||||
decoration: InputDecoration(
|
||||
errorText: _errorMessage == "" ? null : _errorMessage,
|
||||
labelText: 'Spielername',
|
||||
errorText: _errorMessage == "" ? null : _errorMessage, // Display error message if exists
|
||||
labelText: 'Spielername', // Label for text field
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Theme.of(context).colorScheme.primary),
|
||||
|
@ -54,14 +57,14 @@ class _PlayerRegistryState extends State<PlayerRegistry> {
|
|||
onSubmitted: (value) {
|
||||
setState(() {
|
||||
if (_playerController.text.isEmpty) {
|
||||
_errorMessage = "Spielername ist leer!";
|
||||
_errorMessage = "Spielername ist leer!"; // Error for empty name
|
||||
} else if (playernames.contains(value)) {
|
||||
_errorMessage = "Dieser Spieler existiert bereits";
|
||||
_errorMessage = "Dieser Spieler existiert bereits"; // Error for duplicate name
|
||||
_playerController.clear();
|
||||
} else {
|
||||
_errorMessage = "";
|
||||
_playerController.clear();
|
||||
playernames.add(value);
|
||||
playernames.add(value); // Add valid player name to list
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -73,15 +76,15 @@ class _PlayerRegistryState extends State<PlayerRegistry> {
|
|||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
title: Text(
|
||||
playernames[index],
|
||||
playernames[index], // Display player name
|
||||
),
|
||||
trailing: IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
playernames.remove(playernames[index]);
|
||||
playernames.remove(playernames[index]); // Remove player name from list
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.remove)),
|
||||
icon: const Icon(Icons.remove)), // Remove icon button
|
||||
);
|
||||
},
|
||||
),
|
||||
|
@ -93,16 +96,16 @@ class _PlayerRegistryState extends State<PlayerRegistry> {
|
|||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => GameSettings(
|
||||
playernames: playernames,
|
||||
playernames: playernames, // Pass player names to next screen
|
||||
),
|
||||
));
|
||||
} else {
|
||||
setState(() {
|
||||
_errorMessage = "Es müssen mindestens 6 Spieler sein!";
|
||||
_errorMessage = "Es müssen mindestens 6 Spieler sein!"; // Error for not enough players
|
||||
});
|
||||
}
|
||||
},
|
||||
child: const Text('Spiel einstellen'),
|
||||
child: const Text('Spiel einstellen'), // Button to start game settings
|
||||
),
|
||||
const Padding(padding: EdgeInsets.all(30))
|
||||
],
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'package:werwolf/screens/flippingcards.dart';
|
|||
import '../models/game.dart';
|
||||
import '../models/role.dart';
|
||||
|
||||
// Main widget for game settings
|
||||
class GameSettings extends StatefulWidget {
|
||||
final List<String> playernames;
|
||||
const GameSettings({required this.playernames, super.key});
|
||||
|
@ -17,7 +18,7 @@ class _GameSettingsState extends State<GameSettings> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
game = Game(playernames: widget.playernames);
|
||||
game = Game(playernames: widget.playernames); // Initialize the game with player names
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -27,7 +28,7 @@ class _GameSettingsState extends State<GameSettings> {
|
|||
appBar: AppBar(
|
||||
title: Text(
|
||||
"Werwolf",
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
style: Theme.of(context).textTheme.titleLarge, // Use large title style from theme
|
||||
),
|
||||
centerTitle: true,
|
||||
),
|
||||
|
@ -36,8 +37,8 @@ class _GameSettingsState extends State<GameSettings> {
|
|||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
"Anzahl der Spieler ${widget.playernames.length}",
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
"Anzahl der Spieler ${widget.playernames.length}", // Display number of players
|
||||
style: Theme.of(context).textTheme.titleLarge, // Use large title style from theme
|
||||
),
|
||||
const Divider(
|
||||
height: 60,
|
||||
|
@ -47,14 +48,13 @@ class _GameSettingsState extends State<GameSettings> {
|
|||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
"Anzahl der Werwölfe ${game.getWolves()}",
|
||||
style:
|
||||
Theme.of(context).textTheme.bodyLarge,
|
||||
"Anzahl der Werwölfe ${game.getWolves()}", // Display number of werewolves
|
||||
style: Theme.of(context).textTheme.bodyLarge, // Use large body style from theme
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
game.decrementWolves();
|
||||
game.decrementWolves(); // Decrease the number of werewolves
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.remove, color: Colors.white),
|
||||
|
@ -62,7 +62,7 @@ class _GameSettingsState extends State<GameSettings> {
|
|||
IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
game.incrementWolves();
|
||||
game.incrementWolves(); // Increase the number of werewolves
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.add, color: Colors.white),
|
||||
|
@ -75,9 +75,8 @@ class _GameSettingsState extends State<GameSettings> {
|
|||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0, bottom: 20),
|
||||
child: Text(
|
||||
"Spezielle Rollen",
|
||||
style:
|
||||
Theme.of(context).textTheme.titleLarge,
|
||||
"Spezielle Rollen", // Display special roles section
|
||||
style: Theme.of(context).textTheme.titleLarge, // Use large title style from theme
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
|
@ -89,22 +88,20 @@ class _GameSettingsState extends State<GameSettings> {
|
|||
Role role = Role.values[index];
|
||||
return ListTile(
|
||||
title: Text(
|
||||
role.stringValue,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyLarge,
|
||||
role.stringValue, // Display role name
|
||||
style: Theme.of(context).textTheme.bodyLarge, // Use large body style from theme
|
||||
),
|
||||
trailing: Switch(
|
||||
value: game.specialRoles[role],
|
||||
onChanged: (bool value) {
|
||||
setState(() {
|
||||
game.specialRoles[role] = value;
|
||||
game.specialRoles[role] = value; // Toggle special role
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
return Container(); // Return empty container if not a special role
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -113,13 +110,12 @@ class _GameSettingsState extends State<GameSettings> {
|
|||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
FlipingCard(players: game.getAllPlayers()),
|
||||
builder: (context) => FlipingCard(players: game.getAllPlayers()), // Start game
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Text(
|
||||
'Spiel starten!',
|
||||
'Spiel starten!', // Start game button text
|
||||
),
|
||||
),
|
||||
const Padding(padding: EdgeInsets.all(30)),
|
||||
|
|
47
pubspec.lock
47
pubspec.lock
|
@ -118,6 +118,11 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_driver:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
@ -147,6 +152,11 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
fuchsia_remote_debug_protocol:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -171,6 +181,11 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.2"
|
||||
integration_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -283,6 +298,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -291,6 +314,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.2"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -384,6 +415,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
sync_http:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sync_http
|
||||
sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -464,6 +503,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.5"
|
||||
webdriver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webdriver
|
||||
sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -17,6 +17,8 @@ dev_dependencies:
|
|||
sdk: flutter
|
||||
flutter_lints: ^2.0.0
|
||||
test: ^1.25.2
|
||||
integration_test:
|
||||
sdk: flutter
|
||||
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:werwolf/main.dart' as app;
|
||||
import 'package:werwolf/screens/playerregistry.dart';
|
||||
import 'package:werwolf/screens/settings.dart';
|
||||
import 'package:werwolf/screens/flippingcards.dart';
|
||||
import 'package:werwolf/screens/gameboard.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('Werwolf Game Integration Tests', () {
|
||||
testWidgets('Complete game flow', (WidgetTester tester) async {
|
||||
app.main();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Ensure we are on the PlayerRegistry screen
|
||||
expect(find.byType(PlayerRegistry), findsOneWidget);
|
||||
|
||||
// Add players
|
||||
for (int i = 0; i < 6; i++) {
|
||||
await tester.enterText(find.byType(TextField), 'Player $i');
|
||||
await tester.testTextInput.receiveAction(TextInputAction.done);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
// Ensure all players are added
|
||||
for (int i = 0; i < 6; i++) {
|
||||
expect(find.text('Player $i'), findsOneWidget);
|
||||
}
|
||||
|
||||
// Navigate to GameSettings screen
|
||||
await tester.tap(find.text('Spiel einstellen'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(GameSettings), findsOneWidget);
|
||||
|
||||
// Ensure the number of players and wolves are displayed correctly
|
||||
expect(find.text('Anzahl der Spieler 6'), findsOneWidget);
|
||||
expect(find.text('Anzahl der Werwölfe 1'), findsOneWidget);
|
||||
|
||||
// Toggle a special role
|
||||
await tester.tap(find.byType(Switch).first);
|
||||
await tester.pumpAndSettle();
|
||||
expect((tester.widget(find.byType(Switch).first) as Switch).value, true);
|
||||
|
||||
// Navigate to FlipingCard screen
|
||||
await tester.tap(find.text('Spiel starten!'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(FlipingCard), findsOneWidget);
|
||||
|
||||
// Flip through all players
|
||||
for (int i = 0; i < 6; i++) {
|
||||
await tester.tap(find.text('Klick um deine Rolle zu sehen!'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Nächster Spieler'));
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
// Ensure we navigate to the game board
|
||||
await tester.tap(find.text('Spiel anfangen!'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(PlayerGridView), findsOneWidget);
|
||||
|
||||
// Tap to kill a player
|
||||
await tester.tap(find.text('Player 0'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byIcon(Icons.close), findsOneWidget);
|
||||
|
||||
// Skip phase
|
||||
await tester.tap(find.text('Tag skippen'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Nacht skippen'), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:werwolf/screens/settings.dart';
|
||||
import 'package:werwolf/screens/flippingcards.dart';
|
||||
|
||||
void main() {
|
||||
group('GameSettings Tests', () {
|
||||
List<String> playerNames = ['Alice', 'Bob', 'Charlie', 'Dave', 'Eve', 'Frank'];
|
||||
|
||||
testWidgets('Displays number of players', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(home: GameSettings(playernames: playerNames)));
|
||||
|
||||
expect(find.text('Anzahl der Spieler 6'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Displays number of wolves and increments/decrements correctly', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(home: GameSettings(playernames: playerNames)));
|
||||
|
||||
expect(find.text('Anzahl der Werwölfe 1'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.byIcon(Icons.add));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Anzahl der Werwölfe 2'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.byIcon(Icons.remove));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Anzahl der Werwölfe 1'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Displays special roles and toggles switches', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(home: GameSettings(playernames: playerNames)));
|
||||
|
||||
expect(find.text('Spezielle Rollen'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.byType(Switch).first);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect((tester.widget(find.byType(Switch).first) as Switch).value, true);
|
||||
});
|
||||
|
||||
testWidgets('Navigates to FlipingCard screen on start', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(home: GameSettings(playernames: playerNames)));
|
||||
|
||||
await tester.tap(find.text('Spiel starten!'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(FlipingCard), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue