mirror of
https://github.com/wassname/cardsforscience.git
synced 2026-06-27 18:23:07 +08:00
Simulated rules so they are winnable, added win and lose
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
"author": "wassname",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"alertify.js": "^1.0.9",
|
||||
"angular": "^1.4.9",
|
||||
"angular-animate": "^1.5.0",
|
||||
"angular-dragdrop": "^1.0.13",
|
||||
|
||||
+12
-114
@@ -337,35 +337,6 @@ h1 br {
|
||||
left: 2.5em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* https://github.com/mbostock/d3/blob/master/lib/colorbrewer/colorbrewer.css */
|
||||
.Paired .q0-12{fill:rgb(166,206,227)}
|
||||
.Paired .q1-12{fill:rgb(31,120,180)}
|
||||
.Paired .q2-12{fill:rgb(178,223,138)}
|
||||
.Paired .q3-12{fill:rgb(51,160,44)}
|
||||
.Paired .q4-12{fill:rgb(251,154,153)}
|
||||
.Paired .q5-12{fill:rgb(227,26,28)}
|
||||
.Paired .q6-12{fill:rgb(253,191,111)}
|
||||
.Paired .q7-12{fill:rgb(255,127,0)}
|
||||
.Paired .q8-12{fill:rgb(202,178,214)}
|
||||
.Paired .q9-12{fill:rgb(106,61,154)}
|
||||
.Paired .q10-12{fill:rgb(255,255,153)}
|
||||
.Paired .q11-12{fill:rgb(177,89,40)}
|
||||
|
||||
.Paired .q0-12{color:rgb(166,206,227)}
|
||||
.Paired .q1-12{color:rgb(31,120,180)}
|
||||
.Paired .q2-12{color:rgb(178,223,138)}
|
||||
.Paired .q3-12{color:rgb(51,160,44)}
|
||||
.Paired .q4-12{color:rgb(251,154,153)}
|
||||
.Paired .q5-12{color:rgb(227,26,28)}
|
||||
.Paired .q6-12{color:rgb(253,191,111)}
|
||||
.Paired .q7-12{color:rgb(255,127,0)}
|
||||
.Paired .q8-12{color:rgb(202,178,214)}
|
||||
.Paired .q9-12{color:rgb(106,61,154)}
|
||||
.Paired .q10-12{color:rgb(255,255,153)}
|
||||
.Paired .q11-12{color:rgb(177,89,40)}
|
||||
|
||||
.Red {color:red;}
|
||||
.Black {color:black;}
|
||||
|
||||
@@ -394,9 +365,7 @@ h1 br {
|
||||
background: white;
|
||||
font-size: 22px;
|
||||
}
|
||||
#card-deck{
|
||||
font-size: 75px;
|
||||
}
|
||||
|
||||
.ui-grid-cell-contents{
|
||||
font-size: 22px;
|
||||
}
|
||||
@@ -404,6 +373,10 @@ h1 br {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
|
||||
#card-deck{
|
||||
font-size: 75px;
|
||||
}
|
||||
.card-panel {
|
||||
min-height: 130px;
|
||||
min-width: 100px;
|
||||
@@ -413,6 +386,8 @@ h1 br {
|
||||
/*margin: 15px;*/
|
||||
/*font-size: 20px;*/
|
||||
}
|
||||
|
||||
|
||||
.short-lines {
|
||||
line-height: 3em;
|
||||
}
|
||||
@@ -434,6 +409,9 @@ h1 br {
|
||||
.left-list ul{
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
|
||||
/* hypothesis ane */
|
||||
.hypotheses select{
|
||||
height:20px;
|
||||
padding:1px;
|
||||
@@ -514,89 +492,8 @@ h1 br {
|
||||
}
|
||||
}
|
||||
|
||||
/* you can also define the transition style
|
||||
on the base class as well (.repeat-item) */
|
||||
.repeat-item.ng-enter,
|
||||
.repeat-item.ng-leave {
|
||||
-webkit-transition:0.25s linear all;
|
||||
transition:0.25s linear all;
|
||||
}
|
||||
|
||||
.repeat-item.ng-enter,
|
||||
.repeat-item.ng-leave.ng-leave-active {
|
||||
opacity:0;
|
||||
}
|
||||
.repeat-item.ng-leave,
|
||||
.repeat-item.ng-enter.ng-enter-active {
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
.add-item.ng-enter {
|
||||
-webkit-transition:0.25s linear all;
|
||||
transition:0.25s linear all;
|
||||
}
|
||||
|
||||
.add-item.ng-enter {
|
||||
opacity:0;
|
||||
}
|
||||
|
||||
.fadein,
|
||||
.fadeout {
|
||||
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
|
||||
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
|
||||
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
|
||||
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
|
||||
}
|
||||
|
||||
.fadein.ng-hide-remove,
|
||||
.fadeout.ng-hide-add.ng-hide-add-active {
|
||||
opacity: 0;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.fadeout.ng-hide-add,
|
||||
.fadein.ng-hide-remove.ng-hide-remove-active {
|
||||
opacity: 1;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
|
||||
.mainline.ng-leave {
|
||||
-webkit-animation: leave 600ms cubic-bezier(0.445, 0.050, 0.550, 0.950);
|
||||
animation: leave 600ms cubic-bezier(0.445, 0.050, 0.550, 0.950);
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
@-webkit-keyframes leave {
|
||||
to {
|
||||
opacity: 0;
|
||||
height: 0px;
|
||||
top: -70px;
|
||||
}
|
||||
25% {
|
||||
top: 15px;
|
||||
}
|
||||
from {
|
||||
opacity: 1;
|
||||
height: 30px;
|
||||
top: 0px;
|
||||
}
|
||||
}
|
||||
@keyframes leave {
|
||||
to {
|
||||
opacity: 0;
|
||||
height: 0px;
|
||||
top: -70px;
|
||||
}
|
||||
25% {
|
||||
top: 15px;
|
||||
}
|
||||
from {
|
||||
opacity: 1;
|
||||
height: 30px;
|
||||
top: 0px;
|
||||
}
|
||||
}
|
||||
/** animation to add wrong cards from top **/
|
||||
.add-from-top.ng-enter
|
||||
{
|
||||
-webkit-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
|
||||
@@ -620,6 +517,7 @@ h1 br {
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
/** add from right animation **/
|
||||
.add-from-right.ng-enter
|
||||
{
|
||||
-webkit-transition: 200ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<p class="lead">Cards for science</p>
|
||||
|
||||
<p>
|
||||
This is a game with a secret rule. You try to put down the next card and work out the rule by trial and error. The rule is randomised each time and there are hints available. At it's base this is a game of inductive reason and the scientific method.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Hints:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This game is based on <a href="http://www.logicmazes.com/games/eleusis/">Eleusis</a> by Robert Abbott and John Golden's <a href="http://www.logicmazes.com/games/eleusis/express.html">Eleusis</a> Express.
|
||||
</p>
|
||||
+22
-1
@@ -56,4 +56,25 @@ var bootstrap = require("bootstrap");
|
||||
// var Rules = require("js/rules.js");
|
||||
// var UI = require("js/ui.js");
|
||||
// var Game = require("js/game.js");
|
||||
var app = require("js/app.js");
|
||||
// var app = require("js/app.js");
|
||||
|
||||
/** This file exports parts of the app as a library **/
|
||||
var clientApp = module.exports = {
|
||||
ObjectStorage: require("js/storage.js"),
|
||||
Helpers: require("js/helpers.js"),
|
||||
Analytics: require("js/analytics.js"),
|
||||
GameObjects: require("js/gameobjects.js"),
|
||||
Rules: require("js/rules.js"),
|
||||
Simulate: require("js/rules/simulate.js"),
|
||||
UI: require("js/ui.js"),
|
||||
Game: require("js/game.js"),
|
||||
app: require("js/app.js"),
|
||||
};
|
||||
|
||||
// require("html/win.html");
|
||||
// require("html/lose.html");
|
||||
// require("html/game.html");
|
||||
|
||||
// deleteme dev TODO XXX
|
||||
require("js/rules/simulate.html");
|
||||
console.log('break here for dev');
|
||||
|
||||
+38
-29
@@ -48,14 +48,16 @@
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<!-- <li><a href="#" data-toggle="modal" data-target="#achievements-modal"><i class="fa fa-trophy"></i> Achievements</a></li>
|
||||
<li><a href="#" data-toggle="modal" data-target="#stats-modal"><i class="fa fa-bar-chart"></i> Statistics</a></li> -->
|
||||
<!-- <li class="dropdown" ng-controller="SaveController">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-floppy-o"></i> Saved: <span ng-cloak>{{ lastSaved | date : 'H:mm' }}</span> <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="#" ng-click="saveNow()"><i class="fa fa-save"></i> Save now</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#" ng-click="restart()"><i class="fa fa-refresh"></i> Restart</a></li>
|
||||
</ul>
|
||||
</li> -->
|
||||
|
||||
<!-- <li class="dropdown" ng-controller="SaveController as sc"> -->
|
||||
<!-- <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-floppy-o"></i> Saved: <span ng-cloak>{{ lastSaved | date : 'H:mm' }}</span> <span class="caret"></span></a> -->
|
||||
<!-- <ul class="dropdown-menu" role="menu"> -->
|
||||
<!-- <li><a href="#" ng-click="sc.saveNow()"><i class="fa fa-save"></i> Save now</a></li> -->
|
||||
<!-- <li class="divider"></li> -->
|
||||
<li ng-controller="SaveController as sc" ><a href="#" ng-click="sc.restart()"><i class="fa fa-refresh"></i> Restart</a></li>
|
||||
<!-- </ul> -->
|
||||
<!-- </li> -->
|
||||
|
||||
<li><a href="#" data-toggle="modal" data-target="#myModal"><i class="fa fa-users"></i> About</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -100,7 +102,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="column-lab" class="col-xs-6 col-md-6 col-md-6s col-lg-7 col-no-padding-xs" ng-controller="LabController as lc">
|
||||
<div id="column-lab" class="col-xs-6 col-md-6 col-md-6s col-lg-7 col-no-padding-xs" ng-controller="StatsController as lc">
|
||||
|
||||
<div class="row status" ng-cloak>
|
||||
<div class="col-xs-12 text-center col-no-padding-xs">
|
||||
@@ -158,7 +160,7 @@
|
||||
</div>
|
||||
|
||||
<div class="row" id="hints">
|
||||
<div ng-click="dc.revealHint()" class="col-md-6">
|
||||
<div ng-click="dc.revealHint()" analytics-on="click" analytics-event="hint" class="col-md-12">
|
||||
<div class="panel panel-default left-list card-panel">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Hint</h3>
|
||||
@@ -171,24 +173,21 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="rule" ng-click="dc.revealRule()" class="col-md-6">
|
||||
<!-- <div id="rule" ng-click="dc.revealRule()" analytics-on="click" analytics-event="revealRule" class="col-md-6">
|
||||
<div class="panel panel-default left-list card-panel">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Rule</h3>
|
||||
<div ng-cloak>(-{{dc.ruleCost}} score)</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<i ng-cloak>{{dc.rule}}</i>
|
||||
<li ng-repeat="h in dc.ruleInfo" ng-cloak><i>{{h}}</i></li>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<!-- <span id="card-deck" title="deal more cards" ng-click="dc.click()" class="prevent-select">🂠</span> -->
|
||||
<!-- <button id="clearall" class="btn btn-default" ng-click="dc.clearAll()"><i class="fa fa-refresh"></i></button> -->
|
||||
</div>
|
||||
</div>
|
||||
<button id="detector-info" type="button" class="btn btn-info" ng-click="lc.showDetectorInfo()"><i class="fa fa-info"></i></button>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -196,23 +195,14 @@
|
||||
<div class="panel panel-default hidden-xs hidden-sm">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<i class="fa fa-wrench"></i> Guess the rule
|
||||
<i class="fa fa-wrench"></i> Winning: guess which rule
|
||||
</h4>
|
||||
</div>
|
||||
<div class="panel-body scrollable large" id="upgradesLarge">
|
||||
<div id="upgradesContent" class="left-list" ng-controller="RulesController as uc">
|
||||
|
||||
<!-- A more complicated hypothesis display... too complicated I guess -->
|
||||
<!-- <label>Search: <input ng-model="searchText"></label> -->
|
||||
<!-- <ul class="form-inline hypotheses" ng-cloak>
|
||||
<li ng-repeat="rule in uc.rules|filter:searchText">
|
||||
<div cfs-rule="rule" index="$index" ng-model="uc.rules[$index]"></div>
|
||||
<button ng-click="uc.guess($event,rule)" class="btn btn-sm btn-default" type="submit">Guess</button>
|
||||
</li>
|
||||
</ul> -->
|
||||
|
||||
<form class="hypotheses" ng-submit="uc.guess($event,uc.rules2[uc.guessedIndex])">
|
||||
<div class="radio" ng-repeat="rule in uc.rules2">
|
||||
<form class="hypotheses" ng-submit="uc.guess($event,uc.hypotheses[uc.guessedIndex])">
|
||||
<div class="radio" ng-repeat="rule in uc.hypotheses">
|
||||
<label class="{{uc.isGuessed(rule)}}" ng-cloak>
|
||||
<input type="radio" ng-model="uc.guessedIndex" name="ruleRadios" id="ruleRadios-{{$index}}" value="{{$index}}" class="btn btn-sm btn-default">
|
||||
</input>
|
||||
@@ -280,6 +270,24 @@
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="modal fade" id="win-modal" tabindex="-1" role="dialog" aria-labelledby="win-label" aria-hidden="true" ng-controller="RulesController">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
||||
<h4 class="modal-title" id="stats-label"><i class="fa fa-bar-chart"></i> Statistics</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item"><i class="fa fa-location-arrow"></i> : <strong>{{ lab.state.clicks | niceNumber }}</strong></li>
|
||||
<li class="list-group-item"><i class="fa fa-database"></i> : <strong>{{ lab.state.dataSpent | niceNumber }}</strong> used / <strong>{{ lab.state.dataCollected | niceNumber }}</strong> collected</li>
|
||||
<li class="list-group-item"><i class="fa fa-money"></i> : <strong>{{ lab.state.moneySpent | niceNumber }}</strong> spent / <strong>{{ lab.state.moneyCollected | niceNumber }}</strong> gathered</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="modal fade" id="stats-modal" tabindex="-1" role="dialog" aria-labelledby="stats-label" aria-hidden="true" ng-controller="StatsController">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
@@ -298,6 +306,7 @@
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
|
||||
<div id="achievements-container" class="col-xs-6 col-sm-3"></div>
|
||||
<div id="messages-container" class="col-xs-6 col-sm-3"></div>
|
||||
|
||||
@@ -324,7 +333,7 @@
|
||||
<ul>
|
||||
<li><a href="https://github.com/wassname">wassname</a></li>
|
||||
</ul>
|
||||
<p>Feel free to get in touch with us via GitHub or by shooting an message on<br>particle-clicker at wassname.org</a>.</p>
|
||||
<p>Feel free to get in touch with via GitHub or by sending a message on<br>cardsforscience at wassname.org</a>.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ var analytics = module.exports =
|
||||
ga('create', Helpers.analytics,'auto');
|
||||
ga('set', { 'appName': 'Cards For Science', 'appId': '', 'appVersion': '0.6' });
|
||||
ga('set', 'anonymizeIp', true);
|
||||
ga('send','pageview');
|
||||
// ga('send','pageview');// angulartics
|
||||
}
|
||||
|
||||
|
||||
|
||||
+111
-78
@@ -7,13 +7,14 @@
|
||||
var jquery = require("jquery");
|
||||
var jqueryUi = require("jquery-ui");
|
||||
var jqueryUiTouchPunch = require("jquery-ui-touch-punch");
|
||||
var jqueryCookie = require("js-cookie");
|
||||
var jsCookie = require("js-cookie");
|
||||
|
||||
var angular = require("angular");
|
||||
var angularDragdrop = require("angular-dragdrop");
|
||||
var angularAnimate = require("angular-animate");
|
||||
var angulartics = require('angulartics');
|
||||
var angularticsGoogleAnalytics = require('angulartics-google-analytics');
|
||||
var ngAlertify = require("alertify.js/dist/js/ngAlertify.js");
|
||||
|
||||
//app
|
||||
var ObjectStorage = require("js/storage");
|
||||
@@ -22,11 +23,12 @@ var GameObjects = require("js/gameobjects");
|
||||
var analytics = require("js/analytics");
|
||||
var Game = require("js/game");
|
||||
var Rules = require("js/rules.js");
|
||||
var UI = require("js/ui.js");
|
||||
|
||||
var app = (function (Helpers,analytics,Game,Rules) {
|
||||
Helpers.validateSaveVersion();
|
||||
|
||||
var app = angular.module('cardsForScience', ['ngDragDrop','ngAnimate','angulartics', angularticsGoogleAnalytics]);
|
||||
var app = angular.module('cardsForScience', ['ngDragDrop','ngAnimate','angulartics', angularticsGoogleAnalytics,"ngAlertify"]);
|
||||
|
||||
// config
|
||||
app.config(function ($analyticsProvider) {
|
||||
@@ -160,7 +162,7 @@ var app = (function (Helpers,analytics,Game,Rules) {
|
||||
game.lab = lab;
|
||||
game.allObjects.lab = lab;
|
||||
var promise = game.load($http, $q);
|
||||
game.init();
|
||||
game.reset();
|
||||
// return promise;
|
||||
return game;
|
||||
};
|
||||
@@ -259,8 +261,8 @@ var app = (function (Helpers,analytics,Game,Rules) {
|
||||
function TableController($scope, game, lab, $filter) {
|
||||
var vm = this;
|
||||
vm.cards = detector.cards;
|
||||
vm.rule = '';
|
||||
vm.hints = [];
|
||||
vm.ruleInfo = game.ruleInfo;
|
||||
vm.hints = game.hints;
|
||||
vm.limit = -12;
|
||||
vm.hintCost = 10;
|
||||
vm.ruleCost = 300;
|
||||
@@ -279,8 +281,10 @@ var app = (function (Helpers,analytics,Game,Rules) {
|
||||
var result = game.onDrop(event, ui, game);
|
||||
};
|
||||
vm.revealRule = function () {
|
||||
vm.rule = game.rule.describe();
|
||||
lab.state.score -= vm.ruleCost;
|
||||
if (vm.ruleInfo.length===0){
|
||||
vm.ruleInfo.push(game.rule.describe());
|
||||
lab.state.score -= vm.ruleCost;
|
||||
};
|
||||
};
|
||||
vm.revealHint = function () {
|
||||
var hint = game.rule.nextHint();
|
||||
@@ -294,61 +298,17 @@ var app = (function (Helpers,analytics,Game,Rules) {
|
||||
app.controller('TableController', TableController);
|
||||
|
||||
|
||||
function LabController($interval, game, lab) {
|
||||
// todo give workers instead of game
|
||||
var vm = this;
|
||||
vm.lab = lab;
|
||||
vm.showDetectorInfo = function () {
|
||||
if (!vm._detectorInfo) {
|
||||
vm._detectorInfo = Helpers.loadFile('html/detector.html');
|
||||
}
|
||||
UI.showModal('Detector', vm._detectorInfo);
|
||||
};
|
||||
};
|
||||
LabController.$inject = ['$interval', 'game', 'lab'];
|
||||
app.controller('LabController', LabController);
|
||||
|
||||
|
||||
function RulesController($scope, game, lab) {
|
||||
function RulesController($scope, game, lab,$analytics,alertify) {
|
||||
var vm = this;
|
||||
// present just a few hypothesis
|
||||
var rules = Rules.rules.map(function (r) {
|
||||
return angular.copy(r);
|
||||
|
||||
// emit event track (with category and label properties for GA)
|
||||
$analytics.eventTrack('rule', {
|
||||
category: 'rule', label: game.rule.describe()
|
||||
});
|
||||
rules = _.sampleSize(rules, 2);
|
||||
if (!_.find(rules, {
|
||||
description: game.rule.description
|
||||
})) {
|
||||
var rule = angular.copy(game.rule);
|
||||
rule.setOptions({}); // reset the value of this copy to not give away;
|
||||
rules.push(rule);
|
||||
} else {
|
||||
rules.push(angular.copy(_.sample(Rules.rules)));
|
||||
}
|
||||
vm.rules = _.shuffle(rules);
|
||||
|
||||
// or present them without options?
|
||||
var rules2 = Rules.rules.map(function (r) {
|
||||
var rule = angular.copy(r);
|
||||
rule.randomize();
|
||||
return rule;
|
||||
});
|
||||
rules2 = _.sampleSize(rules, 4);
|
||||
|
||||
// add the real rule and a couple of variations
|
||||
var rule = angular.copy(game.rule);
|
||||
rules2.push(rule);
|
||||
var rule = angular.copy(game.rule);
|
||||
rule.randomize();
|
||||
rules2.push(rule);
|
||||
var rule = angular.copy(game.rule);
|
||||
rule.randomize();
|
||||
rules2.push(rule);
|
||||
|
||||
// clean and add to controller
|
||||
rules2 = _.uniq(rules2);
|
||||
rules2 = _.shuffle(rules2);
|
||||
vm.rules2 = rules2;
|
||||
vm.hypotheses = game.hypotheses;
|
||||
|
||||
vm.upgrades = game.upgrades;
|
||||
vm.isVisible = function (upgrade) {
|
||||
@@ -357,15 +317,10 @@ var app = (function (Helpers,analytics,Game,Rules) {
|
||||
vm.isAvailable = function (upgrade) {
|
||||
return upgrade.isAvailable(lab, game.allObjects);
|
||||
};
|
||||
vm.upgrade = function (upgrade) {
|
||||
if (upgrade.buy(lab, game.allObjects)) {
|
||||
UI.showUpdateValue("#update-funding", upgrade.cost);
|
||||
}
|
||||
};
|
||||
/** return a class based on none right or wrong guessed **/
|
||||
vm.isGuessed = function(rule){
|
||||
if (rule.state.guessed===true) return 'bg-success';
|
||||
else if (rule.state.guessed===false) return 'bg-danger';
|
||||
if (rule.guessed===true) return 'bg-success';
|
||||
else if (rule.guessed===false) return 'bg-danger';
|
||||
else return '';
|
||||
|
||||
};
|
||||
@@ -377,17 +332,47 @@ var app = (function (Helpers,analytics,Game,Rules) {
|
||||
if (sameRule && sameOpts) {
|
||||
// right!
|
||||
lab.state.score += 200;
|
||||
lab.state.rulesGuessed.push({
|
||||
key: game.rule.key,
|
||||
options: game.rule.options,
|
||||
description: game.rule.describe(),
|
||||
});
|
||||
if (!rule.state) rule.state={};
|
||||
rule.state.guessed=true;
|
||||
rule.guessed=true;
|
||||
|
||||
alertify.alert(
|
||||
'You have won using inductive logic! <p> <p> Play again?',
|
||||
function(event){
|
||||
event.preventDefault();
|
||||
// ObjectStorage.clear();
|
||||
// $window.location.reload(true); /// reloads are better for ads?
|
||||
game.reset();
|
||||
// since this confirmation was away from the dom we need to
|
||||
// manually refresh
|
||||
$scope.$apply();
|
||||
},function(){}
|
||||
);
|
||||
} else {
|
||||
lab.state.score -= 200;
|
||||
rule.state.guessed=false;
|
||||
rule.guessed=false;
|
||||
lab.state.rulesFailed.push({
|
||||
key: rule.key,
|
||||
options: rule.options,
|
||||
description: rule.describe(),
|
||||
});
|
||||
}
|
||||
|
||||
console.log('guess', arguments);
|
||||
|
||||
|
||||
// vm.winDialouge = function () {
|
||||
// if (!vm._winDialouge) {
|
||||
// vm._winDialouge = Helpers.loadFile('html/win.html');
|
||||
// }
|
||||
// UI.showModal('Win', vm._winDialouge);
|
||||
// };
|
||||
};
|
||||
};
|
||||
RulesController.$inject = ['$scope', 'game', 'lab'];
|
||||
RulesController.$inject = ['$scope', 'game', 'lab','$analytics','alertify'];
|
||||
app.controller('RulesController', RulesController);
|
||||
|
||||
function AchievementsController($scope, game, lab) {
|
||||
@@ -402,35 +387,83 @@ var app = (function (Helpers,analytics,Game,Rules) {
|
||||
AchievementsController.$inject = ['$scope', 'game', 'lab'];
|
||||
app.controller('AchievementsController', AchievementsController);
|
||||
|
||||
function SaveController($scope, $interval, $window, game, lab) {
|
||||
function SaveController($scope, $interval, $window, alertify, game, lab) {
|
||||
var vm = this;
|
||||
game.lastSaved = new Date().getTime();
|
||||
vm.lastSaved = game.lastSaved;
|
||||
;
|
||||
|
||||
vm.saveNow = function () {
|
||||
var saveTime = new Date().getTime();
|
||||
lab.state.time += saveTime - game.lastSaved;
|
||||
game.save();
|
||||
game.lastSaved = saveTime;
|
||||
vm.lastSaved = game.lastSaved;
|
||||
|
||||
// if (lab.state.score<0){
|
||||
// alertify.alert(
|
||||
// 'Your score is below zero, so you lost :( Want to try a different rule?',
|
||||
// function(event){
|
||||
// event.preventDefault();
|
||||
// // ObjectStorage.clear();
|
||||
// // $window.location.reload(true); /// reloads are better for ads?
|
||||
// game.reset();
|
||||
// // since this confirmation was away from the dom we need to
|
||||
// // manually refresh
|
||||
// $scope.$apply();
|
||||
// },function(){}
|
||||
// );
|
||||
// }
|
||||
|
||||
};
|
||||
vm.restart = function () {
|
||||
if ($window.confirm(
|
||||
'Do you really want to restart the game? All progress will be lost.'
|
||||
)) {
|
||||
ObjectStorage.clear();
|
||||
$window.location.reload(true);
|
||||
}
|
||||
console.log('restart');
|
||||
alertify.confirm(
|
||||
'Do you really want to restart the game? All progress will be lost.',
|
||||
function(event){
|
||||
event.preventDefault();
|
||||
// ObjectStorage.clear();
|
||||
// $window.location.reload(true); /// reloads are better for ads?
|
||||
game.reset();
|
||||
// since this confirmation was away from the dom we need to
|
||||
// manually refresh
|
||||
$scope.$apply();
|
||||
},function(){}
|
||||
);
|
||||
};
|
||||
$interval(vm.saveNow, 10000);
|
||||
};
|
||||
SaveController.$inject = ['$scope', '$interval', '$window', 'game', 'lab'];
|
||||
SaveController.$inject = ['$scope', '$interval', '$window', 'alertify', 'game', 'lab'];
|
||||
app.controller('SaveController', SaveController);
|
||||
|
||||
function StatsController($scope, lab) {
|
||||
function StatsController($scope, lab,game,alertify) {
|
||||
var vm = this;
|
||||
vm.lab = lab;
|
||||
vm.lost=false;
|
||||
|
||||
|
||||
$scope.$watch('lc.lab.state.score', function (newValue, oldValue) {
|
||||
if (newValue<0&&!vm.lost){
|
||||
vm.lost=true;
|
||||
alertify.alert(
|
||||
'<p>You lost :( <p> Play again? <p><p>P.S. The rule was: <p>"'+game.rule.describe()+'"',
|
||||
function(event){
|
||||
event.preventDefault();
|
||||
// ObjectStorage.clear();
|
||||
// $window.location.reload(true); /// reloads are better for ads?
|
||||
game.reset();
|
||||
// since this confirmation was away from the dom we need to
|
||||
// manually refresh
|
||||
$scope.$apply();
|
||||
vm.lost=false;
|
||||
|
||||
},function(){}
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
};
|
||||
StatsController.$inject = ['$scope', 'lab'];
|
||||
StatsController.$inject = ['$scope', 'lab','game','alertify'];
|
||||
app.controller('StatsController', StatsController);
|
||||
|
||||
analytics.init();
|
||||
|
||||
+96
-68
@@ -7,6 +7,7 @@ var GameObjects = require("js/gameobjects.js");
|
||||
var Rules = require("js/rules.js");
|
||||
var cards = require("json/cards.json");
|
||||
var achievements = require("json/achievements.json");
|
||||
var ruleSimulations = require("json/simulations.json");
|
||||
|
||||
var Game = module.exports =(function (Helpers, GameObjects, ObjectStorage,Rules,cards,achievements) {
|
||||
'use strict';
|
||||
@@ -21,11 +22,13 @@ var Game = module.exports =(function (Helpers, GameObjects, ObjectStorage,Rules,
|
||||
// lab: this.lab
|
||||
};
|
||||
this.loaded = false;
|
||||
this.rules = Rules.rules;
|
||||
this.rule=undefined;
|
||||
|
||||
this.hypotheses = [];
|
||||
this.lastCards= [];
|
||||
this.hints=[];
|
||||
this.ruleInfo=[];
|
||||
this.incorrectCards= [];
|
||||
this.rule=undefined;
|
||||
this.rules=Rules.rules;
|
||||
this.Rule=Rules.Rule;
|
||||
};
|
||||
@@ -36,56 +39,9 @@ var Game = module.exports =(function (Helpers, GameObjects, ObjectStorage,Rules,
|
||||
return;
|
||||
}
|
||||
|
||||
// I know synchronous requests are bad as they will block the browser.
|
||||
// However, I don't see any other reasonable way to do this in order to
|
||||
// make it work with Angular. If you know a way, let me know, and I'll
|
||||
// give you a beer. - Kevin
|
||||
this.cards = cards; //Helpers.loadFile('json/cards.json');
|
||||
this.achievements = require("json/achievements.json"); //Helpers.loadFile('./json/achievements.json');
|
||||
|
||||
// function successCallback(response) {
|
||||
// return angular.fromJson(response.data);
|
||||
// }
|
||||
//
|
||||
// function errorCallback(response) {
|
||||
// return console.error('Could not get url', response.statusText, response);
|
||||
// }
|
||||
// return $q.all(
|
||||
// $http.get('json/cards.json', {
|
||||
// transformResponse: angular.fromJson
|
||||
// })
|
||||
// .then(function (response) {
|
||||
// return self.cards = response.data;
|
||||
// }),
|
||||
// $http.get('json/workers.json', {
|
||||
// transformResponse: angular.fromJson
|
||||
// })
|
||||
// .then(function (response) {
|
||||
// return self.workers = response.data;
|
||||
// }),
|
||||
// $http.get('json/upgrades.json', {
|
||||
// transformResponse: angular.fromJson
|
||||
// })
|
||||
// .then(
|
||||
// function (response) {
|
||||
// return self.upgrades = response.data;
|
||||
// }),
|
||||
// $http.get('json/achievements.json', {
|
||||
// transformResponse: angular.fromJson
|
||||
// })
|
||||
// .then(
|
||||
// function (response) {
|
||||
// return self.achievements = response.data;
|
||||
// }),
|
||||
// $http.get('json/keywords.json', {
|
||||
// transformResponse: angular.fromJson
|
||||
// })
|
||||
// .then(
|
||||
// function (response) {
|
||||
// return self.keywords = response.data;
|
||||
// })
|
||||
// ).then(function () {
|
||||
|
||||
// Turn JSON files into actual game objects and fill map of all objects
|
||||
var makeGameObject = function (type, object) {
|
||||
// It's okay to define this function here since load is only called
|
||||
@@ -102,54 +58,126 @@ var Game = module.exports =(function (Helpers, GameObjects, ObjectStorage,Rules,
|
||||
function (a) {
|
||||
return makeGameObject(GameObjects.Achievement, a);
|
||||
});
|
||||
// Load states from local store
|
||||
for (var key in self.allObjects) {
|
||||
var o = self.allObjects[key];
|
||||
o.loadState(ObjectStorage.load(key));
|
||||
}
|
||||
|
||||
|
||||
// put cards in extended array with utility methods
|
||||
self.Card = new GameObjects.Cards();
|
||||
self.Card.push.apply(self.Card, self.cards);
|
||||
self.cards = self.Card;
|
||||
|
||||
// add rules to load and save states
|
||||
self.rules.map(function(o){
|
||||
self.allObjects[o.key] = o;
|
||||
});
|
||||
|
||||
// TODO save and load lastCards and incorrectCards
|
||||
|
||||
// Load states from local store
|
||||
for (var key in self.allObjects) {
|
||||
var o = self.allObjects[key];
|
||||
o.loadState(ObjectStorage.load(key));
|
||||
}
|
||||
|
||||
self.loaded = true;
|
||||
return self;
|
||||
};
|
||||
|
||||
Game.prototype.init = function () {
|
||||
Game.prototype.reset = function () {
|
||||
// setup game
|
||||
this.rule = _.sample(Rules.rules);
|
||||
this.rule.randomize();
|
||||
this.rule = this.newRule();
|
||||
|
||||
// check if we have any cards in hand
|
||||
// var totalElements = _(self.cards).map('state.amount').sum();
|
||||
// if (totalElements<1) self.dealHand();
|
||||
this.dealHand();
|
||||
|
||||
// deal first card
|
||||
// TODO make sure these follow rule
|
||||
|
||||
// deal new initial cards
|
||||
this.lastCards.splice(0,this.lastCards.length);
|
||||
this.lastCards.push.apply(this.lastCards,_.sampleSize(this.cards,3));
|
||||
for (var i = 0; i < this.lastCards.length; i++) {
|
||||
this.incorrectCards[i]=[];
|
||||
}
|
||||
|
||||
this.ruleInfo.splice(0,this.ruleInfo.length);
|
||||
this.hints.splice(0,this.hints.length);
|
||||
|
||||
// empty incorrect cards
|
||||
this.incorrectCards.splice(0,this.incorrectCards.length);
|
||||
this.incorrectCards.push([]);
|
||||
this.incorrectCards.push([]);
|
||||
this.incorrectCards.push([]);
|
||||
|
||||
// reset score
|
||||
this.lab.state.score = 200;
|
||||
return self;
|
||||
|
||||
// new set of hypothes
|
||||
this.hypotheses=this.genHypotheses();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Game.prototype.genHypotheses = function () {
|
||||
// get some hypotheses
|
||||
var hypo=[];
|
||||
|
||||
// a random 2, 2 variations of each
|
||||
for (var i = 0; i < 3; i++) {
|
||||
var rule = _.sample(this.rules);
|
||||
rule = angular.copy(rule);
|
||||
rule.randomize();
|
||||
hypo.push(rule);
|
||||
rule = angular.copy(rule);
|
||||
rule.randomize();
|
||||
hypo.push(rule);
|
||||
}
|
||||
|
||||
// add the real rule
|
||||
var rule = angular.copy(this.rule);
|
||||
hypo.push(rule);
|
||||
|
||||
// and a variation of the real rule
|
||||
var rule = angular.copy(this.rule);
|
||||
rule.randomize();
|
||||
hypo.push(rule);
|
||||
|
||||
// clean and remember
|
||||
hypo = _.uniq(hypo);
|
||||
hypo = _.shuffle(hypo);
|
||||
|
||||
// empty old ones
|
||||
this.hypotheses.splice(0,this.hypotheses.length);
|
||||
// put in new ones
|
||||
for (var i = 0; i < hypo.length; i++) {
|
||||
this.hypotheses.push(hypo[i]);
|
||||
}
|
||||
return this.hypotheses;
|
||||
};
|
||||
|
||||
Game.prototype.newRule = function () {
|
||||
var okRules = _.filter(ruleSimulations,function(s){
|
||||
return s.ratioRight>0.1&&s.ratioRight<0.6;
|
||||
});
|
||||
// choose and ok rule
|
||||
var ruleConfig = _.sample(okRules);
|
||||
// now find the rule and set these options
|
||||
var rule = _.find(this.rules,{key:ruleConfig.key});
|
||||
var options = ruleConfig.options;
|
||||
if (typeof options==="string") options = JSON.parse(options);
|
||||
rule.setOptions(options);
|
||||
return this.rule = rule;
|
||||
};
|
||||
|
||||
Game.prototype.dealHand = function (n) {
|
||||
n=n||12;
|
||||
var hand=_.sampleSize(this.cards,n);
|
||||
|
||||
var sample=_.sampleSize(this.cards,n);
|
||||
|
||||
// empty all cards
|
||||
this.cards.map(function(card){
|
||||
card.state.amount=0;
|
||||
});
|
||||
for (var i = 0; i < hand.length; i++) {
|
||||
var card = hand[i];
|
||||
// now increase the value of our sample
|
||||
for (var i = 0; i < sample.length; i++) {
|
||||
var card = sample[i];
|
||||
this.cards.get(card.key).state.amount++;
|
||||
}
|
||||
|
||||
};
|
||||
Game.prototype.onClick = function (event, ui) {
|
||||
var self=this;
|
||||
|
||||
+1
-106
@@ -29,7 +29,7 @@ var GameObjects = module.exports = (function () {
|
||||
}
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
||||
s4() + '-' + s4() + s4() + s4();
|
||||
}
|
||||
};
|
||||
|
||||
/** @class Lab
|
||||
*/
|
||||
@@ -254,109 +254,6 @@ var GameObjects = module.exports = (function () {
|
||||
return this.state.amount -= 1;
|
||||
};
|
||||
|
||||
/** @class Worker
|
||||
* Implement an auto-clicker in the game.
|
||||
*/
|
||||
var Worker = function (obj) {
|
||||
GameObject.apply(this, [obj]);
|
||||
this.state.hired = 0;
|
||||
};
|
||||
|
||||
Worker.prototype = Object.create(GameObject.prototype);
|
||||
|
||||
Worker.prototype.constructor = Worker;
|
||||
|
||||
Worker.prototype.isVisible = function (lab) {
|
||||
if (!lab) {
|
||||
return false;
|
||||
}
|
||||
return this.state.hired > 0 ||
|
||||
lab.state.money >= this.state.cost * GLOBAL_VISIBILITY_THRESHOLD;
|
||||
};
|
||||
|
||||
Worker.prototype.isAvailable = function (lab) {
|
||||
if (!lab) {
|
||||
return false;
|
||||
}
|
||||
return lab.state.money >= this.state.cost;
|
||||
};
|
||||
|
||||
Worker.prototype.hire = function (lab) {
|
||||
if (lab && lab.buy(this.state.cost)) {
|
||||
this.state.hired++;
|
||||
var cost = this.state.cost;
|
||||
this.state.cost = Math.floor(cost * this.cost_increase);
|
||||
return cost;
|
||||
}
|
||||
return -1; // not enough money
|
||||
};
|
||||
|
||||
Worker.prototype.getTotal =
|
||||
function () {
|
||||
return this.state.hired * this.state.rate;
|
||||
};
|
||||
|
||||
/** @class Upgrade
|
||||
*/
|
||||
var Upgrade = function (obj) {
|
||||
GameObject.apply(this, [obj]);
|
||||
this.state.visible = false;
|
||||
this.state.used = false;
|
||||
};
|
||||
|
||||
Upgrade.prototype = Object.create(GameObject.prototype);
|
||||
|
||||
Upgrade.prototype.constructor = Upgrade;
|
||||
|
||||
Upgrade.prototype.meetsRequirements = function (allObjects) {
|
||||
if (!allObjects) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < this.requirements.length; i++) {
|
||||
var req = this.requirements[i];
|
||||
if (allObjects[req.key].state[req.property] < req.threshold) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
Upgrade.prototype.isAvailable = function (lab, allObjects) {
|
||||
if (!lab || !allObjects) {
|
||||
return false;
|
||||
}
|
||||
return !this.state.used && lab.state.money >= this.cost &&
|
||||
this.meetsRequirements(allObjects);
|
||||
};
|
||||
|
||||
Upgrade.prototype.isVisible = function (lab, allObjects) {
|
||||
if (!lab || !allObjects) {
|
||||
return false;
|
||||
}
|
||||
if (!this.state.used &&
|
||||
(this.state.visible ||
|
||||
lab.state.money >= this.cost * GLOBAL_VISIBILITY_THRESHOLD &&
|
||||
this.meetsRequirements(allObjects))) {
|
||||
this._visible = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
Upgrade.prototype.buy = function (lab, allObjects) {
|
||||
if (lab && allObjects && !this.state.used && lab.buy(this.cost)) {
|
||||
for (var i = 0; i < this.targets.length; i++) {
|
||||
var t = this.targets[i];
|
||||
allObjects[t.key].state[t.property] *= this.factor || 1;
|
||||
allObjects[t.key].state[t.property] += this.constant || 0;
|
||||
}
|
||||
this.state.used = true; // How about actually REMOVING used upgrades?
|
||||
this.state.visible = false;
|
||||
return this.cost;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
/** @class Achievement
|
||||
*/
|
||||
@@ -394,8 +291,6 @@ var GameObjects = module.exports = (function () {
|
||||
return {
|
||||
Lab: Lab,
|
||||
Card: Card,
|
||||
Worker: Worker,
|
||||
Upgrade: Upgrade,
|
||||
Achievement: Achievement,
|
||||
Cards: Cards
|
||||
};
|
||||
|
||||
+75
-63
@@ -5,7 +5,7 @@
|
||||
if (!module) module=function(){};
|
||||
var chai;
|
||||
if (!chai){
|
||||
chair = require("chai");
|
||||
chai = require("chai");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -16,11 +16,41 @@ if (!chai){
|
||||
var Rules = module.exports = (function functionName(_,chai) {
|
||||
|
||||
|
||||
/** Generate all combination of arguments from array using functional programming instead of recursive
|
||||
* @param {Object} opts - An array or arrays with keys describing options [['Ben','Jade','Darren'],['Smith','Miller']]
|
||||
* @returns {Array} - An array of arrays e.g. [['Ben','Smith'],[..]]
|
||||
**/
|
||||
function cartesianProductOf(opts) {
|
||||
if (arguments.length>1) opts=arguments;
|
||||
return _.reduce(opts, function(a, b) {
|
||||
return _.flatten(_.map(a, function(x) {
|
||||
return _.map(b, function(y) {
|
||||
return x.concat([y]);
|
||||
});
|
||||
}), true);
|
||||
}, [ [] ]);
|
||||
};
|
||||
|
||||
|
||||
/** Generate all combination of arguments from objects using functional programming instead of recursive
|
||||
* @param {Object} opts - An object or arrays with keys describing options {firstName:['Ben','Jade','Darren'],lastName:['Smith','Miller']}
|
||||
* @returns {Array} - An array of objects e.g. [{firstName:'Ben',LastName:'Smith'},{..]
|
||||
**/
|
||||
function cartesianProductObj(optObj){
|
||||
var opts = _.values(optObj);
|
||||
var keys = _.keys(optObj);
|
||||
var combs = cartesianProductOf(opts);
|
||||
return _.map(combs,function(comb){
|
||||
return _.zipObject(keys,comb);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rule prototype
|
||||
* @param {String} key A short key
|
||||
* @param {String} description Description of the rule using angular templating from options
|
||||
* @param {Function} ruleFunc A function returning a true or a failure message or a error
|
||||
* @param {Function} ruleFunc A function returning a true or a failure message or a assertion error
|
||||
* @param {Object} optionDefaults Default options for the rule e.g. {n:1, parameter:'color'}.
|
||||
* @param {Object} optionDesc Object with object for each option
|
||||
* @param {Array} optionDesc[].possibleVals Array of possible values or empty if they are to many to be enumerated
|
||||
@@ -30,23 +60,44 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
* `The rule uses <%= parameter %>` and for every parameter you can
|
||||
* use `The rule doesn't use <%= parameterUnused %>` to have each unused param substituted in.
|
||||
*/
|
||||
var Rule = function (description, ruleFunc, optionDefaults, optionDesc, hintTmpls) {
|
||||
var Rule = function (key, description, ruleFunc, optionDefaults, optionDesc, hintTmpls) {
|
||||
|
||||
// check inputs
|
||||
if (!(typeof (description) === 'string' || description instanceof String) || !description.length)
|
||||
throw new TypeError('description should be a non empty string');
|
||||
throw new TypeError('Description should be a non empty string');
|
||||
this.description = description;
|
||||
if (!(ruleFunc instanceof Function))
|
||||
throw new TypeError('ruleFunc should be a function');
|
||||
|
||||
this.key=key;
|
||||
this.ruleFunc = ruleFunc;
|
||||
this.optionDesc = optionDesc || {};
|
||||
this.options = this.optionDefaults = optionDefaults || {};
|
||||
this.hintTmpls = hintTmpls || [];
|
||||
|
||||
// init
|
||||
this.state = {};
|
||||
this.hintsUsed = 0;
|
||||
this.state = {
|
||||
hintsUsed: 0,
|
||||
wrongCards: 0,
|
||||
rightCards: 0,
|
||||
wrongGuesses: 0,
|
||||
rightGuesses: 0,
|
||||
};
|
||||
// used for template rendering
|
||||
this.otherOptions={nth:this.nth,lastn:this.lastn};
|
||||
// render hint templates
|
||||
this.hints = this.genHints();
|
||||
// work out all option combos, only takes a second
|
||||
this.optionsPossible=this.genOptions();
|
||||
};
|
||||
Rule.prototype.genOptions = function () {
|
||||
var possibleVals={};
|
||||
for (var prop in this.optionDesc) {
|
||||
if (this.optionDesc.hasOwnProperty(prop)) {
|
||||
possibleVals[prop]=this.optionDesc[prop].possibleVals;
|
||||
}
|
||||
}
|
||||
return this.optionsPossible=cartesianProductObj(possibleVals);
|
||||
};
|
||||
Rule.prototype.setOptions = function (options) {
|
||||
this.options = _.defaults(options, this.optionDefaults);
|
||||
@@ -98,56 +149,6 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
Rule.prototype.describe = function () {
|
||||
return this.describeVariation(this.options);
|
||||
};
|
||||
// Rule.prototype.describeHtml = function (arguments) {
|
||||
// // we want template params where each options is replace with a select box
|
||||
// var tmplParams = {};
|
||||
//
|
||||
// for (var option in this.optionDesc) {
|
||||
// if (this.optionDesc.hasOwnProperty(option)) {
|
||||
// var vals = this.optionDesc[option].possibleVals;
|
||||
// if (vals) {
|
||||
// s = '<select name="' + option + '" ng-model="rule.options.' + option + '" class="form-control input-sm">\n';
|
||||
// for (var i = 0; i < vals.length; i++) {
|
||||
// s += '<option value="' + vals[i] + '">' + vals[i] + '</option>\n';
|
||||
// }
|
||||
// s += '</select>\n';
|
||||
// tmplParams[option] = s;
|
||||
// } else {
|
||||
// tmplParams[option] = option;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return _.template(this.description)(tmplParams);
|
||||
// };
|
||||
/** Generate angular template for this rule **/
|
||||
// Rule.prototype.describeNg = function (arguments) {
|
||||
//
|
||||
// // first put option name into this option template
|
||||
// // _.templateSettings.interpolate = /<%=([\s\S]+?)%>/g;
|
||||
// optionTmpl = '' +
|
||||
// '<select name="<%=option%>" type="number" ng-model="rule.options.<%=option%>" class="form-control input-sm">\n' +
|
||||
// '<option ng-repeat="v in rule.optionDesc.<%=option%>.possibleVals" value="{{v}}">{{v}}</option>\n' +
|
||||
// '</select>\n';
|
||||
//
|
||||
// // we want template params where each options is replace with a select box
|
||||
// var tmplParams = {};
|
||||
//
|
||||
// for (var option in this.optionDesc) {
|
||||
// if (this.optionDesc.hasOwnProperty(option)) {
|
||||
// var vals = this.optionDesc[option].possibleVals;
|
||||
// if (vals) {
|
||||
// tmplParams[option] = _.template(optionTmpl)({
|
||||
// option: option
|
||||
// });
|
||||
// } else {
|
||||
// tmplParams[option] = option;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // now in description replace params with select box
|
||||
// return _.template(this.description)(tmplParams);
|
||||
// };
|
||||
/** Compile description using options to express rule**/
|
||||
Rule.prototype.describeVariation = function (options) {
|
||||
var compiled = _.template(this.description);
|
||||
@@ -191,15 +192,15 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
};
|
||||
/** Get next hint **/
|
||||
Rule.prototype.nextHint = function () {
|
||||
var hint = this.hints[this.hintsUsed];
|
||||
this.hintsUsed++;
|
||||
var hint = this.hints[this.state.hintsUsed];
|
||||
this.state.hintsUsed++;
|
||||
return hint || "";
|
||||
|
||||
};
|
||||
/** Generate an automatic hint from params **/
|
||||
Rule.prototype.genHints = function () {
|
||||
// first manual hints
|
||||
this.hintsUsed = 0;
|
||||
this.state.hintsUsed = 0;
|
||||
var hints = [];
|
||||
|
||||
// compile hints for each unused property
|
||||
@@ -226,7 +227,7 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
for (var optionUnused in unusedOptions) {
|
||||
if (unusedOptions.hasOwnProperty(optionUnused)) {
|
||||
|
||||
// find hint templats that take this unused option
|
||||
// find hint templates that take this unused option
|
||||
for (var i = 0; i < this.hintTmpls.length; i++) {
|
||||
var tmpl = this.hintTmpls[i];
|
||||
if (tmpl.indexOf(optionUnused) >= 0) {
|
||||
@@ -250,8 +251,8 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
}
|
||||
|
||||
// on on a last hint
|
||||
hints.push("That's all the hints for this rule. But don't forget to check for hints for the overall game. This is a game of inductive logic to try to disprove rules.");
|
||||
hints.push("You cheeky blighter. Feel free to restart the game to get a new rule if this one is no fun (it will happen).");
|
||||
hints.push("That's all the hints. But this is a game of inductive logic so try to disprove rules instead of proving them.");
|
||||
hints.push("No more hints you cheeky blighter!");
|
||||
|
||||
// and finally remove duplicate hints
|
||||
hints = _.uniq(hints);
|
||||
@@ -299,6 +300,11 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
}
|
||||
};
|
||||
|
||||
Rule.prototype.loadState =
|
||||
function (state) {
|
||||
$.extend(this.state, state);
|
||||
};
|
||||
|
||||
|
||||
// Now defined actual rules
|
||||
var rules = [];
|
||||
@@ -307,6 +313,7 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
// here is a example rule where the card must have differen't color etc from the last card
|
||||
// but it's abstracted to allow variations
|
||||
new Rule(
|
||||
"d4a2f61a-0fb9-4eb6-9258-3e14ae4cd512",
|
||||
"Next card must not have the same <%= property %> as the <%= lastn(n) %> card",
|
||||
function (card, lastCards, allCards, options) {
|
||||
var lastNCard = lastCards[lastCards.length - this.options.n];
|
||||
@@ -336,10 +343,10 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
]
|
||||
),
|
||||
new Rule(
|
||||
"2b70bd6a-8bdd-49d4-bec7-bfb9de090e78",
|
||||
"If <%= lastn(n) %> cards value was between <%= min %> and <%= max %> play a card that isn't and vice versa.",
|
||||
function (card, lastCards, allCards, options) {
|
||||
var lastNCard = lastCards[lastCards.length - this.options.n];
|
||||
var property = this.options.property;
|
||||
var lastWasbetween = options.min < lastNCard.value && lastNCard.value < options.max;
|
||||
if (lastWasbetween)
|
||||
return chai.expect(card)
|
||||
@@ -382,6 +389,7 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
]
|
||||
),
|
||||
new Rule(
|
||||
"3e12d713-335a-42e7-81ed-7064442f628a",
|
||||
"Play a card with a value <%= min %> to <%= max %> higher than the value of the <%= lastn(n) %> card. The numbers wrap around once they reach the max",
|
||||
function (card, lastCards, allCards, options) {
|
||||
var lastNCard = lastCards[lastCards.length - this.options.n];
|
||||
@@ -426,6 +434,7 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
|
||||
|
||||
new Rule(
|
||||
"99b1d408-000d-41e6-8a0c-886a5d21d06f",
|
||||
"If the <%= lastn(n) %> card is an even-valued card, play a <%= evenColor %> card. Otherwise play the other color",
|
||||
function (card, lastCards, allCards, options) {
|
||||
var lastNCard = lastCards[lastCards.length - this.options.n];
|
||||
@@ -465,6 +474,7 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
),
|
||||
|
||||
new Rule(
|
||||
"4014c459-a7a7-4a49-98f5-302a1b7b89e7",
|
||||
"Play a card that has the same <%= property %> or color as the <%= lastn(n) %> card but not both.",
|
||||
function (card, lastCards, allCards, options) {
|
||||
var lastNCard = lastCards[lastCards.length - options.n];
|
||||
@@ -495,6 +505,7 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
),
|
||||
|
||||
new Rule(
|
||||
"793d93cb-ca09-4cda-8781-6fce02edf09c",
|
||||
"If the <%= lastn(n) %> card's number is higher than <%= min %>, change <%= property %>, and if lower, keep it the same.",
|
||||
function (card, lastCards, allCards, options) {
|
||||
var lastNCard = lastCards[lastCards.length - options.n];
|
||||
@@ -540,6 +551,7 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
]
|
||||
),
|
||||
new Rule(
|
||||
"f4fba793-f886-4db8-9853-240002bb112e",
|
||||
"If the <%= lastn(n) %> card was a <%= property %> card, play a higher value card otherwise lower.",
|
||||
//TODO what if we have a high card? we can only go higher
|
||||
function (card, lastCards, allCards, options) {
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/** Extend chai to be used in defining rules **/
|
||||
|
||||
// might want to use chair string for startswith etc
|
||||
// chai-properties for muliple properties
|
||||
// chai-adhoc for easier additions https://github.com/AnAppAMonth/chai-adhoc
|
||||
var chai = (function functionName(chai) {
|
||||
|
||||
// wrap every chainer to add message to chain? that would be interesting
|
||||
|
||||
// card method that set's name of card?
|
||||
|
||||
// wrap or overide property chain to add to name
|
||||
|
||||
// and methods to compare to Nth last card's property
|
||||
|
||||
// and what about more complex ones like mod and odd and prime
|
||||
|
||||
|
||||
})(chai);
|
||||
+1
-1
@@ -89,7 +89,7 @@ var UI = module.exports = (function (FastClick,Cookies) {
|
||||
if (typeof Cookies.get('cookielaw') === 'undefined') {
|
||||
var alert = '<div id="cookielaw" class="alert alert-info" role="alert">';
|
||||
alert += '<button type="button" class="btn btn-primary">OK</button>';
|
||||
alert += '<i class="fa fa-info-circle alert-glyph"></i> <span class="alert-text">Particle Clicker uses local storage to store your current progress.</span>';
|
||||
alert += '<i class="fa fa-info-circle alert-glyph"></i> <span class="alert-text">Cards for science uses local storage to store your current progress.</span>';
|
||||
alert += '</div>';
|
||||
alert = $(alert);
|
||||
alert.find('button').click(function ()
|
||||
|
||||
+2
-1
@@ -57,7 +57,7 @@ var htmlWebpack = new HtmlWebpackPlugin({
|
||||
var uglifyJsPlugin = new webpack.optimize.UglifyJsPlugin({
|
||||
minimize: !DEBUG,
|
||||
sourceMap: DEBUG,
|
||||
mangle: !DEBUG,
|
||||
mangle: false,//!DEBUG,
|
||||
dropDebugger: true,
|
||||
dropConsole: true,
|
||||
});
|
||||
@@ -85,6 +85,7 @@ module.exports = {
|
||||
target: "web", //web[node,async-node,node-webkit,electron,webworker]
|
||||
entry: {
|
||||
clientApp: 'index.js',
|
||||
// clientLib: 'lib.js',
|
||||
},
|
||||
output: {
|
||||
path: path.join(__dirname, DIR),
|
||||
|
||||
Reference in New Issue
Block a user