#chess.mpl, version 0.6 # # maple commands to read chess moves and display # positions on a board. Some other commands exist # but (so far:) it cannot play chess. # #3-2000,wdj ###############################################################3 ############ file reading and parsing procedures read_in_file:=proc(s::string) #reads in a file, one line at a time, #and prints it out on the screen #s is the filename, eg, s="c:/maple5/bin.wnt/myfile.txt" local line,last,first; first := readline(s); print(first); line := readline(s); while line <> 0 do last := line; print(last); line := readline(s) od; end: read_in_file_to_array:=proc(s::string) #reads in a file, one line at a time, #and prints it out on the screen #s is the filename, eg, s="c:/maple5/bin.wnt/myfile.txt" local FILE,j,line_count,line,last,first,file_array; first := readline(s); line_count:=1; file_array[1]:=first; #lprint(first,` line `,1); line := readline(s); while line <> 0 do line_count:=line_count+1; last := line; file_array[line_count]:=last; #lprint(` line `,line_count,last); #print(last); line := readline(s) od; FILE:=[seq(file_array[j],j=1..line_count)]; RETURN(FILE); end: read_in_file_to_arrays:=proc(s::string) #reads in a file, one line at a time, #and prints it out on the screen **one character at a time** #s is the filename, eg, s="c:/maple5/bin.wnt/myfile.txt" local FILE,j,line_count,line,last,first,file_array,i; first := readline(s); line_count:=1; file_array[1]:=[seq(substring(first,i..i),i=1..length(first))]; lprint(first); line := readline(s); while line <> 0 do line_count:=line_count+1; last := line; file_array[line_count]:=[seq(substring(last,i..i),i=1..length(last))]; #lprint(file_array[line_count],line_count); #print(last); line := readline(s) od; FILE:=[seq(file_array[j],j=1..line_count)]; RETURN(FILE); end: read_moves_from_arrays := proc(L::list) local i, j, k, moves_white, moves_black, numstring, x, y, move, moves; k := 0; moves := []; for i from 0 to 100 do numstring[i] := convert(i, string) end do; for j to nops(L) - 10 do if L[j] = ";" then break end if; if member(L[j], {seq(numstring[i], i = 0 .. 9)}) and L[j + 1] = "." then k := k + 1; moves_white[k] := [seq(L[j + 2 + i], i = 1 .. 7)] ; moves_black[k] := [seq(L[j + 17 + i], i = 1 .. 7)] end if end do; moves := [seq([moves_white[j], moves_black[j]], j = 1 .. k)]; RETURN(moves) end: #read moves from arrays #########translate from chessmaster lan notation to maple chess notation ######## translate_white := proc(s::list) local i, j, move, move1, move2, s1, s2; if s[1] = "O" and s[3] = "O" and s[5] = "O" then move := ["O-O-O"] end if; if s[1] = "O" and s[3] = "O" and s[5] <> "O" then move := ["O-O"] end if; if member(convert(s[1], symbol), {b, f, a, c, g, h, e, d}) and s[3] = "-" then move1 := cat("P", s[1], s[2]); move1 := convert(move1, symbol); if s[3] = "-" then move2 := cat("P", s[4], s[5]) end if; move2 := convert(move2, symbol); if s[6] <> "=" then move := [move1, move2] end if; if s[6] = "=" then move := [move1, move2, "promote", convert(s[7], symbol)] end if end if; if member(convert(s[1], symbol), {b, f, a, c, g, h, e, d}) and s[3] = "x" then move1 := cat("P", s[1], s[2]); move1 := convert(move1, symbol); if s[3] = "x" then move2 := cat("P", s[4], s[5]) end if; move2 := convert(move2, symbol); if s[6] <> "=" then move := [move1, move2, "capture"] end if; if s[6] = "=" then move := [move1, move2, "capture", "promote", convert(s[7], symbol)] end if end if; if member(convert(s[1], symbol), {N, B, Q, K, R}) and s[4] = "-" then move1 := cat(s[1], s[2], s[3]); move1 := convert(move1, symbol); if s[4] = "-" then move2 := cat(s[1], s[5], s[6]) end if; move2 := convert(move2, symbol); move := [move1, move2] end if; if member(convert(s[1], symbol), {N, B, Q, K, R}) and s[4] = "x" then move1 := cat(s[1], s[2], s[3]); move1 := convert(move1, symbol); if s[4] = "x" then move2 := cat(s[1], s[5], s[6]) end if; move2 := convert(move2, symbol); move := [move1, move2, "capture"] end if; RETURN(move) end: #translate white upper_to_lower_case := proc(sym::string) local letters, Letters, i, j, isin, k; letters := ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]; Letters := ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]; isin := member(sym, Letters, k); if isin = true then RETURN(letters[k]) end if; RETURN(false) end: #upper to lower case translate_black := proc(s::list) local i, j, move, move1, move2, s1, s2; if s[1] = "O" and s[3] = "O" and s[5] = "O" then move := ["o-o-o"] end if; if s[1] = "O" and s[3] = "O" and s[5] <> "O" then move := ["o-o"] end if; if member(convert(s[1], symbol), {b, f, a, c, g, h, e, d}) and s[3] = "-" then move1 := cat("p", s[1], s[2]); move1 := convert(move1, symbol); if s[3] = "-" then move2 := cat("p", s[4], s[5]) end if; move2 := convert(move2, symbol); if s[6] <> "=" then move := [move1, move2] end if; if s[6] = "=" then move := [move1, convert( cat(upper_to_lower_case(s[7]), s[4], s[5]), symbol), "promote", convert(upper_to_lower_case(s[7]), symbol)] end if end if; if member(convert(s[1], symbol), {b, f, a, c, g, h, e, d}) and s[3] = "x" then move1 := cat("p", s[1], s[2]); move1 := convert(move1, symbol); if s[3] = "x" then move2 := cat("p", s[4], s[5]) end if; move2 := convert(move2, symbol); if s[6] <> "=" then move := [move1, move2, "capture"] end if; if s[6] = "=" then move := [move1, convert( cat(upper_to_lower_case(s[7]), s[4], s[5]), symbol), "capture", "promote", convert(upper_to_lower_case(s[7]), symbol)] end if end if; if member(convert(s[1], symbol), {N, B, Q, K, R}) and s[4] = "-" then move1 := cat(upper_to_lower_case(s[1]), s[2], s[3]); move1 := convert(move1, symbol); if s[4] = "-" then move2 := cat(upper_to_lower_case(s[1]), s[5], s[6]) end if; move2 := convert(move2, symbol); move := [move1, move2] end if; if member(convert(s[1], symbol), {N, B, Q, K, R}) and s[4] = "x" then move1 := cat(upper_to_lower_case(s[1]), s[2], s[3]); move1 := convert(move1, symbol); if s[4] = "x" then move2 := cat(upper_to_lower_case(s[1]), s[5], s[6]) end if; move2 := convert(move2, symbol); move := [move1, move2, "capture"] end if; if s[1]="." and s[2]="." then RETURN(); fi; RETURN(move) end: #takes a lan game from chessmaster and translates it to #my maple chess notation translate_game := proc(game::list) local i, L, L0, moves; for i to nops(game) do L[i] := read_moves_from_arrays(game[i]) end do; moves := []; for i to nops(game) do if 0 < nops(L[i]) then moves := [op(moves), translate_white(op(L[i])[1]), translate_black(op(L[i])[2])] end if end do; RETURN(moves) end: #translate game translate_chessmaster_game := proc(game::list) RETURN(translate_game(game)); end: ########### GRAPHICS, PIECE PLOTTING, ... one_poly := [[0,0],[0,5],[5,5] ,[5,0]]: greensquare:=polygonplot(one_poly,axes=boxed,color=green,style=patch): whitesquare:=polygonplot(one_poly,axes=boxed,style=patch): king_poly := [[1,1],[4,1],[4,0],[1,0],[1,1],[.7,5/2],[1,4],[3/2,4.5],[2,3.7], [2.5,1],[2,3.7],[2.5,4.7],[3,3.7],[2.5,1],[3,3.7], [3.5,4.5],[4,4],[4.3,5/2],[4,1],[4,0],[1,0],[1,1]]: rking:=display([polygonplot(king_poly,axes=boxed,view=[-0.2..5.2,0..5],color=red),whitesquare]): yking:=display([polygonplot(king_poly,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),whitesquare]): #yking:=polygonplot(king_poly,axes=boxed,view=[-0.2..5.2,0..5],color=yellow): #rking:=polygonplot(king_poly,axes=boxed,view=[-0.2..5.2,0..5],color=red): grking:=display([polygonplot(king_poly,axes=boxed,view=[-0.2..5.2,0..5],color=red),greensquare]): gyking:=display([polygonplot(king_poly,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),greensquare]): queen_poly := [[2.5,0],[1,0],[1,1],[4,1],[4,0],[1,0],[1,1],[1,4.5],[3/2,3],[2,4.5],[2.5,2.5],[3,4.5],[3.5,3],[4,4.5],[4,1],[4,0],[2.5,0]]: yqueen:=display([polygonplot(queen_poly,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),whitesquare]): rqueen:=display([polygonplot(queen_poly,axes=boxed,view=[-0.2..5.2,0..5],color=red),whitesquare]): #yqueen:=polygonplot(queen_poly,axes=boxed,view=[-0.2..5.2,0..5],color=yellow): #rqueen:=polygonplot(queen_poly,axes=boxed,view=[-0.2..5.2,0..5],color=red): gyqueen:=display([polygonplot(queen_poly,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),greensquare]): grqueen:=display([polygonplot(queen_poly,axes=boxed,view=[-0.2..5.2,0..5],color=red),greensquare]): bishop_poly := [[2.5,0],[1,0],[1,1],[4,1],[4,0],[1,0],[1,1],[1.8,1],[1,2.5],[2.5,4.5],[4,2.5],[3.2,1],[4,1],[4,0],[1,0],[2.5,0]]: plus_sign:=[[2.5,1.3],[2.5,3],[1.7,3],[3.3,3],[2.5,3],[2.5,3.7],[2.5,1.3]]: ybishop:=display([polygonplot(bishop_poly,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),polygonplot(plus_sign,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),whitesquare]): rbishop:=display([polygonplot(bishop_poly,axes=boxed,view=[-0.2..5.2,0..5],color=red),polygonplot(plus_sign,axes=boxed,view=[-0.2..5.2,0..5],color=red),whitesquare]): grbishop:=display([polygonplot(bishop_poly,axes=boxed,view=[-0.2..5.2,0..5],color=red),polygonplot(plus_sign,axes=boxed,view=[-0.2..5.2,0..5],color=red),greensquare]): gybishop:=display([polygonplot(bishop_poly,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),polygonplot(plus_sign,axes=boxed,view=[-0.2..5.2,0..5],color=red),greensquare]): pawn_poly := [[2.5,1],[1,1],[4,1],[4,0],[1,0],[1,1],[1.9,1],[1.9,1.6],[1.2,2.6],[2.5,3.5],[3.8,2.6],[3.1,1.6],[3.1,1],[4,1],[2.5,1]]: ypawn:=display([polygonplot(pawn_poly,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),whitesquare]): rpawn:=display([polygonplot(pawn_poly,axes=boxed,view=[-0.2..5.2,0..5],color=red),whitesquare]): grpawn:=display([polygonplot(pawn_poly,axes=boxed,view=[-0.2..5.2,0..5],color=red),greensquare]): gypawn:=display([polygonplot(pawn_poly,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),greensquare]): rook_poly1 := [[1,1],[4,1],[4,0],[1,0],[1,1]]: rook_poly2:=[[2.5,4],[1,4],[1,3.5],[1.8,3.5],[1.8,1],[1.8,3.5],[1,3.5],[1,4],[4,4],[4,3.5],[3.2,3.5],[3.2,1],[1.8,1],[1.8,3.5],[1,3.5],[1,4]]: yrook:=display([polygonplot(rook_poly1,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),polygonplot(rook_poly2,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),whitesquare]): rrook:=display([polygonplot(rook_poly1,axes=boxed,view=[-0.2..5.2,0..5],color=red),polygonplot(rook_poly2,axes=boxed,view=[-0.2..5.2,0..5],color=red),whitesquare]): gyrook:=display([polygonplot(rook_poly1,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),polygonplot(rook_poly2,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),greensquare]): grrook:=display([polygonplot(rook_poly1,axes=boxed,view=[-0.2..5.2,0..5],color=red),polygonplot(rook_poly2,axes=boxed,view=[-0.2..5.2,0..5],color=red),greensquare]): knight_poly := [[2,2],[1,1],[4,1],[4,0],[1,0],[1,1],[2,2],[1,2],[1,3],[2,4],[4,4],[4,1],[1,1],[2,2]]: yknight:=display([polygonplot(knight_poly,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),whitesquare]): rknight:=display([polygonplot(knight_poly,axes=boxed,view=[-0.2..5.2,0..5],color=red),whitesquare]): grknight:=display([polygonplot(knight_poly,axes=boxed,view=[-0.2..5.2,0..5],color=red),greensquare]): gyknight:=display([polygonplot(knight_poly,axes=boxed,view=[-0.2..5.2,0..5],color=yellow),greensquare]): board0:=[[grrook,rknight,grbishop,rqueen,grking,rbishop,grknight,rrook], [rpawn,grpawn,rpawn,grpawn,rpawn,grpawn,rpawn,grpawn], [greensquare,whitesquare,greensquare,whitesquare,greensquare,whitesquare,greensquare,whitesquare], [whitesquare,greensquare,whitesquare,greensquare,whitesquare,greensquare,whitesquare,greensquare], [greensquare,whitesquare,greensquare,whitesquare,greensquare,whitesquare,greensquare,whitesquare], [whitesquare,greensquare,whitesquare,greensquare,whitesquare,greensquare,whitesquare,greensquare], [gypawn,ypawn,gypawn,ypawn,gypawn,ypawn,gypawn,ypawn], [yrook,gyknight,ybishop,gyqueen,yking,gybishop,yknight,gyrook]]: convert_board:=proc(board_in::array) ## convert board to array plot structure local board_out,board,i,j; global p,P,k,K,n,N,q,Q,R,r,b,B; for i from 1 to 8 do for j from 1 to 8 do if type(i+j,odd) then if board_in[i,j]=P then board_out[i,j]:=gypawn; fi; if board_in[i,j]=N then board_out[i,j]:=gyknight; fi; if board_in[i,j]=B then board_out[i,j]:=gybishop; fi; if board_in[i,j]=R then board_out[i,j]:=gyrook; fi; if board_in[i,j]=Q then board_out[i,j]:=gyqueen; fi; if board_in[i,j]=K then board_out[i,j]:=gyking; fi; if board_in[i,j]=0 then board_out[i,j]:=greensquare; fi; fi; if type(i+j,even) then if board_in[i,j]=P then board_out[i,j]:=ypawn; fi; if board_in[i,j]=N then board_out[i,j]:=yknight; fi; if board_in[i,j]=B then board_out[i,j]:=ybishop; fi; if board_in[i,j]=R then board_out[i,j]:=yrook; fi; if board_in[i,j]=Q then board_out[i,j]:=yqueen; fi; if board_in[i,j]=K then board_out[i,j]:=yking; fi; if board_in[i,j]=0 then board_out[i,j]:=whitesquare; fi; fi; if type(i+j,odd) then if board_in[i,j]=p then board_out[i,j]:=grpawn; fi; if board_in[i,j]=n then board_out[i,j]:=grknight; fi; if board_in[i,j]=b then board_out[i,j]:=grbishop; fi; if board_in[i,j]=r then board_out[i,j]:=grrook; fi; if board_in[i,j]=q then board_out[i,j]:=grqueen; fi; if board_in[i,j]=k then board_out[i,j]:=grking; fi; if board_in[i,j]=0 then board_out[i,j]:=greensquare; fi; fi; if type(i+j,even) then if board_in[i,j]=p then board_out[i,j]:=rpawn; fi; if board_in[i,j]=n then board_out[i,j]:=rknight; fi; if board_in[i,j]=b then board_out[i,j]:=rbishop; fi; if board_in[i,j]=r then board_out[i,j]:=rrook; fi; if board_in[i,j]=q then board_out[i,j]:=rqueen; fi; if board_in[i,j]=k then board_out[i,j]:=rking; fi; if board_in[i,j]=0 then board_out[i,j]:=whitesquare; fi; fi; od; od; board:=array([seq([seq(board_out[i,j],j=1..8)],i=1..8)]); RETURN(evalm(board)); end: game_animation:=proc(game::list) local i,board_in,j,position; print(`loading positions; depending on the length of the game, this can take awhile...`); for i from 1 to nops(game) do board_in:=move_piece(board_start,game[i]); position[i]:=display(convert_board(board_in),axes=none): od: display([seq(position[j],j=1..nops(game))],insequence=true,title=`best if viewed at <3 frames per second`); end: ################ parsers, move notation, ... chess_squares:={seq(seq([i,j],i=1..8),j=1..8)}: array_to_algebraic_notation := proc(piece,x, y) local r, s, L1, L2; L1 := [a, b, c, d, e, f, g, h]; L2 := [8,7,6,5,4,3,2,1]; RETURN(cat(piece,L1[x], L2[y])) end: #end proc: algebraic_notation := proc(x, y) local r, s, L1, L2; L1 := [a, b, c, d, e, f, g, h]; L2 := [1, 2, 3, 4, 5, 6, 7, 8]; RETURN(cat(L1[x], L2[y])) end: #end proc: #FENparser := proc(s) #local n, row0, board, x, y, h,i, j, k, m, sym; #for j from 0 to 8 do # sym[j]:=convert(j,symbol); #od; # for i to 8 do # row0[i] := []; # for j to length(s[i]) do # n := convert_string_to_list(s[i])[j]; #print(i, j, n, whattype(n), member(n, [seq(sym[h],h=1..8)],k),k,whattype(k)); # if member(n, {seq(sym[h],h=1..8)}) then # member(n, {seq(sym[h],h=1..8)},k); # row0[i] := [op(row0[i]),seq(0, m = 1 .. k)] # else # if n=sym[0] then row0[i] := [op(row0[i]), 0];fi; # if n<>sym[0] then row0[i] :=[op(row0[i]), n]; fi; # end if # od; # print(row0[i]) # od; # board := array([seq(row0[j], j = 1 .. 8)]); # RETURN(evalm(board)) #end: #end proc: fen_parser:=proc(s::string) ## ## FEN notation string s ## must be in the form s="8/7p/k7/K7/8/8/8/8" ## local i,j,L,rows,R,count; L:=[]; for i from 1 to 8 do rows[i]:=""; od; for j from 1 to length(s) do L:=[op(L),substring(s,j..j)]; od; count:=1; for i from 1 to nops(L) do if L[i]<>"/" then rows[count]:=cat(rows[count],L[i]); fi; if L[i]="/" then count:=count+1; fi; od; R:=[seq(rows[i],i=1..8)]; RETURN(FENparser(R)); end: FENparser := proc(s) local n, row0, board, x, y, h,i, j, k, m, sym; for j from 0 to 8 do sym[j]:=convert(j,symbol); od; for i to 8 do row0[i] := []; for j to length(s[i]) do n := convert_string_to_list(s[i])[j]; #print(i,j,n, whattype(n), member(n, [seq(sym[h],h=1..8)],k),k,whattype(k)); y:=member_location(n, [seq(sym[h],h=1..8)]); if y[1] then # print("yes",y,n,i); k:=y[2]; row0[i] := [op(row0[i]),seq(0, m = 1 .. k)] else if n=sym[0] then row0[i] := [op(row0[i]), 0];fi; if n<>sym[0] then row0[i] :=[op(row0[i]), n]; fi; fi od; # print(row0[i]) od; board := array([seq(row0[j], j = 1 .. 8)]); RETURN(evalm(board)) end: member_location:=proc(x,S::list) local L,i,j,s; for i from 1 to nops(S) do if x=S[i] then RETURN([true,i]); fi; od; RETURN([false,0]); end: convert_string_to_list := proc(s) local len, L, i, x; len := length(s); if len = 1 then RETURN([convert(s,symbol)]) fi; #end if; L := []; for i to len do L := [op(L), convert(substring(s, i), symbol)] od; RETURN(L) end: #end proc: move_piece:=proc(board::array,move::list) #move =[x,y], x=old square=[piece,x1,x2], y=new square=[piece,y1,y2] #x1, y1 = {a,b,...,h}, x2,y2 = {1,2, ..., 8} #board is 8x8 array of pieces and 0's local square,square1,square2,i,j,m,board0,board1,sym; board0:=array(1..8,1..8); board0:=board; board1:=array(1..8,1..8); square:=[[0,0],[0,0]]; for j from 1 to 8 do sym[j]:=convert(j,symbol); od; for i from 1 to 2 do if substring(move[i],2)=a then square[i,1]:=1; fi; if substring(move[i],2)=b then square[i,1]:=2; fi; if substring(move[i],2)=c then square[i,1]:=3; fi; if substring(move[i],2)=d then square[i,1]:=4; fi; if substring(move[i],2)=e then square[i,1]:=5; fi; if substring(move[i],2)=f then square[i,1]:=6; fi; if substring(move[i],2)=g then square[i,1]:=7; fi; if substring(move[i],2)=h then square[i,1]:=8; fi; if substring(move[i],3)=sym[1] then square[i,2]:=8; fi; if substring(move[i],3)=sym[2] then square[i,2]:=7; fi; if substring(move[i],3)=sym[3] then square[i,2]:=6; fi; if substring(move[i],3)=sym[4] then square[i,2]:=5; fi; if substring(move[i],3)=sym[5] then square[i,2]:=4; fi; if substring(move[i],3)=sym[6] then square[i,2]:=3; fi; if substring(move[i],3)=sym[7] then square[i,2]:=2; fi; if substring(move[i],3)=sym[8] then square[i,2]:=1; fi; od; for m from 1 to 8 do for j from 1 to 8 do if (m=square[1,2] and j=square[1,1]) then #board0[m,j]:=board[m,j];else board0[m,j]:=0; fi; if (m=square[2,2] and j=square[2,1]) then #board0[m,j]:=board[m,j]; else board0[m,j]:=substring(move[2],1); fi; od; od; board1:=array([seq([seq(board0[i,j],j=1..8)],i=1..8)]); RETURN(evalm(board1)); end: ## ## reads in a list of moves in maple long algebraic notation ## move_game:=proc(board::array,moves::list) #move =[x,y], x=old square, y=new square #board is 8x8 array of pieces and 0's local moves0,i,j,m,board0,board1,sym; board0:=board; moves0:=[]; for i from 1 to nops(moves)-1 do if (nargs=3 and type(i,odd)) then if (moves[i]<>["O-O"] and moves[i]<>["O-O-O"] and moves[i+1]<>["o-o"] and moves[i+1]<>["o-o-o"]) then print(floor(i/2)+1,` `,moves[i][1],`--`,moves[i][2],` `, moves[i+1][1],`--`,moves[i+1][2]); fi; if ((moves[i]=["O-O"] or moves[i]=["O-O-O"]) and moves[i+1]<>["o-o"] and moves[i+1]<>["o-o-o"]) then print(floor(i/2)+1,` `,op(moves[i]),` `, moves[i+1][1],`--`,moves[i+1][2]); fi; if (moves[i]<>["O-O"] and moves[i]<>["O-O-O"] and (moves[i+1]=["o-o"] or moves[i+1]=["o-o-o"])) then print(floor(i/2)+1,` `,moves[i][1],`--`,moves[i][2],` `, op(moves[i+1])); fi; fi; od; i:=nops(moves); if (nargs=3 and type(i,odd)) then if (moves[i]<>["O-O"] and moves[i]<>["O-O-O"]) then print(floor(i/2)+1,` `,moves[i][1],`--`,moves[i][2]); fi; if ((moves[i]=["O-O"] or moves[i]=["O-O-O"])) then print(floor(i/2)+1,` `,op(moves[i])); fi; #if (moves[i]<>["O-O"] and moves[i]<>["O-O-O"]) then # print(floor(i/2)+1,` `,moves[i][1],`--`,moves[i][2]); #fi; fi; for i from 1 to nops(moves) do if (moves[i]<>["O-O"] and moves[i]<>["O-O-O"] and moves[i]<>["o-o"] and moves[i]<>["o-o-o"]) then moves0:=[op(moves0),moves[i]]; fi; if (moves[i]=["O-O"]) then moves0:=[op(moves0),[Ke1,Kg1],[Rh1,Rf1]]; fi; if (moves[i]=["o-o"]) then moves0:=[op(moves0),[ke8,kg8],[rh8,rf8]]; fi; if moves[i]=["o-o-o"] then moves0:=[op(moves0),[ke8,kc8],[ra8,rd8]]; fi; if moves[i]=["O-O-O"] then moves0:=[op(moves0),[Ke1,Kc1],[Ra1,Rd1]]; fi; od; for i from 1 to nops(moves0) do board0:=move_piece(board0,moves0[i]); od; RETURN(evalm(board0)); end: convert_to_array_notation:=proc(move::list) local square,i,j,s,sym; for j from 1 to 8 do sym[j]:=convert(j,symbol); od; for i from 1 to 2 do if substring(move[i],2)=a then square[i,1]:=1; fi; if substring(move[i],2)=b then square[i,1]:=2; fi; if substring(move[i],2)=c then square[i,1]:=3; fi; if substring(move[i],2)=d then square[i,1]:=4; fi; if substring(move[i],2)=e then square[i,1]:=5; fi; if substring(move[i],2)=f then square[i,1]:=6; fi; if substring(move[i],2)=g then square[i,1]:=7; fi; if substring(move[i],2)=h then square[i,1]:=8; fi; if substring(move[i],3)=sym[1] then square[i,2]:=8; fi; if substring(move[i],3)=sym[2] then square[i,2]:=7; fi; if substring(move[i],3)=sym[3] then square[i,2]:=6; fi; if substring(move[i],3)=sym[4] then square[i,2]:=5; fi; if substring(move[i],3)=sym[5] then square[i,2]:=4; fi; if substring(move[i],3)=sym[6] then square[i,2]:=3; fi; if substring(move[i],3)=sym[7] then square[i,2]:=2; fi; if substring(move[i],3)=sym[8] then square[i,2]:=1; fi; od; if abs(square[1,2]-square[2,2])=2 then RETURN([[substring(move[1],1),square[1,1],square[1,2]],[substring(move[1],1),square[2,1],square[2,2]],"first"]) #the "first" tag may help keep track of when a pawn can be captured ep else RETURN([[substring(move[1],1),square[1,1],square[1,2]],[substring(move[1],1),square[2,1],square[2,2]]]); fi; end: convert_from_array_notation:=proc(square::list) local move,i,j,s,sym; for j from 1 to 8 do sym[j]:=convert(j,symbol); od; for i from 1 to 2 do if square[i,2]=1 then move[i]:=cat(square[i,1],a); fi; if square[i,2]=2 then move[i]:=cat(square[i,1],b); fi; if square[i,2]=3 then move[i]:=cat(square[i,1],c); fi; if square[i,2]=4 then move[i]:=cat(square[i,1],d); fi; if square[i,2]=5 then move[i]:=cat(square[i,1],e); fi; if square[i,2]=6 then move[i]:=cat(square[i,1],f); fi; if square[i,2]=7 then move[i]:=cat(square[i,1],g); fi; if square[i,2]=8 then move[i]:=cat(square[i,1],h); fi; if square[i,3]=1 then move[i]:=cat(move[i],8); fi; if square[i,3]=2 then move[i]:=cat(move[i],7); fi; if square[i,3]=3 then move[i]:=cat(move[i],6); fi; if square[i,3]=4 then move[i]:=cat(move[i],5); fi; if square[i,3]=5 then move[i]:=cat(move[i],4); fi; if square[i,3]=6 then move[i]:=cat(move[i],3); fi; if square[i,3]=7 then move[i]:=cat(move[i],2); fi; if square[i,3]=8 then move[i]:=cat(move[i],1); fi; od; RETURN([move[1],move[2]]); end: swapper:=proc(L::list) RETURN([L[2],L[1]]); end: ############################################################################ # chess rules (moves, in check, ...) ############################################################################ ################# THE PAWN incheck_whitepawn := proc(king, pawn) local skewdiagonal, diagonal, i, horizonal, vertical; diagonal := {[pawn[1] + 1, pawn[2] - 1]}; skewdiagonal := {[pawn[1] - 1, pawn[2] - 1]}; RETURN( member(king, diagonal) or member(king, skewdiagonal)) end: #end proc: incheck_blackpawn := proc(king, pawn) local skewdiagonal, diagonal, i, horizonal, vertical; diagonal := {[pawn[1] - 1, pawn[2] + 1]}; skewdiagonal := {[pawn[1] + 1, pawn[2] + 1]}; RETURN( member(king, diagonal) or member(king, skewdiagonal)) end: #end proc: legal_white_pawn_moves:=proc(board::array ) #assumes it is white's move and finds all legal pawn moves local x,board0,board_out,pawns,i,j,moves,Moves; #first, find all white pawns board_out:=board; board0:=array(1..8,1..8); pawns:=[]; for i from 1 to 8 do for j from 1 to 8 do if board[i,j]=P then pawns:=[op(pawns),swapper([i,j])]; fi; od; od; if nargs>1 then print(evalm(board)); fi; #print(pawns); moves:=[]; #start listing the moves, as ordered #pairs : [old matrix coord, new matrix coord] for x in pawns do if (x[2]<>2 and x[2]>1 and board[x[2]-1,x[1]]=0) then moves:=[op(moves),[[P,op(x)],[P,x[1],x[2]-1]]]; fi; if (x[2]=7 and board[x[2]-1,x[1]]=0 and board[x[2]-2,x[1]]=0) then moves:=[op(moves),[[P,op(x)],[P,x[1],x[2]-2,"first"]]]; fi; if (x[2]=2 and board[x[2]-1,x[1]]=0) then moves:=[op(moves),[[P,op(x)],[Q,x[1],x[2]-1]]]; fi; if (x[2]=2 and board[x[2]-1,x[1]]=0) then moves:=[op(moves),[[P,op(x)],[R,x[1],x[2]-1]]]; fi; if (x[2]=2 and board[x[2]-1,x[1]]=0) then moves:=[op(moves),[[P,op(x)],[N,x[1],x[2]-1]]]; fi; if (x[2]=2 and board[x[2]-1,x[1]]=0) then moves:=[op(moves),[[P,op(x)],[B,x[1],x[2]-1]]]; fi; if (x[1]>1 and x[2]=4 and board[x[2],x[1]-1]=p) then ### should also check if previous black move was pawn to [x[2],x[1]-1] moves:=[op(moves),[[P,op(x)],[P,x[1]-1,x[2]-1,"capture ep",board[x[2],x[1]-1]]]]; board0[x[2],x[1]-1]:=0; #this is useless now but in later versions might be #useful for recording the fact that black's pawn has been captured ep fi; if (x[1]<8 and x[2]=4 and board[x[2],x[1]+1]=p) then ### should also check if previous black move was pawn to [x[2],x[1]+1] moves:=[op(moves),[[P,op(x)],[P,x[1]+1,x[2]-1,"capture ep",board[x[2],x[1]+1]]]]; board0[x[2],x[1]+1]:=0; #this is useless now but in later versions might be #useful for recording the fact that black's pawn has been captured ep fi; if (x[2]<>2 and x[1]>1 and x[2]>1 and member(board[x[2]-1,x[1]-1],{p,n,b,r,q,k})) then moves:=[op(moves),[[P,op(x)],[P,x[1]-1,x[2]-1,"capture",board[x[2]-1,x[1]-1]]]]; fi; if (x[2]=2 and x[1]>1 and member(board[x[2]-1,x[1]-1],{p,n,b,r,q,k})) then moves:=[op(moves),[[P,op(x)],[Q,x[1]-1,x[2]-1,"capture",board[x[2]-1,x[1]-1]]]]; fi; if (x[2]=2 and x[1]>1 and member(board[x[2]-1,x[1]-1],{p,n,b,r,q,k})) then moves:=[op(moves),[[P,op(x)],[R,x[1]-1,x[2]-1,"capture",board[x[2]-1,x[1]-1]]]]; fi; if (x[2]=2 and x[1]>1 and member(board[x[2]-1,x[1]-1],{p,n,b,r,q,k})) then moves:=[op(moves),[[P,op(x)],[B,x[1]-1,x[2]-1,"capture",board[x[2]-1,x[1]-1]]]]; fi; if (x[2]=2 and x[1]>1 and x[2]>1 and member(board[x[2]-1,x[1]-1],{p,n,b,r,q,k})) then moves:=[op(moves),[[P,op(x)],[N,x[1]-1,x[2]-1,"capture",board[x[2]-1,x[1]-1]]]]; fi; if (x[2]<>2 and x[1]<8 and x[2]>1 and member(board[x[2]-1,x[1]+1],{p,n,b,r,q,k})) then moves:=[op(moves),[[P,op(x)],[P,x[1]+1,x[2]-1,"capture",board[x[2]-1,x[1]+1]]]]; fi; if (x[2]=2 and x[1]<8 and member(board[x[2]-1,x[1]+1],{p,n,b,r,q,k})) then moves:=[op(moves),[[P,op(x)],[Q,x[1]+1,x[2]-1,"capture",board[x[2]-1,x[1]+1]]]]; fi; if (x[2]=2 and x[1]<8 and member(board[x[2]-1,x[1]+1],{p,n,b,r,q,k})) then moves:=[op(moves),[[P,op(x)],[R,x[1]+1,x[2]-1,"capture",board[x[2]-1,x[1]+1]]]]; fi; if (x[2]=2 and x[1]<8 and member(board[x[2]-1,x[1]+1],{p,n,b,r,q,k})) then moves:=[op(moves),[[P,op(x)],[B,x[1]+1,x[2]-1,"capture",board[x[2]-1,x[1]+1]]]]; fi; if (x[2]=2 and x[1]<8 and member(board[x[2]-1,x[1]+1],{p,n,b,r,q,k})) then moves:=[op(moves),[[P,op(x)],[N,x[1]+1,x[2]-1,"capture",board[x[2]-1,x[1]+1]]]]; fi; od; Moves:=[seq(convert_from_array_notation(x),x=moves)]; # print(moves); RETURN(moves); end: ## legal_white_pawn_moves legal_black_pawn_moves:=proc(board::array ) #assumes it is white's move and finds all legal pawn moves local x,board0,board_out,pawns,i,j,moves,Moves; #first, find all white pawns board_out:=board; board0:=array(1..8,1..8); pawns:=[]; for i from 1 to 8 do for j from 1 to 8 do if board[i,j]=p then pawns:=[op(pawns),swapper([i,j])]; fi; od; od; if nargs>1 then print(evalm(board)); fi; #print(pawns); moves:=[]; #start listing the moves, as ordered #pairs : [old matrix coord, new matrix coord] for x in pawns do if (x[2]=2 and board[x[2]+1,x[1]]=0 and board[x[2]+2,x[1]]=0) then moves:=[op(moves),[[p,op(x)],[p,x[1],x[2]+2,"first"]]]; #first pawn move can be 2 squares fi; if (x[2]<>7 and x[2]>1 and board[x[2]+1,x[1]]=0) then moves:=[op(moves),[[p,op(x)],[p,x[1],x[2]+1]]]; #ordinary pawn advance fi; if (x[2]=7 and board[x[2]+1,x[1]]=0) then moves:=[op(moves),[[p,op(x)],[q,x[1],x[2]+1]]]; #promote to q fi; if (x[2]=7 and board[x[2]+1,x[1]]=0) then moves:=[op(moves),[[p,op(x)],[r,x[1],x[2]+1]]]; #promote to r fi; if (x[2]=7 and board[x[2]+1,x[1]]=0) then moves:=[op(moves),[[p,op(x)],[n,x[1],x[2]+1]]]; #promote to n fi; if (x[2]=7 and board[x[2]+1,x[1]]=0) then moves:=[op(moves),[[p,op(x)],[b,x[1],x[2]+1]]]; #promote to b fi; if (x[1]>1 and x[2]=5 and board[x[2],x[1]-1]=P) then # ep captures ### should also check if previous white move was pawn to [x[2],x[1]-1] moves:=[op(moves),[[p,op(x)],[p,x[1]-1,x[2]+1,"capture ep",board[x[2],x[1]-1]]]]; board0[x[2],x[1]+1]:=0; #this is useless now but in later versions might be #useful for recording the fact that white's pawn has been captured ep fi; if (x[1]<8 and x[2]=4 and board[x[2],x[1]+1]=P) then # ep captures ### should also check if previous black move was pawn to [x[2],x[1]+1] moves:=[op(moves),[[p,op(x)],[p,x[1]+1,x[2]+1,"capture ep",board[x[2],x[1]+1]]]]; board0[x[2],x[1]+1]:=0; #this is useless now but in later versions might be #useful for recording the fact that black's pawn has been captured ep fi; if (x[2]<>7 and x[1]>1 and x[2]<8 and member(board[x[2]+1,x[1]-1],{P,N,B,R,Q,K})) then moves:=[op(moves),[[p,op(x)],[p,x[1]-1,x[2]+1,"capture",board[x[2]+1,x[1]-1]]]]; #ordinary capture fi; if (x[2]=7 and x[1]>1 and member(board[x[2]+1,x[1]-1],{P,N,B,R,Q,K})) then moves:=[op(moves),[[p,op(x)],[q,x[1]-1,x[2]+1,"capture",board[x[2]+1,x[1]-1]]]];#capture and promote to q fi; if (x[2]=7 and x[1]>1 and member(board[x[2]+1,x[1]-1],{P,N,B,R,Q,K})) then moves:=[op(moves),[[p,op(x)],[r,x[1]-1,x[2]-1,"capture",board[x[2]-1,x[1]-1]]]];#capture and promote to r fi; if (x[2]=7 and x[1]>1 and member(board[x[2]+1,x[1]-1],{P,N,B,R,Q,K})) then moves:=[op(moves),[[p,op(x)],[b,x[1]-1,x[2]-1,"capture",board[x[2]-1,x[1]-1]]]];#capture and promote to b fi; if (x[2]=7 and x[1]>1 and member(board[x[2]+1,x[1]-1],{P,N,B,R,Q,K})) then moves:=[op(moves),[[p,op(x)],[n,x[1]-1,x[2]-1,"capture",board[x[2]-1,x[1]-1]]]];#capture and promote to n fi; if (x[2]<>7 and x[1]<8 and x[2]<8 and member(board[x[2]+1,x[1]+1],{P,N,B,R,Q,K})) then moves:=[op(moves),[[p,op(x)],[p,x[1]+1,x[2]+1,"capture",board[x[2]+1,x[1]+1]]]]; #ordinary capture fi; if (x[2]=7 and x[1]<8 and member(board[x[2]+1,x[1]+1],{P,N,B,R,Q,K})) then moves:=[op(moves),[[p,op(x)],[q,x[1]+1,x[2]+1,"capture",board[x[2]+1,x[1]+1]]]];#capture and promote to q fi; if (x[2]=7 and x[1]<8 and member(board[x[2]+1,x[1]+1],{P,N,B,R,Q,K})) then moves:=[op(moves),[[p,op(x)],[r,x[1]+1,x[2]+1,"capture",board[x[2]+1,x[1]+1]]]];#capture and promote, r fi; if (x[2]=7 and x[1]<8 and member(board[x[2]+1,x[1]+1],{P,N,B,R,Q,K})) then moves:=[op(moves),[[p,op(x)],[b,x[1]+1,x[2]+1,"capture",board[x[2]+1,x[1]+1]]]];#capture and promote, b fi; if (x[2]=7 and x[1]<8 and member(board[x[2]+1,x[1]+1],{P,N,B,R,Q,K})) then moves:=[op(moves),[[p,op(x)],[n,x[1]+1,x[2]+1,"capture",board[x[2]+1,x[1]+1]]]];#capture and promote, n fi; od; Moves:=[seq(convert_from_array_notation(x),x=moves)]; # print(Moves); RETURN(moves); end: ## legal_black_pawn_moves ########################THE QUEEN incheck_queen:=proc(king,queen) local skewdiagonal,diagonal,i,horizonal,vertical; diagonal:={seq([queen[1]+i,queen[2]-i],i=-8..8)}; skewdiagonal:={seq([queen[1]+i,queen[2]+i],i=-8..8)}; horizonal:={seq([queen[1]+i,queen[2]],i=-8..8)}; vertical:={seq([queen[1],queen[2]-i],i=-8..8)}; RETURN(member(king,diagonal) or member(king,skewdiagonal) or member(king,horizonal) or member(king,vertical)); end: white_queen_squares:=proc(board::array,queen::list) local row1,row2,column1,column2,temp,x,skewdiagonal1,diagonal1,skewdiagonal2,diagonal2,i,horizonal,vertical,squares,nextfor; #returns legal queen-move squares (including captures) squares:=[]; row1:=[seq([queen[1]+i,queen[2]],i=1..8)]; column2:=[seq([queen[1],queen[2]+i],i=1..8)]; row2:=[[queen[1]-1,queen[2]],[queen[1]-2,queen[2]], [queen[1]-3,rook[2]],[queen[1]-4,queen[2]], [queen[1]-5,queen[2]],[queen[1]-6,queen[2]], [queen[1]-7,queen[2]],[queen[1]-8,queen[2]]]; column1:=[[queen[1],queen[2]-1],[queen[1],queen[2]-2], [queen[1],queen[2]-3],[queen[1],queen[2]-4], [queen[1],queen[2]-5],[queen[1],queen[2]-6], [queen[1],queen[2]-7],[queen[1],queen[2]-8]]; diagonal1:=[seq([queen[1]+i,queen[2]-i],i=1..8)]; diagonal2:=[[queen[1]-1,queen[2]+1],[queen[1]-2,queen[2]+2], [queen[1]-3,queen[2]+3],[queen[1]-4,queen[2]+4], [queen[1]-5,queen[2]+5],[queen[1]-6,queen[2]+6], [queen[1]-7,queen[2]+7],[queen[1]-8,queen[2]+8]]; skewdiagonal1:=[seq([queen[1]+i,queen[2]+i],i=1..8)]; skewdiagonal2:=[[queen[1]-1,queen[2]-1],[queen[1]-2,queen[2]-2], [queen[1]-3,queen[2]-3],[queen[1]-4,queen[2]-4], [queen[1]-5,queen[2]-5],[queen[1]-6,queen[2]-6], [queen[1]-7,queen[2]-7],[queen[1]-8,queen[2]-8]]; for x in row1 do #print(`row1`,x); if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in row2 do #print(`row2`,x); if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in column1 do #print(`col1`,x); if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in column2 do #print(`col2`,x); if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in diagonal1 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in diagonal2 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in skewdiagonal1 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in skewdiagonal2 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; RETURN(squares); end: #white queen squares legal_white_queen_moves:=proc(board::array ) #assumes it is white's move and finds all legal queen moves local QQ,squares,x,board0,board_out,queens,i,j,moves,Moves; #first, find all white queens board_out:=board; board0:=array(1..8,1..8); queens:=[]; for i from 1 to 8 do for j from 1 to 8 do if board[i,j]=Q then queens:=[op(queens),swapper([i,j])]; fi; od; od; if nargs>1 then print(evalm(board)); fi; #list moves moves:=[]; #print(queens); for QQ in queens do squares:=white_queen_squares(board,QQ); #print(squares); for x in squares do moves:=[op(moves),[[Q,op(QQ)],[Q,op(x)]]]; ; od; od; RETURN(moves); end: #legal queen moves black_queen_squares:=proc(board::array,queen::list) local row1,row2,column1,column2,temp,x,skewdiagonal1,diagonal1,skewdiagonal2,diagonal2,i,horizonal,vertical,squares,nextfor; #returns legal queen-move squares (including captures) squares:=[]; row1:=[seq([queen[1]+i,queen[2]],i=1..8)]; column2:=[seq([queen[1],queen[2]+i],i=1..8)]; row2:=[[queen[1]-1,queen[2]],[queen[1]-2,queen[2]], [queen[1]-3,rook[2]],[queen[1]-4,queen[2]], [queen[1]-5,queen[2]],[queen[1]-6,queen[2]], [queen[1]-7,queen[2]],[queen[1]-8,queen[2]]]; column1:=[[queen[1],queen[2]-1],[queen[1],queen[2]-2], [queen[1],queen[2]-3],[queen[1],queen[2]-4], [queen[1],queen[2]-5],[queen[1],queen[2]-6], [queen[1],queen[2]-7],[queen[1],queen[2]-8]]; diagonal1:=[seq([queen[1]+i,queen[2]-i],i=1..8)]; diagonal2:=[[queen[1]-1,queen[2]+1],[queen[1]-2,queen[2]+2], [queen[1]-3,queen[2]+3],[queen[1]-4,queen[2]+4], [queen[1]-5,queen[2]+5],[queen[1]-6,queen[2]+6], [queen[1]-7,queen[2]+7],[queen[1]-8,queen[2]+8]]; skewdiagonal1:=[seq([queen[1]+i,queen[2]+i],i=1..8)]; skewdiagonal2:=[[queen[1]-1,queen[2]-1],[queen[1]-2,queen[2]-2], [queen[1]-3,queen[2]-3],[queen[1]-4,queen[2]-4], [queen[1]-5,queen[2]-5],[queen[1]-6,queen[2]-6], [queen[1]-7,queen[2]-7],[queen[1]-8,queen[2]-8]]; for x in row1 do #print(`row1`,x); if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in row2 do #print(`row2`,x); if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in column1 do #print(`col1`,x); if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in column2 do #print(`col2`,x); if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in diagonal1 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in diagonal2 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in skewdiagonal1 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in skewdiagonal2 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; RETURN(squares); end: #black queen squares legal_black_queen_moves:=proc(board::array ) #assumes it is black's move and finds all legal queen moves local QQ,squares,x,board0,board_out,queens,i,j,moves,Moves; #first, find all black queens board_out:=board; board0:=array(1..8,1..8); queens:=[]; for i from 1 to 8 do for j from 1 to 8 do if board[i,j]=q then queens:=[op(queens),swapper([i,j])]; fi; od; od; if nargs>1 then print(evalm(board)); fi; #list moves moves:=[]; #print(queens); for QQ in queens do squares:=black_queen_squares(board,QQ); #print(squares); for x in squares do moves:=[op(moves),[[q,op(QQ)],[q,op(x)]]]; ; od; od; RETURN(moves); end: #legal black queen moves ################## THE ROOK incheck_rook:=proc(king,queen) local skewdiagonal,diagonal,i,horizonal,vertical; #diagonal:={seq([queen[1]+i,queen[2]-i],i=-8..8)}; #skewdiagonal:={seq([queen[1]+i,queen[2]+i],i=-8..8)}; horizonal:={seq([queen[1]+i,queen[2]],i=-8..8)}; vertical:={seq([queen[1],queen[2]-i],i=-8..8)}; RETURN(member(king,horizonal) or member(king,vertical)); end: white_rook_squares:=proc(board::array,rook::list) local temp,x,skewdiagonal1,diagonal1,skewdiagonal2,diagonal2,i,horizonal,vertical,squares,nextfor; #returns legal bishop-move squares (including captures squares:=[]; diagonal1:=[seq([rook[1]+i,rook[2]],i=1..8)]; diagonal2:=[seq([rook[1],rook[2]+i],i=1..8)]; skewdiagonal1:=[[rook[1]-1,rook[2]],[rook[1]-2,rook[2]], [rook[1]-3,rook[2]],[rook[1]-4,rook[2]], [rook[1]-5,rook[2]],[rook[1]-6,rook[2]], [rook[1]-7,rook[2]],[rook[1]-8,rook[2]]]; skewdiagonal2:=[[rook[1],rook[2]-1],[rook[1],rook[2]-2], [rook[1],rook[2]-3],[rook[1],rook[2]-4], [rook[1],rook[2]-5],[rook[1],rook[2]-6], [rook[1],rook[2]-7],[rook[1],rook[2]-8]]; for x in diagonal1 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in diagonal2 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in skewdiagonal1 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in skewdiagonal2 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; RETURN(squares); end: #white rook squares legal_white_rook_moves:=proc(board::array ) #assumes it is white's move and finds all legal rook moves local BB,squares,x,board0,board_out,rooks,i,j,moves,Moves; #first, find all white bishops board_out:=board; board0:=array(1..8,1..8); rooks:=[]; for i from 1 to 8 do for j from 1 to 8 do if board[i,j]=R then rooks:=[op(rooks),swapper([i,j])]; fi; od; od; if nargs>1 then print(evalm(board)); fi; #list moves moves:=[]; for BB in rooks do squares:=white_rook_squares(board,BB); for x in squares do moves:=[op(moves),[[R,op(BB)],[R,op(x)]]]; ; od; od; RETURN(moves); end: #legal rook moves black_rook_squares:=proc(board::array,rook::list) local temp,x,skewdiagonal1,diagonal1,skewdiagonal2,diagonal2,i,horizonal,vertical,squares,nextfor; #returns legal bishop-move squares (including captures squares:=[]; diagonal1:=[seq([rook[1]+i,rook[2]],i=1..8)]; diagonal2:=[seq([rook[1],rook[2]+i],i=1..8)]; skewdiagonal1:=[[rook[1]-1,rook[2]],[rook[1]-2,rook[2]], [rook[1]-3,rook[2]],[rook[1]-4,rook[2]], [rook[1]-5,rook[2]],[rook[1]-6,rook[2]], [rook[1]-7,rook[2]],[rook[1]-8,rook[2]]]; skewdiagonal2:=[[rook[1],rook[2]-1],[rook[1],rook[2]-2], [rook[1],rook[2]-3],[rook[1],rook[2]-4], [rook[1],rook[2]-5],[rook[1],rook[2]-6], [rook[1],rook[2]-7],[rook[1],rook[2]-8]]; for x in diagonal1 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in diagonal2 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in skewdiagonal1 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in skewdiagonal2 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; RETURN(squares); end: #black rook squares legal_black_rook_moves:=proc(board::array ) #assumes it is black's move and finds all legal rook moves local rr,squares,x,board0,board_out,rooks,i,j,moves,Moves; #first, find all black bishops board_out:=board; board0:=array(1..8,1..8); rooks:=[]; for i from 1 to 8 do for j from 1 to 8 do if board[i,j]=r then rooks:=[op(rooks),swapper([i,j])]; fi; od; od; if nargs>1 then print(evalm(board)); fi; #list moves moves:=[]; for rr in rooks do squares:=black_rook_squares(board,rr); for x in squares do moves:=[op(moves),[[r,op(rr)],[r,op(x)]]]; ; od; od; RETURN(moves); end: #legal rook moves ############# THE BISHOP incheck_bishop:=proc(king,queen) local skewdiagonal,diagonal,i,horizonal,vertical; diagonal:={seq([queen[1]+i,queen[2]-i],i=-8..8)}; skewdiagonal:={seq([queen[1]+i,queen[2]+i],i=-8..8)}; #horizonal:={seq([queen[1]+i,queen[2]],i=-8..8)}; #vertical:={seq([queen[1],queen[2]-i],i=-8..8)}; RETURN(member(king,diagonal) or member(king,skewdiagonal)); end: legal_white_bishop_moves:=proc(board::array ) #assumes it is white's move and finds all legal bishop moves local BB,squares,x,board0,board_out,bishops,i,j,moves,Moves; #first, find all white bishops board_out:=board; board0:=array(1..8,1..8); bishops:=[]; for i from 1 to 8 do for j from 1 to 8 do if board[i,j]=B then bishops:=[op(bishops),swapper([i,j])]; fi; od; od; if nargs>1 then print(evalm(board)); fi; #list moves moves:=[]; for BB in bishops do squares:=white_bishop_squares(board,BB); for x in squares do moves:=[op(moves),[[B,op(BB)],[B,op(x)]]]; ; od; od; RETURN(moves); end: #legal bishop moves legal_black_bishop_moves:=proc(board::array ) #assumes it is black's move and finds all legal bishop moves local bb,squares,x,board0,board_out,bishops,i,j,moves,Moves; #first, find all black bishops board_out:=board; board0:=array(1..8,1..8); bishops:=[]; for i from 1 to 8 do for j from 1 to 8 do if board[i,j]=b then bishops:=[op(bishops),swapper([i,j])]; fi; od; od; if nargs>1 then print(evalm(board)); fi; #list moves moves:=[]; for bb in bishops do squares:=black_bishop_squares(board,bb); for x in squares do moves:=[op(moves),[[b,op(bb)],[b,op(x)]]]; ; od; od; RETURN(moves); end: white_bishop_squares:=proc(board::array,bishop::list) local temp,x,skewdiagonal1,diagonal1,skewdiagonal2,diagonal2,i,horizonal,vertical,squares,nextfor; #returns legal bishop-move squares (including captures squares:=[]; diagonal1:=[seq([bishop[1]+i,bishop[2]-i],i=1..8)]; diagonal2:=[[bishop[1]-1,bishop[2]+1],[bishop[1]-2,bishop[2]+2], [bishop[1]-3,bishop[2]+3],[bishop[1]-4,bishop[2]+4], [bishop[1]-5,bishop[2]+5],[bishop[1]-6,bishop[2]+6], [bishop[1]-7,bishop[2]+7],[bishop[1]-8,bishop[2]+8]]; skewdiagonal1:=[seq([bishop[1]+i,bishop[2]+i],i=1..8)]; skewdiagonal2:=[[bishop[1]-1,bishop[2]-1],[bishop[1]-2,bishop[2]-2], [bishop[1]-3,bishop[2]-3],[bishop[1]-4,bishop[2]-4], [bishop[1]-5,bishop[2]-5],[bishop[1]-6,bishop[2]-6], [bishop[1]-7,bishop[2]-7],[bishop[1]-8,bishop[2]-8]]; #print(diagonal2); for x in diagonal1 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in diagonal2 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in skewdiagonal1 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in skewdiagonal2 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; RETURN(squares); end: wtest_capture:=proc(x,squares1,board::array) local squares0,nextfor; nextfor:=0; squares0:=squares1; if board[x[2],x[1]]=p then squares0:=[op(squares1),[op(x),"capture", p]]; nextfor:=1; fi; if board[x[2],x[1]]=n then squares0:=[op(squares1),[op(x),"capture", n]]; nextfor:=1; fi; if board[x[2],x[1]]=b then squares0:=[op(squares1),[op(x),"capture", b]]; nextfor:=1;fi; if board[x[2],x[1]]=r then squares0:=[op(squares1),[op(x),"capture", r]]; nextfor:=1;fi; if board[x[2],x[1]]=q then squares0:=[op(squares1),[op(x),"capture", q]]; nextfor:=1;fi; if board[x[2],x[1]]=k then squares0:=[op(squares1),[op(x),"capture", k]]; nextfor:=1;fi; return([nextfor,squares0]); end:########test_capture black_bishop_squares:=proc(board::array,bishop::list) local temp,x,skewdiagonal1,diagonal1,skewdiagonal2,diagonal2,i,horizonal,vertical,squares,nextfor; #returns legal bishop-move squares (including captures) squares:=[]; diagonal1:=[seq([bishop[1]+i,bishop[2]-i],i=1..8)]; diagonal2:=[[bishop[1]-1,bishop[2]+1],[bishop[1]-2,bishop[2]+2], [bishop[1]-3,bishop[2]+3],[bishop[1]-4,bishop[2]+4], [bishop[1]-5,bishop[2]+5],[bishop[1]-6,bishop[2]+6], [bishop[1]-7,bishop[2]+7],[bishop[1]-8,bishop[2]+8]]; skewdiagonal1:=[seq([bishop[1]+i,bishop[2]+i],i=1..8)]; skewdiagonal2:=[[bishop[1]-1,bishop[2]-1],[bishop[1]-2,bishop[2]-2], [bishop[1]-3,bishop[2]-3],[bishop[1]-4,bishop[2]-4], [bishop[1]-5,bishop[2]-5],[bishop[1]-6,bishop[2]-6], [bishop[1]-7,bishop[2]-7],[bishop[1]-8,bishop[2]-8]]; #print(diagonal2); for x in diagonal1 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in diagonal2 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in skewdiagonal1 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; for x in skewdiagonal2 do if member(x,chess_squares) then if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; if member(board[x[2],x[1]],{p,n,q,k,r,b}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; RETURN(squares); end: btest_capture:=proc(x,squares1,board::array) local squares0,nextfor; nextfor:=0; squares0:=squares1; if board[x[2],x[1]]=P then squares0:=[op(squares1),[op(x),"capture", P]]; nextfor:=1; fi; if board[x[2],x[1]]=N then squares0:=[op(squares1),[op(x),"capture", N]]; nextfor:=1; fi; if board[x[2],x[1]]=B then squares0:=[op(squares1),[op(x),"capture", B]]; nextfor:=1;fi; if board[x[2],x[1]]=R then squares0:=[op(squares1),[op(x),"capture", R]]; nextfor:=1;fi; if board[x[2],x[1]]=Q then squares0:=[op(squares1),[op(x),"capture", Q]]; nextfor:=1;fi; if board[x[2],x[1]]=K then squares0:=[op(squares1),[op(x),"capture", K]]; nextfor:=1;fi; return([nextfor,squares0]); end:#test_bishop_capture ########### THE KNIGHT incheck_knight:=proc(king,knight) local knighthops,i; knighthops:={[knight[1]+2,knight[2]+1],[knight[1]+1,knight[2]+2],[knight[1]-1,knight[2]+2], [knight[1]-2,knight[2]+1],[knight[1]-2,knight[2]-1],[knight[1]-1,knight[2]-2], [knight[1]+1,knight[2]-2],[knight[1]+2,knight[2]-1]}; RETURN(member(king,knighthops)); end: white_knight_squares:=proc(board::array,knight::list) local temp,x,hops,i,horizonal,vertical,squares,nextfor; #returns legal knight-move squares (including captures) squares:=[]; hops:=[[knight[1]+1,knight[2]+2],[knight[1]+1,knight[2]-2], [knight[1]-1,knight[2]+2],[knight[1]-1,knight[2]-2], [knight[1]+2,knight[2]-1],[knight[1]+2,knight[2]+1], [knight[1]-2,knight[2]-1],[knight[1]-2,knight[2]+1]]; for x in hops do if member(x,chess_squares) then #print(x,knight); if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; # if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; RETURN(squares); end: #white knight squares legal_white_knight_moves:=proc(board::array ) #assumes it is white's move and finds all legal knight moves local NN,squares,x,board0,board_out,knights,i,j,moves,Moves; #first, find all white bishops board_out:=board; board0:=array(1..8,1..8); knights:=[]; for i from 1 to 8 do for j from 1 to 8 do if board[i,j]=N then knights:=[op(knights),swapper([i,j])]; fi; od; od; if nargs>1 then print(evalm(board)); fi; #list moves moves:=[]; for NN in knights do squares:=white_knight_squares(board,NN); for x in squares do moves:=[op(moves),[[N,op(NN)],[N,op(x)]]]; ; od; od; RETURN(moves); end: #legal white knight moves black_knight_squares:=proc(board::array,knight::list) local temp,x,hops,i,horizonal,vertical,squares,nextfor; #returns legal knight-move squares (including captures) squares:=[]; hops:=[[knight[1]+1,knight[2]+2],[knight[1]+1,knight[2]-2], [knight[1]-1,knight[2]+2],[knight[1]-1,knight[2]-2], [knight[1]+2,knight[2]-1],[knight[1]+2,knight[2]+1], [knight[1]-2,knight[2]-1],[knight[1]-2,knight[2]+1]]; for x in hops do if member(x,chess_squares) then #print(x,knight); if board[x[2],x[1]]=0 then squares:=[op(squares),x]; next; fi; # if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; od; RETURN(squares); end: #black knight squares legal_black_knight_moves:=proc(board::array ) #assumes it is black's move and finds all legal knight moves local NN,squares,x,board0,board_out,knights,i,j,moves,Moves; #first, find all black knights board_out:=board; board0:=array(1..8,1..8); knights:=[]; for i from 1 to 8 do for j from 1 to 8 do if board[i,j]=n then knights:=[op(knights),swapper([i,j])]; fi; od; od; if nargs>1 then print(evalm(board)); fi; #list moves moves:=[]; for NN in knights do squares:=black_knight_squares(board,NN); for x in squares do moves:=[op(moves),[[N,op(NN)],[N,op(x)]]]; ; od; od; RETURN(moves); end: #legal black knight moves ######################### THE KING incheck_kingking := proc(king1, king2) local skewdiagonal, diagonal, i, horizonal, vertical; diagonal := {[king2[1] + 1, king2[2] ],[king2[1] - 1, king2[2] ], [king2[1] + 1, king2[2] + 1],[king2[1] - 1, king2[2] - 1]}; skewdiagonal := {[king2[1], king2[2] + 1], [king2[1], king2[2] - 1], [king2[1]-1, king2[2] + 1], [king2[1]+1, king2[2] - 1]}; RETURN( member(king, diagonal) or member(king, skewdiagonal)) end: #end proc: whiteking_incheck:=proc(board_in::array) #board_in should be in board_start notation #return true of K is in check local i,j,king; ######### first find the king for i from 1 to 8 do for j from 1 to 8 do if board_in[i,j]=K then king:=[i,j]; fi; od; od; #print(king); for i from 1 to 8 do for j from 1 to 8 do if (board_in[i,j]=k and incheck_kingking(king,[i,j])) then RETURN(incheck_kingking(king,[i,j])); fi; if (board_in[i,j]=q and incheck_queen(king,[i,j])) then RETURN(incheck_queen(king,[i,j])); fi; #if board_in[i,j]=b then print(i,j,b); fi; if (board_in[i,j]=b and incheck_bishop(king,[i,j])) then RETURN(incheck_bishop(king,[i,j])); fi; #if board_in[i,j]=r then print(i,j,r); fi; if (board_in[i,j]=r and incheck_rook(king,[i,j])) then RETURN(incheck_rook(king,[i,j])); fi; #if board_in[i,j]=n then print(i,j,n); fi; if (board_in[i,j]=n and incheck_knight(king,[i,j])) then RETURN(incheck_knight(king,[i,j])); fi; #if board_in[i,j]=p then print(i,j,p); fi; if (board_in[i,j]=p and incheck_whitepawn(king,[j,i])) then RETURN(incheck_blackpawn(king,[i,j])); fi; od; od; RETURN(`false`); end: #whiteking_incheck white_king_squares:=proc(board::array,king::list) local temp,x,hops,i,horizonal,vertical,squares,nextfor; #returns legal king-move squares (including captures) squares:=[]; hops:=[[king[1]+1,king[2]],[king[1]-1,king[2]], [king[1]+1,king[2]+1],[king[1]-1,king[2]-1], [king[1],king[2]+1],[king[1],king[2]-1], [king[1]+1,king[2]-1],[king[1]-1,king[2]+1]]; for x in hops do if member(x,chess_squares) then #print(x,king,array_to_algebraic_notation(K,op(king)),array_to_algebraic_notation(K,op(x))); if (board[x[2],x[1]]=0 and not(whiteking_incheck(move_piece(board,[array_to_algebraic_notation(K,op(king)),array_to_algebraic_notation(K,op(x))])))) then squares:=[op(squares),x]; next; fi; # if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; if (board[x[2],x[1]]=0 and not(whiteking_incheck(move_piece(board,[array_to_algebraic_notation(K,op(king)),array_to_algebraic_notation(K,op(x))])))) then temp:=wtest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; fi; od; RETURN(squares); end: #white king squares legal_white_king_moves:=proc(board::array ) #assumes it is white's move and finds all legal king moves local NN,squares,x,board0,board_out,kings,i,j,moves,Moves; #first, find all white kings board_out:=board; board0:=array(1..8,1..8); kings:=[]; for i from 1 to 8 do for j from 1 to 8 do if board[i,j]=K then kings:=[op(kings),swapper([i,j])]; fi; od; od; if nargs>1 then print(evalm(board)); fi; #list moves moves:=[]; for NN in kings do squares:=white_king_squares(board,NN); for x in squares do moves:=[op(moves),[[K,op(NN)],[K,op(x)]]]; ; od; od; RETURN(moves); end: #legal white king moves blackking_incheck:=proc(board_in::array) #board_in should be in board_start notation #return true of k is in check local i,j,king; ######### first find the king for i from 1 to 8 do for j from 1 to 8 do if board_in[i,j]=k then king:=[i,j]; fi; od; od; for i from 1 to 8 do for j from 1 to 8 do if (board_in[i,j]=K and incheck_kingking(king,[i,j])) then RETURN(incheck_kingking(king,[i,j])); fi; if (board_in[i,j]=Q and incheck_queen(king,[i,j])) then RETURN(incheck_queen(king,[i,j])); fi; if (board_in[i,j]=B and incheck_bishop(king,[i,j])) then RETURN(incheck_bishop(king,[i,j])); fi; if (board_in[i,j]=R and incheck_rook(king,[i,j])) then RETURN(incheck_rook(king,[i,j])); fi; if (board_in[i,j]=N and incheck_knight(king,[i,j])) then RETURN(incheck_knight(king,[i,j])); fi; if (board_in[i,j]=P and incheck_blackpawn(king,[j,i])) then RETURN(incheck_whitepawn(king,[i,j])); fi; od; od; RETURN(false); end: #blackking_incheck black_king_squares:=proc(board::array,king::list) local temp,x,hops,i,horizonal,vertical,squares,nextfor; #returns legal king-move squares (including captures) squares:=[]; hops:=[[king[1]+1,king[2]],[king[1]-1,king[2]], [king[1]+1,king[2]+1],[king[1]-1,king[2]-1], [king[1],king[2]+1],[king[1],king[2]-1], [king[1]+1,king[2]-1],[king[1]-1,king[2]+1]]; for x in hops do if member(x,chess_squares) then if (board[x[2],x[1]]=0 and not(blackking_incheck(move_piece(board,[array_to_algebraic_notation(k,op(king)),array_to_algebraic_notation(k,op(x))])))) then squares:=[op(squares),x]; next; fi; # if member(board[x[2],x[1]],{P,N,Q,K,R,B}) then break; fi; if (board[x[2],x[1]]<>0 and not(blackking_incheck(move_piece(board,[array_to_algebraic_notation(k,op(king)),array_to_algebraic_notation(k,op(x))])))) then temp:=btest_capture(x,squares,board); nextfor:=temp[1]; squares:=temp[2]; if nextfor=1 then break;fi; fi; fi; od; RETURN(squares); end: #black king squares legal_black_king_moves:=proc(board::array) #assumes it is black's move and finds all legal king moves local NN,squares,x,board0,board_out,kings,i,j,moves,Moves; #first, find all black kings board_out:=board; board0:=array(1..8,1..8); kings:=[]; for i from 1 to 8 do for j from 1 to 8 do if board[i,j]=k then kings:=[op(kings),swapper([i,j])]; fi; od; od; if nargs>1 then print(evalm(board)); fi; #list moves moves:=[]; for NN in kings do squares:=black_king_squares(board,NN); for x in squares do moves:=[op(moves),[[k,op(NN)],[k,op(x)]]]; ; od; od; RETURN(moves); end: #legal black king moves ################################################################## legal_moves:=proc(board::array,color) local x,y,i,j,moves; moves:=[]; if nargs>2 then print(evalm(board)); fi; if color="white" then moves:=[op(moves),legal_white_pawn_moves(board)]; moves:=[op(moves),legal_white_knight_moves(board)]; moves:=[op(moves),legal_white_bishop_moves(board)]; moves:=[op(moves),legal_white_rook_moves(board)]; moves:=[op(moves),legal_white_queen_moves(board)]; moves:=[op(moves),legal_white_king_moves(board)]; fi; if color="black" then moves:=[op(moves),legal_black_pawn_moves(board)]; moves:=[op(moves),legal_black_knight_moves(board)]; moves:=[op(moves),legal_black_bishop_moves(board)]; moves:=[op(moves),legal_black_rook_moves(board)]; moves:=[op(moves),legal_black_queen_moves(board)]; moves:=[op(moves),legal_black_king_moves(board)]; fi; RETURN(moves); end: ###################################################################3 ### ### some sample positions and games useful for debugging ### # #part of a sample game #[Event "postal match (game 4)"] #[Site "Maryland"] #[Date "1999.06.09"] #[Round "1"] #[Black "Joyner, David"] #[White "Braudes, Mike"] #[Result "*"] #[Opening "*"] #[ECO "*"] # #1. d4 f5 2. g3 Nf6 3. Bg2 g6 #4. Nf3 Bg7 5. c4 O-O 6. O-O d6 #7. Nc3 Qe8 8. b3 e5 9. dxe5 dxe5 #10. Ba3 Rf7 11. Ng5 Rd7 12. Qc2 h6 #13. Nh3 Nc6 14. Bxc6 bxc6 15. f3 Ba6 # # # game4:=[[Pd2,Pd4],[pf7,pf5],[Pg2,Pg3],[ng8,nf6],[Bf1,Bg2],[pg7,pg6],[Ng8, Nf3],[bf8,bg7], [Pc2,Pc4],[ke8,kg8],[rh8,rf8],[Ke1,Kg1],[Rh1,Rf1],[pd7,pd6],[Nb1, Nc3],[qd8,qe8],[Pb2,Pb3],[pe7,pe5], [Pd4,Pe5],[pd6,pe5],[Bc1, Ba3],[rf8, rf7],[Nf3, Ng5],[rf7, rd7],[Qd1, Qc2],[ph7,ph6],[Ng5, Nh3],[nb8, nc6],[Bg2,Bc6],[pb7,pc6],[Pf2,Pf3],[bc8,ba6]]: # #the "immortal game" played in 1851 at Simpson's Divan in London #A. Anderssen vs L. Kierseritzky # #1. e2-e4 e7-e5 2. f2-f4 e5xPf4 3. Bf1-c4 b7-b5 4. Bc4xPb5 Qd8-h4+ #5. Ke1-f1 Ng8-f6 6. Ng1-f3 Qh4-h6 7. d2-d3 Nf6-h5 8. Nf3-h4 c7-c6 #9. Nh4-f5 Qh6-g5 10. g2-g4 Nh5-f6 11. Rh1-g1 c6xBb5 12. h2-h4 Qg5-g6 #13. h4-h5 Qg6-g5 14. Qd1-f3 Nf6-g8 15. Bc1xPf4 Qg5-f6 16. Nb1-c3 Bf8-c5 #17. Nc3-d5! Qf6xPb2 18. Bf4-d6! Bc5xRg1 19. e4-e5 Qb2xRa1+ #20. Kf1-e2 Nb8-a6 21. Nf5xPg7+ Ke8-d8 22. Qf3-f6+ Ng8xQf6 23. Bd6-e7 mate. # # game_immortal:=[[Pe2,Pe4],[pe7,pe5],[Pf2,Pf4],[pe5,pf4,"capture",P],\ [Bf1,Bc4],[pb7,pb5],[Bc4,Bb5,"capture",p],[qd8,qh4,"check"],\ [Ke1,Kf1],[ng8,nf6],[Ng1,Nf3],[qh4,qh6],[Pd2,Pd3],[nf6,nh5],\ [Nf3,Nh4],[pc7,pc6],[Nh4,Nf5],[qh6,qg5],[Pg2,Pg4],[nh5,nf6],\ [Rh1,Rg1],[pc6,pb5,"capture",B],[Ph2,Ph4],[qg5,qg6],\ [Ph4,Ph5],[qg6,qg5],[Qd1,Qf3],[nf6,ng8],[Bc1,Bf4,"capture",P],\ [qg5,qf6],[Nb1,Nc3],[bf8,bc5],[Nc3,Nd5,"!"],[qf6,qb2,"capture",P], [Bf4,Bd6,"!"],[bc5,bg1,"capture",R],[Pe4,Pe5], [qb2,qa1,"check","capture",R],[Kf1,Ke2],[nb8,na6], [Nf5,Ng7,"check","capture",p],[ke8,kd8],[Qf3,Qf6,"check","!"], [ng8,nf6, "capture",Q],[Bd6,Be7,"mate"]]: game_Larsen_Spassky_1970:=[[Pb2, Pb3], [pe7, pe5], [Bc1, Bb2], [nb8, nc6], [Pc2, Pc4], [ng8, nf6], [Ng1, Nf3], [pe5, pe4], [Nf3, Nd4], [bf8, bc5], [Nd4, Nc6, "capture"], [pd7, pc6, "capture"], [Pe2, Pe3], [bc8, bf5], [Qd1, Qc2], [qd8, qe7], [Bf1, Be2], ["o-o-o"], [Pf2, Pf4], [nf6, ng4], [Pg2, Pg3], [ph7, ph5], [Ph2, Ph3], [ph5, ph4], [Ph3, Pg4, "capture"], [ph4, pg3, "capture"], [Rh1, Rg1], [rh8, rh1], [Rg1, Rh1, "capture"], [pg3, pg2], [Rh1, Rf1], [qe7, qh4], [Ke1, Kd1], [pg2, qf1, "capture", "promote", q]]: game_Lasker_Steinitz_1896wc2:= [[Pe2, Pe4], [pe7, pe5], [Ng1, Nf3], [nb8, nc6], [Bf1, Bb5], [bf8, bc5], [Pc2, Pc3], [ng8, ne7], ["O-O"], [ne7, ng6], [Pd2, Pd4], [pe5, pd4, "capture"], [Pc3, Pd4, "capture"], [bc5, bb6], [Nb1, Nc3], ["o-o"], [Pa2, Pa4], [pa7, pa6], [Bb5, Bc4], [ph7, ph6], [Ph2, Ph3], [pd7, pd6], [Bc1, Be3], [nc6, ne7], [Rf1, Re1], [pc7, pc6], [Qd1, Qb3], [bb6, bc7], [Nf3, Nd2], [ra8, rb8], [Ra1, Rc1], [pb7, pb5], [Pa4, Pb5, "capture"], [pa6, pb5, "capture"], [Bc4, Bd3], [kg8, kh8], [Nc3, Ne2], [pf7, pf5], [Pe4, Pf5, "capture"], [bc8, bf5, "capture"], [Bd3, Bf5, "capture"], [rf8, rf5, "capture"], [Ne2, Ng3], [rf5, rf8], [Qb3, Qe6], [qd8, qc8], [Qe6, Qc8, "capture"], [rf8, rc8, "capture"], [Nd2, Nb3], [kh8, kg8], [Ng3, Ne4], [kg8, kf7], [Pg2, Pg3], [kf7, ke8], [Re1, Re2], [ke8, kd7], [Rc1, Re1], [bc7, bb6], [Be3, Bf4], [bb6, bc7], [Ph3, Ph4], [ph6, ph5], [Bf4, Bg5], [bc7, bd8], [Pg3, Pg4], [ph5, pg4, "capture"], [Ph4, Ph5], [ng6, nf8], [Ne4, Nc5], [pd6, pc5, "capture"], [Nb3, Nc5, "capture"], [kd7, kd6], [Bg5, Bf4], [kd6, kd5], [Re2, Re5], [kd5, kc4], [Re1, Rc1], [kc4, kd4, "capture"], [Nc5, Nb3], [kd4, kd3], [Re5, Re3]]: game_Paulsen_Morphy_1857:= [[Pe2, Pe4], [pe7, pe5], [Ng1, Nf3], [nb8, nc6], [Nb1, Nc3], [ng8, nf6], [Bf1, Bb5], [bf8, bc5], ["O-O"], ["o-o"], [Nf3, Ne5, "capture"], [rf8, re8], [Ne5, Nc6, "capture"], [pd7, pc6, "capture"], [Bb5, Bc4], [pb7, pb5], [Bc4, Be2], [nf6, ne4, "capture"], [Nc3, Ne4, "capture"], [re8, re4, "capture"], [Be2, Bf3], [re4, re6], [Pc2, Pc3], [qd8, qd3], [Pb2, Pb4], [bc5, bb6], [Pa2, Pa4], [pb5, pa4, "capture"], [Qd1, Qa4, "capture"], [bc8, bd7], [Ra1, Ra2], [ra8, re8], [Qa4, Qa6], [qd3, qf3, "capture"], [Pg2, Pf3, "capture"], [re6, rg6], [Kg1, Kh1], [bd7, bh3], [Rf1, Rd1], [bh3, bg2], [Kh1, Kg1], [bg2, bf3, "capture"], [Kg1, Kf1], [bf3, bg2], [Kf1, Kg1], [bg2, bh3], [Kg1, Kh1], [bb6, bf2, "capture"], [Qa6, Qf1], [bh3, bf1, "capture"], [Rd1, Rf1, "capture"], [re8, re2], [Ra2, Ra1], [rg6, rh6], [Pd2, Pd4], [bf2, be3]]: game_Byrne_Fischer_1956:= [[Ng1, Nf3], [ng8, nf6], [Pc2, Pc4], [pg7, pg6], [Nb1, Nc3], [bf8, bg7], [Pd2, Pd4], ["o-o"], [Bc1, Bf4], [pd7, pd5], [Qd1, Qb3], [pd5, pc4, "capture"], [Qb3, Qc4, "capture"], [pc7, pc6], [Pe2, Pe4], [nb8, nd7], [Ra1, Rd1], [nd7, nb6], [Qc4, Qc5], [bc8, bg4], [Bf4, Bg5], [nb6, na4], [Qc5, Qa3], [na4, nc3, "capture"], [Pb2, Pc3, "capture"], [nf6, ne4, "capture"], [Bg5, Be7, "capture"], [qd8, qb6], [Bf1, Bc4], [ne4, nc3, "capture"], [Be7, Bc5], [rf8, re8], [Ke1, Kf1], [bg4, be6], [Bc5, Bb6, "capture"], [be6, bc4, "capture"], [Kf1, Kg1], [nc3, ne2], [Kg1, Kf1], [ne2, nd4, "capture"], [Kf1, Kg1], [nd4, ne2], [Kg1, Kf1], [ne2, nc3], [Kf1, Kg1], [pa7, pb6, "capture"], [Qa3, Qb4], [ra8, ra4], [Qb4, Qb6, "capture"], [nc3, nd1, "capture"], [Ph2, Ph3], [ra4, ra2, "capture"], [Kg1, Kh2], [nd1, nf2, "capture"], [Rh1, Re1], [re8, re1, "capture"], [Qb6, Qd8], [bg7, bf8], [Nf3, Ne1, "capture"], [bc4, bd5], [Ne1, Nf3], [nf2, ne4], [Qd8, Qb8], [pb7, pb5], [Ph3, Ph4], [ph7, ph5], [Nf3, Ne5], [kg8, kg7], [Kh2, Kg1], [bf8, bc5], [Kg1, Kf1], [ne4, ng3], [Kf1, Ke1], [bc5, bb4], [Ke1, Kd1], [bd5, bb3], [Kd1, Kc1], [ng3, ne2], [Kc1, Kb1], [ne2, nc3], [Kb1, Kc1], [ra2, rc2]]: game_Botvinnik_Tal_1960wc17:=[[Pe2, Pe4], [pc7, pc6], [Pd2, Pd4], [pd7, pd5], [Nb1, Nc3], [pd5, pe4, "capture"], [Nc3, Ne4, "capture"], [bc8, bf5], [Ne4, Ng3], [bf5, bg6], [Bf1, Bc4], [pe7, pe6], [Ng1, Ne2], [ng8, nf6], [Ne2, Nf4], [bf8, bd6], [Nf4, Ng6, "capture"], [ph7, pg6, "capture"], [Bc1, Bg5], [nb8, nd7], ["O-O"], [qd8, qa5], [Pf2, Pf4], ["o-o-o"], [Pa2, Pa3], [qa5, qc7], [Pb2, Pb4], [nd7, nb6], [Bc4, Be2], [bd6, be7], [Qd1, Qd3], [nf6, nd5], [Bg5, Be7, "capture"], [qc7, qe7, "capture"], [Pc2, Pc4], [nd5, nf6], [Ra1, Rb1], [qe7, qd7], [Rb1, Rd1], [kc8, kb8], [Qd3, Qb3], [qd7, qc7], [Pa3, Pa4], [rh8, rh4], [Pa4, Pa5], [nb6, nc8], [Qb3, Qe3], [nc8, ne7], [Qe3, Qe5], [rh4, rh8], [Pb4, Pb5], [pc6, pb5, "capture"], [Qe5, Qb5, "capture"], [pa7, pa6], [Qb5, Qb2], [rd8, rd7], [Pc4, Pc5], [kb8, ka8], [Be2, Bf3], [ne7, nc6], [Bf3, Bc6, "capture"], [qc7, qc6, "capture"], [Rf1, Rf3], [qc6, qa4], [Rf3, Rd3], [rh8, rc8], [Rd1, Rb1], [qa4, qa5, "capture"], [Rd3, Rb3], [qa5, qc7], [Qb2, Qa3], [ka8, ka7], [Rb3, Rb6], [qc7, qf4, "capture"], [Ng3, Ne2], [qf4, qe4], [Qa3, Qb3], [qe4, qd5], [Rb6, Ra6, "capture"], [ka7, kb8], [Qb3, Qa4]]: board_start:=array([ [r,n,b,q,k,b,n,r], [p,p,p,p,p,p,p,p], [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], [P,P,P,P,P,P,P,P], [R,N,B,Q,K,B,N,R]]): board_test1:=array([ [r,n,b,q,k,b,n,r], [p,P,p,p,p,p,p,p], [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], [P,p,P,P,P,P,P,P], [R,N,B,Q,K,B,N,R]]): board_test2:=array([ [r,n,b,q,k,b,n,r], [p,P,p,p,p,p,p,P], [0,0,0,0,0,P,0,0], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0], [0,0,0,0,0,p,0,0], [P,p,P,P,P,0,P,p], [R,N,B,Q,K,B,N,R]]): board_test3:=array([ [r,n,b,q,k,b,n,r], [p,P,p,p,p,0,p,p], [0,0,0,0,0,0,0,0], [P,p,0,0,0,p,P,0], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0], [P,0,P,P,P,P,0,P], [R,N,B,Q,K,B,N,R]]): board_test4:=array([ [r,n,b,q,k,0,n,r], [0,P,p,p,0,0,p,p], [0,0,0,0,0,0,0,0], [P,p,0,0,0,p,P,0], [0,b,0,0,0,0,0,0], [p,0,0,P,0,0,0,0], [P,0,P,0,0,P,0,P], [R,N,B,Q,K,B,N,R]]): board_matein3_s_lehner:=array([ [0,0,0,0,0,0,0,0], [k,0,0,0,0,0,0,0], [0,p,K,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,0,R,0,0,0], [0,0,0,0,0,0,0,0]]): # #1 board_empty:=array([ [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], [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]]): board_matein6_djivionskiy1855:=array([ [0,0,0,0,0,0,0,0], [0,0,p,0,0,0,0,0], [p,0,0,0,0,0,0,0], [0,0,p,0,0,0,0,0], [k,N,K,0,0,0,0,0], [p,0,0,0,0,0,0,0], [P,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0]]): # #3 board_matein2_v_nabokov:=array([ [0,0,0,N,0,0,0,B], [K,P,0,p,0,0,r,0], [0,Q,p,0,N,0,0,b], [0,0,0,0,k,0,n,R], [0,0,0,0,B,R,0,0], [0,0,p,0,0,0,P,0], [0,0,0,0,n,0,0,0], [0,0,0,0,0,0,0,0]]): # #2 FEN_Lewitzky_vs_Marshall_Breslau1912_finalposition:="5rk1/pp4pp/4p3/2R3Q1/3n4/6qr/P1P2PPP/5RK1": FEN_Grigoriev_endgame_study1923 := "8/8/4k1P1/4p1p1/4K3/3P4/8/8": FEN_matein6_djivionskiy1855 := "8/2p5/p7/2p5/kNK5/p7/P7/8": FEN_Ebers_endgame_study1930 := "8/1p5k/1P1p4/3p4/3Pp2p/2K1P2p/7P/8": FEN_Reti_endgame_study1921:="7K/8/k1P5/7p/8/8/8/8": chess_problems:=proc(n::integer) local board_pos; if n>6 then ERROR(`try again`); fi; if n=1 then print(`White to mate in 3, by S. Lehner`): RETURN(display(convert_board(board_matein3_s_lehner),axes=none)); fi; if n=2 then print(`White to mate in 2, by Vladimir Nabokov`): RETURN(display(convert_board(board_matein2_v_nabokov),axes=none)): fi; if n=3 then print(`White to mate in 6, by Djivionskiy, 1855`): board_pos:=fen_parser(FEN_matein6_djivionskiy1855): RETURN(display(convert_board(board_pos),axes=none)): fi; if n=4 then print(`White to play and win, by Grigoriev, 1923`): board_pos:=fen_parser(FEN_Grigoriev_endgame_study1923 ): RETURN(display(convert_board(board_pos),axes=none)): fi; if n=5 then print(`White to play and win, by Ebers, 1930`): board_pos:=fen_parser(FEN_Ebers_endgame_study1930): RETURN(display(convert_board(board_pos),axes=none)): fi; if n=6 then print(`White to play and draw, by Richard Reti, 1921`): board_pos:=fen_parser(FEN_Reti_endgame_study1921): RETURN(display(convert_board(board_pos),axes=none)): fi; end: solutions_to_chess_problems:=proc(n::integer) if n>6 then ERROR(`try again`); fi; if n=1 then print(`1. Rc2!`); fi; #`White to mate in 3, by S. Lehner` if n=2 then print(`1. Bc2!!`); fi; #`White to mate in 2, by Vladimir Nabokov` if n=3 then print(`1. Nc6`); fi; #`White to mate in 6, by Djivionskiy, 1855` if n=4 then print(`1. g7 Kf7 2. Kf5 Kg8! 3. Kg4! Kf7 4. Kxg5 e4! 5. Kh6!`); fi; #`White to play and win, by Grigoriev, 1923` if n=5 then print(`1. Kb2`); fi; #`White to play and win , by Ebers, 1930 if n=6 then print(`1. Kg7, Kf6, ...`); fi; #`White to play and win, by Reti, 1921 end: # #type what_games(); to see what games chess.mpl has # what_games:=proc() print(`game_immortal: the "immortal game" played in 1851 at Simpson's Divan in London between A. Anderssen vs L. Kierseritzky`); print(`game_Larsen_Spassky_1970: Larsen vs Spassky, USSR-Rest of the World Match, 1970`); print(`game_Lasker_Steinitz_1896wc2: Lasker vs Steinitz, 2nd Match Game, Moscow, 1896`); print(`game_Paulsen_Morphy_1857: Paulsen vs Morphy, New York, 1857`); print(`game_Byrne_Fischer_1956: D. Byrne vs Fischer, New York, 1956, "the game of the century"`); print(`game_Botvinnik_Tal_1960wc17: Botvinnik vs Tal, 17th Match Game, Moscow, 1960`); end: print(`chess.mpl version 0.6 loaded. commands:`); print(`move_piece, move_game, convert_board,game_animation, convert_to_array_notation,`); print(`convert_from_array_notation, legal_white_pawn_moves, legal_black_pawn_moves,`); print(`legal_white_bishop_moves, legal_black_bishop_moves, ..., legal_moves, `); print(`whiteking_incheck, blackking_incheck, array_to_algebraic_notation, `); print(`translate_chessmaster_game, read_in_file_to_arrays, what_games`); print(`chess_problems, solutions_to_chess_problems, fen_parser`); print(` `); print(`written for maple6 (use chess_v5.mpl in maple5)`); print(`written 3-2000 by d joyner,wdj@usna.edu`);