chess.py

Created by ilyas-r

Created on October 05, 2023

14.1 KB

Chess v0.6.
Python Game for Numworks, all models.
By Ilyas R. 2022.

Learn more about the game on: nsi.xyz/chess (FR)

Changelog

Chess v0.6 - 29/08/2022:
- Beta release


from kandinsky import *
from ion import *

# Chess 0.6-SNAPSHOT NumWorks, XX/XX/2022
# Par Ilyas R.
# https://nsi.xyz/chess

pawn = (3584, 4352, 12672, 65504, 32800, 32800, 16448, 8320, 8320, 8320, 8320, 8320, 8320, 8320, 16448, 98352, 131080,
        524284, 524290, 1048577, 2097151)
knight = (480, 1840, 3096, 6220, 12390, 8194, 24577, 16497, 49371, 33166, 33152, 32960, 32864, 98352, 65560, 196616,
          131080, 524284, 524290, 1048577, 2097151)
rook = (101936, 168232, 160200, 131080, 131080, 131056, 32800, 32800, 32800, 32800, 32800, 32800, 32800, 32800, 32800,
        131056, 131080, 524284, 524290, 1048577, 2097151)
bishop = (3584, 4352, 4352, 4352, 3584, 4352, 12672, 24768, 49248, 32928, 33056, 33312, 32800, 49248, 16448, 49248,
          98352, 524284, 524290, 1048577, 2097151)
queen = (1024, 2560, 4352, 130032, 137992, 263172, 524290, 524290, 524290, 524290, 524290, 524290, 262148, 262148,
         131080, 131056, 65552, 524284, 524290, 1048577, 2097151)
king = (917518, 593426, 561442, 545090, 544322, 536962, 524290, 524290, 262148, 262148, 131080, 65552, 65504, 32800,
        16448, 131056, 65552, 524284, 524290, 1048577, 2097151)

pos, initial_pos = [0, 3], []
last_key, pion_selected, move_pion = None, None, None
tour = 0
roque_done = False
pos_pions = [["rook_b", "knight_b", "bishop_b", "king_b", "queen_b", "bishop_b", "knight_b", "rook_b"],
             ["pawn_b", "pawn_b", "pawn_b", "pawn_b", "pawn_b", "pawn_b", "pawn_b", "pawn_b"],
             ["", "", "", "", "", "", "", ""],
             ["", "", "", "", "", "", "", ""],
             ["", "", "", "", "", "", "", ""],
             ["", "", "", "", "", "", "", ""],
             ["pawn_w", "pawn_w", "pawn_w", "pawn_w", "pawn_w", "pawn_w", "pawn_w", "pawn_w"],
             ["rook_w", "knight_w", "bishop_w", "queen_w", "king_w", "bishop_w", "knight_w", "rook_w"]]
t_b, t_w = 4800, 4800
k_w_m, k_b_m, t1_w_m, t1_b_m, t2_w_m, t2_b_m = False, False, False, False, False, False
eat_pion = False
p1, p2 = (4, 7), (0, 7)


def roque(sender_pos, target_pos):
    pion = get_pion_of_pos(sender_pos).split("_")
    if pion[0] != "king":
        return False
    diff = sender_pos[0] - target_pos[0]
    print(diff)
    if pion[1] == "w":
        if 2 <= abs(diff) <= 4 and not k_w_m and ((diff < 0 and not t2_w_m) or (diff > 0 and not
           t1_w_m)) and not_pion_between_target(sender_pos, target_pos, 1):
            print(diff, t1_w_m)
            pos_pions[7][2 if diff > 0 else 6], pos_pions[7][3 if diff > 0 else 5] = pos_pions[sender_pos[1]][sender_pos[0]], pos_pions[7][7*(diff < 0)]
            pos_pions[7][7*(diff < 0)], pos_pions[sender_pos[1]][sender_pos[0]] = "", ""
            return True
        return False
    if pion[1] == "b":
        if 2 <= abs(diff) <= 4 and not k_b_m and ((diff < 0 and not t2_b_m) or (diff > 0 and not
           t1_b_m)) and not_pion_between_target(sender_pos, target_pos, 1):
            print(diff, t1_b_m)
            pos_pions[0][1 if diff > 0 else 5], pos_pions[0][2 if diff > 0 else 4] = pos_pions[sender_pos[1]][sender_pos[0]], pos_pions[0][7*(diff < 0)]
            pos_pions[0][7*(diff < 0)], pos_pions[sender_pos[1]][sender_pos[0]] = "", ""
            return True
        return False


