From 6caec73c0d34b47a32a783192ba1c26276be2a61 Mon Sep 17 00:00:00 2001 From: Andrei Stoica Date: Sat, 21 Dec 2024 07:42:49 -0500 Subject: [PATCH] removing state from TTCGame --- lib/clasic.dart | 77 ++++++++++++++++++++++++++++++++++++++---------- lib/game.dart | 78 +++++++------------------------------------------ 2 files changed, 72 insertions(+), 83 deletions(-) diff --git a/lib/clasic.dart b/lib/clasic.dart index bc9ee39..93091a2 100644 --- a/lib/clasic.dart +++ b/lib/clasic.dart @@ -11,7 +11,17 @@ class ClassicGame extends StatefulWidget { class _ClassicGameState extends State { TTCState turn = TTCState.x; - late TTCGame game; + List data = [ + TTCState.empty, + TTCState.empty, + TTCState.empty, + TTCState.empty, + TTCState.empty, + TTCState.empty, + TTCState.empty, + TTCState.empty, + TTCState.empty, + ]; String get turnText => switch (turn) { TTCState.empty => "", @@ -19,25 +29,58 @@ class _ClassicGameState extends State { TTCState.o => "O", }; - void onTurnEnd() { - setState(() { - turn = switch (turn) { - TTCState.x => TTCState.o, - TTCState.o => TTCState.x, - _ => TTCState.x - }; - }); + void _nextTurn() { + turn = switch (turn) { + TTCState.x => TTCState.o, + TTCState.o => TTCState.x, + _ => TTCState.x + }; } - @override - void initState() { - super.initState(); - game = TTCGame( - turn: turn, - onClick: onTurnEnd, + Widget _invalidChoiceAlert(TTCState existingValue) { + return Dialog( + child: Padding( + padding: EdgeInsets.all(10), + child: Column( + 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 Widget build(BuildContext context) { return Column( @@ -52,7 +95,9 @@ class _ClassicGameState extends State { const Spacer(flex: 1), TTCGame( turn: turn, - onClick: onTurnEnd, + cellOnTapCallback: _cellOnTap, + data: data, + cellTextStyle: const TextStyle(fontSize: 40), ), const Spacer(flex: 5), ], diff --git a/lib/game.dart b/lib/game.dart index 75a9918..6be5f97 100644 --- a/lib/game.dart +++ b/lib/game.dart @@ -1,63 +1,24 @@ import 'package:flutter/material.dart'; import 'state.dart'; -import 'util.dart'; /// Board of a single game of tic tac toe -class TTCGame extends StatefulWidget { +class TTCGame extends StatelessWidget { const TTCGame({ super.key, required this.turn, - this.data, - this.onClick, + required this.cellOnTapCallback, + required this.data, + this.cellTextStyle, }); final TTCState turn; - final List? data; + final List data; - /// hook into acction of tapping on square - final Function? onClick; + /// styling for text in cell + final TextStyle? cellTextStyle; - @override - State createState() => _TTCGameState(); -} - -class _TTCGameState extends State { - late TTCState turn; - late List 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"))); - } - } + /// hook into end of turn cycle; + final Function cellOnTapCallback; Border _genCellBorder( int index, { @@ -75,29 +36,12 @@ class _TTCGameState extends State { decoration: BoxDecoration(border: _genCellBorder(index)), child: TTCCell( state: state, + textStyle: cellTextStyle, stateSetCallback: () { - setCellState(index); + cellOnTapCallback(index); }, )); - @override - void initState() { - super.initState(); - turn = widget.turn; - data = widget.data ?? - [ - TTCState.empty, - TTCState.empty, - TTCState.empty, - TTCState.empty, - TTCState.empty, - TTCState.empty, - TTCState.empty, - TTCState.empty, - TTCState.empty, - ]; - } - @override Widget build(BuildContext context) { List cells = [];