Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,872 changes: 0 additions & 1,872 deletions Controller/RUL2/10_GLR/Sec10a_GLR1.txt

This file was deleted.

1,324 changes: 0 additions & 1,324 deletions Controller/RUL2/10_GLR/Sec10b_GLR2.txt

This file was deleted.

1,325 changes: 0 additions & 1,325 deletions Controller/RUL2/10_GLR/Sec10c_GLR3.txt

This file was deleted.

1,325 changes: 0 additions & 1,325 deletions Controller/RUL2/10_GLR/Sec10d_GLR4.txt

This file was deleted.

2,064 changes: 2,064 additions & 0 deletions Controller/RUL2/10_GLR/Sec10e_GlrMetaGenerated_MANAGED.txt

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/main/resources/tileOrientationCache.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,9 @@
0x5E5EBA00,(0,0)+(1,0)+(2,0)+(3,0)
0x5E5EBB00,(0,0)+(1,0)+(2,0)+(3,0)
0x5F500200,(0,0)+(1,0)+(2,0)+(3,0)+(0,1)+(3,1)+(2,1)+(1,1)
0x5F881600,(0,0)+(1,0)+(2,0)+(3,0)+(0,1)+(3,1)+(2,1)+(1,1)
0x5F885600,(0,0)+(1,0)+(2,0)+(3,0)+(0,1)+(3,1)+(2,1)+(1,1)
0x5F889600,(0,0)+(1,0)+(2,0)+(3,0)+(0,1)+(3,1)+(2,1)+(1,1)
0x5F88D600,(0,0)+(1,0)+(2,0)+(3,0)+(0,1)+(3,1)+(2,1)+(1,1)
0x71006B09,(0,1)+(3,1)+(2,1)+(1,1)
0x71226B09,(0,1)+(3,1)+(2,1)+(1,1)
8 changes: 6 additions & 2 deletions src/main/scala/module/CrossingGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ object CrossingGenerator {
if minor != Subway && !isHrw(minor) && (main.isRhw || minor.isRhw ||
(main.isNwm && (minor.isRhw || minor.isNwm || minor.base.isEmpty || GlrNetworks.contains(minor))) ||
(main.isNwm && isSingleTile(main) && main.height == 0 && (minor == L1Dtr || minor == L2Dtr)) ||
GlrNetworks.contains(main) && (minor.isRhw || minor.isNwm /*|| minor == main*/)
) && intersectionAllowed(main, minor)
GlrNetworks.contains(main) && (
(Road + Street + Onewayroad + Avenue + Rail + L1Dtr + L2Dtr).contains(minor) ||
minor.isRhw || minor.isNwm /*|| minor == main*/ ||
(SamNetworks.contains(minor) && minor != Sam1 && main != Glr3 && main != Glr4) // Sam × Glr3/Glr4 may be activated later
)
) && intersectionAllowed(main, minor)
} yield minor
}
}
Expand Down
16 changes: 6 additions & 10 deletions src/main/scala/module/Curve45Generator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,15 @@ import NetworkProperties.{isSingleTile, isDoubleTile, owr4AltNetwork}
*/

trait Stability { this: RuleGenerator =>
def stabilize(rule: Rule[SymTile]): Seq[Rule[SymTile]] = {
if (rule(0) == rule(2) || rule(1) == rule(3)) {
Seq(rule)
} else { // TODO handle corner cases
Seq(rule, Rule(rule(0), rule(3), rule(2), rule(3)), Rule(rule(2), rule(1), rule(2), rule(3)))
}
}
export NetworkProperties.stabilize
}