def get_pos_of_pion(pion):
    pos_of_pions = []
    for i in range(8):
        for j in range(8):
            if pion != "all":
                if pos_pions[i][j] == pion:
                    pos_of_pions.append((j, i))
            else:
                if pos_pions[i][j] != "":
                    pos_of_pions.append((j, i))
    return pos_of_pions


def get_pion_of_pos(p):
    return pos_pions[p[1]][p[0]]


def switch_pos_pions(sender_pos, target_pos, eat=0, rock=0):
    global tour, eat_pion
    if not rock:
        if not eat:
            pos_pions[sender_pos[1]][sender_pos[0]], pos_pions[target_pos[1]][target_pos[0]] = pos_pions[target_pos[1]][
                    target_pos[0]], pos_pions[sender_pos[1]][sender_pos[0]]
        else:
            pos_pions[target_pos[1]][target_pos[0]] = pos_pions[sender_pos[1]][sender_pos[0]]
            pos_pions[sender_pos[1]][sender_pos[0]] = ""
            eat_pion = False
    tour += 1
    menu()


def default_pions():
    for i in range(8):
        for j in range(8):
            if pos_pions[i][j] != "":
                draw_pion(eval(pos_pions[i][j].split("_")[0]), d_p(j, i, 3)[0], d_p(j, i, 3)[1], get_font([j, i]),
                          get_pion_color([j, i]))


def draw_pion(t, x, y, back=(0,) * 3, font=(170, 170, 170)):
    for i in range(21):
        for j in range(21):
            fill_rect(x + j, y + i, 1, 1, (t[i] >> (20 - j)) & 1 and font or back)


def debug(i_pos, target_pos):
    draw_string("i_p:" + str(i_pos), 221, 90, "black")
    draw_string("t_p:" + str(target_pos), 221, 110, "black")


def gui():
    fill_rect(0, 0, 320, 222, (49, 46, 43))
    plateau()
    draw_string("CHESS", 244, 3, "white", (49, 46, 43))
    draw_string("Blacks:16", 225, 40, "black", (49, 46, 43))
    draw_string("XXXsec", 225, 64, "black", (49, 46, 43))
    draw_string("Round:", 225, 100, "white", (49, 46, 43))
    fill_rect(290, 100, 20, 20, (170, 170, 170) if tour % 2 == 0 else "black")
    draw_string("XXXsec", 225, 140, (170, 170, 170), (49, 46, 43))
    draw_string("Whites:16", 225, 164, (170, 170, 170), (49, 46, 43))
    draw_string("nsi.xyz", 235, 201, "white", (49, 46, 43))
    default_pions()


def menu():
    fill_rect(290, 100, 20, 20, (170, 170, 170) if tour % 2 == 0 else "black")


def plateau():
    for i in range(8):
        for j in range(8):
            fill_rect(3 + j * 27, 3 + i * 27, 27, 27, get_font([j, i]))


def d_p(p_x=0, p_y=0, pion=0):
    return [(3 + 27 * p_x) + pion, (3 + 27 * p_y) + pion]


def get_font(p):
    return ((119, 149, 86) if p[0] % 2 == 0 else (235, 236, 208)) if p[1] % 2 != 0 else (235, 236, 208) \
        if p[0] % 2 == 0 else (119, 149, 86)


def get_pion_color(p):
    return (170, 170, 170) if get_pion_of_pos(p).split("_")[1] == "w" else (0,) * 3


