blob: 70315df41c862f268e668d08ac59c192d9ad6c08 [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;
// Note: Proto and Board are "fake" games intended to demonstrate what we can do.
// Proto is just a drag cards around "game".
// Board is meant to show how one _could_ layout a game of Hearts. This one is not hooked up very well yet.
enum GameType { Proto, Hearts, Poker, Solitaire, Board }
Map<GameType, String> _gameTypeMap = <GameType, String>{
GameType.Proto: "Proto",
GameType.Hearts: "Hearts",
GameType.Poker: "Poker",
GameType.Solitaire: "Solitaire",
};
String gameTypeToString(GameType t) {
return _gameTypeMap[t];
}
GameType stringToGameType(String t) {
GameType gt;
_gameTypeMap.forEach((GameType type, String name) {
if (name == t) {
gt = type;
}
});
return gt;
}
// You should share information like this if you want to setup a game for someone else.
class GameStartData {
String type;
int playerNumber;
int gameID;
int ownerID;
GameStartData(this.type, this.playerNumber, this.gameID, this.ownerID);
GameStartData.fromJSONString(String json) {
var data = JSON.decode(json);
type = data["type"];
playerNumber = data["playerNumber"];
gameID = data["gameID"];
ownerID = data["ownerID"];
}
String toJSONString() {
return JSON.encode({
"type": type,
"playerNumber": playerNumber,
"gameID": gameID,
"ownerID": ownerID
});
}
GameType get gameType => stringToGameType(type);
bool operator ==(Object other) {
if (other is! GameStartData) {
return false;
}
GameStartData gsd = other;
return gsd.type == type &&
gsd.playerNumber == playerNumber &&
gsd.gameID == gameID &&
gsd.ownerID == ownerID;
}
}
typedef void NoArgCb();
/// A game consists of multiple decks and tracks a single deck of cards.
/// It also handles events; when cards are dragged to and from decks.
abstract class Game {
final GameType gameType;
String get gameTypeName; // abstract
final bool isCreator;
final List<List<Card>> cardCollections = new List<List<Card>>();
final List<Card> deck = new List<Card>.from(Card.All);
final int gameID;
final GameLog gamelog;
int _playerNumber;
int get playerNumber => _playerNumber;
// Some subclasses may wish to override this setter to do extra work.
void set playerNumber(int other) {
_playerNumber = other;
}
bool debugMode = false;
String debugString = 'hello?';
NoArgCb updateCallback; // Used to inform components of when a change has occurred. This is especially important when something non-UI related changes what should be drawn.
// A super constructor, don't call this unless you're a subclass.
Game.create(
this.gameType, this.gamelog, this._playerNumber, int numCollections,
{int gameID, bool isCreator})
: gameID = gameID ?? new math.Random().nextInt(0x00FFFFFF),
isCreator = isCreator ?? false {
print("The gameID is ${gameID}");
gamelog.setGame(this);
for (int i = 0; i < numCollections; i++) {
cardCollections.add(new List<Card>());
}
}
List<Card> deckPeek(int numCards, [int start = 0]) {
assert(deck.length >= numCards);
List<Card> cards =
new List<Card>.from(deck.getRange(start, start + numCards));
return cards;
}
// Which card collection has the card?
int findCard(Card card) {
for (int i = 0; i < cardCollections.length; i++) {
if (cardCollections[i].contains(card)) {
return i;
}
}
return -1;
}
void resetCards() {
for (int i = 0; i < cardCollections.length; i++) {
cardCollections[i].clear();
}
deck.clear();
deck.addAll(Card.All);
}
void quit() {
this.gamelog.close();
}
// UNIMPLEMENTED
void move(Card card, List<Card> dest);
void triggerEvents();
void startGameSignal();
}