mastermind2.py

Created by cent20

Created on December 27, 2022

9.64 KB

legit en version beta


from kandinsky import draw_string as txt, fill_rect as rec
from ion import keydown
from random import choice

# Mastermind 0.0 NumWorks, 25.12.2022
# Par Ilyas RAHMOUN & Vincent ROBERT
# https://nsi.xyz/mastermind <3

DARK_C = (42,)*3
LIGHT_C = (142,)*3
BRIGHT_C = (242,)*3
GAME_C = (148, 113, 222)
VOID_C = (255,)*3

COLORS = ((255, 89, 94), (255, 202, 58), (25, 130, 196), (138, 201, 38), (255, 146, 76), (142,)*3, (66, 103, 172),
          (82, 166, 117))
CURSOR = COLOR = LVL = 0

SCOREBOARD = [["Score", 0], ["Max", 0], ["Legit", 0], [None, None]]

GAME_CONFIG = (["Colors", 8], ["Code", 4], ["Dupli", 1], ["Help", 0])
CONFIG_LIMITS = ((5, 8), (3, 6), [0, 1], (0, 1))
GAME = COMBIN = []


def gui(e=0):
    rec(0, 200, 320, 22, GAME_C)
    txt("Code by nsi.xyz/mastermind", 33, 202, BRIGHT_C, GAME_C)
    for i in range(len(GAME_CONFIG)):
        txt(GAME_CONFIG[i][0], 50 - 5*len(GAME_CONFIG[i][0]), 200//(len(GAME_CONFIG) + 1)*(i + 1) - 18, LIGHT_C)
        rec((101 - 18)//2, 200//(len(GAME_CONFIG) + 1)*(i + 1), 18, 18, LIGHT_C)
        txt(str(GAME_CONFIG[i][1]), (101 - 18)//2 + 4, 200//(len(GAME_CONFIG) + 1)*(i + 1), BRIGHT_C, LIGHT_C)
    arrow(255,165,0,LIGHT_C)
    arrow(260,165,1,LIGHT_C)
    arrow(260,165,2,LIGHT_C)
    arrow(260,165,3,LIGHT_C)
    txt("OK",257,165,LIGHT_C)
    if not e:
        plateau()
        config_displayer(0, 1)
    arrows_displayer(0, 1*(e != 0))


def plateau(code=GAME_CONFIG[1][1]):
    rec(101, 1, 118, 198, VOID_C)
    for i in range(10):
        for j in range(code):
            set_cell((j, i), BRIGHT_C)


def config_displayer(conf, state):
    c = GAME_C if state else LIGHT_C
    txt(GAME_CONFIG[conf][0], 50 - 5*len(GAME_CONFIG[conf][0]), 200//(len(GAME_CONFIG) + 1)*(conf + 1) - 18, c)
    rec((101 - 18) // 2, 200 // (len(GAME_CONFIG) + 1) * (conf + 1), 18, 18, c)
    txt(str(GAME_CONFIG[conf][1]), (101 - 18) // 2 + 4, 200 // (len(GAME_CONFIG) + 1) * (conf + 1), BRIGHT_C, c)


def config_updater(conf, incr, f=0):
    global GAME_CONFIG
    c = LIGHT_C if f else GAME_C
    GAME_CONFIG[conf][1] += incr
    txt(str(GAME_CONFIG[conf][1]), (101 - 18)//2 + 4, 200//(len(GAME_CONFIG) + 1)*(conf + 1), BRIGHT_C, c)
    arrows_displayer(conf)
    scoreboard_init()  #Branchement VR
    if conf == 1:
        plateau(GAME_CONFIG[conf][1])


def arrows_displayer(conf, leave=0):
    if leave:
        for i in range(len(GAME_CONFIG)):
            for j in range(2):
                rec((101 - 18)//2 + (25 if j else -17), 200//(len(GAME_CONFIG) + 1)*(i + 1) + 3, 10, 10, VOID_C)
    else:
        if GAME_CONFIG[conf][1] > CONFIG_LIMITS[conf][0]:
            txt("<", (101 - 18)//2 - 17, 200//(len(GAME_CONFIG) + 1)*(conf + 1), GAME_C)
        else:
            txt("<", (101 - 18)//2 - 17, 200//(len(GAME_CONFIG) + 1)*(conf + 1), VOID_C)
        if GAME_CONFIG[conf][1] < CONFIG_LIMITS[conf][1]:
            txt(">", (101 - 18)//2 + 25, 200//(len(GAME_CONFIG) + 1)*(conf + 1), GAME_C)
        else:
            txt(">", (101 - 18)//2 + 25, 200//(len(GAME_CONFIG) + 1)*(conf + 1), VOID_C)


def arrow(x, y, d=0, c=GAME_C):
    for i in range(6):
        rec(x + (23 + i) * (d == 3) - (5 + i) * (d == 0) + (3 + i) * (d % 3 != 0),
            y + (3 + i) * (d % 3 == 0) - (7 + i) * (d == 1) + (22 + i) * (d == 2), 1, 2, c)
        rec(x + (23 + i) * (d == 3) - (5 + i) * (d == 0) + (13 - i) * (d % 3 != 0),
            y + (13 - i) * (d % 3 == 0) - (7 + i) * (d == 1) + (22 + i) * (d == 2), 1, 2, c)


def config_manager(conf, i):
    config_displayer(conf, 0)
    arrows_displayer(conf, 1)
    conf += i
    config_displayer(conf, 1)
    arrows_displayer(conf)


def config_dupli_manager(conf):
    if GAME_CONFIG[1][1] > GAME_CONFIG[0][1]:
        GAME_CONFIG[2][1] = 1
        CONFIG_LIMITS[2][0] = 1
        config_updater(2, 0, 1*(conf != 2))
    else:
        CONFIG_LIMITS[2][0] = 0


def menu():
    global GAME
    config = 0
    last_key = None
    while not (keydown(4) or keydown(52)):
        if keydown(1) and config > 0 and last_key != 1:
            config_manager(config, -1)
            config -= 1
            last_key = 1
        if keydown(2) and config < len(GAME_CONFIG) - 1 and last_key != 2:
            config_manager(config, 1)
            config += 1
            last_key = 2
        if keydown(0) and GAME_CONFIG[config][1] > CONFIG_LIMITS[config][0] and last_key != 0:
            config_updater(config, -1)
            last_key = 0
        if keydown(3) and GAME_CONFIG[config][1] < CONFIG_LIMITS[config][1] and last_key != 3:
            config_updater(config, 1)
            last_key = 3
        config_dupli_manager(config)
        if not (keydown(0) or keydown(1) or keydown(2) or keydown(3)):
            last_key = None
    gui(1)
    GAME = [["" for _ in range(GAME_CONFIG[1][1])] for _ in range(10)]
    indicators_manager(1)


def d_p(p_x=0, p_y=0):
    return (320 - (GAME_CONFIG[1][1]*20 - 2))//2 + 20*p_x, 181 - 20*p_y


def set_cell(pos, color):
    rec(d_p(pos[0])[0], d_p(p_y=pos[1])[1], 18, 18, color)


def indicators_manager(static=0, dyn_del=0, dyn_place=0):
    if static:
        arrow(d_p(-1)[0] + 16, d_p(p_y=LVL)[1], 0)
        arrow(d_p(GAME_CONFIG[1][1])[0] - 16, d_p(p_y=LVL)[1], 3)
        arrow(d_p(CURSOR)[0] + 1, d_p(p_y=LVL)[1] + 17, 1, BRIGHT_C)
        arrow(d_p(CURSOR)[0] + 1, d_p(p_y=LVL + 1)[1] + 17, 1)
    if dyn_del:
        for i in range(GAME_CONFIG[1][1]):
            arrow(d_p(i)[0] + 1, d_p(p_y=LVL + 1)[1] + 17, 1, BRIGHT_C)
    if dyn_place:
        arrow(d_p(CURSOR)[0] + 1, d_p(p_y=LVL + 1)[1] + 17, 1)


def generate_combination():
    suit = []
    while not suit or (len(set(suit)) != len(suit) and GAME_CONFIG[2][1] != 1):
        suit = [choice([i for i in range(GAME_CONFIG[0][1])]) for _ in range(GAME_CONFIG[1][1])]
    return suit


def check_line(line, secret):
    good = sum([line[i] == secret[i] for i in range(len(line))])
    bad = sum([line[i] in secret for i in range(len(line))])-good
    return bad, good

def check_manager(lvl):
    bad, good = check_line(GAME[lvl], COMBIN)
    txt(str(bad), d_p(-1)[0] + 4, d_p(p_y=lvl)[1], "red", VOID_C)
    txt(str(good), d_p(GAME_CONFIG[1][1])[0] + 4, d_p(p_y=lvl)[1], "green", VOID_C)
    scoreboard_manager(bad, good) # VR

def debug():
    txt("".join(str(i) for i in COMBIN), 250, 180, (0, 0, 0))


def scoreboard_init():
    factorielle = lambda n: n * factorielle(n-1) if n != 0 else 1
    if GAME_CONFIG[2][1]==0: # arrangement si pas de dupli
        combi =  int(factorielle(GAME_CONFIG[0][1]) / factorielle(GAME_CONFIG[0][1]-GAME_CONFIG[1][1]))
    else:
        combi = GAME_CONFIG[0][1] ** GAME_CONFIG[1][1]
    SCOREBOARD[0][1] = 100000
    SCOREBOARD[1][1] = SCOREBOARD[2][1] = combi
    scoreboard()


def scoreboard(): # Il y a des truc à sortir d'ici
    # Données dans GAME_CONFIG[i][1]
    # GAME_CONFIG = (["Colors", 8], ["Code", 4], ["Dupli", 1], ["Help", 0])
    # SCOREBOARD = [["Score", 0], ["Max", 0], ["Legit", 0], [None, None]]    
    rec(220,0,100,150,(255,255,255))
    for i in range(3): # TODO désactiver legit si aide = 0 
        txt(SCOREBOARD[i][0], 269 - 5*len(SCOREBOARD[i][0]), 200//(len(SCOREBOARD) + 1)*(i + 1) - 18, DARK_C)
        txt("         ",220, 200//(len(SCOREBOARD) + 1) * (i + 1)) # Nettoie les lignes
        txt(str(SCOREBOARD[i][1]), 269 - 5*len(str(SCOREBOARD[i][1])), 200//(len(SCOREBOARD) + 1) * (i + 1), LIGHT_C)


def scoreboard_manager(b,g):
    global LVL
    SCOREBOARD[0][1] = int(SCOREBOARD[0][1] * (0.80+0.2*g/GAME_CONFIG[1][1]+0.1*b/GAME_CONFIG[1][1]))
    if g == GAME_CONFIG[1][1]:  #WIN
        rec(230,152,70,42,GAME_C)
        txt("WIN", 250, 162, BRIGHT_C, GAME_C)
    elif LVL == 9: #10 à vérifier !
        rec(230,152,70,42,GAME_C)
        txt("LOOSE", 242, 162, BRIGHT_C, GAME_C)
    scoreboard()

def legit_eval():
    global LVL    
    ok = 0
    for _ in range(1000):
        test = generate_combination()
        for i in range(LVL+1):
            #print(test,GAME[i],check_line(test),check_line(GAME[i] ))
            if check_line(GAME[i], COMBIN) != check_line(GAME[i], test):
                break
            if i==LVL:
                ok +=1
    result = max(0.1, round(ok/10,1))
    SCOREBOARD[2][1] = str(result)+"%"
    txt(str(ok),240,0)
    check_manager(LVL)
            
        


def mastermind():
    global CURSOR, COLOR, LVL, GAME, COMBIN
    last_key = None
    gui()
    scoreboard_init()
    menu()
    COMBIN = generate_combination() # VR
    while not keydown(5):
        if keydown(0) and last_key != 0:
            indicators_manager(dyn_del=1)
            CURSOR -= 1
            CURSOR = CURSOR % GAME_CONFIG[1][1]
            indicators_manager(dyn_place=1)
            last_key = 0
        if keydown(3) and last_key != 3:
            indicators_manager(dyn_del=1)
            CURSOR += 1
            CURSOR = CURSOR % GAME_CONFIG[1][1]
            indicators_manager(dyn_place=1)
            last_key = 3
        if keydown(1) and last_key != 1:
            COLOR = (GAME[LVL - 1][CURSOR] - 1) % GAME_CONFIG[0][1] if GAME[LVL][CURSOR] == "" and LVL != 0 else COLOR
            COLOR += 1
            GAME[LVL][CURSOR] = COLOR % GAME_CONFIG[0][1]
            set_cell((CURSOR, LVL), COLORS[COLOR % GAME_CONFIG[0][1]])
            last_key = 1
        if keydown(2) and last_key != 2:
            COLOR = (GAME[LVL - 1][CURSOR] + 1) % GAME_CONFIG[0][1] if GAME[LVL][CURSOR] == "" and LVL != 0 else COLOR
            COLOR -= 1
            GAME[LVL][CURSOR] = COLOR % GAME_CONFIG[0][1]
            set_cell((CURSOR, LVL), COLORS[COLOR % GAME_CONFIG[0][1]])
            last_key = 2
        if (keydown(4) or keydown(52)) and "" not in GAME[LVL]:
            legit_eval()
            LVL += 1
            indicators_manager(1)
        if not (keydown(0) or keydown(1) or keydown(2) or keydown(3)):
            last_key = None


mastermind()

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.