Fix five hand-written cases built on an impossible order
Paris does not border Munich, so it can never support an attack on it. Five of my own cases were built on that support and the new validation pass refused it -- and three of them had been passing for the wrong reason, which is worse than failing. Every one of them now uses a supporter that could actually have made the move it is supporting. The Portugal case takes its support off the Mid-Atlantic, since Spain is the only land province that touches Portugal at all -- which is also why a unit dislodged there has nowhere to go.
This commit is contained in:
+19
-17
@@ -69,9 +69,11 @@ describe('strength', () => {
|
||||
})
|
||||
|
||||
it('dislodges when the attack is supported and the defence is not', () => {
|
||||
// Ruhr, not Paris. A unit may only support into a province it could have
|
||||
// gone to itself, and Paris does not border Munich.
|
||||
const r = run(
|
||||
[A('france', 'bur'), A('france', 'par'), A('germany', 'mun')],
|
||||
[mv('bur', 'mun'), sup('par', 'bur', 'mun'), hold('mun')],
|
||||
[A('france', 'bur'), A('france', 'ruh'), A('germany', 'mun')],
|
||||
[mv('bur', 'mun'), sup('ruh', 'bur', 'mun'), hold('mun')],
|
||||
)
|
||||
expect(r.success.get('bur')).toBe(true)
|
||||
expect(r.dislodged.get('mun')?.attackedFrom).toBe('bur')
|
||||
@@ -79,8 +81,8 @@ describe('strength', () => {
|
||||
|
||||
it('needs more than equal support, because a tie is a bounce', () => {
|
||||
const r = run(
|
||||
[A('france', 'bur'), A('france', 'par'), A('germany', 'mun'), A('germany', 'ruh')],
|
||||
[mv('bur', 'mun'), sup('par', 'bur', 'mun'), hold('mun'), sup('ruh', 'mun', 'mun')],
|
||||
[A('france', 'bur'), A('france', 'tyr'), A('germany', 'mun'), A('germany', 'kie')],
|
||||
[mv('bur', 'mun'), sup('tyr', 'bur', 'mun'), hold('mun'), sup('kie', 'mun', 'mun')],
|
||||
)
|
||||
expect(r.success.get('bur')).toBe(false)
|
||||
expect(r.dislodged.size).toBe(0)
|
||||
@@ -132,20 +134,20 @@ describe('cutting support', () => {
|
||||
// Picardy, not Ruhr: Ruhr does not border Paris, and an attack that
|
||||
// cannot arrive cuts nothing.
|
||||
const r = run(
|
||||
[A('france', 'bur'), A('france', 'par'), A('germany', 'mun'), A('germany', 'pic')],
|
||||
[mv('bur', 'mun'), sup('par', 'bur', 'mun'), hold('mun'), mv('pic', 'par')],
|
||||
[A('france', 'bur'), A('france', 'ruh'), A('germany', 'mun'), A('germany', 'kie')],
|
||||
[mv('bur', 'mun'), sup('ruh', 'bur', 'mun'), hold('mun'), mv('kie', 'ruh')],
|
||||
)
|
||||
expect(r.success.get('par')).toBe(false)
|
||||
expect(r.success.get('ruh')).toBe(false)
|
||||
expect(r.success.get('bur')).toBe(false)
|
||||
})
|
||||
|
||||
it('is not cut by an attack that could never arrive', () => {
|
||||
// The same order from Ruhr, which does not border Paris at all.
|
||||
// Paris does not border Ruhr, so that order is no order at all.
|
||||
const r = run(
|
||||
[A('france', 'bur'), A('france', 'par'), A('germany', 'mun'), A('germany', 'ruh')],
|
||||
[mv('bur', 'mun'), sup('par', 'bur', 'mun'), hold('mun'), mv('ruh', 'par')],
|
||||
[A('france', 'bur'), A('france', 'ruh'), A('germany', 'mun'), A('germany', 'par')],
|
||||
[mv('bur', 'mun'), sup('ruh', 'bur', 'mun'), hold('mun'), mv('par', 'ruh')],
|
||||
)
|
||||
expect(r.success.get('par')).toBe(true)
|
||||
expect(r.success.get('ruh')).toBe(true)
|
||||
expect(r.dislodged.get('mun')).toBeDefined()
|
||||
})
|
||||
|
||||
@@ -153,20 +155,20 @@ describe('cutting support', () => {
|
||||
// Munich attacks the supporter; Munich is what the support is aimed at,
|
||||
// so the support holds and Munich is thrown out by it.
|
||||
const r = run(
|
||||
[A('france', 'bur'), A('france', 'par'), A('germany', 'mun')],
|
||||
[mv('bur', 'mun'), sup('par', 'bur', 'mun'), mv('mun', 'par')],
|
||||
[A('france', 'bur'), A('france', 'ruh'), A('germany', 'mun')],
|
||||
[mv('bur', 'mun'), sup('ruh', 'bur', 'mun'), mv('mun', 'ruh')],
|
||||
)
|
||||
expect(r.success.get('par')).toBe(true)
|
||||
expect(r.success.get('ruh')).toBe(true)
|
||||
expect(r.success.get('bur')).toBe(true)
|
||||
expect(r.dislodged.get('mun')).toBeDefined()
|
||||
})
|
||||
|
||||
it('is cut by being thrown out, however the support was going', () => {
|
||||
const r = run(
|
||||
[A('france', 'bur'), A('france', 'par'), A('germany', 'mun'), A('germany', 'pic'), A('germany', 'bre')],
|
||||
[mv('bur', 'mun'), sup('par', 'bur', 'mun'), hold('mun'), mv('pic', 'par'), sup('bre', 'pic', 'par')],
|
||||
[A('france', 'bur'), A('france', 'ruh'), A('germany', 'mun'), A('germany', 'kie'), A('germany', 'hol')],
|
||||
[mv('bur', 'mun'), sup('ruh', 'bur', 'mun'), hold('mun'), mv('kie', 'ruh'), sup('hol', 'kie', 'ruh')],
|
||||
)
|
||||
expect(r.dislodged.get('par')).toBeDefined()
|
||||
expect(r.dislodged.get('ruh')).toBeDefined()
|
||||
expect(r.success.get('bur')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
+16
-14
@@ -34,8 +34,8 @@ function movement(units: Unit[], orders: Order[]) {
|
||||
describe('after the moving', () => {
|
||||
it('puts the winner in and takes the loser off the board', () => {
|
||||
const { outcome, after } = movement(
|
||||
[A('france', 'bur'), A('france', 'par'), A('germany', 'mun')],
|
||||
[mv('bur', 'mun'), sup('par', 'bur', 'mun'), hold('mun')],
|
||||
[A('france', 'bur'), A('france', 'ruh'), A('germany', 'mun')],
|
||||
[mv('bur', 'mun'), sup('ruh', 'bur', 'mun'), hold('mun')],
|
||||
)
|
||||
expect(after.get('mun')?.power).toBe('france')
|
||||
expect(after.has('bur')).toBe(false)
|
||||
@@ -51,8 +51,8 @@ describe('after the moving', () => {
|
||||
describe('where a beaten unit may go', () => {
|
||||
const setup = () =>
|
||||
movement(
|
||||
[A('france', 'bur'), A('france', 'par'), A('germany', 'mun')],
|
||||
[mv('bur', 'mun'), sup('par', 'bur', 'mun'), hold('mun')],
|
||||
[A('france', 'bur'), A('france', 'ruh'), A('germany', 'mun')],
|
||||
[mv('bur', 'mun'), sup('ruh', 'bur', 'mun'), hold('mun')],
|
||||
)
|
||||
|
||||
it('will not go back the way the attacker came', () => {
|
||||
@@ -62,8 +62,8 @@ describe('where a beaten unit may go', () => {
|
||||
|
||||
it('will not go where somebody is standing', () => {
|
||||
const { outcome, after } = setup()
|
||||
// Paris is where the supporting army still is -- and out of reach anyway.
|
||||
expect(retreatOptions(after, outcome, 'mun')).not.toContain('par')
|
||||
// Ruhr is where the supporting army still stands.
|
||||
expect(retreatOptions(after, outcome, 'mun')).not.toContain('ruh')
|
||||
expect(retreatOptions(after, outcome, 'mun')).toContain('tyr')
|
||||
})
|
||||
|
||||
@@ -71,14 +71,14 @@ describe('where a beaten unit may go', () => {
|
||||
const { outcome, after } = movement(
|
||||
[
|
||||
A('france', 'bur'),
|
||||
A('france', 'par'),
|
||||
A('france', 'ruh'),
|
||||
A('germany', 'mun'),
|
||||
A('austria', 'vie'),
|
||||
A('italy', 'ven'),
|
||||
],
|
||||
[
|
||||
mv('bur', 'mun'),
|
||||
sup('par', 'bur', 'mun'),
|
||||
sup('ruh', 'bur', 'mun'),
|
||||
hold('mun'),
|
||||
mv('vie', 'tyr'),
|
||||
mv('ven', 'tyr'),
|
||||
@@ -101,8 +101,10 @@ describe('where a beaten unit may go', () => {
|
||||
it('is disbanded when there is nowhere at all', () => {
|
||||
// Boxed into a corner: Portugal, attacked from Spain, with the sea taken.
|
||||
const { outcome, after } = movement(
|
||||
[A('france', 'spa'), A('france', 'gas'), F('england', 'mao'), A('italy', 'por')],
|
||||
[mv('spa', 'por'), sup('gas', 'spa', 'por'), hold('mao'), hold('por')],
|
||||
// Only Spain touches Portugal by land, so the support has to come off
|
||||
// the water -- which is also the only other way out of Portugal.
|
||||
[A('france', 'spa'), F('france', 'mao'), A('italy', 'por')],
|
||||
[mv('spa', 'por'), sup('mao', 'spa', 'por'), hold('por')],
|
||||
)
|
||||
expect(outcome.dislodged.has('por')).toBe(true)
|
||||
expect(retreatOptions(after, outcome, 'por')).toEqual([])
|
||||
@@ -114,8 +116,8 @@ describe('where a beaten unit may go', () => {
|
||||
describe('retreating', () => {
|
||||
const setup = () =>
|
||||
movement(
|
||||
[A('france', 'bur'), A('france', 'par'), A('germany', 'mun')],
|
||||
[mv('bur', 'mun'), sup('par', 'bur', 'mun'), hold('mun')],
|
||||
[A('france', 'bur'), A('france', 'ruh'), A('germany', 'mun')],
|
||||
[mv('bur', 'mun'), sup('ruh', 'bur', 'mun'), hold('mun')],
|
||||
)
|
||||
|
||||
it('puts a unit down where it was told', () => {
|
||||
@@ -130,7 +132,7 @@ describe('retreating', () => {
|
||||
const { outcome, after } = movement(
|
||||
[
|
||||
A('france', 'bur'),
|
||||
A('france', 'par'),
|
||||
A('france', 'ruh'),
|
||||
A('germany', 'mun'),
|
||||
A('italy', 'ven'),
|
||||
A('italy', 'tri'),
|
||||
@@ -138,7 +140,7 @@ describe('retreating', () => {
|
||||
],
|
||||
[
|
||||
mv('bur', 'mun'),
|
||||
sup('par', 'bur', 'mun'),
|
||||
sup('ruh', 'bur', 'mun'),
|
||||
hold('mun'),
|
||||
mv('ven', 'tyr'),
|
||||
sup('tri', 'ven', 'tyr'),
|
||||
|
||||
Reference in New Issue
Block a user