def legit_move(sender_pos, target_pos):
    pion = get_pion_of_pos(sender_pos).split("_")
    if pion[0] == "pawn":
        if pion[1] == "b":
            dist = 2 if sender_pos[1] == 1 else 1
            if 0 < target_pos[1] - sender_pos[1] <= dist and sender_pos[0] == target_pos[0]:
                return True
            return False
        else:
            dist = -2 if sender_pos[1] == 6 else -1
            if dist <= target_pos[1] - sender_pos[1] < 0 and sender_pos[0] == target_pos[0]:
                return True
            return False
    if pion[0] == "rook":
        if sender_pos[0] == target_pos[0] or sender_pos[1] == target_pos[1]:
            return True
        return False
    if pion[0] == "knight":
        diff_x, diff_y = abs(sender_pos[0] - target_pos[0]), abs(sender_pos[1] - target_pos[1])
        if (diff_x == 1 and diff_y == 2) or (diff_x == 2 and diff_y == 1):
            return True
        return False
    if pion[0] == "bishop":
        if abs(target_pos[0] - sender_pos[0]) == abs(target_pos[1] - sender_pos[1]):
            return True
        return False
    if pion[0] == "queen":
        if (abs(target_pos[0] - sender_pos[0]) == abs(target_pos[1] - sender_pos[1])) or (sender_pos[0] == target_pos[
           0] or sender_pos[1] == target_pos[1]):
            return True
        return False
    if pion[0] == "king":
        if abs(sender_pos[0] - target_pos[0]) < 2 and abs(sender_pos[1] - target_pos[1]) < 2:
            return True
        return False


def not_pion_between_target(sender_pos, target_pos, rock=0):
    global eat_pion
    all_pos_between_target = []
    pion = get_pion_of_pos(sender_pos).split("_")
    if get_pion_of_pos(target_pos) != "" and pion[1] == get_pion_of_pos(target_pos).split("_")[1] and not rock:
        return False
    for i in range(target_pos[1], sender_pos[1]) if target_pos[1] + 1 - sender_pos[1] < 0 else range(
            sender_pos[1] + -1 * (target_pos[1] + 1 - sender_pos[1] == 0), target_pos[1] + 1):
        for j in range(target_pos[0], sender_pos[0]) if target_pos[0] + 1 - sender_pos[0] < 0 else range(
                sender_pos[0] + -1 * (target_pos[0] + 1 - sender_pos[0] == 0), target_pos[0] + 1):
            if not rock:
                if legit_move(sender_pos, [j, i]) and list(sender_pos) != [j, i] and list(target_pos) != [j, i]:
                    if pion[0] == "queen" or pion[0] == "king":
                        if abs(target_pos[0] - sender_pos[0]) == abs(target_pos[1] - sender_pos[1]):
                            if abs(j - sender_pos[0]) == abs(i - sender_pos[1]):
                                all_pos_between_target.append([j, i])
                        if sender_pos[0] == target_pos[0] or sender_pos[1] == target_pos[1]:
                            all_pos_between_target.append([j, i])
                    else:
                        all_pos_between_target.append([j, i])
            else:
                if list(sender_pos) != [j, i] and list(target_pos) != [j, i]:
                    all_pos_between_target.append([j, i])
    print(all_pos_between_target)
    for i in range(len(all_pos_between_target)):
        if get_pion_of_pos(all_pos_between_target[i]) != "":
            return False
    if get_pion_of_pos(target_pos) != "" and pion[1] != get_pion_of_pos(target_pos).split("_")[1]:
        eat_pion = 1
    return True


def king_is_vulnerable():
    all_moves = []
    for k in range(len(get_pos_of_pion("all"))):
        print(k)
        for i in range(8):
            for j in range(8):
                if legit_move(get_pos_of_pion("all")[k], [j, i]) and not_pion_between_target(get_pos_of_pion("all")[
                     k], [j, i]) and list(get_pos_of_pion("all")[k]) != [j, i]:
                    all_moves.append([j, i])
    king_w_pos = list(get_pos_of_pion("king_w")[0])
    king_b_pos = list(get_pos_of_pion("king_b")[0])
    print(all_moves, king_w_pos, king_b_pos)
    if king_w_pos in all_moves or king_b_pos in all_moves:
        return True
    return False


def all_conditions_to_move(i_p, t_p):
    global k_w_m, k_b_m, t1_w_m, t1_b_m, t2_w_m, t2_b_m, roque_done
    if not_pion_between_target(i_p, t_p) and i_p != t_p and legit_move(i_p, t_p):
        print(i_p)
        if i_p == [0, 0]:
            t1_b_m = True
        if i_p == [3, 0]:
            k_b_m = True
        if i_p == [7, 0]:
            t2_b_m = True
        if i_p == [0, 7]:
            print('b')
            t1_w_m = True
        if i_p == [4, 7]:
            k_w_m = True
        if i_p == [7, 7]:
            t2_w_m = True
        return True
    if roque(tuple(i_p), tuple(t_p)):
        roque_done = True
        return True
    print(roque(tuple(i_p), tuple(t_p)))
    print(i_p, t_p)
    return False


