Check out Symmetric Chess, our featured variant for March, 2024.


[ Help | Earliest Comments | Latest Comments ]
[ List All Subjects of Discussion | Create New Subject of Discussion ]
[ List Earliest Comments Only For Pages | Games | Rated Pages | Rated Games | Subjects of Discussion ]

Single Comment

The Fairychess Include File Tutorial. How to use the fairychess include file to program games for Game Courier.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Wed, Jan 11, 2023 02:49 AM UTC:

I have now written a subroutine that can solve mate-in-one problems for games using the checked and stalemated subroutine in the fairychess include file. When you compose a mate-in-one problem and click on Solve, it will tell you whether it has found a single solution to your problem and what it is. If it has, it will be the only legal move displayed. After making the move, you can click on Compose to enter the solution into your composition. Here is the subroutine:

// Finds each mating move in current position.
// Parameters:
// side: which side is moving
sub findmates side:
    local enemyking extramates king mates moves mv;

    setsystem showoutput true;
    if match #side 1 white White first:
        set king #Kpos;
        set enemyking #kpos;
    else:
        set king #kpos;
        set enemyking #Kpos;
    endif;
    set mates ();
    set extramates ();
    ban none;
    setsystem maxmove 0;
    store main;
    setsystem legalmoves ();
    if not sub stalemated #king:
        set lglmvs $legalmoves;
        foreach move #lglmvs:
            move #move.0 #move.1;
            if sub checked #enemyking:
                setsystem legalmoves ();
                if sub stalemated #enemyking:
                    push mates #move;
                endif;
            endif;
            restore main;
        next;
        set extmvs ();
        if isarray $extralegal:
            set extmvs unique $extralegal;
        endif;
        foreach move #extmvs:
            set moves explode chr 59 #move;
            foreach mv #moves:
                set mv trim #mv;
                eval "MOVE: {#mv}";
            next;
            if sub checked #enemyking:
                setsystem legalmoves ();
                if sub stalemated #enemyking:
                    push extramates #move;
                endif;
            endif;
            restore main;
        next;
    endif;
    setsystem legalmoves #mates;
    setsystem extralegal #extramates;
endsub;

This works by trying all legal moves. For each move, it first tests whether it checks the enemy King, and if it does, it additionally checks if it leaves the opponent with no legal moves. When it's finished, it writes its solutions to the variables that will be used to create the $legalList array, which will be used to display legal moves and populate the Moves field with possible values to enter with it.

Since the $legalList variable is not populated until after the GAME Code program has finished running, this sets $legalmoves and $extralegal separately. The $legalmoves array lists legal moves as coordinate pairs, and the $extralegal array lists them as notation, which is helpful when a move includes more than just a single move from one space to another.

One of the challenges in writing this was figuring out how to execute a move written as notation. When I initially tried it, it wouldn't allow it. What I eventually did was set $maxmoves to zero and turn off all bans. Since this subroutine is run at the very end of the GAME Code program, this doesn't hurt anything. This let me execute the move with the eval command.