Esempio n. 1
0
class PgnInfo(e):
    def __init__(self, parent, pgnlistparent):
        super().__init__("div")
        self.headers = []
        self.parent = parent
        self.pgnlistparent = pgnlistparent

    def getheader(self, key, default):
        for header in self.headers:
            if header[0] == key:
                return header[1]
        return default

    def playerlink(self, username):
        return "<a href='https://lichess.org/@/{}' target='_blank' rel='noopener noreferrer'>{}</a>".format(username, username)

    def parsecontent(self):        
        lines = self.content.split("\n")
        self.headers = []
        for line in lines:
            if line[0] == "[":
                parts = line[1:].split("\"")
                key = parts[0].split(" ")[0]
                value = parts[1].split("\"")[0]
                self.headers.append((key, value))
        self.white = self.getheader("White", "?")        
        self.black = self.getheader("Black", "?")        
        self.result = self.getheader("Result", "?")        
        self.site = self.getheader("Site", "")               
        self.whiteelo =  self.getheader("WhiteElo", "?")
        self.whiteratingdiff =  self.getheader("WhiteRatingDiff", "?")
        self.blackelo =  self.getheader("BlackElo", "?")
        self.blackratingdiff =  self.getheader("BlackRatingDiff", "?")
        self.variant = self.getheader("Variant", "Standard")
        self.timecontrol = self.getheader("TimeControl", "?")
        self.utcdate = self.getheader("UTCDate", "?")
        self.id = self.site.split("/")[-1:][0]

    def idclicked(self):
        self.parent.loadedgameid = self.id
        self.parent.loadedgameside = "white"        
        if self.meblack():
            self.parent.loadedgameside = "black"
        self.parent.pgntext.setpgn(self.content)
        self.bds("dotted").bdw("6").bdc("#00f")
        localStorage.setItem("pgninfo/idclicked", self.id)
        self.pgnlistparent.bookmarkedpi = self
        getconn().sioreq({
            "kind": "parsepgn",
            "owner": self.parent.id,
            "data": self.content
        })

    def mecolor(self):
        if self.white == self.parent.username:
            return WHITE
        if self.black == self.parent.username:
            return BLACK
        return None

    def mewhite(self):
        return self.mecolor() == WHITE

    def meblack(self):
        return self.mecolor() == BLACK

    def hasme(self):
        return not ( self.mecolor() is None )

    def score(self):
        if self.result == "1-0":
            return 1
        if self.result == "0-1":
            return 0
        return 0.5

    def mescore(self):
        if self.hasme():
            if self.mewhite():
                return self.score()
            return 1 - self.score()
        return self.score()

    def meratinginfo(self):
        if self.hasme():
            if self.mewhite():
                return [ self.whiteelo, self.whiteratingdiff ]
            return [ self.blackelo, self.blackratingdiff ]
        return None

    def build(self):        
        self.x().ac("pgninfocontainer")
        self.tcdiv = Div().ac("pgninfotcdiv").html("{} {}".format(self.timecontrol, self.variant))        
        self.whitediv = Div().ac("pgninfoplayerdiv").html(self.playerlink(self.white))        
        self.whiteelodiv = Div().ac("pgninfoplayerelodiv").html("{} {}".format(self.whiteelo, self.whiteratingdiff))        
        if self.meblack():
            self.whitediv.ac("pgninfotheyplayerdiv")
        self.blackdiv = Div().ac("pgninfoplayerdiv").html(self.playerlink(self.black))        
        self.blackelodiv = Div().ac("pgninfoplayerelodiv").html("{} {}".format(self.blackelo, self.blackratingdiff))        
        if self.mewhite():
            self.blackdiv.ac("pgninfotheyplayerdiv")
        self.resultdiv = Div().ac("pgninforesultdiv").html(self.result)
        self.iddiv = Div().ac("pgninfoiddiv").html(self.id)
        self.iddiv.ae("mousedown", self.idclicked)
        mescore = self.mescore()
        if mescore == 1:
            self.ac("pgninfowhitewin")
        elif mescore == 0:
            self.ac("pgninfoblackwin")
        else:
            self.ac("pgninfodraw")
        self.a([self.tcdiv, self.whitediv, self.whiteelodiv, self.blackdiv, self.blackelodiv, self.resultdiv, self.iddiv])
        if self.id == localStorage.getItem("pgninfo/idclicked"):
            self.bds("dashed").bdw("6").bdc("#00f")
        return self

    def setcontent(self, content):
        self.content = content
        self.parsecontent()
        return self.build()