def get_old_pos(key):
    return [pos[0] + (-1 if key == 3 else +1 if key != 1 and key != 2 else 0), pos[1] +
            (-1 if key == 2 else +1 if key != 0 and key != 3 else 0)]


def update_pos_pion(old_p, p, rock=0):
    if not rock:
        fill_rect(d_p(old_p[0])[0], d_p(0, old_p[1])[1], 27, 27, get_font(old_p))
        fill_rect(d_p(p[0])[0], d_p(0, p[1])[1], 27, 27, (186, 202, 43))
        fill_rect(d_p(p[0])[0] + 3, d_p(0, p[1])[1] + 3, 21, 21, get_font(p))
        draw_pion(eval(get_pion_of_pos(p).split("_")[0]), d_p(p[0], 0, 3)[0], d_p(0, p[1], 3)[1],
                  get_font(p), get_pion_color(p))
    else:
        default_pions()


def move_cursor(key, select_mode=0, leave_select_mode=0):
    global pion_selected, initial_pos, roque_done
    if leave_select_mode:
        if all_conditions_to_move(initial_pos, pos):
            print("1", pos_pions)
            switch_pos_pions(initial_pos, pos, 1 * eat_pion, 1 * roque_done)
            print("2", pos_pions)
            update_pos_pion(initial_pos, pos, 1 * roque_done)
            roque_done = 0
            print("3", pos_pions)
    else:
        if select_mode:
            fill_rect(d_p(pos[0])[0], d_p(0, pos[1])[1], 27, 27, (206, 222, 63))
            draw_pion(eval(get_pion_of_pos(pos).split("_")[0]), d_p(pos[0], 0, 3)[0], d_p(0, pos[1], 3)[1],
                      (206, 222, 63), get_pion_color(pos))
            initial_pos = [pos[0], pos[1]]
            pion_selected = True
        if not select_mode and not pion_selected:
            old_pos = get_old_pos(key)
            fill_rect(d_p(old_pos[0])[0], d_p(0, old_pos[1])[1], 27, 27, get_font(old_pos))
            if get_pion_of_pos(old_pos) != "":
                draw_pion(eval(get_pion_of_pos(old_pos).split("_")[0]), d_p(old_pos[0], 0, 3)[0],
                          d_p(0, old_pos[1], 3)[1], get_font(old_pos), get_pion_color(old_pos))
        if not select_mode:
            fill_rect(d_p(pos[0])[0], d_p(0, pos[1])[1], 27, 27, (186, 202, 43))
            fill_rect(d_p(pos[0])[0] + 3, d_p(0, pos[1])[1] + 3, 21, 21, get_font(pos))
            if get_pion_of_pos(pos) != "":
                draw_pion(eval(get_pion_of_pos(pos).split("_")[0]), d_p(pos[0], 0, 3)[0], d_p(0, pos[1], 3)[1],
                          get_font(pos), get_pion_color(pos))
            debug(initial_pos, pos)
            pion_selected = False


def legit_turn(t):
    team_pion = get_pion_of_pos(pos).split("_")[1]
    if (team_pion == "w" and t % 2 == 0) or (team_pion == "b" and t % 2 != 0):
        return True
    return False


def chess():
    gui()
    global pos, last_key, move_pion
    while not keydown(5):
        if keydown(3) and pos[0] < 7 and last_key != 3:
            pos[0] += 1
            move_cursor(3)
            last_key = 3
        if keydown(0) and pos[0] > 0 and last_key != 0:
            pos[0] -= 1
            move_cursor(0)
            last_key = 0
        if keydown(1) and pos[1] > 0 and last_key != 1:
            pos[1] -= 1
            move_cursor(1)
            last_key = 1
        if keydown(2) and pos[1] < 7 and last_key != 2:
            pos[1] += 1
            move_cursor(2)
            last_key = 2
        if keydown(52) and last_key != 52:
            if not move_pion and get_pion_of_pos(pos) != "" and legit_turn(tour):
                move_cursor(42, 1)
                move_pion = True
            elif move_pion:
                move_cursor(42, 0, 1)
                move_pion = False
            last_key = 52
        if not (keydown(0) or keydown(1) or keydown(2) or keydown(3) or keydown(52)):
            last_key = None


chess()
print(roque(p1, p2))

During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:

With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our cookies policy.