mirror of
https://github.com/wassname/cardsforscience.git
synced 2026-06-27 16:14:52 +08:00
Observations and reactions almost working
This commit is contained in:
@@ -371,3 +371,6 @@ h1 br {
|
||||
.Paired .q9-12{color:rgb(106,61,154)}
|
||||
.Paired .q10-12{color:rgb(255,255,153)}
|
||||
.Paired .q11-12{color:rgb(177,89,40)}
|
||||
|
||||
|
||||
/* data tables */
|
||||
|
||||
+33
-17
@@ -12,6 +12,10 @@
|
||||
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="css/angular-datatables.css">
|
||||
<link rel="stylesheet" href="bower_components/datatables/media/css/jquery.dataTables.min.css">
|
||||
<link rel="stylesheet" href="bower_components/datatables/media/css/dataTables.bootstrap.min.css">
|
||||
<link rel="stylesheet" href="bower_components/angular-datatables/dist/plugins/bootstrap/datatables.bootstrap.min.css">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
|
||||
<link rel="icon" type="image/png" href="assets/favicon.png" />
|
||||
@@ -90,9 +94,9 @@
|
||||
<div class="col-md-4" ng-repeat="r in rc.elements">
|
||||
<span ng-show="rc.isVisible(r)"
|
||||
id="{{r.key}}"
|
||||
class="{{r.key}} element element-icon {{ r.state.interesting ? 'blink' : '' }} {{'q'+r.state.color+'-12'}} {{r.state.amount>0 ? '': 'empty'}} ui-draggable"
|
||||
class="{{r.key}} element element-icon {{ r.state.interesting ? 'blink' : '' }} {{'q'+r.state.color+'-12'}} {{r.state.amount>0 ? ' ui-draggable': 'empty'}}"
|
||||
data-element="{{r.key}}"
|
||||
data-drag="{{r.state.amount>0}}"
|
||||
data-drag="true"
|
||||
jqyoui-draggable="{containment:'offset'}"
|
||||
data-jqyoui-options="{{rc.dragOptions}}"
|
||||
data-hashkey={{r.$$hashKey}}
|
||||
@@ -177,22 +181,28 @@
|
||||
<div class="panel panel-default panel-stick">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<i class="fa fa-users"></i> HR
|
||||
<i class="fa fa-users"></i> Observations
|
||||
</h4>
|
||||
</div>
|
||||
<div class="panel-body scrollable large" id="hrLarge">
|
||||
|
||||
<div id="hrContent" ng-controller="HRController as hrc">
|
||||
<ul class="media-list" ng-cloak>
|
||||
<li class="media" ng-repeat="w in hrc.workers" ng-show="hrc.isVisible(w)">
|
||||
<div class="media-body">
|
||||
<h4 class="media-heading">{{ w.name }} <span ng-show="w.state.hired > 0" class="badge">{{ w.state.hired | niceNumber }}</span></h4>
|
||||
<p ng-show="w.state.hired > 0">{{ w.description }}</p>
|
||||
<p ng-show="w.state.hired > 0" class="small">Produce <strong>{{ w.state.rate | niceNumber }}</strong> data per second.</p>
|
||||
<button class="btn btn-primary" ng-disabled="!hrc.isAvailable(w)" ng-click="hrc.hire(w)"><i class="fa fa-user"></i> <small>{{ w.state.cost | currency }}</small></button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<div id="hrContent" ng-controller="ObservationsController as oc">
|
||||
<table datatable="ng" dt-options="oc.dtOptions" class="compact">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Reactants</th>
|
||||
<th>Results</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="o in ::oc.observations" ng-cloak>
|
||||
<td>{{ o.inputs.join('') }}</td>
|
||||
<td>{{ o.results.join('') }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -344,14 +354,20 @@
|
||||
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.17/angular.min.js"></script>
|
||||
<script src="bower_components/angular-dragdrop/src/angular-dragdrop.min.js"></script>
|
||||
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
|
||||
<script src="js/external/jquery.ui.touch-punch.min.js"></script>
|
||||
<script src="js/external/jquery.cookie-1.4.1.min.js"></script>
|
||||
|
||||
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
|
||||
|
||||
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.17/angular.min.js"></script>
|
||||
<script src="bower_components/angular-dragdrop/src/angular-dragdrop.min.js"></script>
|
||||
|
||||
<script src="js/external/retina.js"></script>
|
||||
<script src="js/external/fastclick.js"></script>
|
||||
|
||||
<script src="bower_components/datatables/media/js/jquery.dataTables.min.js"></script>
|
||||
<script src="bower_components/angular-datatables/dist/angular-datatables.min.js"></script>
|
||||
|
||||
<script src="js/storage.js"></script>
|
||||
<script src="js/helpers.js"></script>
|
||||
<script src="js/analytics.js"></script>
|
||||
|
||||
@@ -17,7 +17,7 @@ var app = (function () {
|
||||
// var allObjects = game.allObjects;
|
||||
// var lastSaved;
|
||||
|
||||
var app = angular.module('scienceAlchemy', ['ngDragDrop']);
|
||||
var app = angular.module('scienceAlchemy', ['ngDragDrop', 'datatables']);
|
||||
|
||||
// directives
|
||||
|
||||
@@ -96,8 +96,8 @@ var app = (function () {
|
||||
if (!draggable.hasClass('element-icon')) {
|
||||
var elementStore = vs.elements.get(key);
|
||||
var i = findIndexByHashKey(draggable.data('hashkey'));
|
||||
detector.elements.splice(i,1);
|
||||
elementStore.state.amount+=1;
|
||||
detector.elements.splice(i, 1);
|
||||
elementStore.state.amount += 1;
|
||||
}
|
||||
};
|
||||
vs.doElement = function (item) {
|
||||
@@ -135,7 +135,9 @@ var app = (function () {
|
||||
// containment:false
|
||||
};
|
||||
vm.onDrop = function (event, ui) {
|
||||
detector.onDrop(event, ui, game);
|
||||
var result = detector.onDrop(event, ui, game);
|
||||
if (result)
|
||||
game.lab.observe(result);
|
||||
};
|
||||
vm.click = function () {
|
||||
game.lab.clickDetector();
|
||||
@@ -148,7 +150,7 @@ var app = (function () {
|
||||
console.log('toggleFlameFuel');
|
||||
detector.flamer.toggleFuel();
|
||||
};
|
||||
vm.clearAll = function(){
|
||||
vm.clearAll = function () {
|
||||
detector.clearAll(game);
|
||||
}
|
||||
}]);
|
||||
@@ -180,20 +182,14 @@ var app = (function () {
|
||||
}, 1000);
|
||||
}]);
|
||||
|
||||
app.controller('HRController', ['$scope', 'game', function ($scope, game) {
|
||||
this.workers = game.workers;
|
||||
this.isVisible = function (worker) {
|
||||
return worker.isVisible(game.lab);
|
||||
};
|
||||
this.isAvailable = function (worker) {
|
||||
return worker.isAvailable(game.lab);
|
||||
};
|
||||
this.hire = function (worker) {
|
||||
var cost = worker.hire(game.lab);
|
||||
if (cost > 0) {
|
||||
UI.showUpdateValue("#update-funding", -cost);
|
||||
}
|
||||
app.controller('ObservationsController', ['$scope', 'game', function ($scope, game) {
|
||||
var vm = this;
|
||||
vm.observations = game.lab.state.observations;
|
||||
vm.dtOptions = {
|
||||
paginationType: 'full_numbers',
|
||||
displayLength: 2
|
||||
};
|
||||
|
||||
}]);
|
||||
|
||||
app.controller('UpgradesController', ['$scope', 'game', function ($scope, game) {
|
||||
|
||||
+37
-16
@@ -150,11 +150,12 @@ var Detector = function(){
|
||||
$droppable = angular.element(event.target);
|
||||
|
||||
// if the dragger came from the elements panels, clone it to here
|
||||
var newElement;
|
||||
if ($draggable.hasClass('element-icon')){
|
||||
|
||||
var elementStore = game.elements.filter(function(e){return e.key==$draggable.data('element');})[0];
|
||||
elementStore.state.amount-=1;
|
||||
var newElement = angular.copy(elementStore);
|
||||
newElement = angular.copy(elementStore);
|
||||
newElement.state.top=$draggable.offset().top;
|
||||
newElement.state.left=$draggable.offset().left;
|
||||
this.elements.push(newElement);
|
||||
@@ -168,8 +169,8 @@ var Detector = function(){
|
||||
var draggableLeft = $draggable.offset().left;
|
||||
var draggableWidth = $draggable.height();
|
||||
var draggableRight = draggableLeft + draggableWidth;
|
||||
var $draggables = angular.element('#detector').find('.element').not('.element-icon'); // replace with detector.elements
|
||||
var inputs = $draggables.filter( function() {
|
||||
var detectorDOMElems = angular.element('#detector').find('.element').not('.element-icon'); // replace with detector.elements
|
||||
var intersectingDOMElems = detectorDOMElems.filter( function() {
|
||||
var $elem = angular.element(this);
|
||||
var top = $elem.offset().top;
|
||||
var height = $elem.height();
|
||||
@@ -184,31 +185,51 @@ var Detector = function(){
|
||||
return isCoveredByDraggable;
|
||||
});
|
||||
|
||||
var reaction = this.experiment({inputs:inputs},game);
|
||||
console.log('droppables', inputs.length);
|
||||
// We have the DOM's in the area (maybe missing the newly dropped one)
|
||||
// var droppedModel = game.elements.getByHashKey($draggable.data('hashkey'));
|
||||
var intersectingElements = intersectingDOMElems.toArray().map(function(input){
|
||||
return self.elements.getByHashKey(angular.element(input).data('hashkey'));
|
||||
});
|
||||
|
||||
// make sure we include the dropped element as in some cases
|
||||
// it wont have DOM object yet so it wont be picked up as intersecting
|
||||
if (newElement && intersectingElements.indexOf(newElement)===-1) intersectingElements.push(newElement);
|
||||
|
||||
|
||||
var observation = this.experiment({inputs:intersectingElements,location:$draggable.offset()},game);
|
||||
console.log('droppables', intersectingElements.length, observation);
|
||||
return observation;
|
||||
|
||||
|
||||
},
|
||||
|
||||
/** Run an experiment depending on ingredients and conditions **/
|
||||
/** Run an experiment depending on reactants and conditions **/
|
||||
experiment: function(options,game) {
|
||||
var inputs = options.inputs || [];
|
||||
var inputKeys = inputs.map(function(i,e){return $(e).data('element')});
|
||||
var inputKeys = inputs.map(function(e){return e.key;});
|
||||
inputKeys.sort(); // this makes reaction be independant of order
|
||||
|
||||
var result = game.rules[inputKeys]
|
||||
var result = game.rules[inputKeys];
|
||||
if (result) {
|
||||
return this.reaction(result.ingredients,result.rune,game)
|
||||
this.reaction(result.reactants,result.results, game);
|
||||
} else {
|
||||
result = {
|
||||
reactants: [],
|
||||
catalysts: [],
|
||||
conditions: [],
|
||||
results: [],
|
||||
inputs: inputKeys
|
||||
};
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/** Remove ingredients and make results with animations **/
|
||||
reaction: function(ingredients,results,game){
|
||||
/** Remove reactants and make results with animations **/
|
||||
reaction: function(reactants,results,game){
|
||||
|
||||
// remove ingredients from detector
|
||||
for (var i = 0; i < ingredients.length; i++) {
|
||||
var ingredient = ingredients[i];
|
||||
// remove reactants from detector
|
||||
for (var i = 0; i < reactants.length; i++) {
|
||||
var ingredient = reactants[i];
|
||||
}
|
||||
|
||||
// TODO use angular effects to remove in puff of fade
|
||||
@@ -218,7 +239,7 @@ var Detector = function(){
|
||||
var resultKey = results[i];
|
||||
|
||||
// make sure it's discovered
|
||||
var elementStore = this.elements.filter(function(e){return e.key===resultKey;});
|
||||
var elementStore = game.elements.get(resultKey);
|
||||
elementStore.state.discovered=true;
|
||||
|
||||
// add new element to beaker
|
||||
@@ -229,7 +250,7 @@ var Detector = function(){
|
||||
}
|
||||
|
||||
// effects
|
||||
this.bubblr.start(1500);
|
||||
this.bubblr.bubble();
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
+45
-40
@@ -41,7 +41,7 @@ var Game = (function (Helpers, GameObjects, ObjectStorage) {
|
||||
_this.allObjects[o.key] = o;
|
||||
return o;
|
||||
};
|
||||
this.elements = this.elements.map(
|
||||
this.elements = this.elements.slice(0,20).map(
|
||||
function (r) {
|
||||
return makeGameObject(GameObjects.Element, r);
|
||||
});
|
||||
@@ -65,8 +65,8 @@ var Game = (function (Helpers, GameObjects, ObjectStorage) {
|
||||
|
||||
// put elements in extended array with utility methods
|
||||
this.elementStore = new GameObjects.ElementStore();
|
||||
this.elementStore.push.apply(this.elementStore,this.elements);
|
||||
this.elements=this.elementStore;
|
||||
this.elementStore.push.apply(this.elementStore, this.elements);
|
||||
this.elements = this.elementStore;
|
||||
|
||||
this.rules = this.generateRules();
|
||||
|
||||
@@ -75,46 +75,51 @@ var Game = (function (Helpers, GameObjects, ObjectStorage) {
|
||||
|
||||
/** Generate rules between runes **/
|
||||
Game.prototype.generateRules = function () {
|
||||
var elements = this.elements;
|
||||
// generate rules and store them with a hash of inredients
|
||||
// the rule will be an object with ingredients, catalysts, conditions, results
|
||||
// todo make a strcture that's more like a tree with progression etc
|
||||
// todo add duds, misleading ones, explosions wildcards
|
||||
// todo make this theory based?
|
||||
// todo simulation
|
||||
var rules = {};
|
||||
for (var k = 0; k < this.elements.length * 5; k++) {
|
||||
// make a rules
|
||||
var rule = {
|
||||
ingredients: [],
|
||||
catalysts: [],
|
||||
conditions: [],
|
||||
results: [],
|
||||
inputs: []
|
||||
}
|
||||
var numOfIngredients = 2 + Math.round(Math.random() * 2);
|
||||
for (var i = 0; i < numOfIngredients; i++) {
|
||||
var j = Math.round(Math.random() * (elements.length - 1));
|
||||
rule.ingredients.push(elements[j].key);
|
||||
var rules = ObjectStorage['rules'];
|
||||
if (!rules) {
|
||||
var elements = this.elements;
|
||||
// generate rules and store them with a hash of inredients
|
||||
// the rule will be an object with reactants, catalysts, conditions, results
|
||||
// todo make a strcture that's more like a tree with progression etc
|
||||
// todo add duds, misleading ones, explosions wildcards
|
||||
// todo make this theory based?
|
||||
// todo simulation
|
||||
var rules = {};
|
||||
for (var k = 0; k < this.elements.length * 20; k++) {
|
||||
// make a rules
|
||||
var rule = {
|
||||
reactants: [],
|
||||
catalysts: [],
|
||||
conditions: [],
|
||||
results: [],
|
||||
inputs: []
|
||||
}
|
||||
var numOfIngredients = 2 + Math.round(Math.random() * 2);
|
||||
for (var i = 0; i < numOfIngredients; i++) {
|
||||
var j = Math.round(Math.random() * (elements.length - 1));
|
||||
rule.reactants.push(elements[j].key);
|
||||
}
|
||||
|
||||
if (Math.random() < 0.1) {
|
||||
var j = Math.round(Math.random() * (elements.length - 1));
|
||||
rule.catalysts.push(elements[j].key);
|
||||
}
|
||||
var numOfresults = Math.round(Math.random() * 3);
|
||||
for (var i = 0; i < numOfresults; i++) {
|
||||
var j = Math.round(Math.random() * (elements.length - 1));
|
||||
rule.results.push(elements[j].key);
|
||||
}
|
||||
rule.inputs = [].concat(rule.reactants, rule.catalysts)
|
||||
rule.reactants.sort()
|
||||
rule.results.sort()
|
||||
rule.catalysts.sort()
|
||||
rule.inputs.sort();
|
||||
// index byhash of sorted array of reactants
|
||||
rules[rule.inputs] = rule
|
||||
}
|
||||
|
||||
if (Math.random() < 0.1) {
|
||||
var j = Math.round(Math.random() * (elements.length - 1));
|
||||
rule.catalysts.push(elements[j].key);
|
||||
}
|
||||
var numOfresults = Math.round(Math.random() * 3);
|
||||
for (var i = 0; i < numOfresults; i++) {
|
||||
var j = Math.round(Math.random() * (elements.length - 1));
|
||||
rule.results.push(elements[j].key);
|
||||
}
|
||||
rule.inputs = [].concat(rule.ingredients, rule.catalysts)
|
||||
rule.ingredients.sort()
|
||||
rule.results.sort()
|
||||
rule.catalysts.sort()
|
||||
rule.inputs.sort();
|
||||
// index byhash of sorted array of ingredients
|
||||
rules[rule.inputs] = rule
|
||||
}
|
||||
ObjectStorage['rules'] = rules;
|
||||
return rules;
|
||||
},
|
||||
Game.prototype.save = function () {
|
||||
|
||||
+41
-6
@@ -21,6 +21,15 @@ var GameObjects = (function () {
|
||||
function (state) {
|
||||
$.extend(this.state, state);
|
||||
};
|
||||
GameObject.prototype.guid = function () {
|
||||
function s4() {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1);
|
||||
}
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
||||
s4() + '-' + s4() + s4() + s4();
|
||||
}
|
||||
|
||||
/** @class Lab
|
||||
*/
|
||||
@@ -39,7 +48,8 @@ var GameObjects = (function () {
|
||||
moneySpent: 0,
|
||||
dataCollected: 0,
|
||||
dataSpent: 0,
|
||||
time: 0
|
||||
time: 0,
|
||||
observations: [],
|
||||
}
|
||||
}]);
|
||||
|
||||
@@ -76,6 +86,14 @@ var GameObjects = (function () {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Takes in a rule/observation object and records observation in journal
|
||||
* with reactants, inputs, catalysts, conditions, results
|
||||
***/
|
||||
Lab.prototype.observe = function (observation) {
|
||||
this.state.observations.push(observation);
|
||||
};
|
||||
|
||||
|
||||
Lab.prototype.buy = function (cost) {
|
||||
if (this.state.money >= cost) {
|
||||
@@ -95,15 +113,15 @@ var GameObjects = (function () {
|
||||
ElementStore.prototype.constructor = ElementStore;
|
||||
|
||||
/** Add a random element or specify it's key **/
|
||||
ElementStore.prototype.addToStore = function(element){
|
||||
ElementStore.prototype.addToStore = function (element) {
|
||||
if (!element) this.get(element);
|
||||
if (!element) element = this.select();
|
||||
return element.state.amount+=1;
|
||||
return element.state.amount += 1;
|
||||
};
|
||||
|
||||
/** Select random element from store **/
|
||||
ElementStore.prototype.select = function () {
|
||||
var i = Math.floor((this.length-1)*Math.random());
|
||||
var i = Math.floor((this.length - 1) * Math.random());
|
||||
return this[i];
|
||||
};
|
||||
/** Get element by hashid **/
|
||||
@@ -115,13 +133,29 @@ var GameObjects = (function () {
|
||||
|
||||
/** Get element by hashid **/
|
||||
ElementStore.prototype.getByHashKey = function (hashKey) {
|
||||
return this.filter(function (e) {
|
||||
if (hashKey === undefined) {
|
||||
console.warn('GetByHashKey given an undefined hashkey', hashKey)
|
||||
return;
|
||||
}
|
||||
var res = this.filter(function (e) {
|
||||
return e.$$hashKey === hashKey;
|
||||
})[0];
|
||||
});
|
||||
if (res.length == 1) return res[0];
|
||||
else if (res.length) {
|
||||
console.warn('Got multiple results when filtering on hashKey', hashKey);
|
||||
return res[0];
|
||||
} else {
|
||||
console.warn('Got no results when filtering on hashKey', hashKey);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** Get element by hashid **/
|
||||
ElementStore.prototype.findIndexByHashKey = function (hashKey) {
|
||||
if (hashKey === undefined) {
|
||||
console.warn('FindIndexByHashKey given an undefined hashkey', hashKey)
|
||||
return;
|
||||
}
|
||||
return this.findIndex(function (e) {
|
||||
return e.$$hashKey === hashKey;
|
||||
})[0];
|
||||
@@ -135,6 +169,7 @@ var GameObjects = (function () {
|
||||
this.state.discovered = Math.random() < 0.1;
|
||||
this.state.interesting = Math.random() < 0.1;
|
||||
this.state.color = Math.round(Math.random() * 11);
|
||||
this.uuid=this.guid();
|
||||
};
|
||||
|
||||
Element.prototype = Object.create(GameObject.prototype);
|
||||
|
||||
Reference in New Issue
Block a user