Esempio n. 2
0
class MultipvInfo(e):
    def bestmovesanclickedfactory(self, moveuci, dostore = False):
        def bestmovesanclicked():
            if not ( self.bestmovesanclickedcallback is None ):
                self.bestmovesanclickedcallback(moveuci, dostore)
        return bestmovesanclicked

    def scorebonus(self):
        if "scorebonus" in self.infoi:
            try:
                scorebonus = int(self.infoi["scorebonus"])
                return scorebonus
            except:
                pass
        return 0

    def effscore(self):
        return self.scorenumerical + self.scorebonus()

    def bonussliderchanged(self):
        self.infoi["scorebonus"] = self.bonusslider.v()
        self.build()            
        if not ( self.bonussliderchangedcallback is None ):            
            self.bonussliderchangedcallback()

    def traincombochanged(self):
        self.infoi["metrainweight"] = self.metraincombo.v()
        self.infoi["opptrainweight"] = self.opptraincombo.v()
        self.build()

    def build(self, gamesan = None):            
        self.bestmoveuci = self.infoi["bestmoveuci"]
        self.bestmovesan = self.infoi["bestmovesan"]
        self.scorenumerical = self.infoi["scorenumerical"]
        self.pvsan = self.infoi["pvsan"]
        self.pvsans = self.pvsan.split(" ")
        if len(self.pvsans) > ( self.pvlength + 1 ):
            self.pvsans = self.pvsans[0:self.pvlength + 1]
        if len(self.pvsans) > 1:
            self.pvsans = self.pvsans[1:]
        self.showpv = " ".join(self.pvsans)
        self.pvpgn = self.infoi["pvpgn"]
        self.depth = self.infoi["depth"]
        self.nps = self.infoi["nps"]        
        self.container = Div().ac("multipvinfocontainer")
        self.idiv = Div().ac("multipvinfoi").html("{}.".format(self.i))
        self.bestmovesandiv = Div().ac("multipvinfobestmovesan").html(self.bestmovesan)
        if gamesan == self.bestmovesan:
            self.bestmovesandiv.bc("#fbf")
        self.bestmovesandiv.ae("mousedown", self.bestmovesanclickedfactory(self.bestmoveuci))        
        self.scorenumericaldiv = Div().ac("multipvinfoscorenumerical").html("{}".format(scoreverbal(self.effscore()))).cp()
        self.scorenumericaldiv.ae("mousedown", self.bestmovesanclickedfactory(self.bestmoveuci, True))        
        self.bonussliderdiv = Div().ac("multipvinfobonussliderdiv")
        self.bonusslider = Slider().setmin(-500).setmax(500).ac("multipvinfobonusslider").sv(self.scorebonus())        
        self.bonusslider.ae("change", self.bonussliderchanged)
        self.bonussliderdiv.a(self.bonusslider)
        self.depthdiv = Div().ac("multipvinfodepth").html("{}".format(self.depth))
        self.miscdiv = Div().ac("multipvinfomisc").html("nps {}".format(self.nps))
        self.traindiv = Div().ac("multipvinfomisc").w(100)        
        metrainweight = self.infoi["metrainweight"]        
        hasmetrain = False
        if not metrainweight:
            metrainweight = "0"            
        opptrainweight = self.infoi["opptrainweight"]
        hasopptrain = False
        if not opptrainweight:
            opptrainweight = "0"                
        try:
            if int(metrainweight) > 0:
                hasmetrain = True
            if int(opptrainweight) > 0:
                hasopptrain = True
        except:
            pass
        if hasmetrain and hasopptrain:
            self.trainbc = "#00f"
        elif hasmetrain:
            self.trainbc = "#0f0"
        elif hasopptrain:
            self.trainbc = "#f00"
        else:
            self.trainbc = "inherit"                
        self.metrainweight = int(metrainweight)
        self.opptrainweight = int(opptrainweight)
        self.avgtrainweight = ( self.metrainweight + self.opptrainweight ) / 2.0
        self.trainop = self.avgtrainweight / 10.0
        self.metraincombo = ComboBox().setoptions(TRAIN_OPTIONS, metrainweight, self.traincombochanged)
        self.opptraincombo = ComboBox().setoptions(TRAIN_OPTIONS, opptrainweight, self.traincombochanged)        
        self.traindiv.a([self.metraincombo, self.opptraincombo])        
        self.pvdiv = Div().ac("multipvinfopv").html(self.showpv).c("#070").fw("bold")
        self.container.a([self.idiv, self.bestmovesandiv, self.scorenumericaldiv, self.bonussliderdiv, self.traindiv, self.depthdiv, self.pvdiv])        
        self.container.bc(self.trainbc)
        self.bestmovesandiv.c(scorecolor(self.effscore()))
        self.scorenumericaldiv.c(scorecolor(self.effscore()))        
        self.x().a(self.container)        

    def __init__(self, infoi, pvlength = 4):
        super().__init__("div")
        self.pvlength = pvlength
        self.bestmovesanclickedcallback = None
        self.bonussliderchangedcallback = None
        self.infoi = infoi
        self.i = self.infoi["i"]
        self.build()
