Skip to content
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

Allow slides that are not orthogonal or diagonals #66

Merged
merged 64 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
71cdbe0
customslices
Idonotus Jul 10, 2024
a655f72
render positive and negative gradients
Idonotus Jul 10, 2024
56ade94
Legal move highlighting works™
Idonotus Jul 11, 2024
2df09f0
Now highlighting is actually alligned
Idonotus Jul 11, 2024
8204c6a
Merge remote-tracking branch 'origin/main' into exoticslides
Idonotus Jul 11, 2024
57accee
added knight rider and fixed slope discrepancy
Idonotus Jul 11, 2024
88cd83d
some checkdetection and stop highlights crash
Idonotus Jul 12, 2024
3acb519
general fixes + prep slide tacking
Idonotus Jul 12, 2024
b23b779
Check detection and blocking
Idonotus Jul 12, 2024
7c4bce7
Allow for any line to slide correctly
Idonotus Jul 12, 2024
64a2ee7
jank auto slide allocation
Idonotus Jul 12, 2024
01f3495
fix slide blocking and castling oversight
Idonotus Jul 13, 2024
f54fcb1
doc linekeyfunction
Idonotus Jul 13, 2024
a9f82e7
highlight lines render atleast
Idonotus Jul 14, 2024
7725479
Merge branch 'main' into exoticslides
Idonotus Jul 14, 2024
d3b89c1
boundng box interesection fix
Idonotus Jul 14, 2024
fc2d154
highlight line selection and cleanup
Idonotus Jul 14, 2024
44a907a
moveset slidelimit changes
Idonotus Jul 15, 2024
f023e54
made the rider get its own horse + jsdoc changes
Idonotus Jul 15, 2024
b399920
fixed highlight lines and orthoganol highlights
Idonotus Jul 15, 2024
034d1e5
vertical highlight line selection
Idonotus Jul 15, 2024
3a22d6c
Added knightriders to Knighted Chess variant
Naviary2 Jul 15, 2024
7fad1c0
Merge branch 'main' into exoticslides
Idonotus Jul 16, 2024
8ea0854
renames and arrows
Idonotus Jul 16, 2024
99c5c32
All arrow changes and arrow general fixes
Idonotus Jul 16, 2024
45a1a8f
Jsdoc and renaming
Idonotus Jul 16, 2024
e151390
highlight.js fix
Idonotus Jul 17, 2024
6aebcbf
Merge branch 'main' into exoticslides
Idonotus Jul 17, 2024
3128b1b
"fixed" edgecase
Idonotus Jul 17, 2024
9068375
cleanup
Idonotus Jul 17, 2024
1cd7a78
not me ignoring what the function does
Idonotus Jul 17, 2024
97be0ef
Fixed highlights by doing maths
Idonotus Jul 17, 2024
efb42ae
highlight shouldn't render outside bounding box
Idonotus Jul 17, 2024
2c81b7c
fixed icons being slightly out of place
Idonotus Jul 17, 2024
d5e8580
cleanup + perspective highlightlines
Idonotus Jul 17, 2024
65693b6
more math fixes woth highlights
Idonotus Jul 17, 2024
8b61690
Some cleaning up, added `existingTypes` to the startSnapshot
Naviary2 Jul 18, 2024
d2e6e9a
I presume this is now auto filled out
Naviary2 Jul 18, 2024
960cf4d
Ups ya forgot the archbishop slides
Naviary2 Jul 18, 2024
c9c09c9
Lines now have the correct key! Fixed checkdetection.js after I broke…
Naviary2 Jul 18, 2024
103fe10
Comment changes
Naviary2 Jul 18, 2024
a5cb0de
Added whitespace
Naviary2 Jul 18, 2024
6a69470
Fixed discovered checks
Naviary2 Jul 18, 2024
4bb1247
Use math func instead
Naviary2 Jul 18, 2024
d1c9c1e
fix negative values generating new keys
Idonotus Jul 18, 2024
e97d756
key format changes
Idonotus Jul 18, 2024
eb3448b
Cleaned up a lot in checkdetection.js. Added a lot of JSDoc. Moved so…
Naviary2 Jul 19, 2024
960dc5c
Moved checkmate alg to new script
Naviary2 Jul 19, 2024
d911421
Description for checkmate.js
Naviary2 Jul 19, 2024
9970506
Auto swap to royalcapture when games with colinear slides are detected
Naviary2 Jul 19, 2024
e740a4f
Func renamed
Naviary2 Jul 19, 2024
e6f4697
improve arrow required algorithm
Idonotus Jul 19, 2024
9ca4e82
Document of `math.getLineSteps`
Idonotus Jul 19, 2024
05609eb
highlight outside of render fix
Idonotus Jul 19, 2024
cb50110
cleanup and documentation
Idonotus Jul 19, 2024
3a3e4eb
Lesson learned: review a mass rename
Idonotus Jul 19, 2024
4eba167
CleanUp
Idonotus Jul 19, 2024
7af4499
Merge branch 'main' into exoticslides
Idonotus Jul 20, 2024
b7ccd11
Updated highlights.js algorithm to be bug free and more friendly to c…
Naviary2 Jul 22, 2024
63cab0d
Fix
Naviary2 Jul 22, 2024
aba8b11
Fix
Naviary2 Jul 22, 2024
86f0efa
Merge branch 'exoticslides' of https://github.com/idonotus/infinitech…
Naviary2 Jul 22, 2024
d44ae6d
uhhhh fix????
Naviary2 Jul 22, 2024
6df5bb5
Backwards compatibility with loading old Knighted Chess positions
Naviary2 Jul 22, 2024
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
347 changes: 137 additions & 210 deletions src/client/scripts/game/chess/checkdetection.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/client/scripts/game/chess/formatconverter.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const formatconverter = (function() {
"centaursW": "CE", "centaursB": "ce",
"royalQueensW": "RQ", "royalQueensB": "rq",
"royalCentaursW": "RC", "royalCentaursB": "rc",
"knightridersW": "NR", "knightridersB": "nr",
"obstaclesN": "ob",
"voidsN": "vo"
};
Expand Down
15 changes: 6 additions & 9 deletions src/client/scripts/game/chess/gamefile.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ function gamefile(metadata, { moves = [], variantOptions, gameConclusion } = {})
/** The bounding box surrounding the starting position, without padding.
* @type {BoundingBox} */
box: undefined,
/** A set of all types of pieces that are in this game, without their color extension: `['pawns','queens']` */
existingTypes: undefined,
/** Possible sliding moves in this game, dependant on what pieces there are. */
slidingPossible: undefined
}

