removing state from TTCGame

This commit is contained in:
Andrei Stoica 2024-12-21 07:42:49 -05:00
parent a9df9ab96b
commit 6caec73c0d
2 changed files with 72 additions and 83 deletions

View File

@ -11,7 +11,17 @@ class ClassicGame extends StatefulWidget {
class _ClassicGameState extends State<ClassicGame> { class _ClassicGameState extends State<ClassicGame> {
TTCState turn = TTCState.x; TTCState turn = TTCState.x;
late TTCGame game; List<TTCState> data = [
TTCState.empty,
TTCState.empty,
TTCState.empty,
TTCState.empty,
TTCState.empty,
TTCState.empty,
TTCState.empty,
TTCState.empty,
TTCState.empty,
];
String get turnText => switch (turn) { String get turnText => switch (turn) {
TTCState.empty => "", TTCState.empty => "",
@ -19,25 +29,58 @@ class _ClassicGameState extends State<ClassicGame> {
TTCState.o => "O", TTCState.o => "O",
}; };
void onTurnEnd() { void _nextTurn() {
setState(() { turn = switch (turn) {
turn = switch (turn) { TTCState.x => TTCState.o,
TTCState.x => TTCState.o, TTCState.o => TTCState.x,
TTCState.o => TTCState.x, _ => TTCState.x
_ => TTCState.x };
};
});
} }
@override Widget _invalidChoiceAlert(TTCState existingValue) {
void initState() { return Dialog(
super.initState(); child: Padding(
game = TTCGame( padding: EdgeInsets.all(10),
turn: turn, child: Column(
onClick: onTurnEnd, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Text(
"INVALID CHOICE",
style: TextStyle(fontWeight: FontWeight.bold),
),
Text("${existingValue.name.toUpperCase()} already claimed that"),
ElevatedButton(
onPressed: () => Navigator.pop(context),
child: const Text("Ok")),
],
),
),
); );
} }
bool _checkValidChoice(int index) {
if (data[index] == TTCState.empty) return true;
showDialog(
context: context,
builder: (context) => _invalidChoiceAlert(data[index]),
);
return false;
}
void _cellOnTap(int index) {
if (!_checkValidChoice(index)) {
return;
}
setState(() {
data[index] = turn;
_nextTurn();
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
@ -52,7 +95,9 @@ class _ClassicGameState extends State<ClassicGame> {
const Spacer(flex: 1), const Spacer(flex: 1),
TTCGame( TTCGame(
turn: turn, turn: turn,
onClick: onTurnEnd, cellOnTapCallback: _cellOnTap,
data: data,
cellTextStyle: const TextStyle(fontSize: 40),
), ),
const Spacer(flex: 5), const Spacer(flex: 5),
], ],

View File

@ -1,63 +1,24 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'state.dart'; import 'state.dart';
import 'util.dart';
/// Board of a single game of tic tac toe /// Board of a single game of tic tac toe
class TTCGame extends StatefulWidget { class TTCGame extends StatelessWidget {
const TTCGame({ const TTCGame({
super.key, super.key,
required this.turn, required this.turn,
this.data, required this.cellOnTapCallback,
this.onClick, required this.data,
this.cellTextStyle,
}); });
final TTCState turn; final TTCState turn;
final List<TTCState>? data; final List<TTCState> data;
/// hook into acction of tapping on square /// styling for text in cell
final Function? onClick; final TextStyle? cellTextStyle;
@override /// hook into end of turn cycle;
State<StatefulWidget> createState() => _TTCGameState(); final Function cellOnTapCallback;
}
class _TTCGameState extends State<TTCGame> {
late TTCState turn;
late List<TTCState> data;
void setCellState(int index) {
switch (data[index]) {
case TTCState.empty:
setState(() {
data[index] = turn;
turn = switch (turn) {
TTCState.x => TTCState.o,
TTCState.o => TTCState.x,
TTCState.empty => TTCState.empty,
};
});
widget.onClick?.call();
notifyWin();
break;
default:
ScaffoldMessenger.of(context)
..clearSnackBars()
..showSnackBar(const SnackBar(
content: Text("Invalid Choice: cell already has value")));
}
}
void notifyWin() {
TTCState state = Util.checkWin(data);
if (state != TTCState.empty) {
ScaffoldMessenger.of(context)
..clearSnackBars()
..showSnackBar(
SnackBar(content: Text("${state.name.toUpperCase()} wins")));
}
}
Border _genCellBorder( Border _genCellBorder(
int index, { int index, {
@ -75,29 +36,12 @@ class _TTCGameState extends State<TTCGame> {
decoration: BoxDecoration(border: _genCellBorder(index)), decoration: BoxDecoration(border: _genCellBorder(index)),
child: TTCCell( child: TTCCell(
state: state, state: state,
textStyle: cellTextStyle,
stateSetCallback: () { stateSetCallback: () {
setCellState(index); cellOnTapCallback(index);
}, },
)); ));
@override
void initState() {
super.initState();
turn = widget.turn;
data = widget.data ??
<TTCState>[
TTCState.empty,
TTCState.empty,
TTCState.empty,
TTCState.empty,
TTCState.empty,
TTCState.empty,
TTCState.empty,
TTCState.empty,
TTCState.empty,
];
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
List<Widget> cells = []; List<Widget> cells = [];