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 }