Turn the game into a third-person Mashhad city game
Replace the linear forest walk with an open area of real western Mashhad built from OpenStreetMap data, starting at Park Mellat. A father and child, guided by the Robot Market robot, find vending machines at a park, school, universities, a metro station and a mall, on foot or by car. - Iran province briefing map; only Mashhad is unlocked - Third-person camera, building collision, arcade car and ambient traffic - Minimap and full city map with addresses, opening hours and A* routing - Purchase scoring, missions with cash rewards, ranks and an end screen - Map data build script (OSM + Natural Earth) and new logic tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+43
-11
@@ -1,15 +1,47 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import {createState,productByCode} from '../src/game-state.js';
|
||||
import {createPayment,beginPayment,swipePayment,cancelPayment} from '../src/payment.js';
|
||||
test('Payment charges once, only after ready and explicit swipe',()=>{
|
||||
const s=createState(),p=createPayment(),product=productByCode('21');assert.ok(product);
|
||||
assert.ok(beginPayment(s,p,product));assert.equal(s.balance,500);assert.equal(s.basket.length,0);assert.equal(s.busy,true);
|
||||
assert.equal(swipePayment(s,p),false);assert.equal(beginPayment(s,p,product),false);
|
||||
p.phase='ready';assert.ok(swipePayment(s,p));assert.equal(s.balance,500-product.cost);assert.equal(s.basket.length,1);
|
||||
assert.equal(swipePayment(s,p),false);assert.equal(cancelPayment(s,p),false);
|
||||
import {createState, purchaseBlocker, priceAt, canAffordAnything, formatClock} from '../src/game-state.js';
|
||||
import {createPayment, beginPayment, readyPayment, swipePayment, cancelPayment} from '../src/payment.js';
|
||||
import {machineById, machines} from '../src/locations.js';
|
||||
|
||||
const park = machineById('mellat-park'), school = machineById('school-rahil'), uni = machineById('ferdowsi-university');
|
||||
|
||||
test('Payment charges once, only after ready and an explicit swipe', () => {
|
||||
const state = createState(), payment = createPayment();
|
||||
assert.ok(beginPayment(state, payment, park, 'juice'));
|
||||
assert.equal(state.balance, 500);
|
||||
assert.equal(swipePayment(state, payment), false, 'not ready yet');
|
||||
assert.ok(readyPayment(payment));
|
||||
assert.ok(swipePayment(state, payment));
|
||||
assert.equal(state.balance, 465);
|
||||
assert.equal(swipePayment(state, payment), false, 'no double charge');
|
||||
assert.equal(state.purchases.length, 1);
|
||||
assert.equal(beginPayment(state, createPayment(), park, 'water'), false, 'busy until delivery ends');
|
||||
});
|
||||
test('Cancel or invalid payment never changes balance or basket',()=>{
|
||||
const s=createState(),p=createPayment();assert.equal(beginPayment(s,p,productByCode('20')),false);
|
||||
assert.ok(beginPayment(s,p,productByCode('60')));assert.ok(cancelPayment(s,p));assert.equal(s.balance,500);assert.equal(s.basket.length,0);assert.equal(s.busy,false);
|
||||
|
||||
test('Cancel, closed machines, unknown products and low funds never charge', () => {
|
||||
const state = createState(), payment = createPayment();
|
||||
assert.ok(beginPayment(state, payment, park, 'cake'));
|
||||
assert.ok(cancelPayment(state, payment));
|
||||
assert.equal(state.balance, 500);
|
||||
assert.equal(state.busy, false);
|
||||
assert.equal(purchaseBlocker(state, park, 'not-a-product'), 'unknown');
|
||||
assert.equal(purchaseBlocker(state, school, 'nuts'), 'unknown', 'school does not sell nuts');
|
||||
state.minutes = 14 * 60;
|
||||
assert.equal(purchaseBlocker(state, school, 'water'), 'closed');
|
||||
state.minutes = 9 * 60;
|
||||
state.balance = 10;
|
||||
assert.equal(purchaseBlocker(state, park, 'water'), 'funds');
|
||||
assert.equal(beginPayment(state, payment, park, 'water'), false);
|
||||
});
|
||||
|
||||
test('Prices follow machine discounts and the clock is Persian', () => {
|
||||
assert.equal(priceAt(uni, 'nuts'), 52);
|
||||
assert.equal(priceAt(park, 'nuts'), 65);
|
||||
assert.equal(formatClock(8 * 60 + 5), '۰۸:۰۵');
|
||||
const state = createState();
|
||||
state.balance = 5;
|
||||
assert.equal(canAffordAnything(state, machines), false);
|
||||
state.balance = 15;
|
||||
assert.ok(canAffordAnything(state, machines));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user