Esempio n. 3
0
class BasicBoard(e):
    def clearcanvases(self):
        self.movecanvas.clear()
        self.piececanvashook.x()
        self.arrowdiv.x()

    def ucitosquare(self, squci):
        try:
            file = squci.charCodeAt(0) - "a".charCodeAt(0)
            rank = self.lastrank - ( squci.charCodeAt(1) - "1".charCodeAt(0) )
            return Square(file, rank)
        except:
            return None

    def ucitomove(self, moveuci):        
        if "@" in moveuci:
            try:
                parts = moveuci.split("@")
                sq = self.ucitosquare(parts[1])
                move = Move(sq, sq, Piece(parts[0].toLowerCase(), self.turn()))
                return move
            except:
                return None
        else:
            try:
                move = Move(self.ucitosquare(moveuci[0:2]), self.ucitosquare(moveuci[2:4]))
                try:
                    if len(moveuci) > 4:
                        move.prompiece = Piece(moveuci[4].toLowerCase(), self.turn())                    
                except:
                    print("could not parse prompiece")
                return move
            except:
                return None

    def resize(self, width, height):
        self.squaresize = 35
        self.calcsizes()
        while self.totalheight() < height:
            self.squaresize += 1
            self.calcsizes()
        self.squaresize -= 1
        self.calcsizes()
        self.build()

    def totalheight(self):
        th = self.outerheight + cpick(self.showfen, self.fendivheight, 0)
        if self.variantkey == "crazyhouse":
            th += 2 * self.squaresize
        return th

    def squareuci(self, sq):
        fileletter = String.fromCharCode(sq.file + "a".charCodeAt(0))
        rankletter = String.fromCharCode(self.lastrank - sq.rank + "1".charCodeAt(0))
        return fileletter + rankletter

    def moveuci(self, move):
        fromuci = self.squareuci(move.fromsq)
        touci = self.squareuci(move.tosq)
        promuci = cpick(move.prompiece.isempty(), "", move.prompiece.kind)
        return fromuci + touci + promuci

    def islightfilerank(self, file, rank):
        return ( ( ( file + rank ) % 2 ) == 0 )

    def islightsquare(self, sq):
        return self.islightfilerank(sq.file, sq.rank)

    def squarelist(self):
        squarelist = []
        for file in range(self.numfiles):
            for rank in range(self.numranks):
                squarelist.append(Square(file, rank))
        return squarelist

    def squarecoordsvect(self, sq):
        return Vect(sq.file * self.squaresize, sq.rank * self.squaresize)

    def squarecoordsmiddlevect(self, sq):
        return self.squarecoordsvect(sq).p(Vect(self.squaresize / 2, self.squaresize / 2))

    def piececoordsvect(self, sq):
        return self.squarecoordsvect(sq).p(Vect(self.squarepadding, self.squarepadding))

    def flipawaresquare(self, sq):
        if self.flip:
            return Square(self.lastfile - sq.file, self.lastrank - sq.rank)
        return sq

    def piecedragstartfactory(self, sq, pdiv):
        def piecedragstart(ev):
            if self.promoting or self.show:
                ev.preventDefault()
                return
            self.dragkind = "move"
            self.draggedsq = sq            
            self.draggedpdiv = pdiv
            self.movecanvashook.x()
            pdiv.op(0.1)
        return piecedragstart

    def piecedragfactory(self):
        def piecedrag(ev):            
            pass
        return piecedrag

    def piecedragendfactory(self, sq, pdiv):
        def piecedragend(ev):                        
            pdiv.op(0.5)
        return piecedragend

    def piecedragoverfactory(self, sq):
        def piecedragover(ev):
            ev.preventDefault()            
        return piecedragover

    def ismovepromotion(self, move):
        fromp = self.getpieceatsquare(move.fromsq)
        if ( fromp.kind == "p" ) and ( fromp.color == self.turn() ):
            if self.iswhitesturn():
                if move.tosq.rank == 0:
                    return True
            else:
                if move.tosq.rank == self.lastrank:
                    return True
        return False

    def piecedropfactory(self, sq):
        def piecedrop(ev):
            ev.preventDefault()            
            self.draggedpdiv.pv(self.piececoordsvect(self.flipawaresquare(sq)))
            self.draggedpdiv.zi(100)
            if self.dragkind == "move":                
                self.dragmove = Move(self.draggedsq, sq)
                if self.ismovepromotion(self.dragmove):
                    self.promoting = True
                    self.build()
                elif not ( self.movecallback is None ):
                    self.movecallback(self.variantkey, self.fen, self.moveuci(self.dragmove))
            elif self.dragkind == "set":
                self.container.a(self.draggedpdiv)
                if not ( self.movecallback is None ):
                    setuci = "{}@{}".format(self.draggedsetpiece.kind, self.squareuci(sq))
                    self.movecallback(self.variantkey, self.fen, setuci)
        return piecedrop

    def buildsquares(self):
        self.container.x()
        self.sqdivs = {}
        self.sqhdivs = {}
        for sq in self.squarelist():
            sqclass = cpick(self.islightsquare(sq), "boardsquarelight", "boardsquaredark")
            sqdiv = Div().ac(["boardsquare", sqclass]).w(self.squaresize).h(self.squaresize)
            sqhdiv = Div().pa().w(self.squaresize).h(self.squaresize)
            self.sqdivs[sq.hashkey()] = sqdiv
            self.sqhdivs[sq.hashkey()] = {
                "div": sqhdiv,
                "cumop": 0.0
            }
            fasq = self.flipawaresquare(sq)
            sqdiv.pv(self.squarecoordsvect(fasq))
            sqhdiv.pv(self.squarecoordsvect(fasq))
            sqdiv.ae("dragover", self.piecedragoverfactory(sq))
            sqdiv.ae("drop", self.piecedropfactory(sq))            
            sqhdiv.ae("dragover", self.piecedragoverfactory(sq))
            sqhdiv.ae("drop", self.piecedropfactory(sq))            
            self.container.a([sqdiv, sqhdiv])
            p = self.getpieceatsquare(sq)
            if p.ispiece():
                pdiv = Div().ac("boardpiece").w(self.piecesize).h(self.piecesize).pv(self.piececoordsvect(fasq))
                pdiv.ac(getclassforpiece(p, self.piecestyle)).sa("draggable", True)
                pdiv.ae("dragstart", self.piecedragstartfactory(sq, pdiv))
                pdiv.ae("drag", self.piecedragfactory())
                pdiv.ae("dragend", self.piecedragendfactory(sq, pdiv))
                pdiv.ae("dragover", self.piecedragoverfactory(sq))
                pdiv.ae("drop", self.piecedropfactory(sq))            
                pdiv.zi(10)
                if self.variantkey == "threeCheck":
                    if ( p.kind == "k" ):
                        mul = self.getthreelifesforcolor(p.color)
                        lifesdiv = Div().pa().t(- self.squaresize / 10).l(self.squaresize / 2 + self.squaresize / 10).w(self.squaresize / 2).h(self.squaresize / 2)
                        lifesdiv.ac("boardthreechecklifesdiv").fs(self.squaresize / 1.5).html("{}".format(mul))
                        lifesdiv.c(["#ff0", "#ff0"][p.color])
                        pdiv.a(lifesdiv)
                self.container.a(pdiv)

    def getthreelifesforcolor(self, color):
        parts = self.threefen.split("+")
        mul = 3
        if color == WHITE:
            try:
                mul = int(parts[2])
            except:
                print("warning, could not parse white lifes from", self.threefen)
        if color == BLACK:
            try:
                mul = int(parts[0])
            except:
                print("warning, could not parse black lifes from", self.threefen)
        return mul

    def prompiececlickedfactory(self, prompiecekind):
        def prompiececlicked():
            self.dragmove.prompiece = Piece(prompiecekind, self.turn())
            self.movecallback(self.variantkey, self.fen, self.moveuci(self.dragmove))
        return prompiececlicked

    def buildprominput(self):
        promkinds = prompiecekindsforvariantkey(self.variantkey)
        promsq = self.dragmove.tosq.copy()        
        dir = cpick(promsq.rank >= ( self.numranks / 2 ), -1, 1)
        ppks = prompiecekindsforvariantkey(self.variantkey)
        for ppk in ppks:            
            fapromsq = self.flipawaresquare(promsq)
            pp = Piece(ppk, self.turn())
            psqdiv = Div().pa().cp().zi(150).w(self.squaresize).h(self.squaresize).ac("boardpromotionsquare")
            psqdiv.pv(self.squarecoordsvect(fapromsq))
            ppdiv = Div().pa().cp().zi(200).w(self.piecesize).h(self.piecesize).ac(getclassforpiece(pp, self.piecestyle))
            ppdiv.pv(self.piececoordsvect(fapromsq)).ae("mousedown", self.prompiececlickedfactory(ppk))
            self.container.a([psqdiv, ppdiv])
            promsq = promsq.p(Square(0, dir))

    def promotecancelclick(self):
        self.promoting = False
        self.build()

    def drawmovearrow(self, move, args = {}):                        
        if move is None:
            return
        strokecolor = args.get("strokecolor", "#FFFF00")
        linewidth = args.get("linewidth", 0.2) * self.squaresize
        headwidth = args.get("headwidth", 0.2) * self.squaresize
        headheight = args.get("headheight", 0.2) * self.squaresize        
        tomv = self.squarecoordsmiddlevect(self.flipawaresquare(move.tosq))
        frommv = self.squarecoordsmiddlevect(self.flipawaresquare(move.fromsq))
        if False:
            self.movecanvas.lineWidth(linewidth)
            self.movecanvas.strokeStyle(strokecolor)
            self.movecanvas.fillStyle(strokecolor)        
            self.movecanvas.drawline(frommv, tomv)
            dv = Vect(headwidth, headheight)            
            self.movecanvas.fillRect(tomv.m(dv), tomv.p(dv))
            if not ( move.prompiece.isempty() ):
                pf = 4
                dvp = Vect(linewidth * pf, linewidth * pf)
                move.prompiece.color = self.turn()
                ppdiv = Div().pa().cp().ac(getclassforpiece(move.prompiece, self.piecestyle)).w(linewidth * 2 * pf).h(linewidth * 2 * pf)
                ppdiv.pv(tomv.m(dvp))            
                self.piececanvashook.a(ppdiv)
        arrow = Arrow(frommv, tomv, {
            "linewidth": linewidth,
            "pointwidth": headheight * 4,
            "pointheight": headheight * 4,
            "color": strokecolor
        })
        self.arrowdiv.a(arrow)

    def drawuciarrow(self, uci, args = {}):
        self.drawmovearrow(self.ucitomove(uci), args)

    def highlightsquare(self, sq, bc, op):
        if op == 0:
            return
        margin = self.squaresize * 0.1
        hsize = self.squaresize - 2 * margin
        sqhdiv = self.sqhdivs[sq.hashkey()]                
        if op > sqhdiv["cumop"]:
            sqhdiv["cumop"] = op          
        sqhdiv["div"].x().a(Div().pa().t(margin).l(margin).w(hsize).h(hsize).bc(bc).op(sqhdiv["cumop"]))              

    def highlightmove(self, move, bc, op):        
        self.highlightsquare(move.fromsq, bc, op)
        self.highlightsquare(move.tosq, bc, op)

    def highlightucimove(self, uci, bc, op):        
        self.highlightmove(self.ucitomove(uci), bc, op)

    def buildgenmove(self):
        if "genmove" in self.positioninfo:
            if not ( genmove == "reset" ):
                genmoveuci = self.positioninfo["genmove"]["uci"]
                genmove = self.ucitomove(genmoveuci)
                if not ( genmove is None ):
                    genmove.prompiece = Piece()
                    self.drawmovearrow(genmove)

    def fentextchanged(self):
        if self.fentextchangedcallback:
            self.fentextchangedcallback(self.fentext.getText())

    def build(self):
        self.sectioncontainer = Div().ac("boardsectioncontainer").w(self.outerwidth)
        self.sectioncontainer.bci(self.background)
        self.outercontainer = Div().ac("boardoutercontainer").w(self.outerwidth).h(self.outerheight)
        self.outercontainer.bci(self.background)
        self.container = Div().ac("boardcontainer").w(self.width).h(self.height).t(self.margin).l(self.margin)        
        self.container.bci(self.background)
        self.outercontainer.a(self.container)        
        self.buildsquares()
        self.turndiv = Div().pa().w(self.turndivsize).h(self.turndivsize).bc(cpick(self.iswhitesturn(), "#fff", "#000"))
        if self.variantkey == "racingKings":
            self.turndiv.t(cpick(self.flip, 0, self.outerheight - self.turndivsize))
            if xor(self.isblacksturn(), self.flip):
                self.turndiv.l(0)
            else:
                self.turndiv.l(self.outerwidth - self.turndivsize)
        else:
            self.turndiv.l(self.outerwidth - self.turndivsize).t(cpick(xor(self.isblacksturn(), self.flip), 0, self.outerheight - self.turndivsize))
        self.outercontainer.a(self.turndiv)
        if self.promoting:
            self.buildprominput()
            self.container.ae("mousedown", self.promotecancelclick)
        self.fentext = TextInput({}).w(self.width).fs(10).setText(self.fen)
        self.fentext.changecallback = self.fentextchanged
        self.fendiv = Div().ac("boardfendiv").h(self.fendivheight).a(self.fentext)
        if self.variantkey == "crazyhouse":
            self.whitestorediv = Div().ac("boardstorediv").h(self.squaresize).w(self.outerwidth)
            self.whitestorediv.bci(self.background)
            self.blackstorediv = Div().ac("boardstorediv").h(self.squaresize).w(self.outerwidth)
            self.blackstorediv.bci(self.background)
            self.whitestore = PieceStore({
                "show": self.show,
                "parent": self,
                "color": WHITE,
                "store": self.crazyfen,
                "containerdiv": self.whitestorediv
            })
            self.blackstore = PieceStore({
                "show": self.show,
                "parent": self,
                "color": BLACK,
                "store": self.crazyfen,
                "containerdiv": self.blackstorediv
            })            
            if self.flip:
                self.sectioncontainer.a([self.whitestorediv, self.outercontainer, self.blackstorediv])
            else:
                self.sectioncontainer.a([self.blackstorediv, self.outercontainer, self.whitestorediv])
        else:
            self.sectioncontainer.a([self.outercontainer])
        if self.showfen:
            self.sectioncontainer.a(self.fendiv)
        self.x().a(self.sectioncontainer)
        self.movecanvas = Canvas(self.width, self.height).pa().t(0).l(0)
        self.movecanvashook = Div().pa().t(0).l(0).zi(5).op(0.5)
        self.piececanvashook = Div().pa().t(0).l(0).zi(11).op(0.5)
        self.arrowdiv = Div().pa()
        self.container.a([self.movecanvashook, self.arrowdiv, self.piececanvashook])
        self.movecanvashook.a(self.movecanvas)
        self.buildgenmove()
        return self

    def setflip(self, flip):
        self.flip = flip
        self.build()

    def calcsizes(self):
        self.lastfile = self.numfiles - 1
        self.lastrank = self.numranks - 1
        self.area = self.numfiles * self.numranks
        self.width = self.numfiles * self.squaresize
        self.height = self.numranks * self.squaresize
        self.avgsize = ( self.width + self.height ) / 2
        self.margin = self.marginratio * self.avgsize
        self.squarepadding = self.squarepaddingratio * self.squaresize
        self.piecesize = self.squaresize - 2 * self.squarepadding
        self.outerwidth = self.width + 2 * self.margin
        self.outerheight = self.height + 2 * self.margin
        self.turndivsize = self.margin
        self.fendivheight = 25

    def parseargs(self, args):        
        self.fentextchangedcallback = args.get("fentextchangedcallback", None)
        self.positioninfo = args.get("positioninfo", {})
        self.show = args.get("show", False)
        self.showfen = args.get("showfen", True)
        self.squaresize = args.get("squaresize", 45)
        self.squarepaddingratio = args.get("squarepaddingratio", 0.04)
        self.marginratio = args.get("marginratio", 0.02)
        self.numfiles = args.get("numfiles", 8)
        self.numranks = args.get("numranks", 8)        
        self.piecestyle = args.get("piecestyle", "alpha")
        self.flip = args.get("flip", False)
        self.movecallback = args.get("movecallback", None)
        self.background = "/static/img/backgrounds/" + args.get("background", "wood.jpg")
        self.calcsizes()

    def setpieceati(self, i, p):
        if ( i >= 0 ) and ( i < self.area ):
            self.rep[i] = p
        else:
            print("warning, rep index out of range", i)

    def getpieceati(self, i):
        if ( i >= 0 ) and ( i < self.area ):            
            return self.rep[i]
        return Piece()

    def getpieceatfilerank(self, file, rank):
        i = rank * self.numfiles + file        
        return self.getpieceati(i)

    def getpieceatsquare(self, sq):
        return self.getpieceatfilerank(sq.file, sq.rank)

    def setrepfromfen(self, fen):  
        self.fen = fen
        self.crazyfen = None
        self.threefen = None
        self.rep = [Piece() for i in range(self.area)]
        fenparts = self.fen.split(" ")
        self.rawfen = fenparts[0]
        rawfenparts = self.rawfen.split("/")        
        if self.variantkey == "crazyhouse":
            self.crazyfen = ""
            if "[" in self.rawfen:
                cfenparts = self.rawfen.split("[")
                self.rawfen = cfenparts[0]
                rawfenparts = self.rawfen.split("/")
                cfenparts = cfenparts[1].split("]")
                self.crazyfen = cfenparts[0]
        i = 0
        for rawfenpart in rawfenparts:
            pieceletters = rawfenpart.split("")
            for pieceletter in pieceletters:
                if isvalidpieceletter(pieceletter):
                    self.setpieceati(i, piecelettertopiece(pieceletter))
                    i+=1
                else:
                    mul = 0
                    try:
                        mul = int(pieceletter)                        
                    except:
                        print("warning, multiplicity could not be parsed from", pieceletter)
                    for j in range(mul):
                        self.setpieceati(i, Piece())
                        i += 1
        if i < self.area:
            print("warning, raw fen did not fill board")
        elif i > self.area:
            print("warning, raw fen exceeded board")
        self.turnfen = "w"
        if len(fenparts) > 1:
            self.turnfen = fenparts[1]
        else:
            print("warning, no turn fen")
        self.castlefen = "-"
        if len(fenparts) > 2:
            self.castlefen = fenparts[2]
        else:
            print("warning, no castle fen")
        self.epfen = "-"
        if len(fenparts) > 3:
            self.epfen = fenparts[3]
        else:
            print("warning, no ep fen")
        moveclocksi = cpick(self.variantkey == "threeCheck", 5, 4)
        self.halfmoveclock = 0
        if len(fenparts) > moveclocksi:
            try:
                self.halfmoveclock = int(fenparts[moveclocksi])
            except:
                print("warning, half move clock could not be parsed from", fenparts[4])
        else:
            print("warning, no half move fen")
        self.fullmovenumber = 1
        if len(fenparts) > ( moveclocksi + 1 ):
            try:
                self.fullmovenumber = int(fenparts[moveclocksi + 1])
            except:
                print("warning, full move number could not be parsed from", fenparts[5])
        else:
            print("warning, no full move fen")
        if self.variantkey == "threeCheck":
            if len(fenparts) > 4:
                self.threefen = fenparts[4]        
        self.promoting = False

    def turn(self):
        if self.turnfen == "w":
            return WHITE
        return BLACK

    def iswhitesturn(self):
        return self.turn() == WHITE

    def isblacksturn(self):
        return self.turn() == BLACK

    def initrep(self, args):
        self.variantkey = args.get("variantkey", "standard")
        self.setrepfromfen(args.get("fen", getstartfenforvariantkey(self.variantkey)))

    def setfromfen(self, fen, positioninfo = {}):                        
        self.positioninfo = positioninfo
        self.setrepfromfen(fen)
        self.build()                

    def reset(self):
        self.setfromfen(getstartfenforvariantkey(self.variantkey))

    def __init__(self, args):
        super().__init__("div")        
        self.positioninfo = {}
        self.parseargs(args)
        self.initrep(args)
        self.build()
