/games/static/games/games.js

https://github.com/jonejone/golfstats · JavaScript · 275 lines · 207 code · 48 blank · 20 comment · 21 complexity · 45942d51ca07f520f68c876d2409b790 MD5 · raw file

  1. (function(window, document, undefined) {
  2. /* The "Game" model */
  3. var Game = Backbone.Model.extend({
  4. initialize: function(attrs) {
  5. this.gameholes = new GameHoleList();
  6. this.gameholes.game = this;
  7. this.players = new GOLFSTATS.PlayerList();
  8. if(this.id) {
  9. this.url = '/api/games/' + this.id + '/';
  10. } else {
  11. this.set('created', new Date());
  12. this.set('state', this.STATE_CREATED);
  13. }
  14. if(attrs.players) {
  15. _.each(attrs.players, function(player) {
  16. if(typeof player === 'string') {
  17. this.players.add(GOLFSTATS.players.getByUrl(player));
  18. } else {
  19. this.players.add(player);
  20. }
  21. }, this);
  22. }
  23. this.bind('change:id', function(e) {
  24. this.url = '/api/games/' + this.id + '/';
  25. });
  26. this.bind('change:players', function(e) {
  27. /* Empty players collection first */
  28. this.players.reset();
  29. /* Add the different players */
  30. _.each(this.get('players'), function(player) {
  31. if(typeof player === 'string') {
  32. this.players.add(
  33. GOLFSTATS.players.getByUrl(player));
  34. } else {
  35. this.players.add(player);
  36. }
  37. }, this);
  38. });
  39. this.bind('change:gameholes', function(e){
  40. this.gameholes.reset();
  41. _.each(this.get('gameholes'), function(gh) {
  42. this.gameholes.add(new GameHole(gh));
  43. }, this);
  44. });
  45. if(attrs.gameholes) {
  46. _.each(attrs.gameholes, function(gh) {
  47. this.gameholes.add(new GameHole(gh));
  48. }, this);
  49. }
  50. this.bind('change:course', function(e) {
  51. /* If we get course as a string, objectify it */
  52. if(typeof this.get('course') === 'string') {
  53. this.set('course', GOLFSTATS.courses.getByUrl(
  54. this.get('course')));
  55. }
  56. });
  57. if(attrs.course) {
  58. if(typeof attrs.course === 'string') {
  59. this.set('course', GOLFSTATS.courses.getByUrl(
  60. attrs.course));
  61. }
  62. }
  63. },
  64. url: '/api/games/',
  65. STATE_CREATED: 1,
  66. STATE_STARTED: 2,
  67. STATE_FINISHED: 3,
  68. STATE_ABORTED: 4,
  69. start: function() {
  70. this.set('state', this.STATE_STARTED);
  71. this.set('started', new Date());
  72. },
  73. finish: function() {
  74. this.set('state', this.STATE_FINISHED);
  75. this.set('finished', new Date());
  76. },
  77. abort: function() {
  78. this.set('state', this.STATE_ABORTED);
  79. },
  80. parseNotUsed: function(response) {
  81. /* Set the game course */
  82. response.course = GOLFSTATS.courses.getByUrl(
  83. response.course);
  84. /* Set the players list */
  85. response.players = _.map(response.players, function(player) {
  86. return GOLFSTATS.players.getByUrl(player);
  87. });
  88. /* Parse gameholes */
  89. response.gameholes = _.map(response.gameholes, function(gh) {
  90. /* Since gameholes are unique per game, we can
  91. instantiate new instance instead of fetching */
  92. return new GOLFSTATS.GameHole(gh);
  93. });
  94. return response;
  95. },
  96. toJSON: function() {
  97. var players = this.players.map(function(player) {
  98. return player.getUrl();
  99. });
  100. var gameholes = this.gameholes.map(function(gamehole) {
  101. return {
  102. coursehole: gamehole.get('coursehole').getUrl(),
  103. player: gamehole.get('player').getUrl(),
  104. score: {
  105. 'throws': gamehole.get('score')['throws'],
  106. 'ob_throws': gamehole.get('score')['ob_throws'],
  107. }
  108. }
  109. });
  110. return {
  111. players: players,
  112. course: this.get('course').getUrl(),
  113. gameholes: gameholes,
  114. state: this.get('state'),
  115. creator: this.get('creator')
  116. }
  117. },
  118. /* Will log scores, for convenience */
  119. printScores: function() {
  120. console.log('Playing game on ', this.get('course').get('name'));
  121. this.players.each(function(player) {
  122. var score = this.getTotalScoreByPlayer(player);
  123. console.log(player.get('name'), ' score ', score['score'], 'with', score['throws'], 'throws');
  124. }, this);
  125. },
  126. /* Store scores for a player */
  127. playerScore: function(player, coursehole, score) {
  128. var gamehole =
  129. this.gameholes.getByHoleAndPlayer(
  130. coursehole, player);
  131. if(gamehole.length) {
  132. /* Update existing GameHole */
  133. gamehole[0].set('score', {
  134. 'throws': score['throws'],
  135. 'ob_throws': score['ob_throws'],
  136. });
  137. } else {
  138. /* Create new Gamehole */
  139. this.gameholes.add(new GameHole({
  140. player: player,
  141. coursehole: coursehole,
  142. score: {
  143. 'throws': score['throws'],
  144. ob_throws: score['ob_throws'],
  145. },
  146. game: this,
  147. }));
  148. }
  149. },
  150. /* Get total scores by player */
  151. getTotalScoreByPlayer: function(player) {
  152. var total_throws = 0;
  153. var total_ob = 0;
  154. /* Contains the par on holes played, in case only
  155. a few holes are played */
  156. var par_holes_played = 0;
  157. _.each(this.gameholes.getByPlayer(player), function(gamehole) {
  158. var score = gamehole.get('score');
  159. total_throws += parseInt(score['throws']);
  160. total_ob += parseInt(score['ob_throws']);
  161. par_holes_played += gamehole.get('coursehole').get('par');
  162. });
  163. var score = total_throws - par_holes_played;
  164. return {
  165. 'throws': total_throws,
  166. 'ob_throws': total_ob,
  167. score: score,
  168. };
  169. },
  170. });
  171. /* The collection holding Games */
  172. var GameList = Backbone.Collection.extend({
  173. model: Game, url: '/api/games/',
  174. });
  175. /* Model representing "GameHole" */
  176. var GameHole = Backbone.Model.extend({
  177. initialize: function(attrs) {
  178. if(attrs.player) {
  179. if(typeof attrs.player === 'string') {
  180. this.set('player', GOLFSTATS.players.getByUrl(
  181. attrs.player));
  182. }
  183. }
  184. if(attrs.coursehole) {
  185. if(typeof attrs.coursehole === 'string') {
  186. this.set('coursehole', GOLFSTATS.courseholes.getByUrl(
  187. attrs.coursehole));
  188. }
  189. }
  190. this.bind('change:player', function() {
  191. var player = this.get('player');
  192. if(typeof player === 'string') {
  193. this.set('player', GOLFSTATS.players.getByUrl(player));
  194. }
  195. });
  196. this.bind('change:coursehole', function() {
  197. var ch = this.get('coursehole');
  198. if(typeof ch === 'string') {
  199. this.set('coursehole', GOLFSTATS.courseholes.getByUrl(ch));
  200. }
  201. });
  202. },
  203. });
  204. /* The collection holding "GameHole" */
  205. var GameHoleList = Backbone.Collection.extend({
  206. model: GameHole,
  207. getByPlayer: function(player) {
  208. return this.filter(function(gamehole) {
  209. if(gamehole.get('player') === player) {
  210. return true;
  211. }
  212. });
  213. },
  214. getByHoleAndPlayer: function(coursehole, player) {
  215. return this.filter(function(gamehole) {
  216. if(gamehole.get('player') === player &&
  217. gamehole.get('coursehole') === coursehole) {
  218. return true;
  219. }
  220. });
  221. },
  222. });
  223. /* Make necessary models available in global scope */
  224. window.GOLFSTATS.games = new GameList();
  225. window.GOLFSTATS.Game = Game;
  226. window.GOLFSTATS.GameHole = GameHole;
  227. }(window));