#intellitoy.py by Pedro Izecksohn.
#version: 20260703 15:37 UTC-3
#Local: Rio de Janeiro, RJ, Brazil
#License: You must forgive any mistake and may not modify this code.

import pygame
import random
import math

FONT_SIZE=24

BG_COLOR=(200,200,0)
FONT_COLOR=(0,0,0)
RIGHT_COLOR=(0,255,0)
WRONG_COLOR=(255,0,0)
IMG_BG_COLOR=(0,0,0)
IMG_FRONT_COLOR=(0,0,255)

pygame.init()

MODE=(800,600)
SCREEN=pygame.display.set_mode (MODE)

class Button:
    def __init__(self,text:str, pos:tuple):
        self.text=text
        self.pos=pos
        self.color=FONT_COLOR
    def hit (self, pos:tuple) -> bool:
        w=len(self.text)*FONT_SIZE
        h=FONT_SIZE*2
        return ((self.pos[0] <= pos[0] < self.pos[0]+w) and (self.pos[1] <= pos[1] < self.pos[1]+h))
    def paint (self):
        font = pygame.font.SysFont ("arial", FONT_SIZE)
        img=font.render (self.text, 1, self.color, BG_COLOR)
        SCREEN.blit (img, (self.pos[0], self.pos[1]+FONT_SIZE//2))

def line_list (begin, end) -> list[list]:
    ret:list[tuple] = []
    width=end[0]-begin[0]
    height=end[1]-begin[1]
    if width and (width>height):
        how = height/width
        #print (f"how={how}")
        for ix in range (0, width, 1 if width>0 else -1):
            x = begin[0]+ix
            y = begin[1] + int (how*ix)
            ret.append ([x,y])
    elif height and (height>width):
        woh = width/height
        for iy in range (0, height, 1 if height>0 else -1):
            x=begin[0] + int (iy*woh)
            y=begin[1]+iy
            ret.append ([x, y])
    else:
        ret.append (begin)
    return ret

class Geometric:
    def __init__ (self, center, size):
        self.center=center
        self.size=size
    def get_list (self):
        return line_list (self.center, self.center)
    def paint (self):
        pixels=self.get_list()
        for pos in pixels:
            SCREEN.set_at (pos, IMG_FRONT_COLOR)

class Line (Geometric):
    def __init__(self, center, size):
        if (type(size)==list) or (type(size)==tuple):
            super().__init__ (((((center[0]+size[0])//2), (center[1]+size[1])//2)), math.sqrt (((size[0]-center[0])**2)+((size[1]-center[1])**2)))
            self.a=center
            self.b=size
            return
        super().__init__(center, size)
        width=random.randint(0,size)
        height = int (((size**2)-(width**2))**0.5)
        self.a=[(center[0]-width//2), (center[1]-height//2)]
        self.b=[(center[0]+width//2),(center[1]+height//2)]
    def get_list(self):
        return line_list(self.a, self.b)
    def connects (self, other):
        return (self.a==other.a) or (self.a==other.b) or (self.b==other.b) or (self.b==other.a)

class Triangle (Geometric):
    def __init__(self, center, size):
        super().__init__(center, size)
        incl = random.randint(0,size)/random.randint(1,size)
        temp_xd = random.randint(-size//2,size//2)
        temp_yd = int(temp_xd*incl)
        self.a = [center[0]+temp_xd, center[1]+temp_yd]
        temp_xd2 = size//2-temp_xd
        temp_yd2 = int (math.sqrt (((size**2)-(temp_xd2**2))))
        self.b = [center[0]+temp_xd2, center[1]+temp_yd2]
        temp_xd3 = (temp_xd+temp_xd2)//2
        temp_yd3 = int (math.sqrt ((size**2)-(temp_xd3**2)))
        self.c = [center[0]+temp_xd3, center[1]+temp_yd3]
    def get_list (self):
        return line_list(self.a,self.b) + line_list(self.b,self.c) + line_list(self.c,self.a)

class Rectangle (Triangle):
    def __init__(self, center, size):
        super().__init__(center, size)
        dx=self.c[0]-self.b[0]
        dy=self.c[1]-self.b[1]
        self.d = [self.a[0]+dx, self.a[1]+dy]
    def get_list (self):
        return line_list(self.a,self.b) + line_list(self.a,self.d) + line_list(self.c,self.b) + line_list(self.d,self.c)

def get_random_geometric (pos, size):
    r = random.choice ([Triangle, Rectangle])
    return r (pos, size)

def is_rectangle (l:list):
    for i in range(1,len(l)):
        la=Line(l[0],l[i])
        for j in range(i+1, len(l)-1):
            lb=Line(l[i],l[j])
            if not la.connects(lb):
                continue
            lc=Line(l[j],l[-1])
            if not lb.connects(lc):
                continue
            if lc.connects(la):
                return True
    return False

def main ():
    buttons = [Button ("skip", (MODE[0]//2+FONT_SIZE, MODE[1]//4)), Button ("triangle",(MODE[0]//2+FONT_SIZE, MODE[1]//4*2)), Button ("rectangle", (MODE[0]//2+FONT_SIZE, MODE[1]//4*3))]
    size=random.randint (64, 128)
    form = get_random_geometric ((MODE[0]//4, MODE[1]//2), size)
    while True:
        SCREEN.fill(BG_COLOR)
        for button in buttons:
            button.paint()
        form.paint()
        pygame.display.flip()
        tipo = Rectangle if is_rectangle(form.get_list()) else Triangle
        ev = pygame.event.wait()
        if ev.type==pygame.QUIT:
            return
        if ev.type==pygame.MOUSEBUTTONDOWN:
            for button in buttons:
                if not button.hit (ev.pos):
                    continue
                if button.text=="skip":
                    size=random.randint (64, 128)
                    form = get_random_geometric((MODE[0]//4, MODE[1]//2), size)
                    for button in buttons:
                        button.color = FONT_COLOR
                    break
                if button.text in str(tipo).lower():
                    button.color = RIGHT_COLOR
                else:
                    button.color = WRONG_COLOR
                break


if __name__=="__main__":
    main()