Esempio n. 4
0
 def buildsquares(self):
     self.container.x()
     self.sqdivs = {}
     self.sqhdivs = {}
     for sq in self.squarelist():
         sqclass = cpick(self.islightsquare(sq), "boardsquarelight", "boardsquaredark")
         sqdiv = Div().ac(["boardsquare", sqclass]).w(self.squaresize).h(self.squaresize)
         sqhdiv = Div().pa().w(self.squaresize).h(self.squaresize)
         self.sqdivs[sq.hashkey()] = sqdiv
         self.sqhdivs[sq.hashkey()] = {
             "div": sqhdiv,
             "cumop": 0.0
         }
         fasq = self.flipawaresquare(sq)
         sqdiv.pv(self.squarecoordsvect(fasq))
         sqhdiv.pv(self.squarecoordsvect(fasq))
         sqdiv.ae("dragover", self.piecedragoverfactory(sq))
         sqdiv.ae("drop", self.piecedropfactory(sq))            
         sqhdiv.ae("dragover", self.piecedragoverfactory(sq))
         sqhdiv.ae("drop", self.piecedropfactory(sq))            
         self.container.a([sqdiv, sqhdiv])
         p = self.getpieceatsquare(sq)
         if p.ispiece():
             pdiv = Div().ac("boardpiece").w(self.piecesize).h(self.piecesize).pv(self.piececoordsvect(fasq))
             pdiv.ac(getclassforpiece(p, self.piecestyle)).sa("draggable", True)
             pdiv.ae("dragstart", self.piecedragstartfactory(sq, pdiv))
             pdiv.ae("drag", self.piecedragfactory())
             pdiv.ae("dragend", self.piecedragendfactory(sq, pdiv))
             pdiv.ae("dragover", self.piecedragoverfactory(sq))
             pdiv.ae("drop", self.piecedropfactory(sq))            
             pdiv.zi(10)
             if self.variantkey == "threeCheck":
                 if ( p.kind == "k" ):
                     mul = self.getthreelifesforcolor(p.color)
                     lifesdiv = Div().pa().t(- self.squaresize / 10).l(self.squaresize / 2 + self.squaresize / 10).w(self.squaresize / 2).h(self.squaresize / 2)
                     lifesdiv.ac("boardthreechecklifesdiv").fs(self.squaresize / 1.5).html("{}".format(mul))
                     lifesdiv.c(["#ff0", "#ff0"][p.color])
                     pdiv.a(lifesdiv)
             self.container.a(pdiv)