trait Curve45Generator extends Stability { this: RuleGenerator =>

def hasSharedDiagCurve(n: Network): Boolean = n.typ == AvenueLike

def hasSharpCurveBase(n: Network, inside: Boolean): Boolean = {
n.base.exists(b => b == Dirtroad || b == Road || b == Onewayroad)
n.base.exists(b => b == Dirtroad || b == Road || b == Onewayroad || b == Lightrail)
}

def hasR1CurveBase(n: Network): Boolean = {
Expand All @@ -90,7 +84,8 @@ trait Curve45Generator extends Stability { this: RuleGenerator =>

def hasSharpCurve(n: Network, inside: Boolean): Boolean = {
n >= L1Rhw2 && n <= L4Rhw6s || n >= Tla3 && n <= Nrd4 || n == Tla5 || n == Rd6 || n == Owr5 ||
inside && (n == Ave6 || n == Ave8)
inside && (n == Ave6 || n == Ave8) ||
GlrNetworks.contains(n)
}

def hasMiniCurve(n: Network, inside: Boolean): Boolean = NetworkProperties.hasMiniCurve(n, inside = inside)
Expand All @@ -108,7 +103,8 @@ trait Curve45Generator extends Stability { this: RuleGenerator =>
}

def has90Curve(n: Network, inside: Boolean): Boolean = {
n.isNwm && (isSingleTile(n) || inside && (n == Tla5 || n == Rd4 || n.isOwr4Like))
n.isNwm && (isSingleTile(n) || inside && (n == Tla5 || n == Rd4 || n.isOwr4Like)) ||
GlrNetworks.contains(n)
}

def createCurve45Rules(main: Network): Unit = {
Expand Down
60 changes: 50 additions & 10 deletions src/main/scala/module/GlrRuleGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,57 @@ import NetworkProperties._
class GlrRuleGenerator(var context: RuleTransducer.Context) extends RuleGenerator with Curve45Generator with CrossingGenerator {

def start(): Unit = {
for (main <- GlrNetworks; base <- main.base) {
// Rules += main~WE | (base ~> main)~WE // ortho
// Rules += main~WE | (base ~> main)~WC // ortho stub
// Rules += main~SE~ES | (base ~> main)~WN~NW // diagonal
// curves
// createCurve45Rules(main)
// createCurve90Rules(main)
for (glr <- GlrNetworks; base <- glr.base) {
Rules += glr~WE | (base ~> glr)~WE // ortho
Rules += glr~SE | (base ~> glr)~WN // diagonal
Rules += glr~WE | base~WC | % | glr~WE // ortho stub (TODO implement proper GLR end stubs)
Rules += glr~SE | base~WNC | % | glr~WN // diagonal stub
createCurve45Rules(glr)
createCurve90Rules(glr)
Rules ++= reflections((base ~> glr)~WE | (base ~> glr)~(2,0,62,0)) // Y-wye
Rules ++= reflections((base ~> glr)~(2,0,62,0) | (base ~> glr)~(62,3,0,1)) // Y-wye
Rules ++= reflections((base ~> glr)~(3,0,1,62) | (base ~> glr)~WN) // Y-wye
Rules ++= reflections((base ~> glr)~WE | (base ~> glr)~(2,0,72,0)) // Ψ-wye
Rules ++= reflections((base ~> glr)~(2,0,72,0) | (base ~> glr)~(72,3,2,1)) // Ψ-wye
Rules ++= reflections((base ~> glr)~(3,2,1,72) | (base ~> glr)~WN) // Ψ-wye
Rules ++= reflections((base ~> glr)~(72,3,2,1) | (base ~> glr)~WE) // Ψ-wye
Rules ++= reflections((base ~> glr)~WE | (base ~> glr)~(2,0,33,0)) // orth switch
Rules ++= reflections((base ~> glr)~(2,0,33,0) | (base ~> glr)~(33,0,2,1)) // orth switch
Rules ++= reflections((base ~> glr)~(0,2,1,33) | (base ~> glr)~WN) // orth switch
Rules ++= reflections((base ~> glr)~(33,0,2,1) | (base ~> glr)~WE) // orth switch
Rules ++= reflections((base ~> glr)~WE | (base ~> glr)~(2,0,2,2)) // orth T
Rules ++= reflections((base ~> glr)~WE | (base ~> glr)~(2,2,0,2)) // orth T
Rules ++= reflections((base ~> glr)~NE | (base ~> glr)~(3,2,0,21)) // diag switch
Rules ++= reflections((base ~> glr)~WE | (base ~> glr)~(2,0,21,3)) // diag switch
Rules ++= reflections((base ~> glr)~(2,0,21,3) | (base ~> glr)~(21,3,0,0)) // diag switch
Rules ++= reflections((base ~> glr)~(0,21,3,0) | (base ~> glr)~WS) // diag switch
Rules ++= reflections((base ~> glr)~(0,0,21,3) | (base ~> glr)~(21,13,2,0)) // diag y
Rules ++= reflections((base ~> glr)~(0,21,13,2) | (base ~> glr)~(13,0,2,0)) // diag y
Rules ++= reflections((base ~> glr)~(0,21,13,2) | (base ~> glr)~(13,0,13,0)) // diag y
Rules ++= reflections((base ~> glr)~(0,21,13,2) | (base ~> glr)~(13,0,11,0)) // diag y
Rules ++= reflections((base ~> glr)~(21,13,2,0) | (base ~> glr)~WE) // diag y
Rules ++= reflections((base ~> glr)~(0,0,11,3) | (base ~> glr)~(11,0,11,0)) // diag S
Rules ++= reflections((base ~> glr)~(0,0,11,3) | (base ~> glr)~(11,0,13,0)) // boomerang
Rules ++= reflections((base ~> glr)~(0,0,21,3) | (base ~> glr)~(21,23,2,0)) // diag Ψ
Rules ++= reflections((base ~> glr)~(0,21,23,2) | (base ~> glr)~(23,0,2,1)) // diag Ψ
Rules ++= reflections((base ~> glr)~(21,23,2,0) | (base ~> glr)~WE) // diag Ψ
Rules += glr~(0,2,21,23) | (base ~> glr)~(21,23,2,0) // diag Ψ adjacency
Rules ++= reflections((base ~> glr)~(0,0,21,3) | (base ~> glr)~(21,3,13,0)) // diag boomerang switch
Rules ++= reflections((base ~> glr)~(0,2,21,23) | (base ~> glr)~(21,3,13,0)) // diag boomerang switch adjacency
Rules ++= reflections((base ~> glr)~(21,3,13,0) | (base ~> glr)~(13,0,0,1)) // diag boomerang switch
Rules ++= reflections((base ~> glr)~(0,21,3,13) | (base ~> glr)~WS) // diag boomerang switch
Rules ++= stabilize(glr~SE | base~WN & base~NE | glr~(0,0,21,3) | glr~(21,62,23,0)) // diag X (in) (Note that curved switch has been removed from Lightrail D×D but not from GLR)
Rules ++= stabilize(glr~(0,2,1,23) | base~WN & base~NE | glr~(0,2,21,23) | glr~(21,62,23,0)) // diag X (in) adjacency
Rules += glr~(0,21,62,23) | base~WS & base~WN | % | glr~(62,23,0,21) // diag X (inner)
Rules += glr~(21,62,23,0) | base~WS | % | glr~(23,0,0,1) // diag X (out)

// crossings (O×O, O×D, D×O, D×D)
for (minor <- CrossingGenerator.crossingNetworksOf(main)) {
createCrossingRules(main, minor)
Rules ++= reflections((base ~> glr)~WE | (base ~> glr)~(2,2,2,2)) // O×O (TODO implement Lightrail × GLR)
Rules ++= reflections((base ~> glr)~WE | (base ~> glr)~WE & (base ~> glr)~NE) // O×D (TODO implement Lightrail × GLR)
Rules ++= reflections((base ~> glr)~NE | (base ~> glr)~WS & (base ~> glr)~NS) // D×O
Rules += glr~WE & glr~NE | (base ~> glr)~WE & (base ~> glr)~WS // O×D (inner)
for (minor <- CrossingGenerator.crossingNetworksOf(glr)) {
createCrossingRules(glr, minor)
}
}
}
Expand All @@ -26,7 +66,7 @@ class GlrRuleGenerator(var context: RuleTransducer.Context) extends RuleGenerato

// Compile individually with `sbt "runMain com.sc4nam.module.CompileGlrCode"`.
object CompileGlrCode extends AbstractMain {
lazy val resolve: IdResolver = new MiscResolver orElse new RealRailwayResolver orElse new RhwResolver orElse new NwmResolver orElse new ViaductResolver
lazy val resolve: IdResolver = new MiscResolver orElse new RealRailwayResolver orElse new SamResolver orElse new RhwResolver orElse new NwmResolver orElse new ViaductResolver
val generator = new GlrRuleGenerator(_)
lazy val file = new java.io.File("target/Sec10e_GlrMetaGenerated_MANAGED.txt")
}
46 changes: 44 additions & 2 deletions src/main/scala/module/MiscResolver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -538,22 +538,63 @@ class MiscResolver extends IdResolver {
}
}

// Lightrail crossings
// Lightrail pieces and crossings
add(0x08000500, Lightrail~(0,0,0,2))
add(0x08000200, Lightrail~(0,0,0,1))
add(0x08031600, Lightrail~(0,2,0,13))
add(0x08002200, Lightrail~(0,0,1,13))
add(0x5f882e00, Lightrail~(0,0,2,2))
add(0x082e2d00, Lightrail~(2,2,2,2))
add(0x082e2d00, Lightrail~NS & Lightrail~WE)
add(0x5f882f00, Lightrail~(0,2,2,2))
add(0x5f882f00, Lightrail~NS & Lightrail~CE)
add(0x08014e00, Lightrail~(0,1,62,3))
add(0x08031a00, Lightrail~(0,2,0,62))
add(0x0812ff00, Lightrail~(1,72,3,2))
add(0x08031b00, Lightrail~(0,2,0,72))
add(0x08032500, Lightrail~(0,2,1,33))
add(0x08031700, Lightrail~(0,2,0,33)) // using 33/31 in metarules (instead of 32/52) to facilitate mirroring
add(0x0802f900, Lightrail~(0,21,3,2))
add(0x08001c00, Lightrail~(0,0,1,23))
add(0x08029700, Lightrail~(0,21,13,2))
add(0x08018b00, Lightrail~(0,11,0,11))
add(0x08019500, Lightrail~(0,11,0,13))
add(0x08aa6500, Lightrail~(0,21,23,2))
add(0x08aa5000, Lightrail~(0,21,3,13))

add(0x08dd0300, Rail~ES & Lightrail~NS)
add(0x08dd0400, Rail~EW & Lightrail~NS)
add(0x08dd1400, Rail~NS & Lightrail~ES)
add(0x08dd1500, Rail~SW & Lightrail~ES)
add(0x08aa2000, Lightrail~NS & Lightrail~NE)
add(0x08aa6300, Lightrail~NE & Lightrail~ES)
// add(0x08aa6300, Lightrail~(0,21,62,23)) // the turns have actually been removed by NAM, so it's the same as the line above

// GLR crossings
// GLR pieces and crossings
for ((glr, offset) <- Seq(Glr1, Glr2, Glr3, Glr4).zip(Seq(0, 0x4000, 0x8000, 0xc000))) {
add(0x5f880200 + offset, glr~(0,0,2,2))
add(0x5f880500 + offset, glr~(0,13,0,2))
add(0x5f880400 + offset, glr~(0,0,1,13))
add(0x5f880700 + offset, glr~(3,0,1,62))
add(0x5f880800 + offset, glr~(0,62,0,2))
add(0x5f880900 + offset, glr~(3,2,1,72))
add(0x5f880a00 + offset, glr~(0,72,0,2))
add(0x5f880b00 + offset, glr~(0,2,1,33))
add(0x5f880c00 + offset, glr~(0,33,0,2))
add(0x5f881100 + offset, glr~(2,2,2,2))
add(0x5f881100 + offset, glr~NS & glr~WE)
add(0x5f881180 + offset, glr~NS & Lightrail~WE)
add(0x5f881200 + offset, glr~(0,2,2,2))
add(0x5f881200 + offset, glr~NS & glr~CE)
add(0x5f881300 + offset, glr~(3,2,0,21))
add(0x5f881400 + offset, glr~(0,21,3,0))
add(0x5f881500 + offset, glr~(0,21,13,2))
add(0x5f881600 + offset, glr~(11,0,11,0))
add(0x5f881700 + offset, glr~(0,11,0,13))
add(0x5f882b00 + offset, glr~(0,21,62,23))
add(0x5f882c00 + offset, glr~(0,21,23,2))
add(0x5f882d00 + offset, glr~(0,21,3,13))

// O×O
add(0x5f880300 + offset, glr~NS & Road~WE)
add(0x5f880d00 + offset, glr~NS & Street~WE)
Expand All @@ -575,6 +616,7 @@ class MiscResolver extends IdResolver {
add(0x5f881f00 + offset, glr~NE & Rail~NS)
add(0x5f882000 + offset, glr~NE & Avenue~SN)
add(0x5f882100 + offset, glr~NE & Avenue~NS)
add(0x5f882700 + offset, glr~NS & glr~NE)
// D×D
add(0x5f882200 + offset, glr~NE & Road~NW)
add(0x5f882a00 + offset, glr~NE & Street~NW)
Expand Down
24 changes: 24 additions & 0 deletions src/main/scala/module/NetworkProperties.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ object NetworkProperties {
rhwIntersectionAllowed(a, b)
} else if ((nonintersectingNetworks.contains(a) || nonintersectingNetworks.contains(b)) && a.height == b.height) {
false
} else if (a == Lightrail && (b == L1Dtr || b == L2Dtr)
|| (b == Lightrail && (a == L1Dtr || a == L2Dtr))) {
false // currently L1Dtr/L2Dtr can only cross Glr, but not Lightrail
} else {
true // TODO
}
Expand Down Expand Up @@ -170,4 +173,25 @@ object NetworkProperties {
else throw new IllegalArgumentException(s"network is not OWR-like: $network")
}

/** For rules where all four tiles differ, this adds two stability rules (which are equivalent to the reflections). */
def stabilize(rule: Rule[SymTile]): Seq[Rule[SymTile]] = {
if (rule(0) == rule(2) || rule(1) == rule(3)) {
Seq(rule)
} else { // TODO handle corner cases
Seq(
rule,
Rule(rule(0), rule(3), rule(2), rule(3)),
Rule(rule(2), rule(1), rule(2), rule(3)),
)
}
}

/** Replaces a rule by two others that represent in/out directions in order to carry an override in both directions. */
def reflections(rule: Rule[SymTile]): Seq[Rule[SymTile]] = {
Seq(
Rule(rule(2) , rule(1) , rule(2) , rule(3) ),
Rule(rule(3) * R2F0, rule(0) * R2F0, rule(3) * R2F0, rule(2) * R2F0),
)
}

}
2 changes: 1 addition & 1 deletion src/main/scala/module/SamResolver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import NetworkProperties.{isSingleTile, isTripleTile, nonMirroredOnly, mirroredO

class SamResolver extends IdResolver {

val isSam = Set(Sam1, Sam2, Sam3, Sam4, Sam5, Sam6, Sam7, Sam8, Sam9, Sam10, Sam11)
val isSam: Set[Network] = SamNetworks

val isSimpleSam = Set(Sam1)

Expand Down
8 changes: 0 additions & 8 deletions src/main/scala/module/SamRuleGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@ import NetworkProperties._

class SamRuleGenerator(var context: RuleTransducer.Context) extends RuleGenerator with Adjacencies with Stability {

private def reflections(rule: Rule[SymTile]): Seq[Rule[SymTile]] = {
Seq(
Rule(rule(2), rule(1), rule(2), rule(3)),
Rule(rule(3) * R2F0, rule(0) * R2F0, rule(3) * R2F0, rule(2) * R2F0)
)
}


private def createSamLarge45Curve(sam: Network): Unit = {
// large 45 curve (4x3)
// * (diag)
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/module/SanityChecker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ object SanityChecker {
// should be compared to.
val metaruleFiles = Set(
"Sec7h0_OnslopeMetaGenerated_MANAGED.txt",
// "Sec10e_GlrMetaGenerated_MANAGED.txt",
"Sec10e_GlrMetaGenerated_MANAGED.txt",
)

def isMetaruleFile(path: Path): Boolean = {
Expand Down
Loading