Després de cada tirada, comprovarem si hi ha un guanyador. En cas que no n'hi hagi, mirarem si queden caselles buides; si no s'hi ha, tenim un empat. El text que indica el guanyador o que hi ha empat es mostrarà en el mateix lloc on s'indica a qui toca tirar.
Per poder saber si hi ha caselles buides, crearem una funció que compta quantes caselles hi ha que continguin un determinat valor. Posant-hi el paràmetre 0, sabrem quantes de buides hi ha.
...
int comptaCaselles(int val){
// Compta les caselles que tenen un determinat valor
int total = 0;
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
if(estatCaselles[i][j] == val){
total++;
}
}
}
return total;
}
...
Per saber el guanyador, primer mirem si hi ha tres en línia a les diagonals i després a les fileres i les columnes. En cas que no hi hagi tres fitxes en línia, mirarem si queden caselles; si no n'hi ha, és empat. Si hi ha guanyador o empat, es modifica el text convenientment.
Al costat del text es mostra la fitxa del jugador actual; per això es guarda el guanyador com a jugador actual, així es mostra qui guanya. En cas d'empat, el jugador actual es posa a 0; així la fitxa es mostra transparent i, per tant, no es veu.
...
int guanyador(){
int guanya = 0;
// Atès que només s'afegeix una fitxa cada cop, només hi pot haver un guanyador
// Primer mirem les diagonals
if((estatCaselles[0][0] != 0) && (estatCaselles[0][0] == estatCaselles[1][1])
&& (estatCaselles[0][0] == estatCaselles[2][2])){
guanya = estatCaselles[0][0];
}
if((estatCaselles[0][2] != 0) && (estatCaselles[0][2] == estatCaselles[1][1])
&& (estatCaselles[0][2] == estatCaselles[2][0])){
guanya = estatCaselles[0][2];
}
// Mirem fileres i columnes
for(int i = 0; i < 3; i++){
if((estatCaselles[i][0] != 0) && (estatCaselles[i][0] == estatCaselles[i][1])
&& (estatCaselles[i][0] == estatCaselles[i][2])){
guanya = estatCaselles[i][0];
}
}
for(int i = 0; i < 3; i++){
if((estatCaselles[0][i] != 0) && (estatCaselles[0][i] == estatCaselles[1][i])
&& (estatCaselles[0][i] == estatCaselles[2][i])){
guanya = estatCaselles[0][i];
}
}
// Si no hi ha guanyador, mirem si el taulell ja és ple
// Si ho és, hi ha empat
if((guanya == 0) && (comptaCaselles(0) == 0)){
guanya = 3;
}
// S'acaba la partida si hi ha guanyador o no hi ha caselles
// Es posa com a jugador al guanyador, per mostrar-lo
// En cas d'empat, es deixa buit
if(guanya > 0){
if(guanya == 3){
notificacio = "Empat!";
jugadorActual = 0;
} else {
notificacio = "Guanya:";
jugadorActual = guanya;
}
}
return guanya;
}
...
A la pantalla principal creem una variable per guardar el text que es mostra i la que controla qui és el guanyador. Fem que la pulsació de les caselles només funcioni si la partida no ha acabat i comprovem si hi ha guanyador després de cada tirada.
pant_principal.dart
import 'package:flutter/material.dart'; import 'package:tres_linia/components/casella.dart'; import 'package:tres_linia/components/fitxa.dart'; import 'package:tres_linia/core/estils.dart';
class PantPral extends StatefulWidget {
const PantPral({super.key});
@override
State<PantPral> createState() => _PantPralState();
}
class _PantPralState extends State<PantPral> {
List<List<int>> estatCaselles = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];
int jugadorActual = 1; // Comença el jugador 1
int quiGuanya = 0; // De moment, no hi ha guanyador
String notificacio = "Tira:";
@override
Widget build(BuildContext context) {
return Column(
children: [
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
notificacio,
style: Estils.estilTextInfo
),
SizedBox(
width: 20,
),
Fitxa(estatAct: jugadorActual, mida: 25)
],
),
for(int i = 0; i < 3; i++) filera(i),
Expanded(child: Text(" "))
],
);
}
Row filera(int pY) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
for(int i = 0; i < 3; i++) Casella(posX: i, posY: pY, estAct: estatCaselles[pY][i],
posaFitxa: () {
setState(() {
// L'acció de picar la casella només es fa si la partida està en curs
if(quiGuanya == 0){
if(estatCaselles[pY][i] == 0) {
estatCaselles[pY][i] = jugadorActual;
if(jugadorActual == 1) {
jugadorActual = 2;
} else {
jugadorActual = 1;
}
}
// Després de cada tirada, mirem si hi ha guanyador
quiGuanya = guanyador();
}
});
},
),
],
);
}
int comptaCaselles(int val){
// Compta les caselles que tenen un determinat valor
int total = 0;
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
if(estatCaselles[i][j] == val){
total++;
}
}
}
return total;
}
int guanyador(){
int guanya = 0;
// Atès que només s'afegeix una fitxa cada cop, només hi pot haver un guanyador
// Primer mirem les diagonals
if((estatCaselles[0][0] != 0) && (estatCaselles[0][0] == estatCaselles[1][1])
&& (estatCaselles[0][0] == estatCaselles[2][2])){
guanya = estatCaselles[0][0];
}
if((estatCaselles[0][2] != 0) && (estatCaselles[0][2] == estatCaselles[1][1])
&& (estatCaselles[0][2] == estatCaselles[2][0])){
guanya = estatCaselles[0][2];
}
// Mirem fileres i columnes
for(int i = 0; i < 3; i++){
if((estatCaselles[i][0] != 0) && (estatCaselles[i][0] == estatCaselles[i][1])
&& (estatCaselles[i][0] == estatCaselles[i][2])){
guanya = estatCaselles[i][0];
}
}
for(int i = 0; i < 3; i++){
if((estatCaselles[0][i] != 0) && (estatCaselles[0][i] == estatCaselles[1][i])
&& (estatCaselles[0][i] == estatCaselles[2][i])){
guanya = estatCaselles[0][i];
}
}
// Si no hi ha guanyador, mirem si el taulell ja és ple
// Si ho és, hi ha empat
if((guanya == 0) && (comptaCaselles(0) == 0)){
guanya = 3;
}
// S'acaba la partida si hi ha guanyador o no hi ha caselles
// Es posa com a jugador al guanyador, per mostrar-lo
// En cas d'empat, es deixa buit
if(guanya > 0){
if(guanya == 3){
notificacio = "Empat!";
jugadorActual = 0;
} else {
notificacio = "Guanya:";
jugadorActual = guanya;
}
}
return guanya;
}
}

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.