Exemplo n.º 1
0
LPP* CnLPP::getLPP()
{
    setComment("C(n) LPP " + gameId());
    
    // each line is a structural variable
    
    for (const Line& l: b.getLineList()) {        
        std::string v_name = to_string(l);

        setVariableBounds(v_name, 0.0, 1.0);
    }
    
    // each dot is a structural variable

    for (const Dot& d: b.getDotList()) {
        std::string v_name = "dot_" + to_string(d);
        setVariableBounds(v_name, 0.0, 1.0);

        getObjective().push_back(std::pair<std::string, double>(v_name, -1.0));

        // Constraint for exact problems.
        //
        //   variables are either 0 or 1 (i.e. the move is either played or not)

        if (getFlag("exact")) {
            setVariableBoolean(v_name, true);
        }
    }
    
    // constraints:
    //
    //   (1) for each segment, sum of weights of moves that use this segment is <= 1
    //   (2) for each segment, 
    //          dot_weight >= sum of weights of lines that use this segment
    //
    //   (3) sum of line weights = n
    //
    //   (4) dot_weight for dots from the cross is equal to 1

    //   (1) for each segment, sum of weights of moves that use this segment is <= 1
    //       (IT IS REDUNDANT TO (2) because dot_weight <= 1):
    //   (2) for each segment, 
    //          dot_weight >= sum of weights of moves that remove this segment

    for (const Segment& s: b.getSegmentList()) {
        Constraint c;
        c.setName("used_segment_" + to_string(s));
        
        for (const Line& l: b.getLinesUsingSegment(s)) {                        
            c.addVariable(to_string(l), -1.0);
        }
                
        c.addVariable("dot_" + to_string(s.first), 1.0);
        c.setBound(0.0);
        c.setType(Constraint::GT);            
        addConstraint(c);
    }
    
    // (3) sum of line weights = n
    {
        Constraint c;
        c.setName("startingdots");
        for (const Line& l: b.getLineList()) {
            c.addVariable(to_string(l), 1.0);
        }
        c.setBound(n);
        c.setType(Constraint::EQ);
        addConstraint(c);
    }
        
    //   (4) dot_weight for dots from the cross is equal to 1
    for (const Dot& d: b.getDotList()) {
        if (b.hasDot(d)) {
            Constraint c;
                        
            c.setName("cross_" + to_string(d));
            c.addVariable("dot_" + to_string(d), 1.0);
            c.setBound(1.0);
            c.setType(Constraint::EQ);            
            addConstraint(c);
        }
    }
    
    // symmetric solutions
    if (getFlag("symmetric")) {
        for (const Line&l: b.getLineList()) {
            Line sl = b.centerSymmetry(l);
            
            Constraint c;
            
            c.addVariable(to_string(l), 1.0);
            c.addVariable(to_string(sl), -1.0);
            c.setType(Constraint::EQ);
            c.setBound(0.0);
            c.setName("sym_" + to_string(l));
            
            addConstraint(c);
        }
    }

    return this;
}
Exemplo n.º 2
0
LPP* MorpionLPP::getLPP()
{
    setComment(gameId());

    // each possible move is a structural variable
    // our goal is to maximize sum over all variables

    for (const Move& m: b.getMoveList()) {        
        std::string v_name = to_string(m);

        setVariableBounds(v_name, 0.0, 1.0);
        getObjective().push_back(std::pair<std::string, double>(v_name, 1.0));
        
        // Constraint for exact problems.
        //
        //   mv_ variables are either 0 or 1 (i.e. the move is either played or not)

        if (getFlag("exact") || getFlag("binary_moves")) {
            setVariableBoolean(v_name, true);
        }
    }

    // each segment gives us constraints:
    // (1) if the segment is placed in the starting position
    //    (a) sum of weights of moves that place this segment <= 0
    //    (b) 1 - sum of weights of moves that remove this segment >= 0
    //        i.e. sum of weights of moves that remove this segment <= 1
    // (2) if the segment is not placed in the starting position
    //    (a) sum of weights of moves that place this segment <= 1
    //    (b) sum of weights of moves that place this segment
    //          - sum of weights of moves that remove this segment >= 0
            
    for (const Segment& s: b.getSegmentList()) {
        int x = s.first.x;
        int y = s.first.y;
        int d = s.second;

        std::string constr_name = "segment_" + to_string(x) + "_" + to_string(y) + "_" + to_string(d);

        if (b.hasDot(Dot(x,y))) {
            // (1a)
            {
                Constraint constr;
        
                for (Move& pl: b.getMovesPlacingSegment(s)) {
                    constr.addVariable(to_string(pl), 1.0);
                }
                constr.setName("r1a_" + constr_name);
                constr.setType(Constraint::LT);
                constr.setBound(0.0);
                addConstraint(constr);
            }
            // (1b)
            {
                Constraint constr;
        
                for (Move& rm: b.getMovesRemovingSegment(s)) {
                    constr.addVariable(to_string(rm), 1.0);
                }
                constr.setName("r1b_" + constr_name);
                constr.setType(Constraint::LT);
                constr.setBound(1.0);
                addConstraint(constr);
            }                        
        } else {
            // (2a)
            {
                Constraint constr;
        
                for (Move& pl: b.getMovesPlacingSegment(s)) {
                    constr.addVariable(to_string(pl), 1.0);
                }
                constr.setName("r2a_" + constr_name);
                constr.setType(Constraint::LT);
                constr.setBound(1.0);
                addConstraint(constr);
            }
            // (2b)
            {
                Constraint constr;

                for (Move& pl: b.getMovesPlacingSegment(s)) {
                    constr.addVariable(to_string(pl), 1.0);
                }
                for (Move& rm: b.getMovesRemovingSegment(s)) {
                    constr.addVariable(to_string(rm), -1.0);
                }
                constr.setName("r2b_" + constr_name);
                constr.setType(Constraint::GT);
                constr.setBound(0.0);      
                    
                addConstraint(constr);          
            }
        }        
    }

    // EXTRA CONSTRAINTS:
    //
    // for each move m:
    //   for each dot d required by m:
    //     for each move n placing d that is consistent with m:
    //       weight_m <= sum of weights of n's

    if (getFlag("extra")) {
        for (const Move& m: b.getMoveList()) {
            std::string constr_name = "_" + to_string(m);
        
            for (const Dot& d: m.requiredDots(b.getVariant())) {
                if (b.hasDot(d)) continue;
                
                Constraint constr;
                
                for (const Move& n: b.getMovesPlacingSegment(Segment(d,0))) {
                    if (m.consistentWith(n,b.getVariant())) {
                        constr.addVariable(to_string(n), -1.0);
                    }
                }
                constr.addVariable(to_string(m), 1.0);
                
                constr.setName("extra_" + to_string(d) + constr_name);
                constr.setType(Constraint::LT);
                constr.setBound(0.0);
                
                addConstraint(constr);
            }
        }
    }
    
    // Disallow cycles of length 3 from the solution.
    // Improves fuzzy solutions
    
    if (getFlag("short-cycles")) {         
        for (const Segment& s: b.getSegmentList()) {
        
            int d = s.second;
            
            if (d % 2 == 1) continue;
            
            addConstraints(createCycleConstraints(s, d + 2, d + 5));
            addConstraints(createCycleConstraints(s, d + 6, d + 1));                
        }            
    }
    
    // Constraints for acyclic problems (explanation makes sense for exact problems):
    //
    // OBSOLETE
    //
    // 1. Each move mv_* has accompanying order variable order_*
    // 2. Move that is not picked has always order 0, 
    //    move that is picked has order between 1 and 675
    // 
    // It is accomplished with the condition:
    //      mv_ <= order_ <= 675 * mv_
    //
    // 3. Assume that mv_1 removes segment s and mv_2 places segment s (mv_1 != mv_2). 
    //    Then
    //      order_1 + (1 - mv_1) * 1000 >= order_2 + 1
    //
    //    The (1-mv_1)*1000 term assures that the condition is not enforced
    //      for moves that are not picked (i.e. have mv_1 = 0)
            
    if (getFlag("acyclic")) {
        throw std::string("not implemented");
    }

    // Constraints for symmetric problems.
    //
    // Moves that are symmetric by central symmetry
    //   with center at ref + (1.5,1.5) have to have equal weights
    
    if (getFlag("symmetric")) {
        for (const Move&m: b.getMoveList()) {
            Move sm = b.centerSymmetry(m);
            
            Constraint c;
            
            c.addVariable(to_string(m), 1.0);
            c.addVariable(to_string(sm), -1.0);
            c.setType(Constraint::EQ);
            c.setBound(0.0);
            c.setName("sym_" + to_string(m));
            
            addConstraint(c);
        }
    }

    // dot-acyclic - better implementation of acyclic problems

    // dots that are not placed have dot_ variable equal to 0
    // this is important for --hull option
    // use this not only for dot-acyclic problems
    
    for (const Dot& d: b.getDotList())
    {
        if (b.hasDot(d)) continue;
        
        Constraint c;
        
        c.setName("dotmove_" + to_string(d));
        
        c.addVariable("dot_" + to_string(d), 1.0);
        
        for (const Move& m: b.getMovesPlacingDot(d)) {
            c.addVariable(to_string(m), -b.bound());
        }
        c.setType(Constraint::LT);
        c.setBound(0.0);
        addConstraint(c);                    
    }
    
    if (getFlag("dot-acyclic")) {
        for (int x = 0; x < b.getWidth(); x++) {
            for (int y= 0; y < b.getHeight(); y++) {
                if (b.infeasibleDot(Dot(x,y)) || b.hasDot(Dot(x,y))) continue;
                
                setVariableBounds("dot_" + to_string(Dot(x,y)), 0, b.bound());

                if (getFlag("symmetric")) {
                    Constraint c;
                    
                    if (b.infeasibleDot(b.centerSymmetry(Dot(x,y)))) continue;
                    
                    c.setName("dotsym_");
                    c.addVariable("dot_" + to_string(Dot(x,y)), 1.0);
                    c.addVariable("dot_" + to_string(b.centerSymmetry(Dot(x,y))), -1.0);
                    c.setType(Constraint::EQ);
                    c.setBound(0.0);
                    addConstraint(c);
                }                
            }
        }
        
        for (const Move& m: b.getMoveList()) {
            for (const Dot& rq: m.requiredDots(b.getVariant())) {
                if (b.hasDot(rq)) continue;
                
                Constraint c;
                
                // dot_placed >= dot_required + 1 - (1 - m) * bound
                // i.e. dot_placed - dot_required - bound * m >= 1 - bound
                
                c.setName("dot_");
                c.addVariable("dot_" + to_string(m.placedDot()), 1.0);
                c.addVariable("dot_" + to_string(rq), -1.0);
                c.addVariable(to_string(m), -b.bound());
                c.setBound(1 - b.bound());
                c.setType(Constraint::GT);
                
                addConstraint(c);
            }
        }      
    }

    // Constraints that enforce that the board (if it is rectangle) is 
    // the convex hull of the solution
    if (getFlag("rhull")) {
        // right side
        addConstraint(getSideConstraint(1,0,true));        
        // left side
        addConstraint(getSideConstraint(1,0,false));
        // top side
        addConstraint(getSideConstraint(0,1,true));
        // bottom side
        addConstraint(getSideConstraint(0,1,false));        
    }
    
    // Constraints that enforce that the board (if it is octagon) is 
    // the convex hull of the solution

    if (getFlag("hull")) {
        // right side
        addConstraint(getSideConstraint(1,0,true));        
        // left side
        addConstraint(getSideConstraint(1,0,false));
        // lower right side
        addConstraint(getSideConstraint(1,-1,false));
        // upper left side
        addConstraint(getSideConstraint(1,-1,true));
        // top side
        addConstraint(getSideConstraint(0,1,true));
        // bottom side
        addConstraint(getSideConstraint(0,1,false));
        // lower left side
        addConstraint(getSideConstraint(1,1,false));
        // upper right side
        addConstraint(getSideConstraint(1,1,true));
    }
            
    return this;
}
Exemplo n.º 3
0
LPP* PlusPlusLPP::getLPP()
{
    setComment("++LPP " + gameId());
    
    // each line is a structural variable
    
    for (const Line& l: b.getLineList()) {        
        std::string v_name = to_string(l);

        setVariableBounds(v_name, 0.0, 1.0);
        getObjective().push_back(std::pair<std::string, double>(v_name, 1.0));        
    }
    
    // each dot is a structural variable

    for (const Dot& d: b.getDotList()) {
        std::string v_name = "dot_" + to_string(d);
        setVariableBounds(v_name, 0.0, 1.0);
  
        // Constraint for exact problems.
        //
        //   variables are either 0 or 1 (i.e. the move is either played or not)

        if (getFlag("exact")) {
            setVariableBoolean(v_name, true);
            
            setVariableOrd(v_name, 1000-abs(b.getCRef().x - d.x) - abs(b.getCRef().y - d.y));
        }
    }
    
    // constraints:
    //
    //   (1) for each segment, sum of weights of moves that use this segment is <= 1
    //   (2) for each segment, 
    //          dot_weight >= sum of weights of lines that use this segment
    //
    //   (3) sum of dot weights = 36 + sum of line weights
    //
    //   (4) dot_weight for dots from the cross is equal to 1

    //   (1) for each segment, sum of weights of moves that use this segment is <= 1
    //       (IT IS REDUNDANT TO (2) because dot_weight <= 1):
    //   (2) for each segment, 
    //          dot_weight >= sum of weights of moves that remove this segment
    
    for (const Segment& s: b.getSegmentList()) {
        Constraint c;
        c.setName("used_segment_" + to_string(s));
        
        for (const Line& l: b.getLinesUsingSegment(s)) {                        
            c.addVariable(to_string(l), -1.0);
        }
                
        c.addVariable("dot_" + to_string(s.first), 1.0);
        c.setBound(0.0);
        c.setType(Constraint::GT);            
        addConstraint(c);
    }
    
    //   (3) sum of dot weights <= 36 + sum of line weights
    {
        Constraint c;
        c.setName("startingdots");
        for (const Dot& d: b.getDotList()) {
            c.addVariable("dot_" + to_string(d), 1.0);
        }
        for (const Line& l: b.getLineList()) {
            c.addVariable(to_string(l), -1.0);
        }
        c.setBound(36.0);
        c.setType(Constraint::EQ);
        addConstraint(c);
    }
        
    //   (4) dot_weight for dots from the cross is equal to 1
    for (const Dot& d: b.getDotList()) {
        if (b.hasDot(d)) {
            Constraint c;
                        
            c.setName("cross_" + to_string(d));
            c.addVariable("dot_" + to_string(d), 1.0);
            c.setBound(1.0);
            c.setType(Constraint::EQ);            
            addConstraint(c);
        }
    }
    
    // symmetric solutions
    if (getFlag("symmetric")) {
        for (const Line&l: b.getLineList()) {
            Line sl = b.centerSymmetry(l);
            
            Constraint c;
            
            c.addVariable(to_string(l), 1.0);
            c.addVariable(to_string(sl), -1.0);
            c.setType(Constraint::EQ);
            c.setBound(0.0);
            c.setName("sym_" + to_string(l));
            
            addConstraint(c);
        }

        for (const Dot&d: b.getDotList()) {
            Dot sd = b.centerSymmetry(d);
            
            Constraint c;
            
            c.addVariable("dot_"+to_string(d), 1.0);
            c.addVariable("dot_"+to_string(sd), -1.0);
            c.setType(Constraint::EQ);
            c.setBound(0.0);
            c.setName("dotsym_" + to_string(d));
            
            addConstraint(c);
        }
    }

    // exact hull
    if (getFlag("hull")) {
        // right side
        addConstraint(getSideConstraint(1,0,true));        
        // left side
        addConstraint(getSideConstraint(1,0,false));
        // lower right side
        addConstraint(getSideConstraint(1,-1,false));
        // upper left side
        addConstraint(getSideConstraint(1,-1,true));
        // top side
        addConstraint(getSideConstraint(0,1,true));
        // bottom side
        addConstraint(getSideConstraint(0,1,false));
        // lower left side
        addConstraint(getSideConstraint(1,1,false));
        // upper right side
        addConstraint(getSideConstraint(1,1,true));
    }

    // dots that are not placed have dot_ variable equal to 0
    // this is important for --hull option
    // and possibly for other reasons as well
    
    for (const Dot& d: b.getDotList())
    {
        Constraint c;
        
        c.setName("dotline_" + to_string(d));
        
        c.addVariable("dot_" + to_string(d), 1.0);
        
        for (const Line& l: b.getLinesUsingDot(d)) {
            c.addVariable(to_string(l), -1.0);
        }
        c.setType(Constraint::LT);
        c.setBound(0.0);
        addConstraint(c);                    
    }

    // extra constraints that remove small gaps from the solution
    // there is always an optimal solution without 1-segment gaps

    if (getFlag("extra")) {
        for (const Line& l: b.getLineList()) {
        {
            Constraint c;
            c.setName("smallgaps1_" + to_string(l));
            c.addVariable(to_string(l), 1.0);
            
            Line ol;
            
            if (b.getVariant() == T5) {
                ol = Line(l.st + direction[l.dir]*5, l.dir); if (b.validLine(ol)) { c.addVariable(to_string(ol), 1.0); }
            } else {
                ol = Line(l.st + direction[l.dir]*6, l.dir); if (b.validLine(ol)) { c.addVariable(to_string(ol), 1.0); }
            }
            
            c.setType(Constraint::LT);
            c.setBound(1.0);
            addConstraint(c);
        }
        {
            Constraint c;
            c.setName("smallgaps2_" + to_string(l));
            c.addVariable(to_string(l), 1.0);
            
            Line ol;
            
            if (b.getVariant() == T5) {
                ol = Line(l.st + direction[l.dir]*(-5), l.dir); if (b.validLine(ol)) { c.addVariable(to_string(ol), 1.0); }
            } else {
                ol = Line(l.st + direction[l.dir]*(-6), l.dir); if (b.validLine(ol)) { c.addVariable(to_string(ol), 1.0); }
            }
            
            c.setType(Constraint::LT);
            c.setBound(1.0);
            addConstraint(c);
        }


        }
    }
    
    return this;
}
Exemplo n.º 4
0
LPP* PotentialLPP::getLPP()
{
    setComment("PotentialLPP " + gameId());
    
    // each move is a structural variable
    
    for (const Move& l: b.getMoveList()) {        
        std::string v_name = to_string(l);

        setVariableBounds(v_name, 0.0, 1.0);

        if (getFlag("exact") && getFlag("dot-acyclic")) {
            setVariableBoolean(v_name, true);
            setVariableOrd(v_name, 0);
        }
    }
    
    // each dot is a structural variable

    for (Dot d: b.getDotList()) {
        std::string v_name = "dot_" + to_string(d);

        if (!b.hasDot(d)) {
            getObjective().push_back(std::pair<std::string, double>(v_name, 1.0)); 
        }
            
        // dots are the only boolean variables        
        if (getFlag("exact")) {
            setVariableBoolean(v_name, true);
            if (b.infeasibleDot(d + Dot(1,0)) ||
                b.infeasibleDot(d + Dot(1,1)) ||
                b.infeasibleDot(d + Dot(0,1)) ||
                b.infeasibleDot(d + Dot(1,-1)) ||
                b.infeasibleDot(d + Dot(0,-1)) ||
                b.infeasibleDot(d + Dot(-1,-1)) ||
                b.infeasibleDot(d + Dot(-1,0)) ||
                b.infeasibleDot(d + Dot(-1,1))) 
            {
                Dot n = d - b.getCRef();
                setVariableOrd(v_name, 1 + abs(n.x) + abs(n.y));
            } else {            
                setVariableOrd(v_name, -1);
            }
        }

        // dots that are placed on board have dot variable equal to 1
        if (b.hasDot(d)) {
            setVariableBounds(v_name, 1.0, 1.0);
        } else {
            setVariableBounds(v_name, 0.0, 1.0);
        }
    }
                
    // constraints:
    //
    //   (1) dot at beginning of segment - moves removing segment starting from dot >= 0
    //
    //   (2) dot == sum of weights of moves that place dot
    //
    //   (3) sum of weights of dots - sum of weights of moves <= 36

    // (1)

    // L4
    
    for (const Segment& s: b.getSegmentList()) {
        Constraint c;
        c.setName("sgm_" + to_string(s));        

        c.addVariable("dot_" + to_string(s.first), 1.0);
        for (const Move& m: b.getMovesRemovingSegment(s)) {
            c.addVariable(to_string(m), -1.0);
        }
        c.setType(Constraint::GT);
        c.setBound(0.0);
        addConstraint(c);        
    }

    // L3
    
    for (const Dot& d: b.getDotList()) {
        if (b.hasDot(d)) continue;
        
        Constraint c;
        c.setName("L3_" + to_string(d));
        c.addVariable("dot_" + to_string(d), 1.0f);
        for (const Move& m: b.getMovesPlacingDot(d)) {
            c.addVariable(to_string(m), -1.0f);
        }
        c.setBound(0.0f);
        c.setType(Constraint::EQ);
        addConstraint(c);
    }
/*          
    // (2)
    
    for (const Dot &d: b.getDotList()) {
        if (b.hasDot(d)) continue;
        
        Constraint c;
        c.setName("dotmv_" + to_string(d));
        
        for (const Move &m: b.getMovesPlacingDot(d)) {
            c.addVariable(to_string(m), -1.0);
        }
        c.addVariable("dot_" + to_string(d), 1.0);
        c.setBound(0.0);
        c.setType(Constraint::EQ);
        addConstraint(c);
    }
*/

/*    
    // (3)

    {
    Constraint c;
    c.setName("dots_moves");
    
    for (const Dot &d: b.getDotList()) {
        c.addVariable("dot_"+to_string(d), 1.0);
    }    
    for (const Move &m: b.getMoveList()) {
        c.addVariable(to_string(m), -1.0);
    }
    c.setBound(36.0);
    c.setType(Constraint::LT);
    addConstraint(c);
    
    }
*/

    // dots that are not placed have dot_ variable equal to 0
    // this is important for --hull option
    // use this not only for dot-acyclic problems
/*    
    for (const Dot& d: b.getDotList())
    {
        if (b.hasDot(d)) continue;
        
        Constraint c;
        
        c.setName("dotmove_" + to_string(d));
        
        c.addVariable("dot_" + to_string(d), 1.0);
        
        for (const Move& m: b.getMovesPlacingDot(d)) {
            c.addVariable(to_string(m), -b.bound());
        }
        c.setType(Constraint::LT);
        c.setBound(0.0);
        addConstraint(c);                    
    }
*/
    // Constraints that enforce that the board (if it is an octagon) is 
    // the convex hull of the solution

    if (getFlag("hull")) {
        // right side
        addConstraint(getSideConstraint(1,0,true));        
        // left side
        addConstraint(getSideConstraint(1,0,false));
        // lower right side
        addConstraint(getSideConstraint(1,-1,false));
        // upper left side
        addConstraint(getSideConstraint(1,-1,true));
        // top side
        addConstraint(getSideConstraint(0,1,true));
        // bottom side
        addConstraint(getSideConstraint(0,1,false));
        // lower left side
        addConstraint(getSideConstraint(1,1,false));
        // upper right side
        addConstraint(getSideConstraint(1,1,true));
    }

    if (getFlag("rhull")) {
        // right side
        addConstraint(getSideConstraint(1,0,true));        
        // left side
        addConstraint(getSideConstraint(1,0,false));
        // top side
        addConstraint(getSideConstraint(0,1,true));
        // bottom side
        addConstraint(getSideConstraint(0,1,false));
    }

    if (getFlag("rside")) {
        // right side
        addConstraint(getSideConstraint(1,0,true));        
    }
    
    if (getFlag("symmetric")) {
        for (const Move&m: b.getMoveList()) {
            Move sm = b.centerSymmetry(m);
            
            Constraint c;
            
            c.addVariable(to_string(m), 1.0);
            c.addVariable(to_string(sm), -1.0);
            c.setType(Constraint::EQ);
            c.setBound(0.0);
            c.setName("sym_" + to_string(m));
            
            addConstraint(c);
        }

        for (const Dot& d: b.getDotList()) {
            std::string v_name = "symdot_" + to_string(d);

            Dot sd = b.centerSymmetry(d);
            
            if (b.hasDot(d) || b.hasDot(sd)) {
                continue;
            }
            
            Constraint c;
            
            c.addVariable("dot_" + to_string(d), 1.0);
            c.addVariable("dot_" + to_string(sd), -1.0);
            c.setType(Constraint::EQ);
            c.setBound(0.0);
            c.setName("symdot_" + to_string(d));
            
            addConstraint(c);
        }
    }
    
    // create only acyclic solutions
    
    if (getFlag("dot-acyclic")) {
        for (int x = 0; x < b.getWidth(); x++) {
            for (int y= 0; y < b.getHeight(); y++) {
                if (b.infeasibleDot(Dot(x,y)) || b.hasDot(Dot(x,y))) continue;
                
                setVariableBounds("ord_" + to_string(Dot(x,y)), 0, b.bound());

                if (getFlag("symmetric")) {
                    Constraint c;
                    
                    if (b.infeasibleDot(b.centerSymmetry(Dot(x,y)))) continue;
                    
                    c.setName("ordsym_"+to_string(Dot(x,y)));
                    c.addVariable("ord_" + to_string(Dot(x,y)), 1.0);
                    c.addVariable("ord_" + to_string(b.centerSymmetry(Dot(x,y))), -1.0);
                    c.setType(Constraint::EQ);
                    c.setBound(0.0);
                    addConstraint(c);
                }                
            }
        }
        
        for (const Move& m: b.getMoveList()) {
            for (const Dot& rq: m.requiredDots(b.getVariant())) {
                if (b.hasDot(rq)) continue;
                
                Constraint c;

                // dot_placed >= dot_required + 1 - (1 - m) * bound
                // i.e. dot_placed - dot_required - bound * m >= 1 - bound
                
                c.setName("ord_" + to_string(m) + "_" + to_string(rq));
                c.addVariable("ord_" + to_string(m.placedDot()), 1.0);
                c.addVariable("ord_" + to_string(rq), -1.0);
                c.addVariable(to_string(m), -b.bound());
                c.setBound(1 - b.bound());
                c.setType(Constraint::GT);
             
                addConstraint(c);
            }
        }      
    }

/*
    enum { R = 0, D = 2, L = 4, U = 6 };
    
    std::vector<int> inside_path = { R, U, U, R, D, D, D, R, R, R, D, L, L, L,
                                     D, D, D, L, U, U, U, L, L, L, U, R, R, R };
                                
    Dot r = b.getReference();
    for (auto & d: inside_path) {
        r = r + direction[d];
        
        Constraint c;
        c.setName("inside_" + to_string(r));
        c.addVariable("dot_" + to_string(r), 1.0f);
        c.setBound(1.0f);
        c.setType(Constraint::EQ);
        addConstraint(c);
    }
*/
    
    return this;
}
Exemplo n.º 5
0
EditGameDialog::EditGameDialog(const String &domain, const String &desc)
	: OptionsDialog(domain, "GameOptions") {
	// Retrieve all game specific options.
	const EnginePlugin *plugin = 0;
	// To allow for game domains without a gameid.
	// TODO: Is it intentional that this is still supported?
	String gameId(ConfMan.get("gameid", domain));
	if (gameId.empty())
		gameId = domain;
	// Retrieve the plugin, since we need to access the engine's MetaEngine
	// implementation.
	EngineMan.findGame(gameId, &plugin);
	if (plugin) {
		_engineOptions = (*plugin)->getExtraGuiOptions(domain);
	} else {
		warning("Plugin for target \"%s\" not found! Game specific settings might be missing", domain.c_str());
	}

	// GAME: Path to game data (r/o), extra data (r/o), and save data (r/w)
	String gamePath(ConfMan.get("path", _domain));
	String extraPath(ConfMan.get("extrapath", _domain));
	String savePath(ConfMan.get("savepath", _domain));

	// GAME: Determine the description string
	String description(ConfMan.get("description", domain));
	if (description.empty() && !desc.empty()) {
		description = desc;
	}

	// GUI:  Add tab widget
	TabWidget *tab = new TabWidget(this, "GameOptions.TabWidget");

	//
	// 1) The game tab
	//
	tab->addTab(_("Game"));

	// GUI:  Label & edit widget for the game ID
	if (g_system->getOverlayWidth() > 320)
		new StaticTextWidget(tab, "GameOptions_Game.Id", _("ID:"), _("Short game identifier used for referring to saved games and running the game from the command line"));
	else
		new StaticTextWidget(tab, "GameOptions_Game.Id", _c("ID:", "lowres"), _("Short game identifier used for referring to saved games and running the game from the command line"));
	_domainWidget = new DomainEditTextWidget(tab, "GameOptions_Game.Domain", _domain, _("Short game identifier used for referring to saved games and running the game from the command line"));

	// GUI:  Label & edit widget for the description
	if (g_system->getOverlayWidth() > 320)
		new StaticTextWidget(tab, "GameOptions_Game.Name", _("Name:"), _("Full title of the game"));
	else
		new StaticTextWidget(tab, "GameOptions_Game.Name", _c("Name:", "lowres"), _("Full title of the game"));
	_descriptionWidget = new EditTextWidget(tab, "GameOptions_Game.Desc", description, _("Full title of the game"));

	// Language popup
	_langPopUpDesc = new StaticTextWidget(tab, "GameOptions_Game.LangPopupDesc", _("Language:"), _("Language of the game. This will not turn your Spanish game version into English"));
	_langPopUp = new PopUpWidget(tab, "GameOptions_Game.LangPopup", _("Language of the game. This will not turn your Spanish game version into English"));
	_langPopUp->appendEntry(_("<default>"), (uint32)Common::UNK_LANG);
	_langPopUp->appendEntry("", (uint32)Common::UNK_LANG);
	const Common::LanguageDescription *l = Common::g_languages;
	for (; l->code; ++l) {
		if (checkGameGUIOptionLanguage(l->id, _guioptionsString))
			_langPopUp->appendEntry(l->description, l->id);
	}

	// Platform popup
	if (g_system->getOverlayWidth() > 320)
		_platformPopUpDesc = new StaticTextWidget(tab, "GameOptions_Game.PlatformPopupDesc", _("Platform:"), _("Platform the game was originally designed for"));
	else
		_platformPopUpDesc = new StaticTextWidget(tab, "GameOptions_Game.PlatformPopupDesc", _c("Platform:", "lowres"), _("Platform the game was originally designed for"));
	_platformPopUp = new PopUpWidget(tab, "GameOptions_Game.PlatformPopup", _("Platform the game was originally designed for"));
	_platformPopUp->appendEntry(_("<default>"));
	_platformPopUp->appendEntry("");
	const Common::PlatformDescription *p = Common::g_platforms;
	for (; p->code; ++p) {
		_platformPopUp->appendEntry(p->description, p->id);
	}

	//
	// 2) The engine tab (shown only if there are custom engine options)
	//
	if (_engineOptions.size() > 0) {
		tab->addTab(_("Engine"));

		addEngineControls(tab, "GameOptions_Engine.", _engineOptions);
	}

	//
	// 3) The graphics tab
	//
	_graphicsTabId = tab->addTab(g_system->getOverlayWidth() > 320 ? _("Graphics") : _("GFX"));

	if (g_system->getOverlayWidth() > 320)
		_globalGraphicsOverride = new CheckboxWidget(tab, "GameOptions_Graphics.EnableTabCheckbox", _("Override global graphic settings"), 0, kCmdGlobalGraphicsOverride);
	else
		_globalGraphicsOverride = new CheckboxWidget(tab, "GameOptions_Graphics.EnableTabCheckbox", _c("Override global graphic settings", "lowres"), 0, kCmdGlobalGraphicsOverride);

	addGraphicControls(tab, "GameOptions_Graphics.");

	//
	// 4) The audio tab
	//
	tab->addTab(_("Audio"));

	if (g_system->getOverlayWidth() > 320)
		_globalAudioOverride = new CheckboxWidget(tab, "GameOptions_Audio.EnableTabCheckbox", _("Override global audio settings"), 0, kCmdGlobalAudioOverride);
	else
		_globalAudioOverride = new CheckboxWidget(tab, "GameOptions_Audio.EnableTabCheckbox", _c("Override global audio settings", "lowres"), 0, kCmdGlobalAudioOverride);

	addAudioControls(tab, "GameOptions_Audio.");
	addSubtitleControls(tab, "GameOptions_Audio.");

	//
	// 5) The volume tab
	//
	if (g_system->getOverlayWidth() > 320)
		tab->addTab(_("Volume"));
	else
		tab->addTab(_c("Volume", "lowres"));

	if (g_system->getOverlayWidth() > 320)
		_globalVolumeOverride = new CheckboxWidget(tab, "GameOptions_Volume.EnableTabCheckbox", _("Override global volume settings"), 0, kCmdGlobalVolumeOverride);
	else
		_globalVolumeOverride = new CheckboxWidget(tab, "GameOptions_Volume.EnableTabCheckbox", _c("Override global volume settings", "lowres"), 0, kCmdGlobalVolumeOverride);

	addVolumeControls(tab, "GameOptions_Volume.");

	//
	// 6) The MIDI tab
	//
	_globalMIDIOverride = NULL;
	if (!_guioptions.contains(GUIO_NOMIDI)) {
		tab->addTab(_("MIDI"));

		if (g_system->getOverlayWidth() > 320)
			_globalMIDIOverride = new CheckboxWidget(tab, "GameOptions_MIDI.EnableTabCheckbox", _("Override global MIDI settings"), 0, kCmdGlobalMIDIOverride);
		else
			_globalMIDIOverride = new CheckboxWidget(tab, "GameOptions_MIDI.EnableTabCheckbox", _c("Override global MIDI settings", "lowres"), 0, kCmdGlobalMIDIOverride);

		addMIDIControls(tab, "GameOptions_MIDI.");
	}

	//
	// 7) The MT-32 tab
	//
	_globalMT32Override = NULL;
	if (!_guioptions.contains(GUIO_NOMIDI)) {
		tab->addTab(_("MT-32"));

		if (g_system->getOverlayWidth() > 320)
			_globalMT32Override = new CheckboxWidget(tab, "GameOptions_MT32.EnableTabCheckbox", _("Override global MT-32 settings"), 0, kCmdGlobalMT32Override);
		else
			_globalMT32Override = new CheckboxWidget(tab, "GameOptions_MT32.EnableTabCheckbox", _c("Override global MT-32 settings", "lowres"), 0, kCmdGlobalMT32Override);

		addMT32Controls(tab, "GameOptions_MT32.");
	}

	//
	// 8) The Paths tab
	//
	if (g_system->getOverlayWidth() > 320)
		tab->addTab(_("Paths"));
	else
		tab->addTab(_c("Paths", "lowres"));

	// These buttons have to be extra wide, or the text will be truncated
	// in the small version of the GUI.

	// GUI:  Button + Label for the game path
	if (g_system->getOverlayWidth() > 320)
		new ButtonWidget(tab, "GameOptions_Paths.Gamepath", _("Game Path:"), 0, kCmdGameBrowser);
	else
		new ButtonWidget(tab, "GameOptions_Paths.Gamepath", _c("Game Path:", "lowres"), 0, kCmdGameBrowser);
	_gamePathWidget = new StaticTextWidget(tab, "GameOptions_Paths.GamepathText", gamePath);

	// GUI:  Button + Label for the additional path
	if (g_system->getOverlayWidth() > 320)
		new ButtonWidget(tab, "GameOptions_Paths.Extrapath", _("Extra Path:"), _("Specifies path to additional data used by the game"), kCmdExtraBrowser);
	else
		new ButtonWidget(tab, "GameOptions_Paths.Extrapath", _c("Extra Path:", "lowres"), _("Specifies path to additional data used by the game"), kCmdExtraBrowser);
	_extraPathWidget = new StaticTextWidget(tab, "GameOptions_Paths.ExtrapathText", extraPath, _("Specifies path to additional data used by the game"));

	_extraPathClearButton = addClearButton(tab, "GameOptions_Paths.ExtraPathClearButton", kCmdExtraPathClear);

	// GUI:  Button + Label for the save path
	if (g_system->getOverlayWidth() > 320)
		new ButtonWidget(tab, "GameOptions_Paths.Savepath", _("Save Path:"), _("Specifies where your saved games are put"), kCmdSaveBrowser);
	else
		new ButtonWidget(tab, "GameOptions_Paths.Savepath", _c("Save Path:", "lowres"), _("Specifies where your saved games are put"), kCmdSaveBrowser);
	_savePathWidget = new StaticTextWidget(tab, "GameOptions_Paths.SavepathText", savePath, _("Specifies where your saved games are put"));

	_savePathClearButton = addClearButton(tab, "GameOptions_Paths.SavePathClearButton", kCmdSavePathClear);

	// Activate the first tab
	tab->setActiveTab(0);
	_tabWidget = tab;

	// Add OK & Cancel buttons
	new ButtonWidget(this, "GameOptions.Cancel", _("Cancel"), 0, kCloseCmd);
	new ButtonWidget(this, "GameOptions.Ok", _("OK"), 0, kOKCmd);
}
Exemplo n.º 6
0
int PBGameInfo::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QObject::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    
#ifndef QT_NO_PROPERTIES
     if (_c == QMetaObject::ReadProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: *reinterpret_cast< QString*>(_v) = gameId(); break;
        case 1: *reinterpret_cast< QString*>(_v) = tableId(); break;
        case 2: *reinterpret_cast< QString*>(_v) = tourneyTableId(); break;
        case 3: *reinterpret_cast< QString*>(_v) = siteId(); break;
        case 4: *reinterpret_cast< int*>(_v) = canJoin(); break;
        case 5: *reinterpret_cast< QString*>(_v) = gameFamily(); break;
        case 6: *reinterpret_cast< double*>(_v) = smallBlind(); break;
        case 7: *reinterpret_cast< double*>(_v) = bigBlind(); break;
        case 8: *reinterpret_cast< int*>(_v) = maxSeats(); break;
        case 9: *reinterpret_cast< QString*>(_v) = driver(); break;
        case 10: *reinterpret_cast< int*>(_v) = canOpen(); break;
        case 11: *reinterpret_cast< int*>(_v) = openedTablesCount(); break;
        case 12: *reinterpret_cast< int*>(_v) = tablesMax(); break;
        case 13: *reinterpret_cast< int*>(_v) = tableOpened(); break;
        case 14: *reinterpret_cast< int*>(_v) = tourneyOpened(); break;
        case 15: *reinterpret_cast< int*>(_v) = gameComplete(); break;
        }
        _id -= 16;
    } else if (_c == QMetaObject::WriteProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: setGameId(*reinterpret_cast< QString*>(_v)); break;
        case 1: setTableId(*reinterpret_cast< QString*>(_v)); break;
        case 2: setTourneyTableId(*reinterpret_cast< QString*>(_v)); break;
        case 3: setSiteId(*reinterpret_cast< QString*>(_v)); break;
        case 4: setCanJoin(*reinterpret_cast< int*>(_v)); break;
        case 5: setGameFamily(*reinterpret_cast< QString*>(_v)); break;
        case 6: setSmallBlind(*reinterpret_cast< double*>(_v)); break;
        case 7: setBigBlind(*reinterpret_cast< double*>(_v)); break;
        case 8: setMaxSeats(*reinterpret_cast< int*>(_v)); break;
        case 9: setDriver(*reinterpret_cast< QString*>(_v)); break;
        case 10: setCanOpen(*reinterpret_cast< int*>(_v)); break;
        case 11: setOpenedTablesCount(*reinterpret_cast< int*>(_v)); break;
        case 12: setTablesMax(*reinterpret_cast< int*>(_v)); break;
        case 13: setTableOpened(*reinterpret_cast< int*>(_v)); break;
        case 14: setTourneyOpened(*reinterpret_cast< int*>(_v)); break;
        case 15: setGameComplete(*reinterpret_cast< int*>(_v)); break;
        }
        _id -= 16;
    } else if (_c == QMetaObject::ResetProperty) {
        _id -= 16;
    } else if (_c == QMetaObject::QueryPropertyDesignable) {
        _id -= 16;
    } else if (_c == QMetaObject::QueryPropertyScriptable) {
        _id -= 16;
    } else if (_c == QMetaObject::QueryPropertyStored) {
        _id -= 16;
    } else if (_c == QMetaObject::QueryPropertyEditable) {
        _id -= 16;
    } else if (_c == QMetaObject::QueryPropertyUser) {
        _id -= 16;
    }
#endif // QT_NO_PROPERTIES
    return _id;
}