import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { List data = [ TTCState.empty, TTCState.empty, TTCState.empty, TTCState.empty, TTCState.empty, TTCState.empty, TTCState.empty, TTCState.empty, TTCState.empty, ]; TTCState turn = TTCState.x; void setCellState(int index) { setState(() { data[index] = turn; turn = switch (turn) { TTCState.x => TTCState.o, TTCState.o => TTCState.x, TTCState.empty => TTCState.empty, }; }); } Widget _genCell(int index, TTCState state) => Container( decoration: BoxDecoration(border: Border.all()), child: Center( child: TTCCell( state: state, stateSetCallback: () { setCellState(index); }, ))); Widget _genGridvew() { List cells = []; for (final (index, state) in data.indexed) { cells.add(_genCell(index, state)); } return GridView.count( crossAxisCount: 3, shrinkWrap: true, children: cells, ); } String _turnText(TTCState state) => switch (state) { TTCState.x => "X", TTCState.o => "O", TTCState.empty => "O", }; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, ), body: Padding( padding: EdgeInsets.all(10), child: Column( mainAxisSize: MainAxisSize.min, children: [ const Spacer(flex: 5), Center( child: Text( "${_turnText(turn)}'s turn", style: const TextStyle(fontSize: 30, fontWeight: FontWeight.bold), )), const Spacer(flex: 1), _genGridvew(), const Spacer(flex: 5), ], )), ); } } enum TTCState { empty, x, o } class TTCCell extends StatelessWidget { const TTCCell({super.key, required this.state, this.stateSetCallback}); final TTCState state; final VoidCallback? stateSetCallback; @override Widget build(BuildContext context) => switch (state) { TTCState.empty => ElevatedButton( onPressed: stateSetCallback, child: const Text("none")), TTCState.x => const Text("X"), TTCState.o => const Text("O"), }; }