1
0
Fork 0

Made the game state fully serializable

This commit is contained in:
Michaël Lemaire 2015-03-03 01:00:00 +01:00
parent fc66e2a70f
commit faac0a8648
19 changed files with 132 additions and 18 deletions

View file

@ -24,8 +24,7 @@ module SpaceTac {
newGame(): Game.Universe {
// Currently create a quick battle
var universe = new Game.Universe();
universe.battle = Game.Battle.newQuickRandom(true);
universe.player = universe.battle.fleets[0].player;
universe.startQuickBattle();
return universe;
}
}

View file

@ -1,3 +1,5 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
@ -46,7 +48,7 @@ module SpaceTac.Game {
// Value computed from equipment
// This value can be altered by effects
// Example attributes are health points, action points recovery...
export class Attribute {
export class Attribute extends Serializable {
// Identifying code of this attribute
code: AttributeCode;
@ -58,6 +60,8 @@ module SpaceTac.Game {
// Create an attribute
constructor(code: AttributeCode = AttributeCode.Misc, current: number = 0, maximal: number = null) {
super();
this.code = code;
this.maximal = maximal;
this.current = current;

View file

@ -1,13 +1,17 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// Collection of several attributes
export class AttributeCollection {
export class AttributeCollection extends Serializable {
// Attributes
private attributes: Attribute[];
// Base constructor
constructor() {
super();
this.attributes = [];
}

View file

@ -1,8 +1,10 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// A turn-based battle between fleets
export class Battle {
export class Battle extends Serializable {
// Flag indicating if the battle is ended
ended: boolean;
@ -27,6 +29,8 @@ module SpaceTac.Game {
// Create a battle between two fleets
constructor(fleet1: Fleet = null, fleet2: Fleet = null) {
super();
this.log = new BattleLog();
this.fleets = [fleet1 || new Fleet(), fleet2 || new Fleet()];
this.play_order = [];

View file

@ -1,10 +1,12 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// Log of a battle
// This keeps track of all events in a battle
// It also allows to register a callback to receive these events
export class BattleLog {
export class BattleLog extends Serializable {
// Full list of battle events
events: BaseLogEvent[];
@ -16,6 +18,8 @@ module SpaceTac.Game {
// Create an initially empty log
constructor() {
super();
this.events = [];
this.subscribers = [];
this.filters = [];

View file

@ -1,8 +1,10 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// Result of an ended battle
export class BattleOutcome {
export class BattleOutcome extends Serializable {
// Indicates if the battle is a draw (no winner)
draw: boolean;
@ -13,6 +15,8 @@ module SpaceTac.Game {
loot: Equipment[];
constructor(winner: Fleet) {
super();
this.winner = winner;
this.draw = winner ? false : true;
this.loot = [];

View file

@ -1,8 +1,10 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// Piece of equipment to attach in slots
export class Equipment {
export class Equipment extends Serializable {
// Actual slot this equipment is attached to
attached_to: Slot;
@ -44,6 +46,8 @@ module SpaceTac.Game {
// Basic constructor
constructor(slot: SlotType = null, code: string = null) {
super();
this.slot = slot;
this.code = code;
this.name = code;

View file

@ -1,8 +1,10 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// A fleet of ships
export class Fleet {
export class Fleet extends Serializable {
// Fleet owner
player: Player;
@ -17,6 +19,8 @@ module SpaceTac.Game {
// Create a fleet, bound to a player
constructor(player: Player = null) {
super();
this.level = 1;
this.player = player || new Player();
this.ships = [];

View file

@ -1,8 +1,10 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// One player (human or IA)
export class Player {
export class Player extends Serializable {
// Current fleet
fleet: Fleet;
@ -11,6 +13,8 @@ module SpaceTac.Game {
// Create a player, with an empty fleet
constructor() {
super();
this.fleet = new Fleet(this);
this.ai = null;
}

View file

@ -98,6 +98,9 @@ module SpaceTac.Game {
items: items
};
} else {
if (Object.prototype.toString.call(field_value) === "[object Object]") {
console.error("Non Serializable object", field_value);
}
fields[field_name] = field_value;
}
}

View file

@ -1,8 +1,10 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// A single ship in a Fleet
export class Ship {
export class Ship extends Serializable {
// Fleet this ship is a member of
fleet: Fleet;
@ -56,6 +58,8 @@ module SpaceTac.Game {
// Create a new ship inside a fleet
constructor(fleet: Fleet = null, name: string = null) {
super();
this.attributes = new AttributeCollection();
this.fleet = fleet || new Fleet();
this.name = name;

View file

@ -1,3 +1,5 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
@ -11,7 +13,7 @@ module SpaceTac.Game {
}
// Slot to attach an equipment to a ship
export class Slot {
export class Slot extends Serializable {
// Link to the ship
ship: Ship;
@ -23,6 +25,8 @@ module SpaceTac.Game {
// Create an empty slot for a ship
constructor(ship: Ship, type: SlotType) {
super();
this.ship = ship;
this.type = type;
this.attached = null;

View file

@ -1,9 +1,11 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// Target for a capability
// This could be a location in space, or a ship
export class Target {
export class Target extends Serializable {
// Coordinates of the target
x: number;
y: number;
@ -13,6 +15,8 @@ module SpaceTac.Game {
// Standard constructor
constructor(x: number, y: number, ship: Ship) {
super();
this.x = x;
this.y = y;
this.ship = ship;

View file

@ -1,12 +1,32 @@
/// <reference path="Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// Main game universe
export class Universe {
export class Universe extends Serializable {
// Current connected player
player: Player;
// Currently played battle
battle: Battle;
// Load a game state from a string
static loadFromString(serialized: string): Universe {
var serializer = new Serializer();
return <Universe>serializer.unserialize(serialized);
}
// Start a new "quick battle" game
startQuickBattle(): void {
this.battle = Game.Battle.newQuickRandom(true);
this.player = this.battle.fleets[0].player;
}
// Serializes the game state to a string
saveToString(): string {
var serializer = new Serializer();
return serializer.serialize(this);
}
}
}

View file

@ -1,8 +1,10 @@
/// <reference path="../Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// Base class for action definitions
export class BaseAction {
export class BaseAction extends Serializable {
// Identifier code for the type of action
code: string;
@ -14,6 +16,8 @@ module SpaceTac.Game {
// Create the action
constructor(code: string, needs_target: boolean, equipment: Equipment = null) {
super();
this.code = code;
this.needs_target = needs_target;
this.equipment = equipment;

View file

@ -1,8 +1,10 @@
/// <reference path="../Serializable.ts"/>
module SpaceTac.Game.AI {
"use strict";
// Base class for all Artificial Intelligence interaction
export class AbstractAI {
export class AbstractAI extends Serializable {
// The battle this AI is involved in
battle: Battle;
@ -25,6 +27,8 @@ module SpaceTac.Game.AI {
private workqueue: Function[];
constructor(fleet: Fleet) {
super();
this.fleet = fleet;
this.battle = fleet.battle;
this.async = true;

View file

@ -1,14 +1,18 @@
/// <reference path="../Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// Base class for effects of actions
// Effects can be permanent or temporary (for a number of turns)
export class BaseEffect {
export class BaseEffect extends Serializable {
// Identifier code for the type of effect
code: string;
// Base constructor
constructor(code: string) {
super();
this.code = code;
}

View file

@ -1,8 +1,10 @@
/// <reference path="../Serializable.ts"/>
module SpaceTac.Game {
"use strict";
// Base class for a BattleLog event
export class BaseLogEvent {
export class BaseLogEvent extends Serializable {
// Code of the event (its type)
code: string;
@ -13,6 +15,8 @@ module SpaceTac.Game {
target: Target;
constructor(code: string, ship: Ship = null, target: Target = null) {
super();
this.code = code;
this.ship = ship;
this.target = target;

View file

@ -0,0 +1,32 @@
/// <reference path="../../definitions/jasmine.d.ts"/>
module SpaceTac.Game.Specs {
"use strict";
function applyGameSteps(universe: Universe): void {
universe.battle.advanceToNextShip();
// TODO Make some moves (IA?)
universe.battle.endBattle(universe.battle.fleets[0]);
}
describe("Universe", () => {
it("serializes to a string", () => {
var universe = new Universe();
universe.startQuickBattle();
// Dump and reload
var dumped = universe.saveToString();
var loaded_universe = Universe.loadFromString(dumped);
// Check equality
expect(loaded_universe).toEqual(universe);
// Apply game steps
applyGameSteps(universe);
applyGameSteps(loaded_universe);
// Check equality after game steps
expect(loaded_universe).toEqual(universe);
});
});
}