Let's play with Dinfio!
In this playground, we are going to build a human vs AI chess game.


$ dima install multiprocess
' Chess in Dinfio. Human vs AI
import gui
import multiprocess
import fileio, string
import url, json
var box = array2d(8, 8)
var colour_box_light = [colour.hex("f7deb5"), colour.hex("f7deb5")]
var colour_box_dark = [colour.hex("b58b6a"), colour.hex("b58b6a")]
var colour_box_selected = [colour.hex("32df30"), colour.hex("32df30")]
var colour_box_valid = [colour.hex("9ddb88"), colour.white]
var colour_box_from = [colour.hex("92c4c3"), colour.hex("92c4c3")]
var colour_box_to = [colour.hex("3cb7a1"), colour.hex("3cb7a1")]
var colour_box_check = [colour.hex("ff8d21"), colour.hex("ff8d21")]
var checkmate = false
var is_promotion = false
var thinking = false
var depth_black = 12
var depth_white = 12
var box_from = ""
var box_to = ""
var last_from = ""
var last_to = ""
var last_from_piece = ""
var last_to_piece = ""
var last_mate = inf
var half_move = 0
var full_move = 1
var castling_k = true
var castling_q = true
var castling_K = true
var castling_Q = true
var en_passant = "-"
var current_fen = ""
var ai_assist_from = ""
var ai_assist_to = ""
var ai_assist_to_i = -1
var ai_assist_to_j = -1
start
global window = gui_window("Chess in Dinfio")
global label_title = gui_label("Chess in Dinfio\nHuman vs AI", window, 420, 20, 186, 100, align.centre)
global label_winning_chance = gui_label("White's winning chance:\n50%", window, 420, 80, 186, 100, align.centre)
global label_fen = gui_label("FEN", window, 20, 416, 622, 100)
global button_ai_assistant = gui_button("AI Assistant", window, 420, 128, 186, 26)
global button_reset = gui_button("Reset Board", window, 420, 158, 186, 26)
global button_fen_copy = gui_button("Copy FEN", window, 420, 208, 186, 26)
global button_fen_load = gui_button("Load FEN", window, 420, 238, 186, 26)
global panel_promotion = gui_panel(window, 420, 208, 186, 200)
global label_choose_promotion = gui_label("Choose a piece to promote:", panel_promotion, 0, 0, 186, 100, align.centre)
global button_queen = gui_button("Queen", panel_promotion, 0, 24, 186, 26)
global button_rook = gui_button("Rook", panel_promotion, 0, 54, 186, 26)
global button_bishop = gui_button("Bishop", panel_promotion, 0, 84, 186, 26)
global button_knight = gui_button("Knight", panel_promotion, 0, 114, 186, 26)
global load_window, load_label, load_text, load_button_ok, load_button_cancel
global load_window_shown = false
label_title.setfontsize(16)
label_title.setfontbold(true)
label_winning_chance.setfontsize(12)
label_winning_chance.setfontbold(true)
label_choose_promotion.setfontsize(12)
label_choose_promotion.setfontbold(true)
button_reset.addevent(event.click, reset_board_click())
button_ai_assistant.addevent(event.click, ai_assist())
button_fen_copy.addevent(event.click, copy_fen())
button_fen_load.addevent(event.click, load_fen())
button_queen.addevent(event.click, promotion("Q"))
button_rook.addevent(event.click, promotion("R"))
button_bishop.addevent(event.click, promotion("B"))
button_knight.addevent(event.click, promotion("N"))
panel_promotion.setvisible(false)
for i, 0, 7
for j, 0, 7
x = j * 48
y = i * 48
box[i][j] = gui_panel(window, x + 20, y + 20, 48, 48, true)
box[i][j].piece = ""
box[i][j].position = fromascii(97 + j) & (8 - i)
box[i][j].flag = ""
box[i][j].i = i
box[i][j].j = j
box[i][j].addevent(event.mouseleftdown, box_click(i, j))
endfor
endfor
global button_black_turn = gui_button("Do Black Turn", window, 420, 286, 186, 26)
button_black_turn.addevent(event.click, black_turn_click())
button_black_turn.setvisible(false)
load_assets()
reset_board(true)
window.setheight(448 + window.getheight() - window.getinnerheight())
window.setwidth(622 + window.getwidth() - window.getinnerwidth())
window.setbackgroundcolour(colour.white)
window.show()
stop
function reset_board(render = false)
checkmate = false
is_promotion = false
thinking = false
depth_black = 12
depth_white = 12
box_from = ""
box_to = ""
last_from = ""
last_to = ""
last_from_piece = ""
last_to_piece = ""
last_mate = inf
half_move = 0
full_move = 1
castling_k = true
castling_q = true
castling_K = true
castling_Q = true
en_passant = "-"
ai_assist_from = ""
ai_assist_to = ""
ai_assist_to_i = -1
ai_assist_to_j = -1
for i, 0, 7
for j, 0, 7
box[i][j].piece = ""
box[i][j].flag = ""
endfor
endfor
box[0][0].piece = "r"; box[0][1].piece = "n"; box[0][2].piece = "b"; box[0][3].piece = "q"
box[0][4].piece = "k"; box[0][5].piece = "b"; box[0][6].piece = "n"; box[0][7].piece = "r"
box[1][0].piece = "p"; box[1][1].piece = "p"; box[1][2].piece = "p"; box[1][3].piece = "p"
box[1][4].piece = "p"; box[1][5].piece = "p"; box[1][6].piece = "p"; box[1][7].piece = "p"
box[7][0].piece = "R"; box[7][1].piece = "N"; box[7][2].piece = "B"; box[7][3].piece = "Q"
box[7][4].piece = "K"; box[7][5].piece = "B"; box[7][6].piece = "N"; box[7][7].piece = "R"
box[6][0].piece = "P"; box[6][1].piece = "P"; box[6][2].piece = "P"; box[6][3].piece = "P"
box[6][4].piece = "P"; box[6][5].piece = "P"; box[6][6].piece = "P"; box[6][7].piece = "P"
label_winning_chance.settext("White's winning chance:\n50%")
button_black_turn.setvisible(false)
if render; render(); endif
current_fen = generate_fen("w")
label_fen.settext("FEN: " & current_fen)
stop
function generate_fen(turn = "b")
var result = ""
var empty = 0
for i, 0, 7
empty = 0
for j, 0, 7
if box[i][j].piece == ""
empty += 1
else
if empty > 0; result &= empty; endif
result &= box[i][j].piece
empty = 0
endif
endfor
if empty > 0; result &= empty; endif
result &= "/"
endfor
var castling = ""
if castling_K; castling &= "K"; endif
if castling_Q; castling &= "Q"; endif
if castling_k; castling &= "k"; endif
if castling_q; castling &= "q"; endif
if castling == ""; castling = "-"; endif
result = subleft(result, length(result) - 1) & " " & turn & " " & castling & " " & en_passant & " " & half_move & " " & full_move
return result
stop
function set_fen(fen)
process("includes/stockfish", [fen, 5], nothing, set_fen_callback())
window.settitle("Chess in Dinfio - Validating FEN...")
stop
function set_fen_callback(data)
thinking = false
window.settitle("Chess in Dinfio")
if attribute_exists(data, "error")
messagebox("Invalid FEN.", "Chess in Dinfio")
return
endif
reset_board()
var parts = split(data.fen, " ")
en_passant = parts[3]
half_move = getnumber(parts[4])
full_move = getnumber(parts[5])
castling_K = find(parts[2], "K") != -1
castling_Q = find(parts[2], "Q") != -1
castling_k = find(parts[2], "k") != -1
castling_q = find(parts[2], "q") != -1
var positions = split(parts[0], "/")
var p
for i, 0, 7
for j, 0, 7
box[i][j].piece = ""
box[i][j].flag = ""
endfor
endfor
for i, 0, 7
p = positions[i]
j = 0
k = 0
while k < length(p) && j <= 7
c = substring(p, k, 1)
if getnumber(c) != 0
j += getnumber(c) - 1
else
box[i][j].piece = c
endif
j += 1
k += 1
endwhile
endfor
render()
current_fen = data.fen
label_fen.settext("FEN: " & current_fen)
label_winning_chance.settext("White's winning chance:\n-")
if parts[1] == "b"
button_black_turn.setvisible(true)
endif
stop
function black_turn_click()
black_turn()
button_black_turn.setvisible(false)
stop
function black_turn()
var fen = generate_fen()
stockfish(fen)
stop
function stockfish(fen)
thinking = true
process("includes/stockfish", [fen, depth_black], nothing, stockfish_callback())
window.settitle("Chess in Dinfio - Thinking...")
stop
function stockfish_callback(analysis)
thinking = false
ai_assist_from = ""
ai_assist_to = ""
ai_assist_to_i = -1
ai_assist_to_j = -1
window.settitle("Chess in Dinfio")
if attribute_exists(analysis, "error")
if analysis.error == "Invalid move."
if last_mate == 1
checkmate = true
label_winning_chance.settext("Checkmate!\nWhite wins.")
messagebox("Checkmate! White wins.", "Chess in Dinfio")
return
else
messagebox("Invalid move.", "Chess in Dinfio", message.warning + message.ok)
undo_last_move()
return
endif
else
messagebox(analysis.error, "Chess in Dinfio")
undo_last_move()
return
endif
endif
last_mate = analysis.mate
move(analysis.from, analysis.to)
if analysis.promotion != ""
var box_to = get_box(analysis.to)
box_to.piece = analysis.promotion
render_box(box_to.i, box_to.j)
endif
if is_check()
label_winning_chance.settext("White's winning chance:\n" & round(analysis.win_chance * 100, 2) & "% - It's check!")
else
label_winning_chance.settext("White's winning chance:\n" & round(analysis.win_chance * 100, 2) & "%")
endif
if analysis.checkmate
checkmate = true
label_winning_chance.settext("Checkmate!\nBlack wins.")
messagebox("Checkmate! Black wins.", "Chess in Dinfio")
endif
stop
function ai_assist()
if checkmate || is_promotion || thinking; return; endif
var fen = generate_fen("w")
process("includes/stockfish", [fen, depth_white], nothing, ai_assist_callback())
thinking = true
window.settitle("Chess in Dinfio - Thinking...")
stop
function ai_assist_callback(analysis)
thinking = false
depth_black = 10
window.settitle("Chess in Dinfio")
if attribute_exists(analysis, "error")
messagebox("An error occurs. Please try again later.", "Chess in Dinfio")
return
endif
if box_from != ""
var current_from_box = get_box(box_from)
ai_assist_from = ""
ai_assist_to = ""
ai_assist_to_i = -1
ai_assist_to_j = -1
box[current_from_box.i][current_from_box.j].flag = ""
render_box(current_from_box.i, current_from_box.j)
reset_valid_moves()
endif
var from = analysis.from
var to = analysis.to
var from_box = get_box(from)
var to_box = get_box(to)
ai_assist_from = from
ai_assist_to = to
ai_assist_to_i = to_box.i
ai_assist_to_j = to_box.j
box_from = from
from_box.flag = "selected"
render_box(from_box.i, from_box.j)
get_valid_moves(from_box.i, from_box.j)
stop
function reset_board_click()
i = messagebox("Are you sure you want to reset the board?", "Chess in Dinfio", message.warning + message.yesno)
if i == message.yes
reset_board(true)
endif
stop
function copy_fen()
clipboard.set(current_fen)
messagebox("FEN is copied.", "Chess in Dinfio")
stop
function load_fen()
if load_window_shown; return; endif
load_window = gui_window("Load FEN", 100, 100, false, false)
load_label = gui_label("FEN: ", load_window, 16, 10)
load_text = gui_textbox("", load_window, 16, 32, 268, 24)
load_button_ok = gui_button("Load", load_window, 16, 68, 100, 24)
load_button_cancel = gui_button("Cancel", load_window, 124, 68, 100, 24)
load_window.setheight(108 + load_window.getheight() - load_window.getinnerheight())
load_window.setwidth(305 + load_window.getwidth() - load_window.getinnerwidth())
load_button_ok.addevent(event.click, load_fen_click())
load_button_cancel.addevent(event.click, close_load_window())
load_window.addevent(event.close, load_window_closed())
load_window.show(true)
load_text.setfocus()
load_window_shown = true
stop
function load_fen_click()
var fen = trim(load_text.gettext())
if fen == ""; return; endif
set_fen(fen)
load_window.close()
stop
function close_load_window()
load_window.close()
stop
function load_window_closed()
load_window_shown = false
return true
stop
function box_click(i, j)
if checkmate || is_promotion || thinking; return; endif
position = box[i][j].position
if box[i][j].piece != ""
if position != box_from
if box_from == ""
if is_white_piece(i, j)
' Select the box
box_from = position
box[i][j].flag = "selected"
get_valid_moves(i, j)
endif
else
' Move to valid position
if box[i][j].flag == "valid"
box_to = box[i][j].position
move(box_from, box_to)
if !is_promotion; black_turn(); endif
endif
endif
else
box_from = ""
box[i][j].flag = ""
ai_assist_from = ""
ai_assist_to = ""
ai_assist_to_i = -1
ai_assist_to_j = -1
reset_valid_moves()
endif
render_box(i, j)
else
' Move to valid position
if box[i][j].flag == "valid"
box_to = box[i][j].position
move(box_from, box_to)
if !is_promotion; black_turn(); endif
endif
endif
stop
function promotion(piece)
var to_box = get_box(last_to)
to_box.piece = piece
is_promotion = false
render_box(to_box.i, to_box.j)
black_turn()
panel_promotion.setvisible(false)
stop
function move(from, to)
clear_last_move()
var reset_half_move = false
var from_box = get_box(from)
var to_box = get_box(to)
last_from = from
last_to = to
last_from_piece = from_box.piece
last_to_piece = to_box.piece
if is_opponent(from_box.piece, to_box.piece)
half_move = 0
reset_half_move = true
endif
if is_black_piece(from_box.i, from_box.j)
full_move += 1
endif
if last_from_piece == "k" && from == "e8" && to == "g8"
castling_k = false
castling_q = false
var castling_from_box = get_box("h8")
var castling_to_box = get_box("f8")
castling_from_box.piece = ""
castling_to_box.piece = "r"
render_box(castling_from_box.i, castling_from_box.j)
render_box(castling_to_box.i, castling_to_box.j)
endif
if last_from_piece == "k" && from == "e8" && to == "c8"
castling_k = false
castling_q = false
var castling_from_box = get_box("a8")
var castling_to_box = get_box("d8")
castling_from_box.piece = ""
castling_to_box.piece = "r"
render_box(castling_from_box.i, castling_from_box.j)
render_box(castling_to_box.i, castling_to_box.j)
endif
if last_from_piece == "K" && from == "e1" && to == "g1"
castling_K = false
castling_Q = false
var castling_from_box = get_box("h1")
var castling_to_box = get_box("f1")
castling_from_box.piece = ""
castling_to_box.piece = "R"
render_box(castling_from_box.i, castling_from_box.j)
render_box(castling_to_box.i, castling_to_box.j)
endif
if last_from_piece == "K" && from == "e1" && to == "c1"
castling_K = false
castling_Q = false
var castling_from_box = get_box("a1")
var castling_to_box = get_box("d1")
castling_from_box.piece = ""
castling_to_box.piece = "R"
render_box(castling_from_box.i, castling_from_box.j)
render_box(castling_to_box.i, castling_to_box.j)
endif
if from_box.piece == "K"
castling_K = false
castling_Q = false
endif
if from_box.piece == "k"
castling_k = false
castling_q = false
endif
if from_box.piece == "R" && from_box.position == "a1"
castling_Q = false
endif
if from_box.piece == "R" && from_box.position == "h1"
castling_K = false
endif
if from_box.piece == "r" && from_box.position == "a8"
castling_q = false
endif
if from_box.piece == "r" && from_box.position == "h8"
castling_k = false
endif
to_box.piece = from_box.piece
to_box.flag = "to"
from_box.piece = ""
from_box.flag = "from"
box_from = ""
box_to = ""
if to_box.piece == "p" || to_box.piece == "P"
half_move = 0
reset_half_move = true
endif
if !reset_half_move
half_move += 1
endif
if (last_from_piece == "P" || last_from_piece == "p") && en_passant != ""
if to_box.i == 2 && en_passant == box[2][to_box.j].position
box[3][to_box.j].piece = ""
box[3][to_box.j].flag = ""
render_box(3, to_box.j)
elseif to_box.i == 5 && en_passant == box[5][to_box.j].position
box[4][to_box.j].piece = ""
box[4][to_box.j].flag = ""
render_box(4, to_box.j)
endif
endif
if (last_from_piece == "P" || last_from_piece == "p") && abs(to_box.i - from_box.i) == 2
if to_box.i == 3
en_passant = box[2][to_box.j].position
else
en_passant = box[5][to_box.j].position
endif
else
en_passant = "-"
endif
reset_valid_moves()
render_box(to_box.i, to_box.j)
render_box(from_box.i, from_box.j)
if to_box.i == 0 && to_box.piece == "P"
is_promotion = true
panel_promotion.setvisible(true)
endif
current_fen = generate_fen(iif(is_black_piece(to_box.i, to_box.j), "w", "b"))
label_fen.settext("FEN: " & current_fen)
stop
function undo_last_move()
var from_box = get_box(last_from)
var to_box = get_box(last_to)
from_box.piece = last_from_piece
to_box.piece = last_to_piece
from_box.flag = ""
to_box.flag = ""
half_move -= 1
if half_move < 0; half_move = 0; endif
render_box(to_box.i, to_box.j)
render_box(from_box.i, from_box.j)
stop
function clear_last_move()
var from_box = get_box(last_from)
var to_box = get_box(last_to)
if from_box == nothing; return; endif
from_box.flag = ""
to_box.flag = ""
render_box(to_box.i, to_box.j)
render_box(from_box.i, from_box.j)
stop
function get_valid_moves(i, j)
var piece = box[i][j].piece
valid_move_pawn(piece, i, j)
valid_move_knight(piece, i, j)
valid_move_rook(piece, i, j)
valid_move_bishop(piece, i, j)
valid_move_castling(piece, i, j)
stop
function valid_move_pawn(piece, i, j)
if piece == "P"
if i > 0
if box[i - 1][j].piece == ""
box[i - 1][j].flag = "valid"
render_box(i - 1, j)
endif
endif
if i == 6
if box[i - 2][j].piece == "" && box[i - 1][j].piece == ""
box[i - 2][j].flag = "valid"
render_box(i - 2, j)
endif
endif
if i > 0 && j > 0
if box[i - 1][j - 1].piece != "" && !is_white_piece(i - 1, j - 1)
box[i - 1][j - 1].flag = "valid"
render_box(i - 1, j - 1)
endif
if box[i - 1][j - 1].position == en_passant
box[i - 1][j - 1].flag = "valid"
render_box(i - 1, j - 1)
endif
endif
if i > 0 && j < 7
if box[i - 1][j + 1].piece != "" && !is_white_piece(i - 1, j + 1)
box[i - 1][j + 1].flag = "valid"
render_box(i - 1, j + 1)
endif
if box[i - 1][j + 1].position == en_passant
box[i - 1][j + 1].flag = "valid"
render_box(i - 1, j + 1)
endif
endif
endif
stop
function valid_move_knight(piece, i, j)
if piece == "N"
if i > 1 && j < 7
if !is_white_piece(i - 2, j + 1)
box[i - 2][j + 1].flag = "valid"
render_box(i - 2, j + 1)
endif
endif
if i > 1 && j > 0
if !is_white_piece(i - 2, j - 1)
box[i - 2][j - 1].flag = "valid"
render_box(i - 2, j - 1)
endif
endif
if i < 6 && j < 7
if !is_white_piece(i + 2, j + 1)
box[i + 2][j + 1].flag = "valid"
render_box(i + 2, j + 1)
endif
endif
if i < 6 && j > 0
if !is_white_piece(i + 2, j - 1)
box[i + 2][j - 1].flag = "valid"
render_box(i + 2, j - 1)
endif
endif
if i > 0 && j < 6
if !is_white_piece(i - 1, j + 2)
box[i - 1][j + 2].flag = "valid"
render_box(i - 1, j + 2)
endif
endif
if i > 0 && j > 1
if !is_white_piece(i - 1, j - 2)
box[i - 1][j - 2].flag = "valid"
render_box(i - 1, j - 2)
endif
endif
if i < 7 && j < 6
if !is_white_piece(i + 1, j + 2)
box[i + 1][j + 2].flag = "valid"
render_box(i + 1, j + 2)
endif
endif
if i < 7 && j > 1
if !is_white_piece(i + 1, j - 2)
box[i + 1][j - 2].flag = "valid"
render_box(i + 1, j - 2)
endif
endif
endif
stop
function valid_move_rook(piece, i, j)
if piece == "R" || piece == "Q" || piece == "K"
for x, j + 1, 7
if is_white_piece(i, x); break; endif
if box[i][x].piece == "" || is_black_piece(i, x)
box[i][x].flag = "valid"
render_box(i, x)
endif
if is_black_piece(i, x); break; endif
if piece == "K"; break; endif
endfor
for x, j - 1, 0, -1
if is_white_piece(i, x); break; endif
if box[i][x].piece == "" || is_black_piece(i, x)
box[i][x].flag = "valid"
render_box(i, x)
endif
if is_black_piece(i, x); break; endif
if piece == "K"; break; endif
endfor
for y, i + 1, 7
if is_white_piece(y, j); break; endif
if box[y][j].piece == "" || is_black_piece(y, j)
box[y][j].flag = "valid"
render_box(y, j)
endif
if is_black_piece(y, j); break; endif
if piece == "K"; break; endif
endfor
for y, i - 1, 0, -1
if is_white_piece(y, j); break; endif
if box[y][j].piece == "" || is_black_piece(y, j)
box[y][j].flag = "valid"
render_box(y, j)
endif
if is_black_piece(y, j); break; endif
if piece == "K"; break; endif
endfor
endif
stop
function valid_move_bishop(piece, i, j)
if piece == "B" || piece == "Q" || piece == "K"
var x = j + 1
var y = i + 1
while x <= 7 && y <= 7
if is_white_piece(y, x); break; endif
if box[y][x].piece == "" || is_black_piece(y, x)
box[y][x].flag = "valid"
render_box(y, x)
endif
if is_black_piece(y, x); break; endif
if piece == "K"; break; endif
x += 1
y += 1
endwhile
x = j - 1
y = i - 1
while x >= 0 && y >= 0
if is_white_piece(y, x); break; endif
if box[y][x].piece == "" || is_black_piece(y, x)
box[y][x].flag = "valid"
render_box(y, x)
endif
if is_black_piece(y, x); break; endif
if piece == "K"; break; endif
x -= 1
y -= 1
endwhile
x = j + 1
y = i - 1
while x <= 7 && y >= 0
if is_white_piece(y, x); break; endif
if box[y][x].piece == "" || is_black_piece(y, x)
box[y][x].flag = "valid"
render_box(y, x)
endif
if is_black_piece(y, x); break; endif
if piece == "K"; break; endif
x += 1
y -= 1
endwhile
x = j - 1
y = i + 1
while x >= 0 && y <= 7
if is_white_piece(y, x); break; endif
if box[y][x].piece == "" || is_black_piece(y, x)
box[y][x].flag = "valid"
render_box(y, x)
endif
if is_black_piece(y, x); break; endif
if piece == "K"; break; endif
x -= 1
y += 1
endwhile
endif
stop
function valid_move_castling(piece, i, j)
if piece == "K"
if i == 7 && j == 4
if castling_K
if box[7][5].piece == "" && box[7][6].piece == "" && is_position_safe(7, 4) && is_position_safe(7, 5) && is_position_safe(7, 6)
box[7][6].flag = "valid"
render_box(7, 6)
endif
endif
if castling_Q
if box[7][3].piece == "" && box[7][2].piece == "" && box[7][1].piece == "" && is_position_safe(7, 4) && is_position_safe(7, 3) && is_position_safe(7, 2)
box[7][2].flag = "valid"
render_box(7, 2)
endif
endif
endif
endif
stop
function is_position_safe(i, j)
' Pawn
if i >= 1 && j >= 1; if box[i - 1][j - 1].piece == "p"; return false; endif; endif
if i >= 1 && j <= 6; if box[i - 1][j + 1].piece == "p"; return false; endif; endif
' Knight
if i >= 2 && j >= 1; if box[i - 2][j - 1].piece == "n"; return false; endif; endif
if i >= 2 && j <= 6; if box[i - 2][j + 1].piece == "n"; return false; endif; endif
if i >= 1 && j >= 2; if box[i - 1][j - 2].piece == "n"; return false; endif; endif
if i >= 1 && j <= 5; if box[i - 1][j + 2].piece == "n"; return false; endif; endif
if i <= 5 && j >= 1; if box[i + 2][j - 1].piece == "n"; return false; endif; endif
if i <= 5 && j <= 6; if box[i + 2][j + 1].piece == "n"; return false; endif; endif
if i <= 6 && j >= 2; if box[i + 1][j - 2].piece == "n"; return false; endif; endif
if i <= 6 && j <= 5; if box[i + 1][j + 2].piece == "n"; return false; endif; endif
' Rook or Queen
for x, i - 1, 0, -1
if is_white_piece(x, j); break; endif
if box[x][j].piece == "r" || box[x][j].piece == "q"; return false; endif
if is_black_piece(x, j); break; endif
endfor
for x, i + 1, 7
if is_white_piece(x, j); break; endif
if box[x][j].piece == "r" || box[x][j].piece == "q"; return false; endif
if is_black_piece(x, j); break; endif
endfor
for x, j - 1, 0, -1
if is_white_piece(i, x); break; endif
if box[i][x].piece == "r" || box[i][x].piece == "q"; return false; endif
if is_black_piece(i, x); break; endif
endfor
for x, j + 1, 7
if is_white_piece(i, x); break; endif
if box[i][x].piece == "r" || box[i][x].piece == "q"; return false; endif
if is_black_piece(i, x); break; endif
endfor
' Bishop or Queen
x = j + 1
y = i - 1
while x <= 7 && y >= 0
if is_white_piece(y, x); break; endif
if box[y][x].piece == "b" || box[y][x].piece == "q"; return false; endif
if is_black_piece(y, x); break; endif
x += 1
y -= 1
endwhile
x = j - 1
y = i - 1
while x >= 0 && y >= 0
if is_white_piece(y, x); break; endif
if box[y][x].piece == "b" || box[y][x].piece == "q"; return false; endif
if is_black_piece(y, x); break; endif
x -= 1
y -= 1
endwhile
x = j + 1
y = i + 1
while x <= 7 && y <= 7
if is_white_piece(y, x); break; endif
if box[y][x].piece == "b" || box[y][x].piece == "q"; return false; endif
if is_black_piece(y, x); break; endif
x += 1
y += 1
endwhile
x = j - 1
y = i + 1
while x >= 0 && y <= 7
if is_white_piece(y, x); break; endif
if box[y][x].piece == "b" || box[y][x].piece == "q"; return false; endif
if is_black_piece(y, x); break; endif
x -= 1
y += 1
endwhile
return true
stop
function is_check()
var ii, jj
for i, 0, 7
for j, 0, 7
if box[i][j].piece == "K"
if !is_position_safe(i, j)
box[i][j].flag = "check"
render_box(i, j)
return true
endif
ii = i
jj = j
endif
endfor
endfor
box[ii][jj].flag = ""
render_box(ii, jj)
return false
stop
function reset_valid_moves()
for i, 0, 7
for j, 0, 7
if box[i][j].flag == "valid"
box[i][j].flag = ""
render_box(i, j)
endif
endfor
endfor
stop
function is_white_piece(i, j)
piece = box[i][j].piece
return piece == "R" || piece == "N" || piece == "B" || piece == "Q" || piece == "K" || piece == "P"
stop
function is_black_piece(i, j)
piece = box[i][j].piece
return piece == "r" || piece == "n" || piece == "b" || piece == "q" || piece == "k" || piece == "p"
stop
function is_opponent(piece_1, piece_2)
if piece_1 == "R" || piece_1 == "N" || piece_1 == "B" || piece_1 == "Q" || piece_1 == "K" || piece_1 == "P"
if piece_2 == "r" || piece_2 == "n" || piece_2 == "b" || piece_2 == "q" || piece_2 == "k" || piece_2 == "p"
return true
endif
endif
if piece_1 == "r" || piece_1 == "n" || piece_1 == "b" || piece_1 == "q" || piece_1 == "k" || piece_1 == "p"
if piece_2 == "R" || piece_2 == "N" || piece_2 == "B" || piece_2 == "Q" || piece_2 == "K" || piece_2 == "P"
return true
endif
endif
return false
stop
function render_box(i, j)
box_colour = get_box_colour(i, j)
box[i][j].draw_clear()
box[i][j].draw_setbackgroundcolour(box_colour[0])
box[i][j].draw_setpen(box_colour[1], 0)
box[i][j].draw_rectangle(0, 0, 48, 48)
if box[i][j].flag == "valid"
if ai_assist_to == ""
box[i][j].draw_setpen(colour_box_valid[0], 2)
if !is_black_piece(i, j) && box[i][j].position != en_passant
box[i][j].draw_circle(24, 24, 8)
else
box[i][j].draw_setpen(colour_box_valid[0], 3)
box[i][j].draw_circle(24, 24, 18)
endif
else
if ai_assist_to_i == i && ai_assist_to_j == j
box[i][j].draw_setpen(colour_box_valid[0], 2)
box[i][j].draw_setbrush(colour_box_valid[0])
if !is_black_piece(i, j) && box[i][j].position != en_passant
box[i][j].draw_circle(24, 24, 8)
else
box[i][j].draw_setpen(colour_box_valid[0], 3)
box[i][j].draw_circle(24, 24, 18)
endif
endif
endif
endif
if box[i][j].piece != ""
box[i][j].draw_image(attribute_get(piece_images, box[i][j].piece), 0, 0)
endif
box[i][j].refresh()
stop
function get_box(position)
for i, 0, 7
for j, 0, 7
if position == box[i][j].position
return box[i][j]
endif
endfor
endfor
return nothing
stop
function get_box_colour(i, j)
if box[i][j].flag == "" || box[i][j].flag == "valid"
if i % 2 == 0
return iif(((i + 1) * (j + 1)) % 2 == 0, colour_box_dark, colour_box_light)
else
return iif(j % 2 == 0, colour_box_dark, colour_box_light)
endif
elseif box[i][j].flag == "selected"
return colour_box_selected
elseif box[i][j].flag == "from"
return colour_box_from
elseif box[i][j].flag == "to"
return colour_box_to
elseif box[i][j].flag == "check"
return colour_box_check
endif
stop
function load_assets()
var path = getfoldername(getcurrentfile()) & "/includes/assets/"
global piece_images = {
p: image(path & "black-pawn.png"),
n: image(path & "black-knight.png"),
b: image(path & "black-bishop.png"),
q: image(path & "black-queen.png"),
k: image(path & "black-king.png"),
r: image(path & "black-rook.png"),
P: image(path & "white-pawn.png"),
N: image(path & "white-knight.png"),
B: image(path & "white-bishop.png"),
Q: image(path & "white-queen.png"),
K: image(path & "white-king.png"),
R: image(path & "white-rook.png")
}
stop
function render()
for i, 0, 7
for j, 0, 7
render_box(i, j)
endfor
endfor
stop