Last active
December 2, 2024 20:27
-
-
Save fel-cesar/41febeba2e6423155b6f8d489a5b1d32 to your computer and use it in GitHub Desktop.
Felipe César - Uriel live coding
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
// BEGIN OF TEST | |
// 1 - Analyze the code and set a plan. (run first) - OK | |
// 2 - Select a solution for game logic (check winner, check tie, etc...) | |
// 3 - Select a state management solutin, probably "setState" directly for simplicity sake. | |
// 4 - "hello workd" UI to test logic | |
// 5 - finish players logic | |
// 6 - Polish solution | |
// ------ | |
// END OF TEST | |
// We couldnt finish all the app requirements ontime, although the next steps would be... | |
// 1 - Prevent the selection of the same tile and scoring ( inside playTurn for simplicity) | |
// 2 - Test and fix reset logic ( if errors) | |
// 3 - Check all requirements where met | |
// 4 - Polish (improve check winner algorithm, UI, improve state management, etc...) | |
void main() { | |
runApp(const TicTacToeApp()); | |
} | |
class TicTacToeApp extends StatelessWidget { | |
const TicTacToeApp({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return const MaterialApp( | |
title: 'Tic Tac Toe', | |
home: GameScreen(), | |
debugShowCheckedModeBanner: false, | |
); | |
} | |
} | |
class GameScreen extends StatefulWidget { | |
const GameScreen({super.key}); | |
@override | |
GameScreenState createState() => GameScreenState(); | |
} | |
class GameScreenState extends State<GameScreen> { | |
// Game state variables | |
List<String> board = []; // 1 - 9 | |
String currentPlayer = 'X'; | |
final String player1 = 'O'; | |
final String player2 = 'X'; | |
String? winner; | |
int scoreX = 0; | |
int scoreO = 0; | |
String message = ''; | |
void resetBoard() { | |
board = List.generate(9, (index) => ''); | |
winner = null; | |
List<String> shiffledList = (<String>['X', 'O']..shuffle()); | |
currentPlayer = shiffledList[0]; | |
} | |
void playTurn(int tileSelected) { | |
board[tileSelected] = currentPlayer; | |
// check winner | |
final String? winner = checkWinner(); | |
if (winner != null) { | |
if (winner == player1) { | |
scoreX++; | |
} | |
if (winner == player2) { | |
scoreO++; | |
} | |
} else if (board.contains('')) { | |
currentPlayer = currentPlayer == 'X' ? 'O' : 'X'; | |
} else { | |
message = "it`a draw"; | |
} | |
} | |
String? checkWinner() { | |
// TODO: Think in the algorithm instead of hard coding the combinations. | |
// Define the winning combinations | |
const List<List<int>> winningCombinations = <List<int>>[ | |
[0, 1, 2], | |
[3, 4, 5], | |
[6, 7, 8], | |
[0, 3, 6], | |
[1, 4, 7], | |
[2, 5, 8], | |
[0, 4, 8], | |
[2, 4, 6] | |
]; | |
// Define the player string to be returned. | |
for (final List<int> combo in winningCombinations) { | |
if (board[combo[0]] == currentPlayer && | |
board[combo[1]] == currentPlayer && | |
board[combo[2]] == currentPlayer) { | |
return currentPlayer; | |
} | |
} | |
// If it is a tie | |
return null; | |
} | |
@override | |
void initState() { | |
resetBoard(); | |
super.initState(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: const Text('Tic Tac Toe'), | |
), | |
body: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
Text('Player X: $scoreX', style: const TextStyle(fontSize: 20)), | |
Text('Player O: $scoreO', style: const TextStyle(fontSize: 20)), | |
GridView.builder( | |
shrinkWrap: true, | |
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( | |
crossAxisCount: 3, | |
childAspectRatio: 1.0, | |
mainAxisSpacing: 8.0, | |
crossAxisSpacing: 8.0, | |
), | |
itemCount: 9, | |
itemBuilder: (context, index) { | |
return GestureDetector( | |
onTap: () { | |
setState(() { | |
playTurn(index); | |
}); | |
}, | |
child: Container( | |
decoration: BoxDecoration( | |
border: Border.all(color: Colors.black), | |
), | |
child: Center( | |
child: Text( | |
board[index], | |
style: const TextStyle(fontSize: 32), | |
), | |
), | |
), | |
); | |
}, | |
), | |
], | |
), | |
floatingActionButton: FloatingActionButton( | |
onPressed: () => {}, | |
child: const Icon(Icons.refresh), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment