-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
308 lines (261 loc) · 8.37 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
/* eslint-disable no-alert */
/**************
* SLICE 1
**************/
function updateCoffeeView(coffeeQty) {
// your code here
const coffeeCounter = document.getElementById("coffee_counter");
coffeeCounter.innerText = coffeeQty;
}
function clickCoffee(data) {
// your code here
data.coffee += 1;
updateCoffeeView(data.coffee);
renderProducers(data);
}
/**************
* SLICE 2
**************/
function unlockProducers(producers, coffeeCount) {
// your code here
return producers.map((producer) => {
if (coffeeCount >= producer.price / 2) {
producer.unlocked = true;
}
});
}
function getUnlockedProducers(data) {
// your code here
return data.producers.filter((producer) => producer.unlocked);
}
function makeDisplayNameFromId(id) {
// your code here
return id
.split("_")
.map((word) => word[0].toUpperCase() + word.slice(1).toLowerCase())
.join(" ");
}
// You shouldn't need to edit this function-- its tests should pass once you've written makeDisplayNameFromId
function makeProducerDiv(producer) {
const containerDiv = document.createElement("div");
containerDiv.className = "producer";
const displayName = makeDisplayNameFromId(producer.id);
const currentCost = producer.price;
const html = `
<div class="producer-column">
<div class="producer-title">${displayName}</div>
<div class="buy">
<button type="button" id="buy_${producer.id}">Buy</button>
<span class="price"> ${producer.price} coffee </span>
</div>
<div class="sell">
<button type="button" id="sell_${producer.id}">Sell </button>
<span class="price"> ${Math.ceil(
updateSellPrice(producer.price) / 4
)} coffee </span>
</div>
</div>
<div class="producer-column">
<div>Quantity: ${producer.qty}</div>
<div>Coffee/second: ${producer.cps}</div>
<div>Cost: ${currentCost} coffee</div>
</div>
`;
containerDiv.innerHTML = html;
return containerDiv;
}
function deleteAllChildNodes(parent) {
// your code here
while (parent.firstChild) {
parent.removeChild(parent.firstChild);
}
}
function renderProducers(data) {
// your code here
const producerContainer = document.getElementById("producer_container");
deleteAllChildNodes(producerContainer);
unlockProducers(data.producers, data.coffee);
getUnlockedProducers(data).map((unlockedProducer) => {
producerContainer.appendChild(makeProducerDiv(unlockedProducer));
});
}
/**************
* SLICE 3
**************/
function getProducerById(data, producerId) {
// your code here
return data.producers.filter((producer) => producer.id === producerId)[0];
}
function canAffordProducer(data, producerId) {
// your code here
if (data.coffee >= getProducerById(data, producerId).price) {
return true;
}
return false;
}
function canSellProducer(data, producerId) {
// your code here
if (getProducerById(data, producerId).qty > 0) {
return true;
}
return false;
}
function updateCPSView(cps) {
// your code here
const cpsIndicator = document.getElementById("cps");
cpsIndicator.innerText = cps;
}
function updatePrice(oldPrice) {
// your code here
return Math.floor(oldPrice * 1.25);
}
function updateSellPrice(oldPrice) {
// try to revert price back to old price before buying
return Math.ceil(oldPrice / 1.25);
}
function attemptToBuyProducer(data, producerId) {
// your code here
let wantedProducer = getProducerById(data, producerId);
if (canAffordProducer(data, producerId)) {
wantedProducer.qty += 1;
data.coffee -= wantedProducer.price;
wantedProducer.price = updatePrice(wantedProducer.price);
data.totalCPS += wantedProducer.cps;
return true;
}
return false;
}
function attemptToSellProducer(data, producerId) {
let unwantedProducer = getProducerById(data, producerId);
if (canSellProducer(data, producerId)) {
unwantedProducer.qty -= 1;
// want to sell for 1/4 of the PREVIOUS price
data.coffee += Math.ceil(updateSellPrice(unwantedProducer.price) / 4);
unwantedProducer.price = updateSellPrice(unwantedProducer.price);
data.totalCPS -= unwantedProducer.cps;
return true;
}
return false;
}
function buyButtonClick(event, data) {
// your code here
if (
event.target.tagName === "BUTTON" &&
event.target.id.slice(0, 3) === "buy"
) {
let wantedProducerId = getProducerById(data, event.target.id.slice(4)).id;
if (canAffordProducer(data, wantedProducerId)) {
attemptToBuyProducer(data, wantedProducerId);
renderProducers(data);
updateCoffeeView(data.coffee);
updateCPSView(data.totalCPS);
} else {
window.alert("Not enough coffee!");
}
}
}
function sellButtonClick(event, data) {
// your code here
if (
event.target.tagName === "BUTTON" &&
event.target.id.slice(0, 4) === "sell"
) {
let unwantedProducerId = getProducerById(data, event.target.id.slice(5)).id;
if (canSellProducer(data, unwantedProducerId)) {
attemptToSellProducer(data, unwantedProducerId);
renderProducers(data);
updateCoffeeView(data.coffee);
updateCPSView(data.totalCPS);
} else {
window.alert(
`You have no ${makeDisplayNameFromId(unwantedProducerId)} to sell!`
);
}
}
}
function save(data) {
window.localStorage.setItem("saveData", JSON.stringify(data));
}
// user can save game manually, though the game state is automattically saved every second
function saveGameButtonClick(event, data) {
if (event.target.tagName === "BUTTON" && event.target.id === "save_game") {
save(data);
event.target.innerText = "Saved!";
}
}
function tick(data) {
// your code here
data.coffee += data.totalCPS;
updateCoffeeView(data.coffee);
// useful when loading from local save data
updateCPSView(data.totalCPS);
renderProducers(data);
}
/*************************
* Start your engines!
*************************/
// You don't need to edit any of the code below
// But it is worth reading so you know what it does!
// So far we've just defined some functions; we haven't actually
// called any of them. Now it's time to get things moving.
// We'll begin with a check to see if we're in a web browser; if we're just running this code in node for purposes of testing, we don't want to 'start the engines'.
// How does this check work? Node gives us access to a global variable /// called `process`, but this variable is undefined in the browser. So,
// we can see if we're in node by checking to see if `process` exists.
if (typeof process === "undefined") {
// Get starting data from the window object
// (This comes from data.js)
if (Object.hasOwn(window.localStorage, "saveData")) {
const saveData = window.localStorage.getItem("saveData");
data = JSON.parse(saveData);
} else {
const data = window.data;
}
// Add an event listener to the giant coffee emoji
const bigCoffee = document.getElementById("big_coffee");
bigCoffee.addEventListener("click", () => clickCoffee(data));
// Add an event listener to the container that holds all of the producers
// Pass in the browser event and our data object to the event listener
const producerContainer = document.getElementById("producer_container");
producerContainer.addEventListener("click", (event) => {
buyButtonClick(event, data);
sellButtonClick(event, data);
});
const newOrSaveGame = document.getElementById("new-or-save-game");
newOrSaveGame.addEventListener("click", (event) => {
if (event.target.tagName === "BUTTON" && event.target.id === "new_game") {
if (confirm("Start a new game?\nAll of your progress will be erased!")) {
data = window.newData;
}
}
saveGameButtonClick(event, data);
});
// Call the tick function passing in the data object once per second
// also saves every second
setInterval(() => {
tick(data);
save(data);
}, 1000);
}
// Meanwhile, if we aren't in a browser and are instead in node
// we'll need to exports the code written here so we can import and
// Don't worry if it's not clear exactly what's going on here;
// We just need this to run the tests in Mocha.
else if (process) {
module.exports = {
updateCoffeeView,
clickCoffee,
unlockProducers,
getUnlockedProducers,
makeDisplayNameFromId,
makeProducerDiv,
deleteAllChildNodes,
renderProducers,
updateCPSView,
getProducerById,
canAffordProducer,
updatePrice,
attemptToBuyProducer,
buyButtonClick,
tick,
};
}