scalable reversi logic

(4+2n)**2グリッドのリバーシです。
a1 styleを経由して[getScale, getValue, getScaledValues, getValues, ...]を使用可能。

scalable reversi

declare

1. declare b, is0, is1
let b,is0,is1

2. declare is, fIs, tIs, pattern
const is=[],fIs=[],tIs=[],pattern=`([a-z]+)(\\d+)`

3. declare c8
,c8=(n,i,x,y,v,c)=>((fX,tX,fY,tY)=>{
    if(v<fX&&v<fY)c(i,-1-n,fX<fY?fX:fY)
    if(v<fY)c(i,-n,fY)
    if(v<tX&&v<fY)c(i,1-n,tX<fY?tX:fY)
    if(v<fX)c(i,-1,fX)
    if(v<tX)c(i,1,tX)
    if(v<fX&&v<tY)c(i,-1+n,fX<tY?fX:tY)
    if(v<tY)c(i,n,tY)
    if(v<tX&&v<tY)c(i,1+n,tX<tY?tX:tY)
})(x,n-x-1,y,n-y-1)

4. declare getBIs, setBIs, setB
,getBIs=(is,n,i,x,y)=>(c=>c8(n,i,x,y,1,c))((i,addend,l)=>{
    const isL=is.length
    while(l--&&is0.includes(i+=addend))is.push(i)
    if(!is1.includes(i))is.length=isL
})||is
,setBIs=(n,i,x,y)=>{
    const is=getBIs([i],n,i,x,y)
    forEach(false,is,i=>is1.push(i))
    is0.length=reduce(false,is0,(a,v)=>{
        if(!is.includes(v))is0[a++]=v
        return a
    },0)
}
,setB=(v=b)=>{
    [is0,is1]=(b=!v)?[fIs,tIs]:[tIs,fIs]
}

5. declare setIs
,setIs=n=>(is.length=0)||(c=>forEach(false,is0,i=>c8(n,i,i%n,i/n>>>0,0,c)))((i,addend)=>is0.includes(i+=addend)||is1.includes(i)||is.includes(i)||getBIs([],n,i,i%n,i/n>>>0).length&&is.push(i))

6. declare accessors
this.getB=()=>!b
this.hasI=i=>is.includes(i)
this.hasFI=i=>fIs.includes(i)
this.hasTI=i=>tIs.includes(i)
this.getLs=()=>[fIs.length,tIs.length]

getValue

7. declare this.getValue
this.getValue=(n,x,y)=>setBIs(n,x+y*n,x,y)||setB()||setIs(n)||!is.length&&setB()||setIs(n)||new Col(x).alphabet+(1+y)

getScale

7. declare regExp
const regExp=RegExp(`^${pattern}${pattern}`)

8. declare vs
,vs=(vs=>map(false,[new Uint8Array(12),new Uint8Array(12)],(v,i)=>{
    v.set(map(false,3,i?(v=>(_,i)=>v|vs[1+i])(vs[0]<<4):(c=>(v=>(_,i)=>v|c(vs[1+i]))(c(vs[0])<<4))(v=>0b1100&v|0b11^0b0011&v)))
    v.set(map(false,3,(_,i)=>(0b11000000&v[i])>>2|(0b00110000&v[i])<<2|(0b00001100&v[i])>>2|(0b00000011&v[i])<<2),3)
    v.set(map(false,6,(_,i)=>0b11111111^v[i]),6)
    return v
}))(new Uint8Array([0b0001,0b0000,0b0010,0b1000]))

9. declare this.getScale
this.getScale=v=>(v=v.match(regExp))&&(v=[new Col(v[1]).number,v[2]-1,new Col(v[3]).number,v[4]-1])&&(p=>{
    p=4>p?0:p-3
    forEach(false,4,(_,i)=>v[i]-=p)
    const b=1&(v[0]-v[1])
    v=v[0]<<6|v[1]<<4|v[2]<<2|v[3]<<0
    for(let i=0;i<4;i++,p++,v-=0b01010101)if(vs[b].includes(v))return[4+(p<<1),b]
})(reduce(false,v,(a,v)=>a.limit(false,v),0))

getScaledValues, getValues

7. declare regExp
const regExp=RegExp(pattern,`g`)

getScaledValues

8. declare this.getScaledValues
this.getScaledValues=(v,addend)=>(v=v.matchAll(regExp))&&(vs=>{
    for(v of v)vs+=new Col(new Col(v[1]).number+addend).alphabet+(Number(v[2])+addend)
    return vs
})(``)

getValues

8. declare this.getValues
this.getValues=(n,{b,v=``,l=-1})=>(fIs.length=tIs.length=0)||(v=>(fIs[0]=(tIs[0]=(v-n)/2)-1)&&(tIs[1]=(fIs[1]=(v+n)/2)-1))(n**2)&&setB(b)||(v=v.matchAll(regExp))&&(vs=>{
    const length=l,c=(x,y)=>!l||!(x<n&&y<n)||(i=>setB()||setIs(n)||!is.includes(i)&&setB()||setIs(n)||!is.includes(i)||!l--||setBIs(n,i,x,y)||!(vs+=v[0]))(x+y*n)
    for(v of v)if(c(new Col(v[1]).number,v[2]-1))break
    return vs&&setB()||setIs(n)||[vs,0>length?~l:length]
})(``)