GAME / FREE / MIT EXAMPLE SOURCE

Quiet moves

A board for two

Local chess with legal moves, king safety, castling, en passant, promotion, checkmate, and stalemate.

Quiet moves, running as a native Yeho application on Windows
Actual native application capture. The downloadable source produces this example.

Take it for a spin.

Select a piece, then a highlighted destination. Choose promotion with Q, N, B, or T for rook. R resets.

Extract the Windows download to a writable folder and open chess.exe. Escape closes it. Database examples keep their local data in the working folder.

See how it works.

Value snapshots, pure move simulation, attack maps, and rule composition.

Local two-player chess. No AI, clocks, online play, repetition claims, or fifty-move draw adjudication.

READ / CHANGE / UNDERSTAND

The whole example is yours.

These are the exact files in the source download. Start with the model, then follow the window’s event loop. Comments explain the decisions.

model.yh
// Signed pieces encode side: positive is White, negative is Black.
// 1 pawn, 2 knight, 3 bishop, 4 rook, 5 queen, 6 king. Zero is empty.
Side(int piece) returns int
{
    if piece>0
    {
        return 1
    }
    if piece<0
    {
        return -1
    }
    return 0
}
Abs(int value) returns int
{
    if value<0
    {
        return -value
    }
    return value
}
Column(int square) returns int
{
    return square-square/8*8
}
Step(int value) returns int
{
    if value<0
    {
        return -1
    }
    if value>0
    {
        return 1
    }
    return 0
}
PieceName(int piece) returns text
{
    list of text names=["","P","N","B","R","Q","K"]
    return names[Abs(piece)]
}
class Chess
{
    list of int board=[]
    int turn=1
    int passant=-1
    bool whiteKing=true
    bool whiteQueen=true
    bool blackKing=true
    bool blackQueen=true
    text status="White to move"
    int moves=0
    Chess()
    {
        this.Reset()
    }
    Reset()
    {
        this.board=[-4, -2, -3, -5, -6, -3, -2, -4, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 4, 2, 3, 5, 6, 3, 2, 4]
        this.turn=1
        this.passant=-1
        this.whiteKing=true
        this.whiteQueen=true
        this.blackKing=true
        this.blackQueen=true
        this.status="White to move"
        this.moves=0
    }
    ClearPath(list of int position,int from,int to) returns bool
    {
        int x=Column(from)+Step(Column(to)-Column(from))
        int y=from/8+Step(to/8-from/8)
        while x!=Column(to) or y!=to/8
        {
            if position[y*8+x]!=0
            {
                return false
            }
            x=x+Step(Column(to)-Column(from))
            y=y+Step(to/8-from/8)
        }
        return true
    }
    // Attack tests deliberately ignore king safety and castling. Pawns attack
    // diagonally even when the target is empty; this matters for castling checks.
    Attacks(list of int position,int from,int to) returns bool
    {
        int piece=Abs(position[from])
        int dx=Column(to)-Column(from)
        int dy=to/8-from/8
        if piece==1
        {
            return Abs(dx)==1 and dy==-Side(position[from])
        }
        if piece==2
        {
            return (Abs(dx)==1 and Abs(dy)==2) or (Abs(dx)==2 and Abs(dy)==1)
        }
        if piece==6
        {
            return Abs(dx)<=1 and Abs(dy)<=1 and from!=to
        }
        bool shape=(piece==3 and Abs(dx)==Abs(dy)) or (piece==4 and (dx==0 or dy==0)) or (piece==5 and (dx==0 or dy==0 or Abs(dx)==Abs(dy)))
        return from!=to and shape and this.ClearPath(position,from,to)
    }
    Checked(list of int position,int side) returns bool
    {
        int king=-1
        for piece at i in position
        {
            if piece==side*6
            {
                king=i
            }
        }
        if king<0
        {
            return true
        }
        for piece at i in position
        {
            if Side(piece)==-side and this.Attacks(position,i,king)
            {
                return true
            }
        }
        return false
    }
    Apply(list of int position,int from,int to,int promotion=5) returns list of int
    {
        int piece=position[from]
        // Lists are value data here. Simulations must never mutate the live board.
        if Abs(piece)==1 and to==this.passant and position[to]==0
        {
            position[to+Side(piece)*8]=0
        }
        if Abs(piece)==6 and Abs(to-from)==2
        {
            int rook=from+3
            int destination=from+1
            if to<from
            {
                rook=from-4
                destination=from-1
            }
            position[destination]=position[rook]
            position[rook]=0
        }
        position[to]=piece
        position[from]=0
        if Abs(piece)==1 and (to/8==0 or to/8==7)
        {
            position[to]=Side(piece)*promotion
        }
        return position
    }
    Legal(int from,int to) returns bool
    {
        if from<0 or from>=64 or to<0 or to>=64 or from==to
        {
            return false
        }
        int piece=this.board[from]
        int side=Side(piece)
        int type=Abs(piece)
        if side!=this.turn or Side(this.board[to])==side or Abs(this.board[to])==6
        {
            return false
        }
        int dx=Column(to)-Column(from)
        int dy=to/8-from/8
        bool valid=false
        if type==1
        {
            int home=6
            if side==-1
            {
                home=1
            }
            valid=(dx==0 and dy==-side and this.board[to]==0) or (dx==0 and dy==-side*2 and from/8==home and this.board[to]==0 and this.board[from-side*8]==0) or (Abs(dx)==1 and dy==-side and (Side(this.board[to])==-side or (to==this.passant and this.board[to+side*8]==-side)))
        }
        else
        {
            valid=this.Attacks(this.board,from,to)
        }
        if type==6 and dy==0 and Abs(dx)==2 and ((side==1 and from==60) or (side==-1 and from==4))
        {
            bool rights=this.whiteKing
            if dx<0
            {
                rights=this.whiteQueen
            }
            if side==-1
            {
                rights=this.blackKing
                if dx<0
                {
                    rights=this.blackQueen
                }
            }
            int rook=from+3
            if dx<0
            {
                rook=from-4
            }
            valid=rights and this.board[rook]==side*4 and this.ClearPath(this.board,from,rook) and !this.Checked(this.board,side) and !this.Checked(this.Apply(this.board,from,from+Step(dx)),side)
        }
        return valid and !this.Checked(this.Apply(this.board,from,to),side)
    }
    Move(int from,int to,int promotion=5) returns bool
    {
        if !this.Legal(from,to) or promotion<2 or promotion>5
        {
            return false
        }
        int piece=this.board[from]
        this.board=this.Apply(this.board,from,to,promotion)
        // Rights are irreversible, including when a home rook is captured.
        if from==60
        {
            this.whiteKing=false
            this.whiteQueen=false
        }
        if from==4
        {
            this.blackKing=false
            this.blackQueen=false
        }
        if from==63 or to==63
        {
            this.whiteKing=false
        }
        if from==56 or to==56
        {
            this.whiteQueen=false
        }
        if from==7 or to==7
        {
            this.blackKing=false
        }
        if from==0 or to==0
        {
            this.blackQueen=false
        }
        this.passant=-1
        if Abs(piece)==1 and Abs(to-from)==16
        {
            this.passant=(to+from)/2
        }
        this.turn=-this.turn
        this.moves=this.moves+1
        this.status="White to move"
        if this.turn==-1
        {
            this.status="Black to move"
        }
        bool any=false
        for a from 0 < 64
        {
            if Side(this.board[a])==this.turn
            {
                for b from 0 < 64
                {
                    if this.Legal(a,b)
                    {
                        any=true
                        end
                    }
                }
            }
            if any
            {
                end
            }
        }
        bool check=this.Checked(this.board,this.turn)
        if check
        {
            this.status=this.status+" / check"
        }
        if !any
        {
            this.status="Stalemate"
            if check
            {
                this.status="Checkmate"
            }
        }
        return true
    }
}