Skip to content

Commit

Permalink
improve as refact array of bypass criteria parameter instead of stric…
Browse files Browse the repository at this point in the history
…t boolean
  • Loading branch information
snk-js committed Jun 4, 2023
1 parent 24775f3 commit 054d8d0
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 21 deletions.
25 changes: 19 additions & 6 deletions __tests__/validate_fen.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -524,13 +524,26 @@ test.each([
expect(validateFen(fen)).toMatchObject({ ok })
})

test('test non-strict fen validation', () => {
test('non-strict fen validation parameter (FEN with no kings)', () => {
const noKingFen = '8/8/8/8/4R3/8/8/8 w - - 0 1'
// chess: Chess(fen, strict) -> Chess
// strict is false will by bypass
// the 4th to 11th checks in validateFen
// most of them are about 8x8 board constraints
// king presence, and en passant rule matching
const chess = new Chess(noKingFen, false)
// strict is false will by bypass the 4th to 11th checks in validateFen

// 1st criterion: 6 space-seperated fields?
// 2nd criterion: move number field is a integer value > 0?
// 3rd criterion: half move counter is an integer >= 0?
// 4th criterion: 4th field is a valid e.p.-string?
// 5th criterion: 3th field is a valid castle-string?
// 6th criterion: 2nd field is "w" (white) or "b" (black)?
// 7th criterion: 1st field contains 8 rows?
// 8th criterion: every row is valid?
// 9th criterion: is en-passant square legal?
// 10th criterion: does chess position contain exact two kings?
// 11th criterion: are any pawns on the first or eighth rows?

const chess = new Chess(noKingFen, {
// if not strict, we don't need to check the remaining criterions
bypass: [4, 5, 6, 7, 8, 9, 10, 11],
})
expect(chess.fen()).toBe(noKingFen)
})
35 changes: 20 additions & 15 deletions src/chess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export type Square =
export const DEFAULT_POSITION =
'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'

export const DEFAULT_STRICT_FEN = true
export const DEFAULT_STRICT_FEN: number[] = []

export type Piece = {
color: Color
Expand Down Expand Up @@ -293,7 +293,7 @@ function swapColor(color: Color): Color {
return color === WHITE ? BLACK : WHITE
}

export function validateFen(fen: string, strict?: boolean) {
export function validateFen(fen: string, bypass?: number[]) {
let validations = []
const tokens = fen.split(/\s+/)

Expand Down Expand Up @@ -453,12 +453,8 @@ export function validateFen(fen: string, strict?: boolean) {
return { ok: true }
})

if (!strict) {
// if not strict, we don't need to check the remaining criterions
const notStrictCriterions = [4, 5, 6, 7, 8, 9, 10, 11]
validations = validations.filter(
(_, index) => !notStrictCriterions.includes(index + 1)
)
if (bypass?.length) {
validations = validations.filter((_, index) => !bypass.includes(index + 1))
}

for (let i = 0; i < validations.length; i++) {
Expand Down Expand Up @@ -581,6 +577,10 @@ function strippedSan(move: string) {
return move.replace(/=/, '').replace(/[+#]?[?!]*$/, '')
}

type Config = {
bypass: number[]
}

export class Chess {
private _board = new Array<Piece>(128)
private _turn: Color = WHITE
Expand All @@ -592,11 +592,15 @@ export class Chess {
private _history: History[] = []
private _comments: Record<string, string> = {}
private _castling: Record<Color, number> = { w: 0, b: 0 }
private _strict: boolean
private _bypass: number[]

constructor(fen = DEFAULT_POSITION, strict = DEFAULT_STRICT_FEN) {
this._strict = strict
this.load(fen, false, strict)
constructor(
fen = DEFAULT_POSITION,
config: Config = { bypass: DEFAULT_STRICT_FEN }
) {
const { bypass } = config
this._bypass = bypass
this.load(fen, false, bypass)
}

clear(keepHeaders = false) {
Expand All @@ -610,6 +614,7 @@ export class Chess {
this._history = []
this._comments = {}
this._header = keepHeaders ? this._header : {}
this._bypass = []
this._updateSetup(this.fen())
}

Expand All @@ -619,7 +624,7 @@ export class Chess {
}
}

load(fen: string, keepHeaders = false, strict = true) {
load(fen: string, keepHeaders = false, bypass = DEFAULT_STRICT_FEN) {
let tokens = fen.split(/\s+/)

// append commonly omitted fen tokens
Expand All @@ -630,7 +635,7 @@ export class Chess {

tokens = fen.split(/\s+/)

const { ok, error } = validateFen(fen, strict)
const { ok, error } = validateFen(fen, bypass)
if (!ok) {
throw new Error(error)
}
Expand Down Expand Up @@ -799,7 +804,7 @@ export class Chess {
}

reset() {
this.load(DEFAULT_POSITION, false, this._strict)
this.load(DEFAULT_POSITION, false, this._bypass)
}

get(square: Square) {
Expand Down

0 comments on commit 054d8d0

Please sign in to comment.