M6: plånbok, biljetter, kortet i telefonen och seedade minispel
All checks were successful
release / build-release (push) Successful in 1m41s
All checks were successful
release / build-release (push) Successful in 1m41s
- sim.Wallet: IC-kort, kontanter, pappersbiljett, telefon med batteri, spenderat; följer med mellan banor (Game.Wallet) - internal/minigame: gemensamt Game-gränssnitt (Update/Done/Success), all slump från del-seeds: TopUp (hitta チャージ, belopp, mata sedlar), Ticket (taxetavla med resmål på japanska), Crowd (tidsfönster, två försök), Ride (stationerna passerar, kliv av vid resmålet) - sim.Run: spärren kräver biljett på biljettbanor annars användbart kort; telefonen ger ×1,1 fart men 15 % seedad omskanning (frysning 1,5 s), dött batteri gör kortet oanvändbart; automaten startar påfyllning eller biljettköp; tåget kontrollerar biljetten; fulla tåg kräver trängsel; resan avgör vinst/förlust (fel station, åkte förbi, fel tåg); StepMini låter klockan och sällskapet ticka medan rörelsen pausar - level: ticketRequired, rideStops, Train.Crowded; 002 är biljettbana med fullt tåg och fyra stopp; ordboken har stationer (kind) + sju nya namn - game: vyer för minispelen, plånbok i HUD, P i menyn = kort i telefonen, förlustorsaker och spenderat på resultatet, flaggor -phone/-card, skriptkommandon hold/waitstop; inforuta/minikarta döljs under minispel - plan: M7b (Björn) – tågvind, ankomstindikator nära rälsen, in-/utkörningsanimation för tåg och bussar – i spelbeskrivning, roadmap, testplan - docs/README/wiki med tre nya bilder (automat, biljettavla, tågresa) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -72,6 +72,7 @@ const (
|
||||
DefaultDwellSec = 10.0
|
||||
DefaultFareYen = 200
|
||||
MaxParty = 5
|
||||
DefaultRideStops = 3
|
||||
)
|
||||
|
||||
// Status returnerar om tåget står vid perrongen vid tiden t, och hur många
|
||||
@@ -94,6 +95,7 @@ type Train struct {
|
||||
Line Text `json:"line"` // linjens namn
|
||||
Destination Text `json:"destination"` // slutstation
|
||||
Correct bool `json:"correct"` // tar spelaren till rätt resmål
|
||||
Crowded bool `json:"crowded"` // fullt tåg: minispel för att få plats
|
||||
Schedule Schedule `json:"schedule"`
|
||||
}
|
||||
|
||||
@@ -106,17 +108,19 @@ type SignText struct {
|
||||
|
||||
// Level är en bana.
|
||||
type Level struct {
|
||||
ID string `json:"id"`
|
||||
Name Text `json:"name"`
|
||||
Difficulty int `json:"difficulty"` // 1 (lätt) … 5 (svår)
|
||||
Destination Text `json:"destination"` // dit spelaren ska
|
||||
TimeLimitSec int `json:"timeLimitSec"` // 0 = ingen tidsgräns
|
||||
ParSec int `json:"parSec"` // "bra tid" för tre stjärnor (0 = räknas ut från kortaste vägen)
|
||||
Party int `json:"party"` // antal i sällskapet inkl. spelaren (0 = 1)
|
||||
FareYen int `json:"fareYen"` // vad spärren drar från kortet (0 = standard)
|
||||
Grid []string `json:"grid"`
|
||||
Trains []Train `json:"trains"`
|
||||
Signs []SignText `json:"signs"`
|
||||
ID string `json:"id"`
|
||||
Name Text `json:"name"`
|
||||
Difficulty int `json:"difficulty"` // 1 (lätt) … 5 (svår)
|
||||
Destination Text `json:"destination"` // dit spelaren ska
|
||||
TimeLimitSec int `json:"timeLimitSec"` // 0 = ingen tidsgräns
|
||||
ParSec int `json:"parSec"` // "bra tid" för tre stjärnor (0 = räknas ut från kortaste vägen)
|
||||
Party int `json:"party"` // antal i sällskapet inkl. spelaren (0 = 1)
|
||||
TicketRequired bool `json:"ticketRequired"` // spärren kräver pappersbiljett (köps i automaten) i stället för kort
|
||||
RideStops int `json:"rideStops"` // antal stationer på tågresan (0 = DefaultRideStops)
|
||||
FareYen int `json:"fareYen"` // vad spärren drar från kortet (0 = standard)
|
||||
Grid []string `json:"grid"`
|
||||
Trains []Train `json:"trains"`
|
||||
Signs []SignText `json:"signs"`
|
||||
}
|
||||
|
||||
// Point är en rutkoordinat.
|
||||
@@ -240,6 +244,15 @@ func (l *Level) Validate() error {
|
||||
if l.Party == 0 {
|
||||
l.Party = 1
|
||||
}
|
||||
if l.RideStops == 0 {
|
||||
l.RideStops = DefaultRideStops
|
||||
}
|
||||
if l.RideStops < 2 || l.RideStops > 8 {
|
||||
return fmt.Errorf("level %s: rideStops måste vara 2–8", l.ID)
|
||||
}
|
||||
if l.TicketRequired && len(l.Find(TicketMachine)) == 0 {
|
||||
return fmt.Errorf("level %s: biljettkrav utan biljettautomat (T)", l.ID)
|
||||
}
|
||||
if l.Party > MaxParty {
|
||||
return fmt.Errorf("level %s: sällskapet får vara högst %d", l.ID, MaxParty)
|
||||
}
|
||||
|
||||
@@ -288,3 +288,21 @@ func TestPartyAndParDefaults(t *testing.T) {
|
||||
t.Fatal("W och K ska vara passerbara rutor")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTicketAndRideFields(t *testing.T) {
|
||||
l := mustParse(t, sample)
|
||||
if l.RideStops != DefaultRideStops || l.TicketRequired || l.Trains[0].Crowded {
|
||||
t.Fatalf("standard: stops=%d ticket=%v crowded=%v", l.RideStops, l.TicketRequired, l.Trains[0].Crowded)
|
||||
}
|
||||
if _, err := Parse([]byte(strings.Replace(sample, `"difficulty": 1`, `"difficulty": 1, "ticketRequired": true`, 1))); err == nil {
|
||||
t.Fatal("biljettkrav utan automat ska ge fel")
|
||||
}
|
||||
if _, err := Parse([]byte(strings.Replace(sample, `"difficulty": 1`, `"difficulty": 1, "rideStops": 1`, 1))); err == nil {
|
||||
t.Fatal("för få stopp ska ge fel")
|
||||
}
|
||||
ok := strings.Replace(strings.Replace(sample, `"#S..#P#"`, `"#ST.#P#"`, 1), `"difficulty": 1`, `"difficulty": 1, "ticketRequired": true, "rideStops": 4`, 1)
|
||||
l2 := mustParse(t, ok)
|
||||
if !l2.TicketRequired || l2.RideStops != 4 {
|
||||
t.Fatal("fälten ska läsas")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user