/ public_html / script / src / build.js
build.js
  1  'use strict';
  2  
  3  import {CONST} from './const.js';
  4  import {adjacent} from './adjacent.js';
  5  import {default as $} from 'jquery';
  6  
  7  const GEN = Symbol(), SOCKET = Symbol(), PLAYER = Symbol();
  8  
  9  export class Build {
 10      constructor(g, s, p) {
 11          this[GEN] = g;
 12          this[SOCKET] = s;
 13          this[PLAYER] = p;
 14      }
 15  
 16      house(i, j, data) {
 17          this[SOCKET].emit('build:house', [i, j], (err, res) => {
 18              this[GEN].next([err, res]);
 19          });
 20          data.houses[i][j] = [1, this[PLAYER]];
 21          this.houseHide(data);
 22      }
 23      houseShow(data) {
 24          //Count houses, don't show if there are 5
 25          for(let i = 0, c = 0; i < data.houses.length; i++) {
 26              for(let j = 0; j < data.houses[i].length; j++) {
 27                  if(data.houses[i][j][0] === 1 && data.houses[i][j][1] === this[PLAYER]) {
 28                      if(++c === 5) {
 29                          return;
 30                      }
 31                  }
 32              }
 33          }
 34          for(let i = 0; i < data.houses.length; i++) {
 35              for(let j = 0; j < data.houses[i].length; j++) {
 36                  //Check if each house should be buildable
 37                  if(data.houses[i][j][0] === 0) { //If the house is not already built
 38                      //Count available resources
 39                      let hand = data.players[this[PLAYER]].hand[CONST.RESOURCE];
 40                      let hasResources = (hand[CONST.WOOL] && hand[CONST.WOOD] && hand[CONST.BRICK] && hand[CONST.WHEAT]);
 41                      let adj_road = adjacent(i, j, 'house', 'road');
 42                      let adj_house = adjacent(i, j, 'house', 'house');
 43                      //Check for the adjacent roads
 44                      let n;
 45                      for(n = 0; n < adj_road.length; n++) {
 46                          if(data.roads[adj_road[n][0]][adj_road[n][1]] === this[PLAYER]) {
 47                              break;
 48                          }
 49                      }
 50                      //Allow if the player has resources and there is a road nearby
 51                      //Or if in setup mode a house can be built anywhere
 52                      if(data.gameState === CONST.SETUP || (n !== adj_road.length && hasResources)) {
 53                          //Check for adjacent houses
 54                          for(n = 0; n < adj_house.length; n++) {
 55                              if(data.houses[adj_house[n][0]][adj_house[n][1]][0]) {
 56                                  break;
 57                              }
 58                          }
 59                          //Don't allow if there is a house too close
 60                          if(n === adj_house.length) {
 61                              $('.house_row').eq(i).children('.house').eq(j)
 62                                  .addClass('buildable')
 63                                  .off('click')
 64                                  .click(() => {
 65                                      this.house(i, j, data);
 66                                  });
 67                          }
 68                      }
 69                  }
 70              }
 71          }
 72      }
 73      houseHide(data) {
 74          for(let i = 0; i < data.houses.length; i++) {
 75              for(let j = 0; j < data.houses[i].length; j++) {
 76                  //Hide each house that's not built and remove the onclick handler
 77                  let house = $('.house_row').eq(i).children('.house').eq(j)
 78                      .off('click')
 79                      .removeClass('buildable');
 80              }
 81          }
 82      }
 83  
 84      road(i, j, free, data) {
 85          this[SOCKET].emit('build:road', [i, j, free], (err, res) => {
 86              this[GEN].next([err, res]);
 87          });
 88          data.roads[i][j] = this[PLAYER];
 89          this.roadHide(data);
 90      }
 91      roadShow(data, options) {
 92          let intersection, free;
 93          if(Array.isArray(options)) {
 94              //If options is an array, it is setup phase
 95              intersection = options;
 96              free = true;
 97          } else {
 98              //Otherwise, the only option is if it is free
 99              free = !!options;
100          }
101          //Count roads, don't show if there are 15
102          for(let i = 0, c = 0; i < data.roads.length; i++) {
103              for(let j = 0; j < data.roads[i].length; j++) {
104                  if(data.roads[i][j] === this[PLAYER]) {
105                      if(++c === 15) {
106                          if(free) {
107                              //Continue automatically if it's road building played
108                              window.setTimeout(() => {
109                                  this[GEN].next(['You have too many roads', [data, null]]);
110                              }, 0);
111                          }
112                          return;
113                      }
114                  }
115              }
116          }
117          let hand = data.players[this[PLAYER]].hand[CONST.RESOURCE];
118          if(free || (hand[CONST.WOOD] && hand[CONST.BRICK])) {
119              //If the player has enough resources
120              if(intersection) {
121                  //If an intersection is being forced, only allow houses around there
122                  let roads = adjacent(intersection[0], intersection[1], "house", "road");
123                  for(let [i, j] of roads) {
124                      if(data.roads[i][j] === -1) {
125                          $('.road_row').eq(i).children('.road').eq(j)
126                              .addClass('buildable')
127                              .off('click')
128                              .click(() => {
129                                  this.road(i, j, free, data);
130                              });
131                      }
132                  }
133              } else {
134                  for(let i = 0; i < data.roads.length; i++) {
135                      for(let j = 0; j < data.roads[i].length; j++) {
136                          //Otherwise, get all roads that aren't yet built
137                          if(data.roads[i][j] === -1) {
138                              let roads = adjacent(i, j, "road", "road");
139                              let n;
140                              for(n = 0; n < roads.length; n++) {
141                                  if(data.roads[roads[n][0]][roads[n][1]] === this[PLAYER]) {
142                                      break;
143                                  }
144                              }
145                              if(n !== roads.length) {
146                                  $('.road_row').eq(i).children('.road').eq(j)
147                                      .addClass('buildable')
148                                      .off('click')
149                                      .click(() => {
150                                          this.road(i, j, free, data);
151                                      });
152                              }
153                          }
154                      }
155                  }
156              }
157          }
158      }
159      roadHide(data) {
160          for(let i = 0; i < data.roads.length; i++) {
161              for(let j = 0; j < data.roads[j].length; j++) {
162                  //Hide each road that's not built and remove the onclick handler
163                  let road = $('.road_row').eq(i).children('.road').eq(j)
164                      .off('click')
165                      .removeClass('buildable');
166              }
167          }
168      }
169  
170      city(i, j, data) {
171          this[SOCKET].emit('build:city', [i, j], (err, res) => {
172              this[GEN].next([err, res]);
173          });
174          data.houses[i][j][0] = 2;
175          this.cityHide(data);
176      }
177      cityShow(data) {
178          //Count houses, don't show if there are 5
179          for(let i = 0, c = 0; i < data.houses.length; i++) {
180              for(let j = 0; j < data.houses[i].length; j++) {
181                  if(data.houses[i][j][0] === 2 && data.houses[i][j][1] === this[PLAYER]) {
182                      if(++c === 4) {
183                          return;
184                      }
185                  }
186              }
187          }
188          if(data.players[this[PLAYER]].hand[CONST.RESOURCE][CONST.ORE] >= 3 && data.players[this[PLAYER]].hand[CONST.RESOURCE][CONST.WHEAT] >= 2) {
189              for(let i = 0; i < data.houses.length; i++) {
190                  for(let j = 0; j < data.houses[i].length; j++) {
191                      if(data.houses[i][j][0] === 1 && data.houses[i][j][1] === this[PLAYER]) {
192                          $(".house_row").eq(i).children(".house").eq(j)
193                              .addClass('buildable city')
194                              .click(() => {
195                                  this.city(i, j, data);
196                              });
197                      }
198                  }
199              }
200          }
201      }
202      cityHide(data) {
203          for(let i = 0; i < data.houses.length; i++) {
204              for(let j = 0; j < data.houses[i].length; j++) {
205                  $(".house_row").eq(i).children(".house").eq(j)
206                      .off('click')
207                      .removeClass('buildable');
208              }
209          }
210      }
211  }