all: remove koka code, move go to repo root
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
|||||||
[submodule "std"]
|
|
||||||
path = std
|
|
||||||
url = git@github.com:koka-community/std.git
|
|
||||||
@@ -25,7 +25,7 @@ import (
|
|||||||
"github.com/disgoorg/disgo/rest"
|
"github.com/disgoorg/disgo/rest"
|
||||||
httpmiddle "github.com/go-chi/chi/v5/middleware"
|
httpmiddle "github.com/go-chi/chi/v5/middleware"
|
||||||
|
|
||||||
"git.sunturtle.xyz/zephyr/horse/horse"
|
"git.sunturtle.xyz/zephyr/horse"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import (
|
|||||||
"github.com/disgoorg/disgo/discord"
|
"github.com/disgoorg/disgo/discord"
|
||||||
"github.com/disgoorg/disgo/handler"
|
"github.com/disgoorg/disgo/handler"
|
||||||
|
|
||||||
|
"git.sunturtle.xyz/zephyr/horse"
|
||||||
"git.sunturtle.xyz/zephyr/horse/cmd/horsebot/autocomplete"
|
"git.sunturtle.xyz/zephyr/horse/cmd/horsebot/autocomplete"
|
||||||
"git.sunturtle.xyz/zephyr/horse/horse"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type skillServer struct {
|
type skillServer struct {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import (
|
|||||||
"zombiezen.com/go/sqlite"
|
"zombiezen.com/go/sqlite"
|
||||||
"zombiezen.com/go/sqlite/sqlitex"
|
"zombiezen.com/go/sqlite/sqlitex"
|
||||||
|
|
||||||
"git.sunturtle.xyz/zephyr/horse/horse"
|
"git.sunturtle.xyz/zephyr/horse"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
go run ./horsegen "$@"
|
|
||||||
go generate ./horse/...
|
|
||||||
go fmt ./...
|
|
||||||
go test ./...
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
# horse
|
|
||||||
|
|
||||||
This directory contains manually written code and types on which the generated code depends.
|
|
||||||
|
|
||||||
The generated code is in ./global; other regions will follow the same convention once they are supported.
|
|
||||||
It is always safe to delete the entire directories and regenerate them.
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
module horse/character
|
|
||||||
|
|
||||||
import horse/game-id
|
|
||||||
|
|
||||||
pub struct character-detail
|
|
||||||
character-id: character-id
|
|
||||||
name: string
|
|
||||||
|
|
||||||
pub fun detail(
|
|
||||||
c: character-id,
|
|
||||||
?character/show: (character-id) -> string
|
|
||||||
): character-detail
|
|
||||||
Character-detail(c, c.show)
|
|
||||||
|
|
||||||
pub fun character-detail/show(d: character-detail): string
|
|
||||||
val Character-detail(Character-id(id), name) = d
|
|
||||||
name ++ " (ID " ++ id.show ++ ")"
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
module horse/game-id
|
|
||||||
|
|
||||||
// Game ID for characters, cards, skills, races, &c.
|
|
||||||
// Values for different categories may overlap.
|
|
||||||
pub alias game-id = int
|
|
||||||
|
|
||||||
// Specific game ID types.
|
|
||||||
// I've already made mistakes with ID categories and I haven't even committed this file yet.
|
|
||||||
|
|
||||||
pub struct scenario-id
|
|
||||||
game-id: game-id
|
|
||||||
|
|
||||||
// Game ID for characters.
|
|
||||||
// Generally numbers in the range 1000-9999.
|
|
||||||
pub struct character-id
|
|
||||||
game-id: game-id
|
|
||||||
|
|
||||||
// Game ID for trainees, i.e. costume instances of characters.
|
|
||||||
// Generally a character ID with two digits appended.
|
|
||||||
pub struct uma-id
|
|
||||||
game-id: game-id
|
|
||||||
|
|
||||||
// Game ID for skills.
|
|
||||||
pub struct skill-id
|
|
||||||
game-id: game-id
|
|
||||||
|
|
||||||
// Game ID for skill groups.
|
|
||||||
pub struct skill-group-id
|
|
||||||
game-id: game-id
|
|
||||||
|
|
||||||
// Game ID for skill icons.
|
|
||||||
pub struct skill-icon-id
|
|
||||||
game-id: game-id
|
|
||||||
|
|
||||||
// Game ID for races,
|
|
||||||
// i.e. "Tenno Sho (Spring)" and not "Tenno Sho (Spring) at Kyoto Racecourse."
|
|
||||||
pub struct race-id
|
|
||||||
game-id: game-id
|
|
||||||
|
|
||||||
// Game ID for race thumbnails.
|
|
||||||
pub struct race-thumbnail-id
|
|
||||||
game-id: game-id
|
|
||||||
|
|
||||||
// Game ID for saddles,
|
|
||||||
// i.e. one or more race wins that appear as a title.
|
|
||||||
pub struct saddle-id
|
|
||||||
game-id: game-id
|
|
||||||
|
|
||||||
// Game ID for sparks,
|
|
||||||
// i.e. succession factors.
|
|
||||||
pub struct spark-id
|
|
||||||
game-id: game-id
|
|
||||||
|
|
||||||
// Game ID for spark groups,
|
|
||||||
// i.e. all rarities (star counts) of a single spark.
|
|
||||||
pub struct spark-group-id
|
|
||||||
game-id: game-id
|
|
||||||
|
|
||||||
// order2 comparison between any game ID types.
|
|
||||||
pub inline fun order2(x: a, y: a, ?a/game-id: (a) -> game-id): order2<a>
|
|
||||||
match x.game-id.cmp(y.game-id)
|
|
||||||
Lt -> Lt2(x, y)
|
|
||||||
Eq -> Eq2(x)
|
|
||||||
Gt -> Gt2(x, y)
|
|
||||||
|
|
||||||
// Comparison between any game ID types.
|
|
||||||
pub inline fun cmp(x: a, y: a, ?a/game-id: (a) -> game-id): order
|
|
||||||
x.game-id.cmp(y.game-id)
|
|
||||||
|
|
||||||
// Equality between any game ID types.
|
|
||||||
pub inline fun (==)(x: a, y: a, ?a/game-id: (a) -> game-id): bool
|
|
||||||
x.game-id == y.game-id
|
|
||||||
|
|
||||||
// Check whether a game ID is valid, i.e. nonzero.
|
|
||||||
pub inline fun is-valid(x: a, ?a/game-id: (a) -> game-id): bool
|
|
||||||
x.game-id != 0
|
|
||||||
|
|
||||||
// Construct an invalid game ID.
|
|
||||||
pub inline fun default/game-id(): game-id
|
|
||||||
0
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
module horse/global
|
|
||||||
|
|
||||||
import horse/game-id
|
|
||||||
|
|
||||||
// Shared saddle affinity bonus.
|
|
||||||
// `s` should be the complete list of all saddles shared between the veterans.
|
|
||||||
pub fun saddle-bonus(s: list<saddle-id>): int
|
|
||||||
s.length
|
|
||||||
124
horse/legacy.kk
124
horse/legacy.kk
@@ -1,124 +0,0 @@
|
|||||||
module horse/legacy
|
|
||||||
|
|
||||||
import std/num/decimal
|
|
||||||
import std/data/linearmap
|
|
||||||
import std/data/linearset
|
|
||||||
import horse/game-id
|
|
||||||
import horse/spark
|
|
||||||
import horse/prob/dist
|
|
||||||
|
|
||||||
// A legacy, or parent and grandparents.
|
|
||||||
pub struct legacy
|
|
||||||
uma: veteran
|
|
||||||
sub1: veteran
|
|
||||||
sub2: veteran
|
|
||||||
|
|
||||||
// A veteran, or the result of a completed career.
|
|
||||||
pub struct veteran
|
|
||||||
uma: uma-id
|
|
||||||
sparks: list<spark-id>
|
|
||||||
saddles: list<saddle-id>
|
|
||||||
|
|
||||||
// Get all saddles shared between two lists thereof.
|
|
||||||
pub fun shared-saddles(a: list<saddle-id>, b: list<saddle-id>): list<saddle-id>
|
|
||||||
val sa: linearSet<saddle-id> = a.foldl(linear-set(Nil)) fn(s, id) if id.is-valid then s.add(id) else s
|
|
||||||
val c: linearSet<saddle-id> = b.foldl(linear-set(Nil)) fn(s, id) if sa.member(id) then s.add(id) else s
|
|
||||||
c.list
|
|
||||||
|
|
||||||
// Get the individual affinity for a legacy.
|
|
||||||
// Any invalid ID is treated as giving 0.
|
|
||||||
pub fun parent-affinity(
|
|
||||||
trainee: uma-id,
|
|
||||||
legacy: legacy,
|
|
||||||
other-parent: uma-id,
|
|
||||||
?character-id: (uma-id) -> character-id,
|
|
||||||
?saddle-bonus: (list<saddle-id>) -> int,
|
|
||||||
?pair-affinity: (a: character-id, b: character-id) -> int,
|
|
||||||
?trio-affinity: (a: character-id, b: character-id, c: character-id) -> int
|
|
||||||
): int
|
|
||||||
val t = trainee.character-id
|
|
||||||
val p1 = legacy.uma.uma.character-id
|
|
||||||
val s1 = legacy.sub1.uma.character-id
|
|
||||||
val s2 = legacy.sub2.uma.character-id
|
|
||||||
val p2 = other-parent.character-id
|
|
||||||
pair-affinity(t, p1) + pair-affinity(p1, p2)
|
|
||||||
+ trio-affinity(t, p1, s1) + trio-affinity(t, p1, s2)
|
|
||||||
+ saddle-bonus(shared-saddles(legacy.uma.saddles, legacy.sub1.saddles)) + saddle-bonus(shared-saddles(legacy.uma.saddles, legacy.sub2.saddles))
|
|
||||||
|
|
||||||
// Get the individual affinities for a legacy's sub-legacies.
|
|
||||||
// The first value is the legacy for the `legacy.sub1` and the second is for
|
|
||||||
// `legacy.sub2`.
|
|
||||||
// Any invalid ID is treated as giving 0.
|
|
||||||
pub fun sub-affinity(
|
|
||||||
trainee: uma-id,
|
|
||||||
legacy: legacy,
|
|
||||||
?character-id: (uma-id) -> character-id,
|
|
||||||
?saddle-bonus: (list<saddle-id>) -> int,
|
|
||||||
?trio-affinity: (a: character-id, b: character-id, c: character-id) -> int
|
|
||||||
): (int, int)
|
|
||||||
val t = trainee.character-id
|
|
||||||
val p = legacy.uma.uma.character-id
|
|
||||||
val s1 = legacy.sub1.uma.character-id
|
|
||||||
val s2 = legacy.sub2.uma.character-id
|
|
||||||
val r1 = trio-affinity(t, p, s1) + saddle-bonus(shared-saddles(legacy.uma.saddles, legacy.sub1.saddles))
|
|
||||||
val r2 = trio-affinity(t, p, s2) + saddle-bonus(shared-saddles(legacy.uma.saddles, legacy.sub2.saddles))
|
|
||||||
(r1, r2)
|
|
||||||
|
|
||||||
// Associate each spark with its actual chance to activate given an individual
|
|
||||||
// affinity value and the possible effects when it does.
|
|
||||||
pub fun uma/inspiration(l: list<spark-id>, affinity: int, ?spark-type: (spark-id) -> spark-type, ?rarity: (spark-id) -> rarity, ?effects: (spark-id) -> list<list<spark-effect>>): list<(spark-id, decimal, list<list<spark-effect>>)>
|
|
||||||
val a = decimal(1 + affinity, -2)
|
|
||||||
l.map() fn(id) (id, min(id.base-proc * a, 1.decimal), id.effects)
|
|
||||||
|
|
||||||
// Get the complete list of effects that may occur in an inspiration event
|
|
||||||
// and the respective probability of activation.
|
|
||||||
// Duplicates, i.e. multiple veterans with the same spark, are preserved.
|
|
||||||
pub fun inspiration(
|
|
||||||
trainee: uma-id,
|
|
||||||
parent1: legacy,
|
|
||||||
parent2: legacy,
|
|
||||||
?character-id: (uma-id) -> character-id,
|
|
||||||
?saddle-bonus: (list<saddle-id>) -> int,
|
|
||||||
?pair-affinity: (a: character-id, b: character-id) -> int,
|
|
||||||
?trio-affinity: (a: character-id, b: character-id, c: character-id) -> int,
|
|
||||||
?spark-type: (spark-id) -> spark-type,
|
|
||||||
?rarity: (spark-id) -> rarity,
|
|
||||||
?effects: (spark-id) -> list<list<spark-effect>>
|
|
||||||
): list<(spark-id, decimal, list<list<spark-effect>>)>
|
|
||||||
val p1a = parent-affinity(trainee, parent1, parent2.uma.uma)
|
|
||||||
val p2a = parent-affinity(trainee, parent2, parent1.uma.uma)
|
|
||||||
val (s11a, s12a) = sub-affinity(trainee, parent1)
|
|
||||||
val (s21a, s22a) = sub-affinity(trainee, parent2)
|
|
||||||
[
|
|
||||||
inspiration(parent1.uma.sparks, p1a),
|
|
||||||
inspiration(parent1.sub1.sparks, s11a),
|
|
||||||
inspiration(parent1.sub2.sparks, s12a),
|
|
||||||
inspiration(parent2.uma.sparks, p2a),
|
|
||||||
inspiration(parent2.sub1.sparks, s21a),
|
|
||||||
inspiration(parent2.sub2.sparks, s22a),
|
|
||||||
].concat
|
|
||||||
|
|
||||||
// Reduce a spark effect list to the skill it is able to give.
|
|
||||||
pub fun skills(l: list<list<spark-effect>>): maybe<skill-id>
|
|
||||||
val r: linearSet<skill-id> = l.head(Nil).foldl(linear-set(Nil)) fn(s, eff)
|
|
||||||
match eff
|
|
||||||
Skill-Hint(id, _) -> s + id
|
|
||||||
_ -> s
|
|
||||||
r.list.head
|
|
||||||
|
|
||||||
// Reduce a spark effect list to the aptitude it is able to give.
|
|
||||||
pub fun aptitudes(l: list<list<spark-effect>>): maybe<aptitude>
|
|
||||||
val r: linearSet<aptitude> = l.head(Nil).foldl(linear-set(Nil)) fn(s, eff)
|
|
||||||
match eff
|
|
||||||
Aptitude-Up(apt) -> s + apt
|
|
||||||
_ -> s
|
|
||||||
r.list.head
|
|
||||||
|
|
||||||
// Get the overall chance of each count of sparks, including zero, providing a
|
|
||||||
// given type of effect activating in a single inspiration event.
|
|
||||||
pub fun inspiration-gives(l: list<(spark-id, decimal, list<list<spark-effect>>)>, f: (list<list<spark-effect>>) -> maybe<a>, ?a/(==): (a, a) -> bool): linearMap<a, list<decimal>>
|
|
||||||
val m: linearMap<_, list<decimal>> = l.foldl(LinearMap(Nil)) fn(m, (_, p, eff))
|
|
||||||
match f(eff)
|
|
||||||
Nothing -> m
|
|
||||||
Just(a) -> m.map/update(a, [p]) fn(cur, pp) pp.append(cur)
|
|
||||||
m.map() fn(_, v) poisson-binomial(v)
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
module horse/movement
|
|
||||||
|
|
||||||
// Surface types.
|
|
||||||
pub type surface
|
|
||||||
Turf
|
|
||||||
Dirt
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Shows a string representation of the `surface` type.
|
|
||||||
pub fun surface/show(this : surface) : e string
|
|
||||||
match this
|
|
||||||
Turf -> "Turf"
|
|
||||||
Dirt -> "Dirt"
|
|
||||||
|
|
||||||
// Race distance types.
|
|
||||||
pub type distance
|
|
||||||
Sprint
|
|
||||||
Mile
|
|
||||||
Medium
|
|
||||||
Long
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Shows a string representation of the `distance` type.
|
|
||||||
pub fun distance/show(this : distance) : e string
|
|
||||||
match this
|
|
||||||
Sprint -> "Sprint"
|
|
||||||
Mile -> "Mile"
|
|
||||||
Medium -> "Medium"
|
|
||||||
Long -> "Long"
|
|
||||||
|
|
||||||
// Running styles.
|
|
||||||
pub type style
|
|
||||||
Front-Runner
|
|
||||||
Pace-Chaser
|
|
||||||
Late-Surger
|
|
||||||
End-Closer
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Equality comparison of the `style` type.
|
|
||||||
pub fun style/(==)(this : style, other : style) : e bool
|
|
||||||
match (this, other)
|
|
||||||
(Front-Runner, Front-Runner) -> True
|
|
||||||
(Pace-Chaser, Pace-Chaser) -> True
|
|
||||||
(Late-Surger, Late-Surger) -> True
|
|
||||||
(End-Closer, End-Closer) -> True
|
|
||||||
(_, _) -> False
|
|
||||||
|
|
||||||
// Shows a string representation of the `style` type.
|
|
||||||
pub fun style/show(this : style) : e string
|
|
||||||
match this
|
|
||||||
Front-Runner -> "Front Runner"
|
|
||||||
Pace-Chaser -> "Pace Chaser"
|
|
||||||
Late-Surger -> "Late Surger"
|
|
||||||
End-Closer -> "End Closer"
|
|
||||||
|
|
||||||
// Aptitude levels.
|
|
||||||
pub type aptitude-level
|
|
||||||
G
|
|
||||||
F
|
|
||||||
E
|
|
||||||
D
|
|
||||||
C
|
|
||||||
B
|
|
||||||
A
|
|
||||||
S
|
|
||||||
|
|
||||||
// Get the integer value for an aptitude level, starting at G -> 1.
|
|
||||||
pub fun aptitude-level/int(l: aptitude-level): int
|
|
||||||
match l
|
|
||||||
G -> 1
|
|
||||||
F -> 2
|
|
||||||
E -> 3
|
|
||||||
D -> 4
|
|
||||||
C -> 5
|
|
||||||
B -> 6
|
|
||||||
A -> 7
|
|
||||||
S -> 8
|
|
||||||
|
|
||||||
// Get the aptitude level corresponding to an integer, starting at 1 -> G.
|
|
||||||
pub fun int/aptitude-level(l: int): maybe<aptitude-level>
|
|
||||||
match l
|
|
||||||
1 -> Just(G)
|
|
||||||
2 -> Just(F)
|
|
||||||
3 -> Just(E)
|
|
||||||
4 -> Just(D)
|
|
||||||
5 -> Just(C)
|
|
||||||
6 -> Just(B)
|
|
||||||
7 -> Just(A)
|
|
||||||
8 -> Just(S)
|
|
||||||
_ -> Nothing
|
|
||||||
|
|
||||||
// Comparison of the `aptitude-level` type.
|
|
||||||
pub fun aptitude-level/cmp(this : aptitude-level, other : aptitude-level) : e order
|
|
||||||
cmp(this.int, other.int)
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Fip comparison of the `aptitude-level` type.
|
|
||||||
pub fun aptitude-level/order2(this : aptitude-level, other : aptitude-level) : order2<aptitude-level>
|
|
||||||
match (this, other)
|
|
||||||
(G, G) -> Eq2(G)
|
|
||||||
(G, other') -> Lt2(G, other')
|
|
||||||
(this', G) -> Gt2(G, this')
|
|
||||||
(F, F) -> Eq2(F)
|
|
||||||
(F, other') -> Lt2(F, other')
|
|
||||||
(this', F) -> Gt2(F, this')
|
|
||||||
(E, E) -> Eq2(E)
|
|
||||||
(E, other') -> Lt2(E, other')
|
|
||||||
(this', E) -> Gt2(E, this')
|
|
||||||
(D, D) -> Eq2(D)
|
|
||||||
(D, other') -> Lt2(D, other')
|
|
||||||
(this', D) -> Gt2(D, this')
|
|
||||||
(C, C) -> Eq2(C)
|
|
||||||
(C, other') -> Lt2(C, other')
|
|
||||||
(this', C) -> Gt2(C, this')
|
|
||||||
(B, B) -> Eq2(B)
|
|
||||||
(B, other') -> Lt2(B, other')
|
|
||||||
(this', B) -> Gt2(B, this')
|
|
||||||
(A, A) -> Eq2(A)
|
|
||||||
(A, other') -> Lt2(A, other')
|
|
||||||
(this', A) -> Gt2(A, this')
|
|
||||||
(S, S) -> Eq2(S)
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Shows a string representation of the `aptitude-level` type.
|
|
||||||
pub fun aptitude-level/show(this : aptitude-level) : string
|
|
||||||
match this
|
|
||||||
G -> "G"
|
|
||||||
F -> "F"
|
|
||||||
E -> "E"
|
|
||||||
D -> "D"
|
|
||||||
C -> "C"
|
|
||||||
B -> "B"
|
|
||||||
A -> "A"
|
|
||||||
S -> "S"
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
module horse/prob/dist
|
|
||||||
|
|
||||||
import std/num/decimal
|
|
||||||
|
|
||||||
tail fun pb-step(pn: list<decimal>, pi: decimal, pmfkm1: decimal, pmf: list<decimal>, next: ctx<list<decimal>>): list<decimal>
|
|
||||||
match pn
|
|
||||||
Nil -> next ++. Nil // final step overall
|
|
||||||
Cons(_, pp) -> match pmf
|
|
||||||
Cons(pmfk, pmf') ->
|
|
||||||
val next' = next ++ ctx Cons(pi * pmfkm1 + (1.decimal - pi) * pmfk, hole)
|
|
||||||
pb-step(pp, pi, pmfk, pmf', next')
|
|
||||||
Nil -> next ++. Cons(pi * pmfkm1, Nil) // last step of this iteration
|
|
||||||
|
|
||||||
// Given `n` different Bernoulli processes with respective probabilities in `pn`,
|
|
||||||
// find the distribution of `k` successes for `k` ranging from 0 to `n` inclusive.
|
|
||||||
// The index in the result list corresponds to `k`.
|
|
||||||
pub fun pmf/poisson-binomial(pn: list<decimal>): list<decimal>
|
|
||||||
pn.foldl([1.decimal]) fn(pmf, pi)
|
|
||||||
match pmf
|
|
||||||
Cons(pmf0, pmf') -> pb-step(pn, pi, pmf0, pmf', ctx Cons((1.decimal - pi) * pmf0, hole))
|
|
||||||
Nil -> impossible("fold started with non-empty pmf but got empty pmf")
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
module horse/prob/kfl
|
|
||||||
|
|
||||||
// kfl is a semiring of probabilities formed by vibes.
|
|
||||||
pub type kfl
|
|
||||||
// Effectively if not literally impossible events.
|
|
||||||
Impossible
|
|
||||||
// Not worth aiming for, but can technically still happen.
|
|
||||||
Probably-Not
|
|
||||||
// You expect it not to happen most of the time, but it might still be worth
|
|
||||||
// trying for it if you're being forced to play to your outs.
|
|
||||||
Doubtful
|
|
||||||
// More likely that it won't happen, but a success isn't surprising.
|
|
||||||
Unlikely
|
|
||||||
// Either it does or it doesn't.
|
|
||||||
Mayhapsibly
|
|
||||||
// Decent chance it doesn't happen, but you still expect it to.
|
|
||||||
Probably
|
|
||||||
// You expect it to happen most of the time, but accept that there will be failures.
|
|
||||||
Most-Likely
|
|
||||||
// Very close to guaranteed, but technically with a small chance to fail.
|
|
||||||
Cry-If-Not
|
|
||||||
// Absolutely guaranteed events.
|
|
||||||
Guaranteed
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Comparison of the `kfl` type.
|
|
||||||
pub fun cmp(this : kfl, other : kfl) : e order
|
|
||||||
match (this, other)
|
|
||||||
(Impossible, Impossible) -> Eq
|
|
||||||
(Impossible, _) -> Lt
|
|
||||||
(_, Impossible) -> Gt
|
|
||||||
(Probably-Not, Probably-Not) -> Eq
|
|
||||||
(Probably-Not, _) -> Lt
|
|
||||||
(_, Probably-Not) -> Gt
|
|
||||||
(Doubtful, Doubtful) -> Eq
|
|
||||||
(Doubtful, _) -> Lt
|
|
||||||
(_, Doubtful) -> Gt
|
|
||||||
(Unlikely, Unlikely) -> Eq
|
|
||||||
(Unlikely, _) -> Lt
|
|
||||||
(_, Unlikely) -> Gt
|
|
||||||
(Mayhapsibly, Mayhapsibly) -> Eq
|
|
||||||
(Mayhapsibly, _) -> Lt
|
|
||||||
(_, Mayhapsibly) -> Gt
|
|
||||||
(Probably, Probably) -> Eq
|
|
||||||
(Probably, _) -> Lt
|
|
||||||
(_, Probably) -> Gt
|
|
||||||
(Most-Likely, Most-Likely) -> Eq
|
|
||||||
(Most-Likely, _) -> Lt
|
|
||||||
(_, Most-Likely) -> Gt
|
|
||||||
(Cry-If-Not, Cry-If-Not) -> Eq
|
|
||||||
(Cry-If-Not, _) -> Lt
|
|
||||||
(_, Cry-If-Not) -> Gt
|
|
||||||
(Guaranteed, Guaranteed) -> Eq
|
|
||||||
|
|
||||||
// Shows a string representation of the `kfl` type.
|
|
||||||
pub fun show(this : kfl) : e string
|
|
||||||
match this
|
|
||||||
Impossible -> "impossible"
|
|
||||||
Probably-Not -> "probably not"
|
|
||||||
Doubtful -> "doubtful"
|
|
||||||
Unlikely -> "unlikely"
|
|
||||||
Mayhapsibly -> "mayhapsibly"
|
|
||||||
Probably -> "probably"
|
|
||||||
Most-Likely -> "most likely"
|
|
||||||
Cry-If-Not -> "cry if not"
|
|
||||||
Guaranteed -> "guaranteed"
|
|
||||||
|
|
||||||
// KFL multiplication, or the probability of cooccurrence of two independent events.
|
|
||||||
pub fun (*)(a: kfl, b: kfl): e kfl
|
|
||||||
val (l, h) = match a.cmp(b) // this operation is commutative
|
|
||||||
Gt -> (b, a)
|
|
||||||
_ -> (a, b)
|
|
||||||
match (l, h)
|
|
||||||
(r, Guaranteed) -> r // factor out Guaranteed cases
|
|
||||||
(Impossible, _) -> Impossible
|
|
||||||
(Probably-Not, _) -> Impossible
|
|
||||||
(r, Cry-If-Not) -> r // factor out further Cry-If-Not cases
|
|
||||||
(Doubtful, Most-Likely) -> Probably-Not
|
|
||||||
(Doubtful, _) -> Impossible
|
|
||||||
(Unlikely, Most-Likely) -> Doubtful
|
|
||||||
(Unlikely, Probably) -> Doubtful
|
|
||||||
(Unlikely, Mayhapsibly) -> Probably-Not
|
|
||||||
(Unlikely, _) -> Probably-Not // (Unlikely, Unlikely) because commutative
|
|
||||||
(Mayhapsibly, Most-Likely) -> Unlikely
|
|
||||||
(Mayhapsibly, Probably) -> Unlikely
|
|
||||||
(Mayhapsibly, _) -> Unlikely
|
|
||||||
(Probably, Most-Likely) -> Mayhapsibly
|
|
||||||
(Probably, _) -> Unlikely
|
|
||||||
(Most-Likely, _) -> Probably
|
|
||||||
// These two are only needed because the type system doesn't understand commutativity.
|
|
||||||
(Cry-If-Not, _) -> Cry-If-Not
|
|
||||||
(Guaranteed, _) -> Guaranteed
|
|
||||||
|
|
||||||
// KFL addition, or the probability of occurrence of at least one of two independent events.
|
|
||||||
pub fun (+)(a: kfl, b: kfl): e kfl
|
|
||||||
val (l, h) = match a.cmp(b) // this operation is commutative
|
|
||||||
Gt -> (b, a)
|
|
||||||
_ -> (a, b)
|
|
||||||
match (l, h)
|
|
||||||
// Cases with _ on the right are (a, a) due to commutativity.
|
|
||||||
// Cases with _ on the left simplify later cases that all absorb to the right.
|
|
||||||
(Guaranteed, _) -> Guaranteed
|
|
||||||
(_, Guaranteed) -> Guaranteed
|
|
||||||
(Cry-If-Not, _) -> Guaranteed
|
|
||||||
(Most-Likely, Cry-If-Not) -> Cry-If-Not
|
|
||||||
(Most-Likely, _) -> Cry-If-Not
|
|
||||||
(_, Cry-If-Not) -> Cry-If-Not
|
|
||||||
(Probably, Most-Likely) -> Cry-If-Not
|
|
||||||
(Probably, _) -> Most-Likely
|
|
||||||
(_, Most-Likely) -> Most-Likely
|
|
||||||
(Mayhapsibly, Probably) -> Most-Likely
|
|
||||||
(Mayhapsibly, _) -> Probably
|
|
||||||
(Unlikely, Probably) -> Most-Likely
|
|
||||||
(Unlikely, Mayhapsibly) -> Probably
|
|
||||||
(Unlikely, _) -> Mayhapsibly
|
|
||||||
(_, Probably) -> Probably
|
|
||||||
(Doubtful, Mayhapsibly) -> Probably
|
|
||||||
(Doubtful, Unlikely) -> Mayhapsibly
|
|
||||||
(Doubtful, _) -> Unlikely
|
|
||||||
(_, Mayhapsibly) -> Mayhapsibly
|
|
||||||
(_, Unlikely) -> Unlikely
|
|
||||||
(Probably-Not, Doubtful) -> Unlikely
|
|
||||||
(Probably-Not, _) -> Probably-Not
|
|
||||||
(_, Doubtful) -> Doubtful
|
|
||||||
(_, Probably-Not) -> Probably-Not
|
|
||||||
(_, Impossible) -> Impossible
|
|
||||||
|
|
||||||
// KFL union, or the probability of occurrence of exactly one of two independent events.
|
|
||||||
pub fun either(a: kfl, b: kfl): e kfl
|
|
||||||
val (l, h) = match a.cmp(b) // this operation is commutative
|
|
||||||
Gt -> (b, a)
|
|
||||||
_ -> (a, b)
|
|
||||||
match (l, h)
|
|
||||||
(Impossible, r) -> r
|
|
||||||
(Probably-Not, Guaranteed) -> Cry-If-Not
|
|
||||||
(Probably-Not, r) -> r
|
|
||||||
(Doubtful, Guaranteed) -> Most-Likely
|
|
||||||
(Doubtful, Cry-If-Not) -> Most-Likely
|
|
||||||
(Doubtful, Most-Likely) -> Probably
|
|
||||||
(Doubtful, Probably) -> Mayhapsibly
|
|
||||||
(Doubtful, Mayhapsibly) -> Mayhapsibly
|
|
||||||
(Doubtful, Unlikely) -> Mayhapsibly
|
|
||||||
(Doubtful, _) -> Unlikely
|
|
||||||
(Unlikely, Guaranteed) -> Probably
|
|
||||||
(Unlikely, Cry-If-Not) -> Mayhapsibly
|
|
||||||
(Unlikely, Most-Likely) -> Mayhapsibly
|
|
||||||
(Unlikely, _) -> Probably
|
|
||||||
(Mayhapsibly, Guaranteed) -> Mayhapsibly
|
|
||||||
(Mayhapsibly, Cry-If-Not) -> Mayhapsibly
|
|
||||||
(Mayhapsibly, Most-Likely) -> Mayhapsibly
|
|
||||||
(Mayhapsibly, _) -> Probably
|
|
||||||
(Probably, Guaranteed) -> Unlikely
|
|
||||||
(Probably, Cry-If-Not) -> Unlikely
|
|
||||||
(Probably, Most-Likely) -> Unlikely
|
|
||||||
(Probably, _) -> Mayhapsibly
|
|
||||||
(Most-Likely, _) -> Doubtful
|
|
||||||
(Cry-If-Not, _) -> Probably-Not
|
|
||||||
(Guaranteed, _) -> Impossible
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
module horse/prob/pmf
|
|
||||||
|
|
||||||
import std/core/list
|
|
||||||
|
|
||||||
// Discrete-support probability distribution implemented as a list with the invariant
|
|
||||||
// that support is always given in increasing order.
|
|
||||||
pub type pmf<s, v>
|
|
||||||
Event(s: s, v: v, next: pmf<s, v>)
|
|
||||||
End
|
|
||||||
|
|
||||||
// Add an independent event to the distribution.
|
|
||||||
pub fun add(p: pmf<s, v>, s: s, v: v, ?s/cmp: (a: s, b: s) -> order, ?v/(+): (new: v, old: v) -> e v): e pmf<s, v>
|
|
||||||
match p
|
|
||||||
End -> Event(s, v, End)
|
|
||||||
Event(s', v', next) -> match s.cmp(s')
|
|
||||||
Lt -> Event(s, v, Event(s', v', next))
|
|
||||||
Eq -> Event(s, v + v', next)
|
|
||||||
Gt -> Event(s', v', add(next, s, v))
|
|
||||||
|
|
||||||
// Replace an event in the distribution.
|
|
||||||
pub inline fun set(p: pmf<s, v>, s: s, v: v, ?s/cmp: (a: s, b: s) -> order): e pmf<s, v>
|
|
||||||
p.add(s, v, cmp, fn(new, old) new)
|
|
||||||
|
|
||||||
// Construct a pmf from a list of (support, value) entries.
|
|
||||||
pub fun list/pmf(l: list<(s, v)>, ?s/cmp: (a: s, b: s) -> order, ?v/(+): (new: v, old: v) -> e v): e pmf<s, v>
|
|
||||||
l.foldl(End) fn(p, (s, v)) p.add(s, v)
|
|
||||||
|
|
||||||
// Fold over the entries of the distribution.
|
|
||||||
pub tail fun foldl(p: pmf<s, v>, init: a, f: (a, s, v) -> e a): e a
|
|
||||||
match p
|
|
||||||
End -> init
|
|
||||||
Event(s, v, next) -> foldl(next, f(init, s, v), f)
|
|
||||||
|
|
||||||
// Convert the distribution to a list of entries.
|
|
||||||
pub fun pmf/list(p: pmf<s, v>): list<(s, v)>
|
|
||||||
p.foldl(Nil) fn(l, s, v) Cons((s, v), l)
|
|
||||||
|
|
||||||
// Distribution of cooccurrence of two events described by their distributions.
|
|
||||||
pub fun (*)(a: pmf<s, v>, b: pmf<s, v>, ?s/cmp: (a: s, b: s) -> order, ?v/(*): (a: v, b: v) -> e v): e pmf<s, v>
|
|
||||||
match a
|
|
||||||
End -> End
|
|
||||||
Event(sa, va, nexta) -> match b
|
|
||||||
End -> End
|
|
||||||
Event(sb, vb, nextb) -> match sa.cmp(sb)
|
|
||||||
Lt -> nexta * b
|
|
||||||
Eq -> Event(sa, va * vb, nexta * nextb)
|
|
||||||
Gt -> a * nextb
|
|
||||||
|
|
||||||
// Distribution of occurrence of at least one of two events described by their distributions.
|
|
||||||
pub fun (+)(a: pmf<s, v>, b: pmf<s, v>, ?s/cmp: (a: s, b: s) -> order, ?v/(+): (a: v, b: v) -> e v): e pmf<s, v>
|
|
||||||
match a
|
|
||||||
End -> b
|
|
||||||
Event(sa, va, nexta) -> match b
|
|
||||||
End -> a
|
|
||||||
Event(sb, vb, nextb) -> match sa.cmp(sb)
|
|
||||||
Lt -> Event(sa, va, nexta + b)
|
|
||||||
Eq -> Event(sa, va + vb, nexta + nextb)
|
|
||||||
Gt -> Event(sb, vb, a + nextb)
|
|
||||||
301
horse/race.kk
301
horse/race.kk
@@ -1,301 +0,0 @@
|
|||||||
module horse/race
|
|
||||||
|
|
||||||
import std/data/linearset
|
|
||||||
import horse/game-id
|
|
||||||
|
|
||||||
pub struct race-detail
|
|
||||||
race-id: race-id
|
|
||||||
name: string
|
|
||||||
grade: grade
|
|
||||||
thumbnail-id: race-thumbnail-id
|
|
||||||
// Some careers contain unusual versions of races, e.g. Tenno Sho (Spring)
|
|
||||||
// in Hanshin instead of Kyoto for Narita Taishin and Biwa Hayahide.
|
|
||||||
// For such races, this field holds the normal race ID.
|
|
||||||
primary: race-id
|
|
||||||
|
|
||||||
pub fun detail(
|
|
||||||
r: race-id,
|
|
||||||
?race/show: (race-id) -> string,
|
|
||||||
?race/grade: (race-id) -> grade,
|
|
||||||
?race/thumbnail: (race-id) -> race-thumbnail-id,
|
|
||||||
?race/primary: (race-id) -> race-id
|
|
||||||
): race-detail
|
|
||||||
Race-detail(r, r.show, r.grade, r.thumbnail, r.primary)
|
|
||||||
|
|
||||||
pub fun race-detail/show(r: race-detail): string
|
|
||||||
val Race-detail(Race-id(id), name) = r
|
|
||||||
name ++ " (ID " ++ id.show ++ ")"
|
|
||||||
|
|
||||||
// Race grades.
|
|
||||||
pub type grade
|
|
||||||
Pre-OP
|
|
||||||
OP
|
|
||||||
G3
|
|
||||||
G2
|
|
||||||
G1
|
|
||||||
EX
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Comparison of the `grade` type.
|
|
||||||
pub fun grade/cmp(this : grade, other : grade) : e order
|
|
||||||
match (this, other)
|
|
||||||
(Pre-OP, Pre-OP) -> Eq
|
|
||||||
(Pre-OP, _) -> Lt
|
|
||||||
(_, Pre-OP) -> Gt
|
|
||||||
(OP, OP) -> Eq
|
|
||||||
(OP, _) -> Lt
|
|
||||||
(_, OP) -> Gt
|
|
||||||
(G3, G3) -> Eq
|
|
||||||
(G3, _) -> Lt
|
|
||||||
(_, G3) -> Gt
|
|
||||||
(G2, G2) -> Eq
|
|
||||||
(G2, _) -> Lt
|
|
||||||
(_, G2) -> Gt
|
|
||||||
(G1, G1) -> Eq
|
|
||||||
(G1, _) -> Lt
|
|
||||||
(_, G1) -> Gt
|
|
||||||
(EX, EX) -> Eq
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Shows a string representation of the `grade` type.
|
|
||||||
pub fun grade/show(this : grade) : e string
|
|
||||||
match this
|
|
||||||
Pre-OP -> "Pre-OP"
|
|
||||||
OP -> "OP"
|
|
||||||
G3 -> "G3"
|
|
||||||
G2 -> "G2"
|
|
||||||
G1 -> "G1"
|
|
||||||
EX -> "EX"
|
|
||||||
|
|
||||||
pub struct saddle-detail
|
|
||||||
saddle-id: saddle-id
|
|
||||||
name: string
|
|
||||||
races: list<race-id>
|
|
||||||
saddle-type: saddle-type
|
|
||||||
// For careers with unusual races, granted saddles also differ.
|
|
||||||
// This field holds the normal saddle's ID for such cases.
|
|
||||||
primary: saddle-id
|
|
||||||
|
|
||||||
pub fun saddle/detail(
|
|
||||||
id: saddle-id,
|
|
||||||
?saddle/show: (saddle-id) -> string,
|
|
||||||
?saddle/races: (saddle-id) -> list<race-id>,
|
|
||||||
?saddle/saddle-type: (saddle-id) -> saddle-type,
|
|
||||||
?saddle/primary: (saddle-id) -> saddle-id
|
|
||||||
): saddle-detail
|
|
||||||
Saddle-detail(id, id.show, id.races, id.saddle-type, id.primary)
|
|
||||||
|
|
||||||
pub fun saddle-detail/show(s: saddle-detail): string
|
|
||||||
val Saddle-detail(Saddle-id(id), name, _, _, Saddle-id(primary)) = s
|
|
||||||
if id == primary then name else name ++ " (Alternate " ++ id.show ++ ")"
|
|
||||||
|
|
||||||
// Types of saddles.
|
|
||||||
pub type saddle-type
|
|
||||||
Honor // multiple race wins: classic triple crown, dual grand prix, &c.
|
|
||||||
G3-Win
|
|
||||||
G2-Win
|
|
||||||
G1-Win
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Shows a string representation of the `saddle-type` type.
|
|
||||||
pub fun saddle-type/show(this : saddle-type) : e string
|
|
||||||
match this
|
|
||||||
Honor -> "Honor"
|
|
||||||
G3-Win -> "G3"
|
|
||||||
G2-Win -> "G2"
|
|
||||||
G1-Win -> "G1"
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Equality comparison of the `saddle-type` type.
|
|
||||||
pub fun saddle-type/(==)(this : saddle-type, other : saddle-type) : e bool
|
|
||||||
match (this, other)
|
|
||||||
(Honor, Honor) -> True
|
|
||||||
(G3-Win, G3-Win) -> True
|
|
||||||
(G2-Win, G2-Win) -> True
|
|
||||||
(G1-Win, G1-Win) -> True
|
|
||||||
(_, _) -> False
|
|
||||||
|
|
||||||
// Turn that a race occurred.
|
|
||||||
pub struct turn
|
|
||||||
year: turn-year
|
|
||||||
month: turn-month
|
|
||||||
half: turn-half
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Equality comparison of the `turn` type.
|
|
||||||
pub fun turn/(==)(this : turn, other : turn) : e bool
|
|
||||||
match (this, other)
|
|
||||||
(Turn(year, month, half), Turn(year', month', half')) -> year == year' && month == month' && half == half'
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Fip comparison of the `turn` type.
|
|
||||||
pub fun turn/order2(this : turn, other : turn) : e order2<turn>
|
|
||||||
match (this, other)
|
|
||||||
(Turn(year, month, half), Turn(year', month', half')) ->
|
|
||||||
match year.order2(year')
|
|
||||||
Eq2(year_eq) ->
|
|
||||||
match month.order2(month')
|
|
||||||
Eq2(month_eq) ->
|
|
||||||
match half.order2(half')
|
|
||||||
Eq2(half_eq) -> Eq2(Turn(year_eq, month_eq, half_eq))
|
|
||||||
Lt2(half_lt, half_gt) -> Lt2(Turn(year_eq, month_eq, half_lt), Turn(year_eq, month_eq, half_gt))
|
|
||||||
Gt2(half_lt, half_gt) -> Gt2(Turn(year_eq, month_eq, half_lt), Turn(year_eq, month_eq, half_gt))
|
|
||||||
Lt2(month_lt, month_gt) -> Lt2(Turn(year_eq, month_lt, half), Turn(year_eq, month_gt, half'))
|
|
||||||
Gt2(month_lt, month_gt) -> Gt2(Turn(year_eq, month_lt, half'), Turn(year_eq, month_gt, half))
|
|
||||||
Lt2(year_lt, year_gt) -> Lt2(Turn(year_lt, month, half), Turn(year_gt, month', half'))
|
|
||||||
Gt2(year_lt, year_gt) -> Gt2(Turn(year_lt, month', half'), Turn(year_gt, month, half))
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Shows a string representation of the `turn` type.
|
|
||||||
pub fun turn/show(this : turn) : e string
|
|
||||||
this.year.show ++ " " ++ this.half.show ++ " " ++ this.month.show
|
|
||||||
|
|
||||||
pub type turn-year
|
|
||||||
Junior
|
|
||||||
Classic
|
|
||||||
Senior
|
|
||||||
Finale
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Equality comparison of the `turn-year` type.
|
|
||||||
pub fun turn-year/(==)(this : turn-year, other : turn-year) : e bool
|
|
||||||
match (this, other)
|
|
||||||
(Junior, Junior) -> True
|
|
||||||
(Classic, Classic) -> True
|
|
||||||
(Senior, Senior) -> True
|
|
||||||
(Finale, Finale) -> True
|
|
||||||
(_, _) -> False
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Fip comparison of the `turn-year` type.
|
|
||||||
pub fun turn-year/order2(this : turn-year, other : turn-year) : e order2<turn-year>
|
|
||||||
match (this, other)
|
|
||||||
(Junior, Junior) -> Eq2(Junior)
|
|
||||||
(Junior, other') -> Lt2(Junior, other')
|
|
||||||
(this', Junior) -> Gt2(Junior, this')
|
|
||||||
(Classic, Classic) -> Eq2(Classic)
|
|
||||||
(Classic, other') -> Lt2(Classic, other')
|
|
||||||
(this', Classic) -> Gt2(Classic, this')
|
|
||||||
(Senior, Senior) -> Eq2(Senior)
|
|
||||||
(Senior, other') -> Lt2(Senior, other')
|
|
||||||
(this', Senior) -> Gt2(Senior, this')
|
|
||||||
(Finale, Finale) -> Eq2(Finale)
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Shows a string representation of the `turn-year` type.
|
|
||||||
pub fun turn-year/show(this : turn-year) : e string
|
|
||||||
match this
|
|
||||||
Junior -> "Junior Year"
|
|
||||||
Classic -> "Classic Year"
|
|
||||||
Senior -> "Senior Year"
|
|
||||||
Finale -> "Finale 1" // the 1 is in the game
|
|
||||||
|
|
||||||
pub type turn-month
|
|
||||||
January
|
|
||||||
February
|
|
||||||
March
|
|
||||||
April
|
|
||||||
May
|
|
||||||
June
|
|
||||||
July
|
|
||||||
August
|
|
||||||
September
|
|
||||||
November
|
|
||||||
December
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Equality comparison of the `turn-month` type.
|
|
||||||
pub fun turn-month/(==)(this : turn-month, other : turn-month) : e bool
|
|
||||||
match (this, other)
|
|
||||||
(January, January) -> True
|
|
||||||
(February, February) -> True
|
|
||||||
(March, March) -> True
|
|
||||||
(April, April) -> True
|
|
||||||
(May, May) -> True
|
|
||||||
(June, June) -> True
|
|
||||||
(July, July) -> True
|
|
||||||
(August, August) -> True
|
|
||||||
(September, September) -> True
|
|
||||||
(November, November) -> True
|
|
||||||
(December, December) -> True
|
|
||||||
(_, _) -> False
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Fip comparison of the `turn-month` type.
|
|
||||||
pub fun turn-month/order2(this : turn-month, other : turn-month) : e order2<turn-month>
|
|
||||||
match (this, other)
|
|
||||||
(January, January) -> Eq2(January)
|
|
||||||
(January, other') -> Lt2(January, other')
|
|
||||||
(this', January) -> Gt2(January, this')
|
|
||||||
(February, February) -> Eq2(February)
|
|
||||||
(February, other') -> Lt2(February, other')
|
|
||||||
(this', February) -> Gt2(February, this')
|
|
||||||
(March, March) -> Eq2(March)
|
|
||||||
(March, other') -> Lt2(March, other')
|
|
||||||
(this', March) -> Gt2(March, this')
|
|
||||||
(April, April) -> Eq2(April)
|
|
||||||
(April, other') -> Lt2(April, other')
|
|
||||||
(this', April) -> Gt2(April, this')
|
|
||||||
(May, May) -> Eq2(May)
|
|
||||||
(May, other') -> Lt2(May, other')
|
|
||||||
(this', May) -> Gt2(May, this')
|
|
||||||
(June, June) -> Eq2(June)
|
|
||||||
(June, other') -> Lt2(June, other')
|
|
||||||
(this', June) -> Gt2(June, this')
|
|
||||||
(July, July) -> Eq2(July)
|
|
||||||
(July, other') -> Lt2(July, other')
|
|
||||||
(this', July) -> Gt2(July, this')
|
|
||||||
(August, August) -> Eq2(August)
|
|
||||||
(August, other') -> Lt2(August, other')
|
|
||||||
(this', August) -> Gt2(August, this')
|
|
||||||
(September, September) -> Eq2(September)
|
|
||||||
(September, other') -> Lt2(September, other')
|
|
||||||
(this', September) -> Gt2(September, this')
|
|
||||||
(November, November) -> Eq2(November)
|
|
||||||
(November, other') -> Lt2(November, other')
|
|
||||||
(this', November) -> Gt2(November, this')
|
|
||||||
(December, December) -> Eq2(December)
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Shows a string representation of the `turn-month` type.
|
|
||||||
pub fun turn-month/show(this : turn-month) : e string
|
|
||||||
match this
|
|
||||||
January -> "January"
|
|
||||||
February -> "February"
|
|
||||||
March -> "March"
|
|
||||||
April -> "April"
|
|
||||||
May -> "May"
|
|
||||||
June -> "June"
|
|
||||||
July -> "July"
|
|
||||||
August -> "August"
|
|
||||||
September -> "September"
|
|
||||||
November -> "November"
|
|
||||||
December -> "December"
|
|
||||||
|
|
||||||
pub type turn-half
|
|
||||||
Early
|
|
||||||
Late
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Equality comparison of the `turn-half` type.
|
|
||||||
pub fun turn-half/(==)(this : turn-half, other : turn-half) : e bool
|
|
||||||
match (this, other)
|
|
||||||
(Early, Early) -> True
|
|
||||||
(Late, Late) -> True
|
|
||||||
(_, _) -> False
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Fip comparison of the `turn-half` type.
|
|
||||||
pub fun turn-half/order2(this : turn-half, other : turn-half) : e order2<turn-half>
|
|
||||||
match (this, other)
|
|
||||||
(Early, Early) -> Eq2(Early)
|
|
||||||
(Early, other') -> Lt2(Early, other')
|
|
||||||
(this', Early) -> Gt2(Early, this')
|
|
||||||
(Late, Late) -> Eq2(Late)
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Shows a string representation of the `turn-half` type.
|
|
||||||
pub fun turn-half/show(this : turn-half) : e string
|
|
||||||
match this
|
|
||||||
Early -> "Early"
|
|
||||||
Late -> "Late"
|
|
||||||
249
horse/skill.kk
249
horse/skill.kk
@@ -1,249 +0,0 @@
|
|||||||
module horse/skill
|
|
||||||
|
|
||||||
// This module contains skill-related definitions
|
|
||||||
// common to all versions of the game.
|
|
||||||
|
|
||||||
import std/num/decimal
|
|
||||||
import horse/game-id
|
|
||||||
import horse/movement
|
|
||||||
|
|
||||||
// Full details about a skill.
|
|
||||||
pub struct skill-detail
|
|
||||||
skill-id: skill-id
|
|
||||||
name: string
|
|
||||||
description: string
|
|
||||||
group-id: skill-group-id
|
|
||||||
rarity: rarity
|
|
||||||
group-rate: int
|
|
||||||
grade-value: int
|
|
||||||
wit-check: bool
|
|
||||||
activations: list<activation>
|
|
||||||
owner: maybe<uma-id>
|
|
||||||
sp-cost: int
|
|
||||||
icon-id: skill-icon-id
|
|
||||||
|
|
||||||
pub fun detail(
|
|
||||||
s: skill-id,
|
|
||||||
?skill/show: (skill-id) -> string,
|
|
||||||
?skill/description: (skill-id) -> string,
|
|
||||||
?skill/group: (skill-id) -> skill-group-id,
|
|
||||||
?skill/rarity: (skill-id) -> rarity,
|
|
||||||
?skill/group-rate: (skill-id) -> int,
|
|
||||||
?skill/grade-value: (skill-id) -> int,
|
|
||||||
?skill/wit-check: (skill-id) -> bool,
|
|
||||||
?skill/activations: (skill-id) -> list<activation>,
|
|
||||||
?skill/unique-owner: (skill-id) -> maybe<uma-id>,
|
|
||||||
?skill/sp-cost: (skill-id) -> int,
|
|
||||||
?skill/icon-id: (skill-id) -> skill-icon-id
|
|
||||||
): skill-detail
|
|
||||||
Skill-detail(
|
|
||||||
s,
|
|
||||||
s.show,
|
|
||||||
s.description,
|
|
||||||
s.group,
|
|
||||||
s.rarity,
|
|
||||||
s.group-rate,
|
|
||||||
s.grade-value,
|
|
||||||
s.wit-check,
|
|
||||||
s.activations,
|
|
||||||
s.unique-owner,
|
|
||||||
s.sp-cost,
|
|
||||||
s.icon-id
|
|
||||||
)
|
|
||||||
|
|
||||||
pub fun skill-detail/show(d: skill-detail, ?character/show: (character-id) -> string, ?uma/show: (uma-id) -> string): string
|
|
||||||
val Skill-detail(Skill-id(id), name, desc, _, rarity, _, grade-value, wit-check, activations, owner, sp-cost, _) = d
|
|
||||||
val r = name ++ " (ID " ++ id.show ++ "): " ++ desc ++ " " ++ activations.map(activation/show).join(". ") ++ (if wit-check then ". Wit check. " else ". No wit check. ") ++ rarity.show ++ " costing " ++ sp-cost.show ++ " SP, worth " ++ grade-value.show ++ " grade value."
|
|
||||||
match owner
|
|
||||||
Nothing -> r
|
|
||||||
Just(owner-id) -> match owner-id.show
|
|
||||||
"" -> r ++ " Unique skill of Uma with ID " ++ owner-id.show ++ "."
|
|
||||||
owner-name -> r ++ " Unique skill of " ++ owner-name ++ "."
|
|
||||||
|
|
||||||
// Skill rarity levels.
|
|
||||||
pub type rarity
|
|
||||||
Common // white
|
|
||||||
Rare // gold
|
|
||||||
Unique-Low // 1*/2* unique
|
|
||||||
Unique-Upgraded // 3*+ unique on a trainee upgraded from 1*/2*
|
|
||||||
Unique // base 3* unique
|
|
||||||
|
|
||||||
pub fun rarity/show(r: rarity): string
|
|
||||||
match r
|
|
||||||
Common -> "Common"
|
|
||||||
Rare -> "Rare"
|
|
||||||
Unique-Low -> "Unique (1\u2606/2\u2606)"
|
|
||||||
Unique-Upgraded -> "Unique (3\u2606+ from 1\u2606/2\u2606 upgraded)"
|
|
||||||
Unique -> "Unique (3\u2606+)"
|
|
||||||
|
|
||||||
// Condition and precondition logic.
|
|
||||||
pub alias condition = string
|
|
||||||
|
|
||||||
// Activation conditions and effects.
|
|
||||||
// A skill has one or two activations.
|
|
||||||
pub struct activation
|
|
||||||
precondition: condition
|
|
||||||
condition: condition
|
|
||||||
duration: decimal // seconds
|
|
||||||
dur-scale: dur-scale
|
|
||||||
cooldown: decimal // seconds
|
|
||||||
abilities: list<ability> // one to three elements
|
|
||||||
|
|
||||||
pub fun activation/show(a: activation, ?character/show: (character-id) -> string): string
|
|
||||||
match a
|
|
||||||
Activation("", condition, duration, _, _, abilities) | !duration.is-pos -> condition ++ " -> " ++ abilities.show
|
|
||||||
Activation("", condition, duration, Direct-Dur, cooldown, abilities) | cooldown >= 500.decimal -> condition ++ " -> for " ++ duration.show ++ "s, " ++ abilities.show
|
|
||||||
Activation("", condition, duration, dur-scale, cooldown, abilities) | cooldown >= 500.decimal -> condition ++ " -> for " ++ duration.show ++ "s " ++ dur-scale.show ++ ", " ++ abilities.show
|
|
||||||
Activation("", condition, duration, Direct-Dur, cooldown, abilities) -> condition ++ " -> for " ++ duration.show ++ "s on " ++ cooldown.show ++ "s cooldown, " ++ abilities.show
|
|
||||||
Activation("", condition, duration, dur-scale, cooldown, abilities) -> condition ++ " -> for " ++ duration.show ++ "s " ++ dur-scale.show ++ " on " ++ cooldown.show ++ "s cooldown, " ++ abilities.show
|
|
||||||
Activation(precondition, condition, duration, _, _, abilities) | !duration.is-pos -> precondition ++ " -> " ++ condition ++ " -> " ++ abilities.show
|
|
||||||
Activation(precondition, condition, duration, Direct-Dur, cooldown, abilities) | cooldown >= 500.decimal -> precondition ++ " -> " ++ condition ++ " -> for " ++ duration.show ++ "s, " ++ abilities.show
|
|
||||||
Activation(precondition, condition, duration, dur-scale, cooldown, abilities) | cooldown >= 500.decimal -> precondition ++ " -> " ++ condition ++ " -> for " ++ duration.show ++ "s " ++ dur-scale.show ++ ", " ++ abilities.show
|
|
||||||
Activation(precondition, condition, duration, Direct-Dur, cooldown, abilities) -> precondition ++ " -> " ++ condition ++ " -> for " ++ duration.show ++ "s on " ++ cooldown.show ++ "s cooldown, " ++ abilities.show
|
|
||||||
Activation(precondition, condition, duration, dur-scale, cooldown, abilities) -> precondition ++ " -> " ++ condition ++ " -> for " ++ duration.show ++ "s " ++ dur-scale.show ++ " on " ++ cooldown.show ++ "s cooldown, " ++ abilities.show
|
|
||||||
|
|
||||||
// Special scaling types for skill activation durations.
|
|
||||||
pub type dur-scale
|
|
||||||
Direct-Dur
|
|
||||||
Front-Distance-Dur
|
|
||||||
Multiply-Remaining-HP
|
|
||||||
Increment-Pass
|
|
||||||
Midrace-Side-Block-Time-Dur
|
|
||||||
Multiply-Remaining-HP2
|
|
||||||
|
|
||||||
pub fun dur-scale/show(s: dur-scale): string
|
|
||||||
match s
|
|
||||||
Direct-Dur -> "with no scaling"
|
|
||||||
Front-Distance-Dur -> "scaling with distance from the front"
|
|
||||||
Multiply-Remaining-HP -> "scaling with remaining HP"
|
|
||||||
Increment-Pass -> "increasing with each pass while active"
|
|
||||||
Midrace-Side-Block-Time-Dur -> "scaling with mid-race phase blocked side time"
|
|
||||||
Multiply-Remaining-HP2 -> "scaling with remaining HP"
|
|
||||||
|
|
||||||
// Effects of activating a skill.
|
|
||||||
pub struct ability
|
|
||||||
ability-type: ability-type
|
|
||||||
value-usage: value-usage
|
|
||||||
target: target
|
|
||||||
|
|
||||||
pub fun ability/show(a: ability, ?character/show: (character-id) -> string): string
|
|
||||||
match a
|
|
||||||
Ability(t, Direct, Self) -> t.show
|
|
||||||
Ability(t, Direct, target) -> t.show ++ " " ++ target.show
|
|
||||||
Ability(t, v, Self) -> t.show ++ " " ++ v.show
|
|
||||||
Ability(t, v, target) -> t.show ++ " " ++ target.show ++ " " ++ v.show
|
|
||||||
|
|
||||||
// Skill ability effects.
|
|
||||||
pub type ability-type
|
|
||||||
Passive-Speed(bonus: decimal)
|
|
||||||
Passive-Stamina(bonus: decimal)
|
|
||||||
Passive-Power(bonus: decimal)
|
|
||||||
Passive-Guts(bonus: decimal)
|
|
||||||
Passive-Wit(bonus: decimal)
|
|
||||||
Great-Escape
|
|
||||||
Vision(bonus: decimal)
|
|
||||||
HP(rate: decimal)
|
|
||||||
Gate-Delay(rate: decimal)
|
|
||||||
Frenzy(add: decimal)
|
|
||||||
Current-Speed(add: decimal)
|
|
||||||
Target-Speed(add: decimal)
|
|
||||||
Lane-Speed(add: decimal)
|
|
||||||
Accel(add: decimal)
|
|
||||||
Lane-Change(add: decimal)
|
|
||||||
|
|
||||||
pub fun ability-type/show(a: ability-type): string
|
|
||||||
match a
|
|
||||||
Passive-Speed(bonus) -> bonus.show ++ " Speed"
|
|
||||||
Passive-Stamina(bonus) -> bonus.show ++ " Stamina"
|
|
||||||
Passive-Power(bonus) -> bonus.show ++ " Power"
|
|
||||||
Passive-Guts(bonus) -> bonus.show ++ " Guts"
|
|
||||||
Passive-Wit(bonus) -> bonus.show ++ " Wit"
|
|
||||||
Great-Escape -> "enable Great Escape style"
|
|
||||||
Vision(bonus) -> bonus.show ++ " vision"
|
|
||||||
HP(rate) | rate.is-pos -> show(rate * 100.decimal) ++ "% HP recovery"
|
|
||||||
HP(rate) -> show(rate * 100.decimal) ++ "% HP loss"
|
|
||||||
Gate-Delay(rate) -> rate.show ++ "× gate delay"
|
|
||||||
Frenzy(add) -> add.show ++ "s longer Rushed"
|
|
||||||
Current-Speed(rate) -> rate.show ++ "m/s current speed"
|
|
||||||
Target-Speed(rate) -> rate.show ++ "m/s target speed"
|
|
||||||
Lane-Speed(rate) -> rate.show ++ "m/s lane change speed"
|
|
||||||
Accel(rate) -> rate.show ++ "m/s² acceleration"
|
|
||||||
Lane-Change(rate) -> rate.show ++ " course width movement"
|
|
||||||
|
|
||||||
// Special scaling types for skill abilities.
|
|
||||||
pub type value-usage
|
|
||||||
Direct
|
|
||||||
Team-Speed
|
|
||||||
Team-Stamina
|
|
||||||
Team-Power
|
|
||||||
Team-Guts
|
|
||||||
Team-Wit
|
|
||||||
Multiply-Random
|
|
||||||
Multiply-Random2
|
|
||||||
Climax
|
|
||||||
Max-Stat
|
|
||||||
Passive-Count
|
|
||||||
Front-Distance-Add
|
|
||||||
Midrace-Side-Block-Time
|
|
||||||
Speed-Scaling
|
|
||||||
Speed-Scaling2
|
|
||||||
Arc-Global-Potential
|
|
||||||
Max-Lead-Distance
|
|
||||||
|
|
||||||
pub fun value-usage/show(v: value-usage): string
|
|
||||||
match v
|
|
||||||
Direct -> "with no scaling"
|
|
||||||
Team-Speed -> "scaling with team Speed"
|
|
||||||
Team-Stamina -> "scaling with team Stamina"
|
|
||||||
Team-Power -> "scaling with team Power"
|
|
||||||
Team-Guts -> "scaling with team Guts"
|
|
||||||
Team-Wit -> "scaling with team Wit"
|
|
||||||
Multiply-Random -> "scaling with a random multiplier (0×, 0.02×, or 0.04×)"
|
|
||||||
Multiply-Random2 -> "scaling with a random multiplier (0×, 0.02×, or 0.04×)"
|
|
||||||
Climax -> "scaling with the number of races won during training"
|
|
||||||
Max-Stat -> "scaling with the value of the user's highest stat"
|
|
||||||
Passive-Count -> "scaling with the number of Passive skills activated"
|
|
||||||
Front-Distance-Add -> "scaling with distance from the leader"
|
|
||||||
Midrace-Side-Block-Time -> "scaling with mid-race phase blocked side time"
|
|
||||||
Speed-Scaling -> "scaling with overall speed"
|
|
||||||
Speed-Scaling2 -> "scaling with overall speed"
|
|
||||||
Arc-Global-Potential -> "scaling with L'Arc global potential"
|
|
||||||
Max-Lead-Distance -> "scaling with the distance of the longest lead obtained in the first two thirds of the race"
|
|
||||||
|
|
||||||
// Who a skill ability targets.
|
|
||||||
pub type target
|
|
||||||
Self
|
|
||||||
Sympathizers
|
|
||||||
In-View
|
|
||||||
Frontmost(limit: int)
|
|
||||||
Ahead(limit: int)
|
|
||||||
Behind(limit: int)
|
|
||||||
All-Teammates
|
|
||||||
Style(style: style)
|
|
||||||
Rushing-Ahead(limit: int)
|
|
||||||
Rushing-Behind(limit: int)
|
|
||||||
Rushing-Style(style: style)
|
|
||||||
Specific-Character(who: character-id)
|
|
||||||
Triggering
|
|
||||||
|
|
||||||
pub fun target/show(t: target, ?character/show: (character-id) -> string): string
|
|
||||||
match t
|
|
||||||
Self -> "self"
|
|
||||||
Sympathizers -> "others with Sympathy"
|
|
||||||
In-View -> "others in field of view"
|
|
||||||
Frontmost(limit) -> "frontmost " ++ limit.show
|
|
||||||
Ahead(limit) | limit >= 18 -> "others ahead"
|
|
||||||
Ahead(limit) -> "next " ++ limit.show ++ " others ahead"
|
|
||||||
Behind(limit) | limit >= 18 -> "others behind"
|
|
||||||
Behind(limit) -> "next " ++ limit.show ++ " others behind"
|
|
||||||
All-Teammates -> "all teammates"
|
|
||||||
Style(s) -> "other " ++ s.show ++ "s"
|
|
||||||
Rushing-Ahead(limit) | limit >= 18 -> "others rushing ahead"
|
|
||||||
Rushing-Ahead(limit) -> "next " ++ limit.show ++ " others rushing ahead"
|
|
||||||
Rushing-Behind(limit) | limit >= 18 -> "others rushing behind"
|
|
||||||
Rushing-Behind(limit) -> "next " ++ limit.show ++ " others rushing behind"
|
|
||||||
Rushing-Style(s) -> "rushing " ++ s.show ++ "s"
|
|
||||||
Specific-Character(who) -> match who.show
|
|
||||||
"" -> "character with ID " ++ who.show
|
|
||||||
name -> name
|
|
||||||
Triggering -> "whosoever triggered this skill"
|
|
||||||
175
horse/spark.kk
175
horse/spark.kk
@@ -1,175 +0,0 @@
|
|||||||
module horse/spark
|
|
||||||
|
|
||||||
import std/num/decimal
|
|
||||||
import horse/game-id
|
|
||||||
import horse/movement
|
|
||||||
|
|
||||||
// A spark on a veteran.
|
|
||||||
pub struct spark-detail
|
|
||||||
spark-id: spark-id
|
|
||||||
typ: spark-type
|
|
||||||
rarity: rarity
|
|
||||||
|
|
||||||
pub fun detail(id: spark-id, ?spark/spark-type: (spark-id) -> spark-type, ?spark/rarity: (spark-id) -> rarity): spark-detail
|
|
||||||
Spark-detail(id, id.spark-type, id.rarity)
|
|
||||||
|
|
||||||
pub fun spark-detail/show(s: spark-detail, ?spark/show: (spark-id) -> string): string
|
|
||||||
s.spark-id.show ++ " " ++ "\u2605".repeat(s.rarity.int)
|
|
||||||
|
|
||||||
// The category of a spark; roughly, blue, pink, green, or white, with some
|
|
||||||
// further subdivisions.
|
|
||||||
pub type spark-type
|
|
||||||
Stat // blue
|
|
||||||
Aptitude // red/pink
|
|
||||||
Unique // green
|
|
||||||
Race
|
|
||||||
Skill
|
|
||||||
// skip Carnival Bonus
|
|
||||||
Scenario
|
|
||||||
Surface
|
|
||||||
Distance
|
|
||||||
Style
|
|
||||||
Hidden
|
|
||||||
|
|
||||||
// Spark targets and effects.
|
|
||||||
pub type spark-effect
|
|
||||||
Stat-Up(s: stat, amount: int)
|
|
||||||
SP-Up(amount: int)
|
|
||||||
// skip Carnival Bonus
|
|
||||||
Random-Stat-Up(amount: int)
|
|
||||||
Aptitude-Up(a: aptitude, amount: int)
|
|
||||||
Skill-Hint(s: skill-id, levels: int)
|
|
||||||
Stat-Cap-Up(s: stat, amount: int)
|
|
||||||
|
|
||||||
// Get the base probability for a spark to trigger during a single inheritance.
|
|
||||||
pub fun decimal/base-proc(id: spark-id, ?spark-type: (spark-id) -> spark-type, ?rarity: (spark-id) -> rarity): decimal
|
|
||||||
val t = id.spark-type
|
|
||||||
val r = id.rarity
|
|
||||||
match (t, r)
|
|
||||||
(Stat, One) -> 70.decimal(-2)
|
|
||||||
(Stat, Two) -> 80.decimal(-2)
|
|
||||||
(Stat, Three) -> 90.decimal(-2)
|
|
||||||
(Aptitude, One) -> 1.decimal(-2)
|
|
||||||
(Aptitude, Two) -> 3.decimal(-2)
|
|
||||||
(Aptitude, Three) -> 5.decimal(-2)
|
|
||||||
(Unique, One) -> 5.decimal(-2)
|
|
||||||
(Unique, Two) -> 10.decimal(-2)
|
|
||||||
(Unique, Three) -> 15.decimal(-2)
|
|
||||||
(Race, One) -> 1.decimal(-2)
|
|
||||||
(Race, Two) -> 2.decimal(-2)
|
|
||||||
(Race, Three) -> 3.decimal(-2)
|
|
||||||
(_, One) -> 3.decimal(-2)
|
|
||||||
(_, Two) -> 6.decimal(-2)
|
|
||||||
(_, Three) -> 9.decimal(-2)
|
|
||||||
|
|
||||||
// The level or star count of a spark.
|
|
||||||
pub type rarity
|
|
||||||
One
|
|
||||||
Two
|
|
||||||
Three
|
|
||||||
|
|
||||||
pub fun rarity/int(l: rarity): int
|
|
||||||
match l
|
|
||||||
One -> 1
|
|
||||||
Two -> 2
|
|
||||||
Three -> 3
|
|
||||||
|
|
||||||
pub fun rarity/show(l: rarity): string
|
|
||||||
match l
|
|
||||||
One -> "1"
|
|
||||||
Two -> "2"
|
|
||||||
Three -> "3"
|
|
||||||
|
|
||||||
// Stat (blue) spark.
|
|
||||||
pub type stat
|
|
||||||
Speed
|
|
||||||
Stamina
|
|
||||||
Power
|
|
||||||
Guts
|
|
||||||
Wit
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Shows a string representation of the `stat` type.
|
|
||||||
pub fun stat/show(this : stat) : e string
|
|
||||||
match this
|
|
||||||
Speed -> "Speed"
|
|
||||||
Stamina -> "Stamina"
|
|
||||||
Power -> "Power"
|
|
||||||
Guts -> "Guts"
|
|
||||||
Wit -> "Wit"
|
|
||||||
|
|
||||||
// Aptitude (red/pink) spark.
|
|
||||||
pub type aptitude
|
|
||||||
Turf
|
|
||||||
Dirt
|
|
||||||
Sprint
|
|
||||||
Mile
|
|
||||||
Medium
|
|
||||||
Long
|
|
||||||
Front-Runner
|
|
||||||
Pace-Chaser
|
|
||||||
Late-Surger
|
|
||||||
End-Closer
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Fip comparison of the `aptitude` type.
|
|
||||||
pub fun aptitude/order2(this : aptitude, other : aptitude) : e order2<aptitude>
|
|
||||||
match (this, other)
|
|
||||||
(Turf, Turf) -> Eq2(Turf)
|
|
||||||
(Turf, other') -> Lt2(Turf, other')
|
|
||||||
(this', Turf) -> Gt2(Turf, this')
|
|
||||||
(Dirt, Dirt) -> Eq2(Dirt)
|
|
||||||
(Dirt, other') -> Lt2(Dirt, other')
|
|
||||||
(this', Dirt) -> Gt2(Dirt, this')
|
|
||||||
(Sprint, Sprint) -> Eq2(Sprint)
|
|
||||||
(Sprint, other') -> Lt2(Sprint, other')
|
|
||||||
(this', Sprint) -> Gt2(Sprint, this')
|
|
||||||
(Mile, Mile) -> Eq2(Mile)
|
|
||||||
(Mile, other') -> Lt2(Mile, other')
|
|
||||||
(this', Mile) -> Gt2(Mile, this')
|
|
||||||
(Medium, Medium) -> Eq2(Medium)
|
|
||||||
(Medium, other') -> Lt2(Medium, other')
|
|
||||||
(this', Medium) -> Gt2(Medium, this')
|
|
||||||
(Long, Long) -> Eq2(Long)
|
|
||||||
(Long, other') -> Lt2(Long, other')
|
|
||||||
(this', Long) -> Gt2(Long, this')
|
|
||||||
(Front-Runner, Front-Runner) -> Eq2(Front-Runner)
|
|
||||||
(Front-Runner, other') -> Lt2(Front-Runner, other')
|
|
||||||
(this', Front-Runner) -> Gt2(Front-Runner, this')
|
|
||||||
(Pace-Chaser, Pace-Chaser) -> Eq2(Pace-Chaser)
|
|
||||||
(Pace-Chaser, other') -> Lt2(Pace-Chaser, other')
|
|
||||||
(this', Pace-Chaser) -> Gt2(Pace-Chaser, this')
|
|
||||||
(Late-Surger, Late-Surger) -> Eq2(Late-Surger)
|
|
||||||
(Late-Surger, other') -> Lt2(Late-Surger, other')
|
|
||||||
(this', Late-Surger) -> Gt2(Late-Surger, this')
|
|
||||||
(End-Closer, End-Closer) -> Eq2(End-Closer)
|
|
||||||
|
|
||||||
// Automatically generated.
|
|
||||||
// Equality comparison of the `aptitude` type.
|
|
||||||
pub fun aptitude/(==)(this : aptitude, other : aptitude) : e bool
|
|
||||||
match (this, other)
|
|
||||||
(Turf, Turf) -> True
|
|
||||||
(Dirt, Dirt) -> True
|
|
||||||
(Sprint, Sprint) -> True
|
|
||||||
(Mile, Mile) -> True
|
|
||||||
(Medium, Medium) -> True
|
|
||||||
(Long, Long) -> True
|
|
||||||
(Front-Runner, Front-Runner) -> True
|
|
||||||
(Pace-Chaser, Pace-Chaser) -> True
|
|
||||||
(Late-Surger, Late-Surger) -> True
|
|
||||||
(End-Closer, End-Closer) -> True
|
|
||||||
(_, _) -> False
|
|
||||||
|
|
||||||
// Shows a string representation of the `aptitude` type.
|
|
||||||
pub fun aptitude/show(this : aptitude): string
|
|
||||||
match this
|
|
||||||
Turf -> "Turf"
|
|
||||||
Dirt -> "Dirt"
|
|
||||||
Sprint -> "Sprint"
|
|
||||||
Mile -> "Mile"
|
|
||||||
Medium -> "Medium"
|
|
||||||
Long -> "Long"
|
|
||||||
Front-Runner -> "Front Runner"
|
|
||||||
Pace-Chaser -> "Pace Chaser"
|
|
||||||
Late-Surger -> "Late Surger"
|
|
||||||
End-Closer -> "End Closer"
|
|
||||||
27
horse/uma.kk
27
horse/uma.kk
@@ -1,27 +0,0 @@
|
|||||||
module horse/uma
|
|
||||||
|
|
||||||
import horse/game-id
|
|
||||||
import horse/movement
|
|
||||||
|
|
||||||
// Details of an uma, or character card.
|
|
||||||
pub struct uma-detail
|
|
||||||
uma-id: uma-id
|
|
||||||
character-id: character-id
|
|
||||||
sprint: aptitude-level
|
|
||||||
mile: aptitude-level
|
|
||||||
medium: aptitude-level
|
|
||||||
long: aptitude-level
|
|
||||||
front-runner: aptitude-level
|
|
||||||
pace-chaser: aptitude-level
|
|
||||||
late-surger: aptitude-level
|
|
||||||
end-closer: aptitude-level
|
|
||||||
turf: aptitude-level
|
|
||||||
dirt: aptitude-level
|
|
||||||
unique: skill-id
|
|
||||||
skill1: skill-id
|
|
||||||
skill2: skill-id
|
|
||||||
skill3: skill-id
|
|
||||||
skill-pl2: skill-id
|
|
||||||
skill-pl3: skill-id
|
|
||||||
skill-pl4: skill-id
|
|
||||||
skill-pl5: skill-id
|
|
||||||
@@ -3,7 +3,7 @@ package horse_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.sunturtle.xyz/zephyr/horse/horse"
|
"git.sunturtle.xyz/zephyr/horse"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTenThousandthsString(t *testing.T) {
|
func TestTenThousandthsString(t *testing.T) {
|
||||||
1
std
1
std
Submodule std deleted from 41b8aed39e
295
test/example.kk
295
test/example.kk
@@ -1,295 +0,0 @@
|
|||||||
module test/example
|
|
||||||
|
|
||||||
import std/num/decimal
|
|
||||||
import std/data/linearmap
|
|
||||||
import horse/game-id
|
|
||||||
import horse/global
|
|
||||||
import horse/global/character
|
|
||||||
import horse/global/saddle
|
|
||||||
import horse/global/skill
|
|
||||||
import horse/global/spark
|
|
||||||
import horse/global/uma
|
|
||||||
import horse/legacy
|
|
||||||
|
|
||||||
val p1 = Legacy(
|
|
||||||
uma = Veteran(
|
|
||||||
uma = Uma-id(102001), // seiun sky
|
|
||||||
sparks = [
|
|
||||||
301, // 1* power
|
|
||||||
2102, // 2* front runner
|
|
||||||
10200103, // 3* angling and scheming
|
|
||||||
1000302, // 2* osaka hai
|
|
||||||
1001001, // 1* japanese derby
|
|
||||||
1001101, // 1* yasuda kinen
|
|
||||||
1001701, // 1* qe2
|
|
||||||
2001402, // 2* non-standard distance
|
|
||||||
2004301, // 1* focus
|
|
||||||
2005301, // 1* early lead
|
|
||||||
2012401, // 1* front runner straightaways
|
|
||||||
2012502, // 2* front runner corners
|
|
||||||
2015201, // 1* front runner savvy
|
|
||||||
2016001, // 1* groundwork
|
|
||||||
2016102, // 2* thh
|
|
||||||
2016402, // 2* lone wolf
|
|
||||||
3000201, // 1* unity cup
|
|
||||||
].map(Spark-id(_)),
|
|
||||||
saddles = [
|
|
||||||
1, // classic triple crown
|
|
||||||
2, // senior autumn triple crown
|
|
||||||
4, // senior spring triple crown
|
|
||||||
5, // tenno sweep
|
|
||||||
6, // dual grand prix
|
|
||||||
7, // dual miles
|
|
||||||
10, // arima kinen
|
|
||||||
11, // japan cup
|
|
||||||
12, // derby
|
|
||||||
13, // tss
|
|
||||||
14, // takarazuka kinen
|
|
||||||
15, // tsa
|
|
||||||
16, // kikuka sho
|
|
||||||
17, // osaka hai
|
|
||||||
18, // satsuki sho
|
|
||||||
21, // yasuda kinen
|
|
||||||
23, // mile championship
|
|
||||||
25, // victoria mile
|
|
||||||
26, // qe2
|
|
||||||
33, // asahi hai fs
|
|
||||||
34, // hopeful stakes
|
|
||||||
96, // mainichi hai
|
|
||||||
].map(Saddle-id(_))
|
|
||||||
),
|
|
||||||
sub1 = Veteran(
|
|
||||||
uma = Uma-id(102601), // mihono bourbon
|
|
||||||
sparks = [
|
|
||||||
302, // 2* power
|
|
||||||
3303, // 3* medium
|
|
||||||
10260102, // 2* g00 1st
|
|
||||||
1001201, // 1* takarazuka kinen
|
|
||||||
1001702, // 2* qe2
|
|
||||||
1001901, // 1* japan cup
|
|
||||||
2004302, // 2* focus
|
|
||||||
2004502, // 2* prudent positioning
|
|
||||||
2012502, // 2* front corners
|
|
||||||
2015202, // 2* front savvy
|
|
||||||
2016002, // 2* groundwork
|
|
||||||
2016401, // 1* lone wolf
|
|
||||||
3000201, // 1* unity cup
|
|
||||||
].map(Spark-id(_)),
|
|
||||||
saddles = [
|
|
||||||
2, // senior autumn triple crown
|
|
||||||
6, // dual grand prix
|
|
||||||
7, // dual miles
|
|
||||||
10, // arima kinen
|
|
||||||
11, // japan cup
|
|
||||||
12, // derby
|
|
||||||
14, // takarazuka kinen
|
|
||||||
15, // tsa
|
|
||||||
17, // osaka hai
|
|
||||||
18, // satsuki sho
|
|
||||||
21, // yasuda kinen
|
|
||||||
23, // mile championship
|
|
||||||
25, // victoria mile
|
|
||||||
26, // qe2
|
|
||||||
27, // nhk mile cup
|
|
||||||
33, // asahi hai fs
|
|
||||||
34, // hopeful stakes
|
|
||||||
49, // spring stakes
|
|
||||||
].map(Saddle-id(_))
|
|
||||||
),
|
|
||||||
sub2 = Veteran(
|
|
||||||
uma = Uma-id(102401), // mayano top gun
|
|
||||||
sparks = [
|
|
||||||
302, // 2* power
|
|
||||||
1103, // 3* turf
|
|
||||||
10240101, // 1* flashy landing
|
|
||||||
1000601, // 1* tss
|
|
||||||
1001202, // 2* takarazuka kinen
|
|
||||||
1001502, // 2* kikuka sho
|
|
||||||
1001601, // 1* tsa
|
|
||||||
1002102, // 2* hanshin jf
|
|
||||||
1002301, // 1* arima kinen
|
|
||||||
2003503, // 3* corner recovery
|
|
||||||
2003802, // 2* straightaway recovery
|
|
||||||
2004602, // 2* ramp up
|
|
||||||
2005502, // 2* final push
|
|
||||||
2012702, // 2* leader's pride
|
|
||||||
2016002, // 2* groundwork
|
|
||||||
3000102, // 2* ura finale
|
|
||||||
].map(Spark-id(_)),
|
|
||||||
saddles = [
|
|
||||||
1, // classic triple crown
|
|
||||||
2, // senior autumn triple crown
|
|
||||||
4, // senior spring triple crown
|
|
||||||
5, // tenno sweep
|
|
||||||
6, // dual grand prix
|
|
||||||
7, // dual miles
|
|
||||||
10, // arima kinen
|
|
||||||
11, // japan cup
|
|
||||||
12, // derby
|
|
||||||
13, // tss
|
|
||||||
14, // takarazuka kinen
|
|
||||||
15, // tsa
|
|
||||||
16, // kikuka sho
|
|
||||||
18, // satsuki sho
|
|
||||||
21, // yasuda kinen
|
|
||||||
23, // mile championship
|
|
||||||
25, // victoria mile
|
|
||||||
26, // qe2
|
|
||||||
34, // hopeful stakes
|
|
||||||
35, // hanshin jf
|
|
||||||
].map(Saddle-id(_))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
val p2 = Legacy(
|
|
||||||
uma = Veteran(
|
|
||||||
uma = Uma-id(102601), // mihono bourbon
|
|
||||||
sparks = [
|
|
||||||
302,
|
|
||||||
3303,
|
|
||||||
1001201,
|
|
||||||
1001702,
|
|
||||||
1001901,
|
|
||||||
2004302,
|
|
||||||
2004502,
|
|
||||||
2012502,
|
|
||||||
2015202,
|
|
||||||
2016002,
|
|
||||||
2016401,
|
|
||||||
3000201,
|
|
||||||
10260102,
|
|
||||||
].map(Spark-id(_)),
|
|
||||||
saddles = [
|
|
||||||
2,
|
|
||||||
6,
|
|
||||||
7,
|
|
||||||
10,
|
|
||||||
11,
|
|
||||||
12,
|
|
||||||
14,
|
|
||||||
15,
|
|
||||||
17,
|
|
||||||
18,
|
|
||||||
21,
|
|
||||||
23,
|
|
||||||
25,
|
|
||||||
26,
|
|
||||||
27,
|
|
||||||
33,
|
|
||||||
34,
|
|
||||||
49,
|
|
||||||
].map(Saddle-id(_))
|
|
||||||
),
|
|
||||||
sub1 = Veteran(
|
|
||||||
uma = Uma-id(102402), // wedding mayano
|
|
||||||
sparks = [
|
|
||||||
203,
|
|
||||||
3202,
|
|
||||||
1000701,
|
|
||||||
1000802,
|
|
||||||
1001201,
|
|
||||||
1001803,
|
|
||||||
2003502,
|
|
||||||
2003701,
|
|
||||||
2004301,
|
|
||||||
2005502,
|
|
||||||
2012401,
|
|
||||||
2016402,
|
|
||||||
10240202,
|
|
||||||
].map(Spark-id(_)),
|
|
||||||
saddles = [
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
6,
|
|
||||||
7,
|
|
||||||
10,
|
|
||||||
11,
|
|
||||||
12,
|
|
||||||
14,
|
|
||||||
15,
|
|
||||||
16,
|
|
||||||
18,
|
|
||||||
21,
|
|
||||||
23,
|
|
||||||
25,
|
|
||||||
26,
|
|
||||||
27,
|
|
||||||
33,
|
|
||||||
34,
|
|
||||||
48,
|
|
||||||
].map(Saddle-id(_))
|
|
||||||
),
|
|
||||||
sub2 = Veteran(
|
|
||||||
uma = Uma-id(100201), // silence suzuka
|
|
||||||
sparks = [
|
|
||||||
203,
|
|
||||||
1101,
|
|
||||||
1001901,
|
|
||||||
1002203,
|
|
||||||
1002302,
|
|
||||||
2000101,
|
|
||||||
2000201,
|
|
||||||
2001902,
|
|
||||||
2003501,
|
|
||||||
2005401,
|
|
||||||
2016001,
|
|
||||||
3000102,
|
|
||||||
10020101,
|
|
||||||
].map(Spark-id(_)),
|
|
||||||
saddles = [
|
|
||||||
2,
|
|
||||||
6,
|
|
||||||
10,
|
|
||||||
11,
|
|
||||||
12,
|
|
||||||
14,
|
|
||||||
15,
|
|
||||||
17,
|
|
||||||
18,
|
|
||||||
21,
|
|
||||||
25,
|
|
||||||
26,
|
|
||||||
27,
|
|
||||||
33,
|
|
||||||
34,
|
|
||||||
40,
|
|
||||||
42,
|
|
||||||
44,
|
|
||||||
45,
|
|
||||||
46,
|
|
||||||
49,
|
|
||||||
59,
|
|
||||||
61,
|
|
||||||
63,
|
|
||||||
65,
|
|
||||||
111,
|
|
||||||
113,
|
|
||||||
117,
|
|
||||||
126,
|
|
||||||
].map(Saddle-id(_))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
val trainee = Uma-id(104601) // smart falcon
|
|
||||||
|
|
||||||
pub fun main()
|
|
||||||
val p1a = parent-affinity(trainee, p1, p2.uma.uma)
|
|
||||||
val p2a = parent-affinity(trainee, p2, p1.uma.uma)
|
|
||||||
val (s11a, s12a) = sub-affinity(trainee, p1)
|
|
||||||
val (s21a, s22a) = sub-affinity(trainee, p2)
|
|
||||||
println("trainee: " ++ trainee.show)
|
|
||||||
println("p1: " ++ p1.uma.uma.show ++ " affinity " ++ p1a.show)
|
|
||||||
println("s1-1: " ++ p1.sub1.uma.show ++ " affinity " ++ s11a.show)
|
|
||||||
println("s1-2: " ++ p1.sub2.uma.show ++ " affinity " ++ s12a.show)
|
|
||||||
println("p2: " ++ p2.uma.uma.show ++ " affinity " ++ p1a.show)
|
|
||||||
println("s1-1: " ++ p2.sub1.uma.show ++ " affinity " ++ s21a.show)
|
|
||||||
println("s1-2: " ++ p2.sub2.uma.show ++ " affinity " ++ s22a.show)
|
|
||||||
val inspo = inspiration(trainee, p1, p2)
|
|
||||||
val s = inspiration-gives(inspo, legacy/skills)
|
|
||||||
val a = inspiration-gives(inspo, legacy/aptitudes)
|
|
||||||
println("\nskills:")
|
|
||||||
s.list.foreach() fn((skill, pmf))
|
|
||||||
println(" " ++ skill.show ++ ": " ++ pmf.show)
|
|
||||||
println("\naptitudes:")
|
|
||||||
a.list.foreach() fn((apt, pmf))
|
|
||||||
println(" " ++ apt.show ++ ": " ++ pmf.show)
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
module test/global
|
|
||||||
|
|
||||||
import horse/global/character
|
|
||||||
import horse/global/race
|
|
||||||
import horse/global/saddle
|
|
||||||
import horse/global/scenario
|
|
||||||
import horse/global/skill
|
|
||||||
import horse/global/spark
|
|
||||||
import horse/global/uma
|
|
||||||
|
|
||||||
pub fun main()
|
|
||||||
()
|
|
||||||
Reference in New Issue
Block a user