blob: 28c071bac500655c8e759ee1abb629c69e948076 [file] [log] [blame]
// 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));
}
}