Esempio n. 5
0
class FileUploader(e):
    def fileinputchanged(self):
        self.files = self.fileinput.files()
        self.handlefiles()

    def preventdefaults(self, ev):
        ev.preventDefault()
        ev.stopPropagation()

    def highlight(self):
        self.droparea.ac("highlight")

    def unhighlight(self):
        self.droparea.rc("highlight")

    def log(self, html):
        self.infoitems.append(html)
        self.infoitems.reverse()
        self.info.html("<br>".join(self.infoitems))
        self.infoitems.reverse()

    def loginfo(self, content):
        try:
            json = JSON.parse(content)
            if json["success"]:
                if self.dirbrowseruploadedcallback:
                    self.dirbrowseruploadedcallback()
                    self.log("Uploaded <span class='fileuploadfilename'>{}</span> .".format(json["filename"]))
                else:
                    path = "/uploads/{}".format(json["savefilename"])                
                    self.log("uploaded <span class='fileuploadfilename'>{}</span> <a href='{}' target='_blank' rel='noopener noreferrer'>{}</a> <br> <font size='2'> media link <a href='{}' target='_blank' rel='noopener noreferrer'>{}</a> </font>".format(json["filename"], path, path, json["medialink"], json["medialink"]))    
            else:
                self.log("<span class='fileuploaderror'>File upload failed. Status: {} .</span>".format(json["status"]))
        except:            
            self.log("Error parsing response as JSON.")

    def uploadfile(self, file):        
        if self.url is None:
            print("no upload url")
            return

        formdata = __new__ (FormData())

        formdata.append('files', file)
        formdata.append('drive', self.drive)
        if self.getuid:            
            formdata.append('uid', self.getuid())        
        if self.dirbrowsergetpathcallback:
            formdata.append("dirpath", self.dirbrowsergetpathcallback())

        __pragma__("jsiter")

        args = {
            "method": 'POST',
            "body": formdata
        }

        __pragma__("nojsiter")

        fetch(self.url, args).then(
            lambda response: response.text().then(
                lambda content: self.loginfo(content),
                lambda err: self.loginfo(err)    
            ),
            lambda err: self.loginfo(err)
        )

    def handlefiles(self, files = self.files):
        for i in range(files.length):
            print("uploading file {}".format(i))
            self.uploadfile(files.item(i))

    def handledrop(self, ev):
        self.dt = ev.dataTransfer
        self.files = self.dt.files

        self.handlefiles()

    def build(self):
        self.x()
        self.droparea = Div("fileuploaddroparea")
        self.form = Form().ac("fileuploadform")
        self.desc = P().ac("fileuploadp").html("Upload {}s with the file dialog or by dragging and dropping them onto the dashed region".format(self.acceptdisplay))
        self.fileinput = FileInput().ac("fileuploadfileelem").setmultiple(self.multiple).setaccept(self.accept)        
        self.fileinput.sa("id", "fileinputelement")
        self.fileinput.ae("change", self.fileinputchanged)
        self.button = Label().ac("fileuploadbutton").sa("for", "fileinputelement").html("Select some {}s".format(self.acceptdisplay))
        self.form.a([self.desc, self.fileinput, self.button])
        self.droparea.a(self.form)
        for eventname in ["dragenter", "dragover", "dragleave", "drop"]:
            self.droparea.ae(eventname, self.preventdefaults)
        for eventname in ["dragenter", "dragover"]:
            self.droparea.ae(eventname, self.highlight)
        for eventname in ["dragleave", "drop"]:
            self.droparea.ae(eventname, self.unhighlight)
        self.droparea.ae("drop", self.handledrop)
        self.info = Div("fileuploadinfo")
        self.infoitems = []
        self.a([self.droparea, self.info])

    def __init__(self, args = {}):
        super().__init__("div")
        self.url = args.get("url", None)
        self.multiple = args.get("multiple", True)
        self.accept = args.get("accept", "image/*")
        self.acceptdisplay = args.get("acceptdisplay", "image")
        self.drive = args.get("drive", False)
        self.dirbrowseruploadedcallback = args.get("dirbrowseruploadedcallback", None)        
        self.dirbrowsergetpathcallback = args.get("dirbrowsergetpathcallback", None)
        self.getuid = args.get("getuid", None)
        self.build()