import 'package:flutter/material.dart'; import 'dart:math'; void main() { runApp(const TripleTriadApp()); } class TripleTriadApp extends StatelessWidget { const TripleTriadApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Triple Triad', debugShowCheckedModeBanner: false, theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.purple), useMaterial3: true, ), home: const GameScreen(), ); } } class Card { final String name; final int top; final int right; final int bottom; final int left; final Color color; final String owner; Card({ required this.name, required this.top, required this.right, required this.bottom, required this.left, required this.color, this.owner = '', }); Card copyWith({String? owner}) { return Card( name: name, top: top, right: right, bottom: bottom, left: left, color: color, owner: owner ?? this.owner, ); } } class GameScreen extends StatefulWidget { const GameScreen({super.key}); @override State createState() => _GameScreenState(); } class _GameScreenState extends State { List board = List.filled(9, null); List playerHand = []; List aiHand = []; Card? selectedCard; String currentPlayer = 'player'; int playerScore = 5; int aiScore = 5; bool gameOver = false; final List allCards = [ Card(name: 'Dragon', top: 9, right: 6, bottom: 2, left: 8, color: Colors.red.shade700), Card(name: 'Phoenix', top: 7, right: 7, bottom: 7, left: 2, color: Colors.orange.shade700), Card(name: 'Ifrit', top: 9, right: 8, bottom: 2, left: 6, color: Colors.red.shade600), Card(name: 'Shiva', top: 6, right: 7, bottom: 4, left: 9, color: Colors.blue.shade700), Card(name: 'Bahamut', top: 9, right: 9, bottom: 6, left: 4, color: Colors.purple.shade700), Card(name: 'Leviathan', top: 7, right: 5, bottom: 8, left: 7, color: Colors.blue.shade600), Card(name: 'Odin', top: 8, right: 8, bottom: 5, left: 3, color: Colors.grey.shade700), Card(name: 'Titan', top: 8, right: 4, bottom: 8, left: 6, color: Colors.brown.shade700), Card(name: 'Ramuh', top: 4, right: 9, bottom: 5, left: 8, color: Colors.yellow.shade800), Card(name: 'Carbuncle', top: 8, right: 4, bottom: 4, left: 8, color: Colors.green.shade700), ]; @override void initState() { super.initState(); _initGame(); } void _initGame() { final shuffled = List.from(allCards)..shuffle(); playerHand = shuffled.sublist(0, 5).map((c) => c.copyWith(owner: 'player')).toList(); aiHand = shuffled.sublist(5, 10).map((c) => c.copyWith(owner: 'ai')).toList(); board = List.filled(9, null); selectedCard = null; currentPlayer = 'player'; playerScore = 5; aiScore = 5; gameOver = false; setState(() {}); } void _selectCard(Card card) { if (currentPlayer != 'player' || gameOver) return; setState(() { selectedCard = card; }); } void _placeCard(int position) { if (board[position] != null || selectedCard == null || gameOver) return; if (currentPlayer != 'player') return; setState(() { board[position] = selectedCard; playerHand.remove(selectedCard); selectedCard = null; }); _checkCaptures(position, 'player'); _updateScore(); if (_isGameOver()) { _endGame(); return; } currentPlayer = 'ai'; Future.delayed(const Duration(milliseconds: 800), _aiTurn); } void _aiTurn() { if (aiHand.isEmpty || gameOver) return; // Simple AI: find best move int bestPosition = -1; int bestCaptures = -1; Card? bestCard; for (var card in aiHand) { for (int i = 0; i < 9; i++) { if (board[i] == null) { int captures = _simulateCaptures(i, card, 'ai'); if (captures > bestCaptures) { bestCaptures = captures; bestPosition = i; bestCard = card; } } } } if (bestCard != null && bestPosition != -1) { setState(() { board[bestPosition] = bestCard; aiHand.remove(bestCard); }); _checkCaptures(bestPosition, 'ai'); _updateScore(); if (_isGameOver()) { _endGame(); return; } currentPlayer = 'player'; } } int _simulateCaptures(int position, Card card, String owner) { int captures = 0; final row = position ~/ 3; final col = position % 3; // Check top if (row > 0) { final topCard = board[position - 3]; if (topCard != null && topCard.owner != owner && card.top > topCard.bottom) { captures++; } } // Check right if (col < 2) { final rightCard = board[position + 1]; if (rightCard != null && rightCard.owner != owner && card.right > rightCard.left) { captures++; } } // Check bottom if (row < 2) { final bottomCard = board[position + 3]; if (bottomCard != null && bottomCard.owner != owner && card.bottom > bottomCard.top) { captures++; } } // Check left if (col > 0) { final leftCard = board[position - 1]; if (leftCard != null && leftCard.owner != owner && card.left > leftCard.right) { captures++; } } return captures; } void _checkCaptures(int position, String owner) { final card = board[position]!; final row = position ~/ 3; final col = position % 3; // Check top if (row > 0) { final topPos = position - 3; final topCard = board[topPos]; if (topCard != null && topCard.owner != owner && card.top > topCard.bottom) { board[topPos] = topCard.copyWith(owner: owner); } } // Check right if (col < 2) { final rightPos = position + 1; final rightCard = board[rightPos]; if (rightCard != null && rightCard.owner != owner && card.right > rightCard.left) { board[rightPos] = rightCard.copyWith(owner: owner); } } // Check bottom if (row < 2) { final bottomPos = position + 3; final bottomCard = board[bottomPos]; if (bottomCard != null && bottomCard.owner != owner && card.bottom > bottomCard.top) { board[bottomPos] = bottomCard.copyWith(owner: owner); } } // Check left if (col > 0) { final leftPos = position - 1; final leftCard = board[leftPos]; if (leftCard != null && leftCard.owner != owner && card.left > leftCard.right) { board[leftPos] = leftCard.copyWith(owner: owner); } } } void _updateScore() { int pScore = playerHand.length; int aScore = aiHand.length; for (var card in board) { if (card != null) { if (card.owner == 'player') pScore++; else aScore++; } } playerScore = pScore; aiScore = aScore; } bool _isGameOver() { return board.every((cell) => cell != null); } void _endGame() { setState(() { gameOver = true; }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFF1a1a2e), appBar: AppBar( title: const Text('Triple Triad'), backgroundColor: const Color(0xFF16213e), actions: [ IconButton( icon: const Icon(Icons.refresh), onPressed: _initGame, ), ], ), body: SafeArea( child: Column( children: [ // AI Hand Container( height: 100, padding: const EdgeInsets.all(8), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: aiHand.map((card) => Padding( padding: const EdgeInsets.symmetric(horizontal: 4), child: _buildMiniCard(card, false), )).toList(), ), ), // Score Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _buildScoreCard('AI', aiScore, Colors.red.shade700), _buildScoreCard('Player', playerScore, Colors.blue.shade700), ], ), ), // Game Board Expanded( child: Center( child: AspectRatio( aspectRatio: 1, child: Container( padding: const EdgeInsets.all(16), child: GridView.builder( physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, crossAxisSpacing: 8, mainAxisSpacing: 8, ), itemCount: 9, itemBuilder: (context, index) { return GestureDetector( onTap: () => _placeCard(index), child: _buildBoardCell(board[index]), ); }, ), ), ), ), ), // Player Hand Container( height: 120, padding: const EdgeInsets.all(8), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: playerHand.map((card) => Padding( padding: const EdgeInsets.symmetric(horizontal: 4), child: GestureDetector( onTap: () => _selectCard(card), child: _buildHandCard(card, selectedCard == card), ), )).toList(), ), ), if (gameOver) Container( padding: const EdgeInsets.all(16), child: Column( children: [ Text( playerScore > aiScore ? 'You Win!' : playerScore < aiScore ? 'AI Wins!' : 'Draw!', style: const TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.white, ), ), const SizedBox(height: 8), ElevatedButton( onPressed: _initGame, child: const Text('New Game'), ), ], ), ), ], ), ), ); } Widget _buildScoreCard(String label, int score, Color color) { return Container( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), decoration: BoxDecoration( color: color, borderRadius: BorderRadius.circular(8), ), child: Column( children: [ Text( label, style: const TextStyle(color: Colors.white, fontSize: 12), ), Text( '$score', style: const TextStyle( color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold, ), ), ], ), ); } Widget _buildBoardCell(Card? card) { if (card == null) { return Container( decoration: BoxDecoration( color: const Color(0xFF0f3460), borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.white24), ), ); } return _buildFullCard(card); } Widget _buildHandCard(Card card, bool selected) { return Container( width: 70, decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), border: Border.all( color: selected ? Colors.yellow : Colors.transparent, width: 3, ), ), child: _buildFullCard(card), ); } Widget _buildMiniCard(Card card, bool faceUp) { return Container( width: 50, decoration: BoxDecoration( color: faceUp ? card.color : Colors.grey.shade800, borderRadius: BorderRadius.circular(6), border: Border.all(color: Colors.white24), ), ); } Widget _buildFullCard(Card card) { final isPlayerCard = card.owner == 'player'; return Container( decoration: BoxDecoration( color: isPlayerCard ? Colors.blue.shade700 : Colors.red.shade700, borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.white24, width: 2), ), child: Stack( children: [ Center( child: Text( card.name, style: const TextStyle( color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold, ), textAlign: TextAlign.center, ), ), Positioned( top: 4, left: 0, right: 0, child: Center( child: Text( '${card.top}', style: const TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ), Positioned( right: 4, top: 0, bottom: 0, child: Center( child: Text( '${card.right}', style: const TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ), Positioned( bottom: 4, left: 0, right: 0, child: Center( child: Text( '${card.bottom}', style: const TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ), Positioned( left: 4, top: 0, bottom: 0, child: Center( child: Text( '${card.left}', style: const TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ), ], ), ); } }