Last active
February 26, 2020 15:32
-
-
Save digitaljoni/17ea02484468fd2079d0f6514cade6a4 to your computer and use it in GitHub Desktop.
Simple Card Game
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'; | |
| final Map<String, String> suitSymbols = { | |
| 'd': '♦️', | |
| 'h': '♥️', | |
| 's': '♠️', | |
| 'c': '♣️' | |
| }; | |
| class Card { | |
| Card(this.suit, this.rank); | |
| final String suit; | |
| final int rank; | |
| final Map<int, String> rankNames = { | |
| 11: 'Jack', | |
| 12: 'Queen', | |
| 13: 'King', | |
| 1: 'Ace', | |
| }; | |
| String get rankName => rankNames[rank] ?? '$rank'; | |
| String get suitSymbol => suitSymbols[suit]; | |
| @override | |
| String toString() { | |
| return '$rankName of $suitSymbol'; | |
| } | |
| } | |
| class Deck { | |
| List<Card> cards = <Card>[]; | |
| Deck() { | |
| final List<String> suits = suitSymbols.keys.toList(); | |
| suits.forEach((String suit) { | |
| for (int rank = 1; rank <= 13; rank++) { | |
| cards.add(Card(suit, rank)); | |
| } | |
| }); | |
| } | |
| void shuffle() { | |
| cards.shuffle(); | |
| } | |
| Card dealCard() { | |
| final Card topCard = cards.first; | |
| cards.remove(topCard); | |
| return topCard; | |
| } | |
| @override | |
| String toString() { | |
| return cards.map((Card card) => card).join(', '); | |
| } | |
| } | |
| // Entrypoint | |
| void main() => runApp(SimpleCardGameApp()); | |
| class SimpleCardGameApp extends StatelessWidget { | |
| @override | |
| Widget build(BuildContext context) { | |
| return MaterialApp( | |
| title: 'Simple Card Game', | |
| debugShowCheckedModeBanner: false, | |
| theme: ThemeData( | |
| primarySwatch: Colors.green, canvasColor: Colors.green[100]), | |
| home: GamePage(), | |
| ); | |
| } | |
| } | |
| class GamePage extends StatefulWidget { | |
| @override | |
| _GamePageState createState() => _GamePageState(); | |
| } | |
| class _GamePageState extends State<GamePage> { | |
| Deck deck; | |
| Card card1; | |
| Card card2; | |
| Card playerCard; | |
| bool isCovered; | |
| String message = ''; | |
| @override | |
| void initState() { | |
| super.initState(); | |
| newGame(); | |
| } | |
| void newGame() { | |
| isCovered = true; | |
| playerCard = null; | |
| // Build New Deck | |
| deck = Deck(); | |
| // Shuffle | |
| deck.shuffle(); | |
| // Deal 2 cards; | |
| card1 = deck.dealCard(); | |
| card2 = deck.dealCard(); | |
| // Show message ready to play | |
| setState(() { | |
| message = 'Pick A Card!'; | |
| }); | |
| } | |
| void _onTap(Card selectedCard) { | |
| // get cpuCard | |
| final Card cpuCard = (card1 != selectedCard) ? card1 : card2; | |
| // compareCards | |
| setState(() { | |
| playerCard = selectedCard; | |
| isCovered = false; | |
| if (selectedCard.rank == cpuCard.rank) { | |
| message = 'It\'s a tie'; | |
| } else if (selectedCard.rank > cpuCard.rank) { | |
| message = 'You won!'; | |
| } else { | |
| message = 'CPU won!'; | |
| } | |
| }); | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| return Scaffold( | |
| appBar: AppBar( | |
| title: Text('Simple Card Game'), | |
| ), | |
| body: Center( | |
| child: Column( | |
| mainAxisAlignment: MainAxisAlignment.center, | |
| children: <Widget>[ | |
| Row( | |
| mainAxisAlignment: MainAxisAlignment.center, | |
| children: <Widget>[ | |
| CardWidget( | |
| card: card1, | |
| isCovered: isCovered, | |
| onTap: _onTap, | |
| isPlayerCard: playerCard == card1, | |
| ), | |
| CardWidget( | |
| card: card2, | |
| isCovered: isCovered, | |
| onTap: _onTap, | |
| isPlayerCard: playerCard == card2, | |
| ), | |
| ], | |
| ), | |
| Text( | |
| '$message', | |
| style: Theme.of(context).textTheme.headline4, | |
| ), | |
| (!isCovered) | |
| ? Container( | |
| width: 200.0, | |
| height: 44.0, | |
| child: FlatButton( | |
| shape: RoundedRectangleBorder( | |
| borderRadius: BorderRadius.all( | |
| Radius.circular(44.0), | |
| ), | |
| ), | |
| color: Colors.red, | |
| onPressed: () { | |
| newGame(); | |
| }, | |
| child: Text( | |
| 'Play Again!', | |
| style: TextStyle( | |
| color: Colors.white, | |
| ), | |
| ), | |
| ), | |
| ) | |
| : Container( | |
| width: 200.0, | |
| height: 44.0, | |
| ), | |
| ], | |
| ), | |
| ), | |
| ); | |
| } | |
| } | |
| class CardWidget extends StatelessWidget { | |
| CardWidget({this.card, this.isCovered, this.onTap, this.isPlayerCard}); | |
| final Card card; | |
| final bool isCovered; | |
| final Function onTap; | |
| final bool isPlayerCard; | |
| Widget cover() { | |
| return Container( | |
| width: 80.0, | |
| height: 130.0, | |
| color: Colors.red, | |
| ); | |
| } | |
| Widget cardFace() { | |
| return Container( | |
| child: Column( | |
| mainAxisAlignment: MainAxisAlignment.center, | |
| children: <Widget>[ | |
| Text( | |
| card.rankName, | |
| style: TextStyle( | |
| fontSize: 25, | |
| ), | |
| ), | |
| Text( | |
| card.suitSymbol, | |
| style: TextStyle( | |
| fontSize: 35, | |
| ), | |
| ), | |
| ], | |
| )); | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| return GestureDetector( | |
| onTap: isCovered | |
| ? () { | |
| onTap(card); | |
| } | |
| : null, | |
| child: Container( | |
| width: 100.0, | |
| height: 150.0, | |
| margin: EdgeInsets.all(10.0), | |
| padding: EdgeInsets.all(10.0), | |
| decoration: BoxDecoration( | |
| color: Colors.white, | |
| borderRadius: BorderRadius.all( | |
| Radius.circular(5), | |
| ), | |
| border: isPlayerCard | |
| ? Border.all( | |
| color: Colors.lightGreen, | |
| width: 5.0, | |
| ) | |
| : null, | |
| ), | |
| child: isCovered ? cover() : cardFace(), | |
| ), | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment