-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add comparison constraints #7
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ class ConstraintDisplays { | |
this.Quad, | ||
this.Givens, | ||
this.OutsideClue, | ||
this.Comparison, | ||
] | ||
} | ||
} | ||
|
@@ -553,7 +554,6 @@ ConstraintDisplays.Dot = class Dot extends BaseConstraintDisplayItem { | |
return dot; | ||
} | ||
} | ||
|
||
ConstraintDisplays.Letter = class Letter extends BaseConstraintDisplayItem { | ||
drawItem(constraint, _) { | ||
const cells = constraint.cells; | ||
|
@@ -1230,3 +1230,56 @@ ConstraintDisplays.Givens = class Givens extends BaseConstraintDisplayItem { | |
this._maskMap.clear(); | ||
} | ||
} | ||
|
||
ConstraintDisplays.Comparison = class Comparison extends BaseConstraintDisplayItem { | ||
drawItem(constraint, options) { | ||
const primaryCell = constraint.primaryCell; | ||
const secondaryCells = constraint.secondaryCells; | ||
|
||
let result = createSvgElement("g"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
let drawDecoration = (primaryCell, secondaryCell) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pull this out into a proper method. No reason for this to be inline. |
||
// Find the midpoint between the squares. | ||
let [x0, y0] = this.cellIdCenter(primaryCell); | ||
let [x1, y1] = this.cellIdCenter(secondaryCell); | ||
let x = (x0 + x1) / 2; | ||
let y = (y0 + y1) / 2; | ||
const cellSize = DisplayItem.CELL_SIZE; | ||
const comparisonSize = 0.1 * cellSize; | ||
const inset = 0; | ||
const squash = 0.75; | ||
var dC = x0 < x1 ? 1 : (x0 > x1 ? -1 : 0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, sorry, forgot this wasn't an index. Then just use |
||
var dR = y0 < y1 ? 1 : (y0 > y1 ? -1 : 0); | ||
let directions; | ||
if (dC == 0) { | ||
// Vertical comparison | ||
if (dR == 0) | ||
throw new Error("Whelp this makes no sense") | ||
let comparisonDirection = dR * constraint.mode; | ||
directions = [ | ||
'M', x - comparisonSize, y - comparisonDirection * comparisonSize * squash - dR * inset, | ||
'L', x , y + comparisonDirection * comparisonSize * squash - dR * inset, | ||
'L', x + comparisonSize, y - comparisonDirection * comparisonSize * squash - dR * inset, | ||
] | ||
} else { | ||
if (dC == 0) throw new Error("Whelp this makes no sense") | ||
let comparisonDirection = dC * constraint.mode; | ||
directions = [ | ||
'M', x - comparisonDirection * comparisonSize * squash - dC * inset, y - comparisonSize, | ||
'L', x + comparisonDirection * comparisonSize * squash - dC * inset, y, | ||
'L', x - comparisonDirection * comparisonSize * squash - dC * inset, y + comparisonSize, | ||
] | ||
} | ||
let path = createSvgElement('path'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
path.setAttribute('d', directions.join(' ')); | ||
path.setAttribute('fill', 'transparent'); | ||
path.setAttribute('stroke', 'black'); | ||
path.setAttribute('stroke-width', 1); | ||
path.setAttribute('stroke-linecap', 'round'); | ||
result.appendChild(path); | ||
} | ||
for (let secondaryCell of secondaryCells) | ||
drawDecoration(primaryCell, secondaryCell) | ||
this._svg.append(result); | ||
return result; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1632,6 +1632,63 @@ class SudokuConstraint { | |
); | ||
} | ||
|
||
static Comparison = class Comparison extends SudokuConstraintBase { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed, change to |
||
static DESCRIPTION = (` | ||
Comparison: compare value between adjacent cells.`); | ||
static CATEGORY = 'LinesAndSets'; | ||
static DISPLAY_CONFIG = { | ||
displayClass: 'Comparison', | ||
}; | ||
static ARGUMENT_CONFIG = { | ||
label: "mode", | ||
options: [ | ||
{ value: '1', text: 'Maximum' }, | ||
{ value: '-1', text: 'Minimum' }, | ||
], | ||
}; | ||
|
||
static VALIDATE_CELLS_FN = ([primary, ...secondaries], shape) => { | ||
if (!secondaries.length) | ||
return false; | ||
for (let secondary of secondaries) { | ||
if (!this._cellsAreAdjacent([primary, secondary], shape)) | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
constructor(mode, primaryCell, ...secondaryCells) { | ||
secondaryCells.sort(); | ||
super([mode, primaryCell, ...secondaryCells]); | ||
this.mode = +mode; | ||
this.primaryCell = primaryCell; | ||
this.secondaryCells = secondaryCells; | ||
} | ||
|
||
static displayName() { | ||
return 'Comparison' | ||
} | ||
|
||
_symbol() { | ||
switch (this.mode) { | ||
case 1: | ||
return '>'; | ||
case -1: | ||
return '<'; | ||
default: | ||
throw new Error("Invalid state") | ||
} | ||
} | ||
chipLabel() { | ||
return `${this.primaryCell} ${this._symbol()} [${this.secondaryCells}]`; | ||
} | ||
|
||
static fnKey = memoize((mode, numValues) => | ||
SudokuConstraint.Binary.fnToKey((a, b) => (mode < 0) ? (a < b) : (a > b), numValues) | ||
); | ||
|
||
} | ||
|
||
static X = class X extends SudokuConstraintBase { | ||
static DESCRIPTION = (` | ||
Values must add to 10. Adjacent cells only.`); | ||
|
@@ -2865,6 +2922,17 @@ class SudokuBuilder { | |
yield new SudokuConstraintHandler.Sum(cells, 5); | ||
break; | ||
|
||
case 'Comparison': { | ||
let mode = constraint.mode; | ||
let primaryCell = shape.parseCellId(constraint.primaryCell).cell; | ||
let fn = SudokuConstraint.Comparison.fnKey(mode, shape.numValues); | ||
for (let secondary of constraint.secondaryCells) { | ||
let secondaryCell = shape.parseCellId(secondary).cell; | ||
yield new SudokuConstraintHandler.BinaryConstraint(primaryCell, secondaryCell, fn); | ||
} | ||
break; | ||
} | ||
|
||
case 'ValueIndexing': | ||
{ | ||
const cells = constraint.cells.map( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this before
Letter
. Constraints are rendered in this order.