| // Copyright 2015 The Vanadium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| part of game_component; |
| |
| class SolitaireGameComponent extends GameComponent { |
| SolitaireGameComponent(Croupier croupier, NoArgCb cb, |
| {Key key, double width, double height}) |
| : super(croupier, cb, key: key, width: width, height: height); |
| |
| SolitaireGameComponentState createState() => |
| new SolitaireGameComponentState(); |
| } |
| |
| class SolitaireGameComponentState |
| extends GameComponentState<SolitaireGameComponent> { |
| @override |
| Widget build(BuildContext context) { |
| SolitaireGame game = config.game as SolitaireGame; |
| |
| // Build Solitaire and have it fill up the card level map. |
| // Unfortunately, this is required so that we can know which card components |
| // to collect. |
| Widget solitaireWidget = buildSolitaire(); |
| |
| List<Widget> children = new List<Widget>(); |
| children.add(new Container( |
| decoration: new BoxDecoration(backgroundColor: Colors.grey[300]), |
| width: config.width, |
| height: config.height, |
| child: solitaireWidget)); |
| if (game.phase == SolitairePhase.Play) { |
| // All cards are visible. |
| List<int> visibleCardCollectionIndexes = |
| game.cardCollections.asMap().keys.toList(); |
| |
| children.add(this.buildCardAnimationLayer(visibleCardCollectionIndexes)); |
| } |
| |
| return new Container( |
| width: config.width, height: config.height, child: new Stack(children)); |
| } |
| |
| void _cheatCallback() { |
| setState(() { |
| SolitaireGame game = config.game as SolitaireGame; |
| game.cheatUI(); |
| }); |
| } |
| |
| void _endRoundDebugCallback() { |
| setState(() { |
| SolitaireGame game = config.game as SolitaireGame; |
| game.jumpToScorePhaseDebug(); |
| }); |
| } |
| |
| Widget _makeDebugButtons() { |
| if (config.game.debugMode == false) { |
| return new Flex([ |
| new Flexible(flex: 4, child: _makeButton('Quit', _quitGameCallback)) |
| ]); |
| } |
| return new Container( |
| width: config.width, |
| child: new Flex([ |
| new Flexible( |
| flex: 1, child: new Text('P${config.game.playerNumber}')), |
| new Flexible(flex: 5, child: _makeButton('Cheat', _cheatCallback)), |
| new Flexible( |
| flex: 5, child: _makeButton('End Round', _endRoundDebugCallback)), |
| new Flexible(flex: 4, child: _makeButton('Quit', _quitGameCallback)) |
| ])); |
| } |
| |
| @override |
| Widget _makeButton(String text, NoArgCb callback, {bool inactive: false}) { |
| var borderColor = inactive ? Colors.grey[500] : Colors.white; |
| var backgroundColor = inactive ? Colors.grey[500] : null; |
| return new FlatButton( |
| child: new Container( |
| decoration: new BoxDecoration( |
| border: new Border.all(width: 1.0, color: borderColor), |
| backgroundColor: backgroundColor), |
| padding: new EdgeDims.all(10.0), |
| child: new Text(text)), |
| onPressed: inactive ? null : callback); |
| } |
| |
| Widget buildSolitaire() { |
| SolitaireGame game = config.game as SolitaireGame; |
| |
| switch (game.phase) { |
| case SolitairePhase.Deal: |
| return showDeal(); |
| case SolitairePhase.Play: |
| return showPlay(); |
| case SolitairePhase.Score: |
| return showScore(); |
| default: |
| assert(false); |
| return null; |
| } |
| } |
| |
| NoArgCb _makeFlipCallback(int index) { |
| SolitaireGame game = config.game as SolitaireGame; |
| return () { |
| game.flipCardUI(index); |
| }; |
| } |
| |
| void _moveCallback(logic_card.Card card, List<logic_card.Card> collection) { |
| setState(() { |
| SolitaireGame game = config.game; |
| String reason = game.canPlay(card, collection); |
| if (reason == null) { |
| game.move(card, collection); |
| } else { |
| print("You can't do that! ${reason}"); |
| game.debugString = reason; |
| } |
| }); |
| } |
| |
| Widget showPlay() { |
| SolitaireGame game = config.game as SolitaireGame; |
| |
| double cardSize = config.width / 8.0; |
| |
| List<Widget> row1 = new List<Widget>(); |
| List<CardCollectionComponent> aces = [0, 1, 2, 3].map((int i) { |
| return new CardCollectionComponent( |
| game.cardCollections[SolitaireGame.OFFSET_ACES + i], |
| true, |
| CardCollectionOrientation.show1, |
| widthCard: cardSize, |
| heightCard: cardSize, |
| acceptCallback: _moveCallback, |
| dragChildren: true, |
| acceptType: DropType.card, |
| useKeys: true); |
| }).toList(); |
| row1.add(new Row(aces)); |
| |
| row1.add(new Row([ |
| new CardCollectionComponent( |
| game.cardCollections[SolitaireGame.OFFSET_DISCARD], |
| true, |
| CardCollectionOrientation.show1, |
| widthCard: cardSize, |
| heightCard: cardSize, |
| dragChildren: true, |
| useKeys: true), |
| new GestureDetector( |
| child: new CardCollectionComponent( |
| game.cardCollections[SolitaireGame.OFFSET_DRAW], |
| false, |
| CardCollectionOrientation.show1, |
| widthCard: cardSize, |
| heightCard: cardSize, |
| useKeys: true), |
| onTap: game.canDrawCard ? game.drawCardUI : null), |
| ])); |
| |
| List<Widget> row2 = new List<Widget>(); |
| for (int i = 0; i < 7; i++) { |
| row2.add(new GestureDetector( |
| child: new CardCollectionComponent( |
| game.cardCollections[SolitaireGame.OFFSET_DOWN + i], |
| false, |
| CardCollectionOrientation.show1, |
| widthCard: cardSize, |
| heightCard: cardSize, |
| useKeys: true), |
| onTap: game.cardCollections[SolitaireGame.OFFSET_UP + i].length == 0 |
| ? _makeFlipCallback(i) |
| : null)); |
| } |
| List<Widget> row3 = new List<Widget>(); |
| for (int i = 0; i < 7; i++) { |
| row3.add(new CardCollectionComponent( |
| game.cardCollections[SolitaireGame.OFFSET_UP + i], |
| true, |
| CardCollectionOrientation.vert, |
| widthCard: cardSize, |
| heightCard: cardSize, |
| height: config.height * 0.6, |
| acceptCallback: _moveCallback, |
| dragChildren: true, |
| acceptType: DropType.card, |
| useKeys: true)); |
| } |
| |
| return new Column([ |
| new Row(row1, justifyContent: FlexJustifyContent.spaceBetween), |
| new Row(row2, justifyContent: FlexJustifyContent.spaceBetween), |
| new Row(row3, justifyContent: FlexJustifyContent.spaceBetween), |
| _makeDebugButtons() |
| ]); |
| } |
| |
| Widget showScore() { |
| SolitaireGame game = config.game as SolitaireGame; |
| |
| return new Container( |
| decoration: new BoxDecoration(backgroundColor: Colors.pink[500]), |
| child: new Flex([ |
| new Text('Player ${game.playerNumber}'), |
| _makeButton("Return to Lobby", _quitGameCallback), |
| _makeDebugButtons() |
| ], direction: FlexDirection.vertical)); |
| } |
| |
| Widget showDeal() { |
| SolitaireGame game = config.game as SolitaireGame; |
| |
| return new Container( |
| decoration: new BoxDecoration(backgroundColor: Colors.pink[500]), |
| child: new Flex([ |
| new Text('Player ${game.playerNumber}'), |
| _makeButton('Deal', game.dealCardsUI), |
| _makeDebugButtons() |
| ], |
| direction: FlexDirection.vertical, |
| justifyContent: FlexJustifyContent.spaceBetween)); |
| } |
| } |