this.gameRules = {
Expand All @@ -67,14 +71,8 @@ function gamefile(metadata, { moves = [], variantOptions, gameConclusion } = {})
this.ourPieces = undefined;
/** Pieces organized by key: `{ '1,2':'queensW', '2,3':'queensW' }` */
this.piecesOrganizedByKey = undefined;
/** Pieces organized by row: `{ 2:[{type:'queensW',coords:[1,2]}] }` */
this.piecesOrganizedByRow = undefined;
/** Pieces organized by column: `{ 1:[{type:'queensW',coords:[1,2]}] }` */
this.piecesOrganizedByColumn = undefined;
/** Pieces organized by up-diagonal (slope 1). Each diagonal is given the integer value of it's y-intercept on the grid. i.e. The '0' diagonal intersects (0,0), the '1' diagonal intersects (0,1)... */
this.piecesOrganizedByUpDiagonal = undefined;
/** Pieces organized by down-diagonal (slope -1). Each diagonal is given the integar value of it's y-intercept on the grid. i.e. The '0' diagonal intersects (0,0), the '1' diagonal intersects (0,1)... */
this.piecesOrganizedByDownDiagonal = undefined;
/** Pieces organized by lines: `{ '1,0' { 2:[{type:'queensW',coords:[1,2]}] } }` */
this.piecesOrganizedByLines = undefined;

/** The object that contains the buffer model to render the pieces */
this.mesh = {
Expand Down Expand Up @@ -159,7 +157,6 @@ function gamefile(metadata, { moves = [], variantOptions, gameConclusion } = {})
/** The number of half-moves played since the last capture or pawn push. */
this.moveRuleState = this.gameRules.moveRule ? this.startSnapshot.moveRuleState : undefined;
area.initStartingAreaBox(this);

/** The move list. @type {Move[]} */
this.moves = [];
/** Index of the move we're currently viewing in the moves list. -1 means we're looking at the very beginning of the game. */
Expand Down
140 changes: 61 additions & 79 deletions src/client/scripts/game/chess/legalmoves.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
/** An object containing all the legal moves of a piece.
* @typedef {Object} LegalMoves
* @property {Object} individual - A list of the legal jumping move coordinates: `[[1,2], [2,1]]`
* @property {number[]} horizontal - A length-2 array containing the legal left and right slide limits: `[-5, Infinity]`
* @property {number[]} vertical - A length-2 array containing the legal bottom and top slide limits: `[-Infinity, 1]`
* @property {number[]} diagonalUp - A length-2 array containing the legal down-left, and up-right slides, where the number represents the `x` limit: `[-Infinity, 7]`
* @property {number[]} diagonalDown - A length-2 array containing the legal up-left, and down-right slides, where the number represents the `x` limit: `[3, 15]`
* @property {Object} sliding - A dict containing length-2 arrays with the legal left and right slide limits: `{[1,0]:[-5, Infinity]}`
*/

const legalmoves = (function(){
Expand All @@ -34,7 +31,9 @@ const legalmoves = (function(){
// For every piece moveset...
for (let i = 0; i < pieces.white.length; i++) {
const thisPieceType = pieces.white[i]
const thisPieceIndividualMoveset = getPieceMoveset(gamefile, thisPieceType).individual;
var thisPieceIndividualMoveset
if (getPieceMoveset(gamefile, thisPieceType).individual) thisPieceIndividualMoveset = getPieceMoveset(gamefile, thisPieceType).individual;
else thisPieceIndividualMoveset = []

// For each individual move...
for (let a = 0; a < thisPieceIndividualMoveset.length; a++) {
Expand Down Expand Up @@ -87,39 +86,34 @@ const legalmoves = (function(){
const thisPieceMoveset = getPieceMoveset(gamefile, type) // Default piece moveset

let legalIndividualMoves = [];
let legalHorizontalMoves;
let legalVerticalMoves;
let legalUpDiagonalMoves;
let legalDownDiagonalMoves;
let legalSliding = {};

if (!onlyCalcSpecials) {

// Legal jumping/individual moves

shiftIndividualMovesetByCoords(thisPieceMoveset.individual, coords)
legalIndividualMoves = moves_RemoveOccupiedByFriendlyPieceOrVoid(gamefile, thisPieceMoveset.individual, color)

// Legal sliding moves

let key = coords[1]; // Key is y level for horizontal slide
legalHorizontalMoves = slide_CalcLegalLimit(gamefile.piecesOrganizedByRow[key], false, thisPieceMoveset.horizontal, coords, color)
key = coords[0] // Key is x for vertical slide
legalVerticalMoves = slide_CalcLegalLimit(gamefile.piecesOrganizedByColumn[key], true, thisPieceMoveset.vertical, coords, color)
key = math.getUpDiagonalFromCoords(coords) // Key is -x + y for up-diagonal slide
legalUpDiagonalMoves = slide_CalcLegalLimit(gamefile.piecesOrganizedByUpDiagonal[key], false, thisPieceMoveset.diagonalUp, coords, color)
key = math.getDownDiagonalFromCoords(coords) // Key is x + y for down-diagonal slide
legalDownDiagonalMoves = slide_CalcLegalLimit(gamefile.piecesOrganizedByDownDiagonal[key], false, thisPieceMoveset.diagonalDown, coords, color)
if (thisPieceMoveset.sliding) {
let lines = gamefile.startSnapshot.slidingPossible;
for (let i=0; i<lines.length; i++) {
const line = lines[i];
if (!thisPieceMoveset.sliding[line]) continue;
const key = math.getKeyFromLine(line,coords);
legalSliding[line] = slide_CalcLegalLimit(gamefile.piecesOrganizedByLines[line][key],line, thisPieceMoveset.sliding[line], coords, color);
};
};

}

// Add any special moves!
if (gamefile.specialDetects[trimmedType]) gamefile.specialDetects[trimmedType](gamefile, coords, color, legalIndividualMoves)

let moves = {
individual: legalIndividualMoves,
horizontal: legalHorizontalMoves,
vertical: legalVerticalMoves,
diagonalUp: legalUpDiagonalMoves,
diagonalDown: legalDownDiagonalMoves,
sliding: legalSliding
}

// Skip if we've selected the opposite side's piece (edit mode)
Expand Down Expand Up @@ -164,47 +158,50 @@ const legalmoves = (function(){
return individualMoves;
}

// Takes in specified organized list, direction of the slide, the current moveset...
// Shortens the moveset by pieces that block it's path.
function slide_CalcLegalLimit (organizedLine, lineIsVertical, slideMoveset, coords, color) {
/**
* Takes in specified organized list, direction of the slide, the current moveset...
* Shortens the moveset by pieces that block it's path.
* @param {*} organizedLine
* @param {*} line
* @param {*} slidinget
* @param {*} coords
* @param {*} color
* @returns
*/
function slide_CalcLegalLimit (organizedLine, line, slidinget, coords, color) {

if (!slideMoveset) return // Return undefined if there is no slide moveset
if (!slidinget) return; // Return undefined if there is no slide moveset

// The default slide is [-Infinity, Infinity], change that if there are any pieces blocking our path!

// For most we'll be comparing the x values, only exception is the columns.
const zeroOrOne = lineIsVertical ? 1 : 0
const limit = [slideMoveset[0] + coords[zeroOrOne], slideMoveset[1] + coords[zeroOrOne]]

const zeroOrOne = line[0] == 0 ? 1 : 0
const limit = [slidinget[0], slidinget[1]]
// Iterate through all pieces on same line
for (let i = 0; i < organizedLine.length; i++) {
// What are the coords of this piece?
const thisPiece = organizedLine[i] // { type, coords }
const thisPieceXorY = thisPiece.coords[zeroOrOne]
const thisPieceSteps = Math.floor((thisPiece.coords[zeroOrOne]-coords[zeroOrOne])/line[zeroOrOne])
const thisPieceColor = math.getPieceColorFromType(thisPiece.type)
const isFriendlyPiece = color === thisPieceColor
const isVoid = thisPiece.type === 'voidsN';

// Is the piece to the left of us or right of us?
if (thisPieceXorY < coords[zeroOrOne]) { // To our left
if (thisPieceSteps < 0) { // To our left

// What would our new left slide limit be? If it's an opponent, it's legal to capture it.
const newLeftSlideLimit = isFriendlyPiece || isVoid ? thisPieceXorY + 1 : thisPieceXorY

const newLeftSlideLimit = isFriendlyPiece || isVoid ? thisPieceSteps + 1 : thisPieceSteps
// If the piece x is closer to us than our current left slide limit, update it
if (newLeftSlideLimit > limit[0]) limit[0] = newLeftSlideLimit

} else if (thisPieceXorY > coords[zeroOrOne]) { // To our right
} else if (thisPieceSteps > 0) { // To our right

// What would our new right slide limit be? If it's an opponent, it's legal to capture it.
const newRightSlideLimit = isFriendlyPiece || isVoid ? thisPieceXorY - 1 : thisPieceXorY

const newRightSlideLimit = isFriendlyPiece || isVoid ? thisPieceSteps - 1 : thisPieceSteps
// If the piece x is closer to us than our current left slide limit, update it
if (newRightSlideLimit < limit[1]) limit[1] = newRightSlideLimit

} // else this is us, don't do anything.
}

return limit;
}

Expand Down Expand Up @@ -237,38 +234,17 @@ const legalmoves = (function(){
}
}

// Do one of the horizontal moves match?
const horizontal = legalMoves.horizontal;
if (horizontal && endCoords[1] == startCoords[1]) {
// Compare the clicked x tile with this horizontal moveset
if (endCoords[0] >= horizontal[0] && endCoords[0] <= horizontal[1]) return true;
}

// Do one of the vertical moves match?
const vertical = legalMoves.vertical;
if (vertical && endCoords[0] == startCoords[0]) {
// Compare the clicked y tile with this vertical moveset
if (endCoords[1] >= vertical[0] && endCoords[1] <= vertical[1]) return true;
}
for (var strline in legalMoves.sliding) {
let line = math.getCoordsFromKey(strline);
let limits = legalMoves.sliding[strline];

// Do one of the up-diagonal moves match?
const diagonalUp = legalMoves.diagonalUp;
let selectedPieceDiagonal = math.getUpDiagonalFromCoords(startCoords);
let clickedCoordsDiagonal = math.getUpDiagonalFromCoords(endCoords);
if (diagonalUp && selectedPieceDiagonal == clickedCoordsDiagonal) {
// Compare the clicked x tile with this diagonal moveset
if (endCoords[0] >= diagonalUp[0] && endCoords[0] <= diagonalUp[1]) return true;
}
let selectedPieceLine = math.getKeyFromLine(line,startCoords);
let clickedCoordsLine = math.getKeyFromLine(line,endCoords);
if (!limits || selectedPieceLine !== clickedCoordsLine) continue;

// Do one of the down-diagonal moves match?
const diagonalDown = legalMoves.diagonalDown;
selectedPieceDiagonal = math.getDownDiagonalFromCoords(startCoords);
clickedCoordsDiagonal = math.getDownDiagonalFromCoords(endCoords);
if (diagonalDown && selectedPieceDiagonal == clickedCoordsDiagonal) {
// Compare the clicked x tile with this diagonal moveset
if (endCoords[0] >= diagonalDown[0] && endCoords[0] <= diagonalDown[1]) return true;
if (!doesSlidingNetContainSquare(limits, line, startCoords, endCoords)) continue;
return true;
}

return false;
}

Expand Down Expand Up @@ -334,7 +310,7 @@ const legalmoves = (function(){
// Test if that piece's legal moves contain the destinationCoords.
const legalMoves = legalmoves.calculate(gamefile, piecemoved);
// This should pass on any special moves tags at the same time.
if (!legalmoves.checkIfMoveLegal(legalMoves, moveCopy.startCoords, moveCopy.endCoords)) { // Illegal move
if (!legalmoves.checkIfMoveLegal(gamefile, legalMoves, moveCopy.startCoords, moveCopy.endCoords)) { // Illegal move
console.log(`Opponent's move is illegal because the destination coords are illegal. Move: ${JSON.stringify(moveCopy)}`)
return rewindGameAndReturnReason(`Destination coordinates are illegal. inCheck: ${JSON.stringify(gamefile.inCheck)}. attackers: ${JSON.stringify(gamefile.attackers)}. originalMoveIndex: ${originalMoveIndex}. inCheckB4Forwarding: ${inCheckB4Forwarding}. attackersB4Forwarding: ${JSON.stringify(attackersB4Forwarding)}`);
}
Expand Down Expand Up @@ -370,25 +346,31 @@ const legalmoves = (function(){
}
}

// TODO: moveset changes
// This requires coords be on the same line as the sliding moveset.
function doesSlideMovesetContainSquare (slideMoveset, lineIsVertical, coords) {
function doesSlidingNetContainSquare(slidinget, line, pieceCoords, coords) {

const xOrY = lineIsVertical ? coords[1] : coords[0];
const axis = line[0] === 0 ? 1 : 0
const coordMag = coords[axis];
const min = slidinget[0] * line[axis] + pieceCoords[axis]
const max = slidinget[1] * line[axis] + pieceCoords[axis]

if (xOrY < slideMoveset[0]) return false;
if (xOrY > slideMoveset[1]) return false;
if (coordMag < min) return false;
if (coordMag > max) return false;

return true;
}

// Accepts the calculated legal moves, tests to see if there are any
/**
* Accepts the calculated legal moves, tests to see if there are any
* @param {LegalMoves} moves
* @returns {boolean}
*/
function hasAtleast1Move (moves) { // { individual, horizontal, vertical, ... }

if (moves.individual.length > 0) return true;
if (doesSlideHaveWidth(moves.horizontal)) return true;
if (doesSlideHaveWidth(moves.vertical)) return true;
if (doesSlideHaveWidth(moves.diagonalUp)) return true;
if (doesSlideHaveWidth(moves.diagonalDown)) return true;
for (var line in moves.sliding)
if (doesSlideHaveWidth(moves.sliding[line])) return true;

function doesSlideHaveWidth(slide) { // [-Infinity, Infinity]
if (!slide) return false;
Expand All @@ -403,7 +385,7 @@ const legalmoves = (function(){
getPieceMoveset,
calculate,
checkIfMoveLegal,
doesSlideMovesetContainSquare,
doesSlidingNetContainSquare,
hasAtleast1Move,
slide_CalcLegalLimit,
isOpponentsMoveLegal
Expand Down
Loading