from candidates import *
from voters import *
from plurality import *
from borda import *
from copeland import *
from approval import *
from stv import *
from dodgson import *
from election import *
from voter_permutations import *
from voter_distr import *
from aux import *

if __name__ == "__main__":
    run_experiment()


class ex_threeway:
    num_voters = None
    num_cands = None
    rule1 = None
    rule2 = None
    rule1ws = None
    rule2ws = None

    def __init__(self, rule1='plurality', rule2='borda', rule3='copeland'):
        self.num_voters = 2
        self.num_cands = 2
        self.rule1 = rule1
        self.rule2 = rule2
        self.rule3 = rule3
        self.rule1ws = []
        self.rule2ws = []
        self.rule3ws = []

    def run_experiment(self):
        while self.rule1ws == self.rule2ws and self.rule2ws == self.rule3ws:
            #print "********************************"
            self.generate_instance()
            #print 'winner %s: %s' % (self.rule1,self.rule1ws)
            #print 'winner %s: %s' % (self.rule2,self.rule2ws)
            #print 'winner %s: %s' % (self.rule3,self.rule3ws)            
            if self.num_voters <= 7*factorial(self.num_cands):
                self.num_voters += 1
                #print "more voters"
            else:
                self.num_cands += 1
                #print "more cands"
                self.num_voters = 2
            print self.num_voters, self.num_cands
            #print "********************************"

    def generate_instance(self):
        cs = candidates(None, self.num_cands)
        vp = perm(cs.candidates)

        if self.rule1 == 'approval' or self.rule1 == 'even_and_equal' \
            or self.rule2 == 'approval' or self.rule2 == 'even_and_equal' \
            or self.rule2 == 'approval' or self.rule3 == 'even_and_equal':

            vd = voter_distr(self.num_voters, (self.num_cands-1)*factorial(self.num_cands))
            vdset = vd.generate(self.num_voters, (self.num_cands-1)*factorial(self.num_cands))

            vtypes = []
            for p in vp: #generate all cut,perm tuples
                for i in range(1, self.num_cands):
                    vtypes.append((p, i))
        
            for dis in vdset:
                votes = []
                j = 0            
                for p,cut in vtypes:
                    for i in range(0,dis[j]):
                        votes.append(voter(None,cs,p,cut))
                    j += 1
                vs = voters(cs, None, votes)
                self.find_winners(vs)
                if self.rule1ws != self.rule2ws and self.rule1ws != self.rule3ws and \
                    self.rule2ws != self.rule3ws and len(self.rule1ws) == 1 and \
                    len(self.rule2ws) == 1 and len(self.rule3ws) == 1:
                    stri = 'experiments/%s_vs_%s_vs_%s.blt' % (self.rule1,self.rule2, self.rule3)
                    print "outputting %s!!!" % stri
                    vs.output_blt(stri)
                    break

        else:
            vd = voter_distr(self.num_voters, factorial(self.num_cands))
            vdset = vd.generate(self.num_voters, factorial(self.num_cands))

            for dis in vdset:
                votes = []
                for j in range(0,len(vp)):
                    for i in range(0,dis[j]):
                        votes.append(voter(None,cs,vp[j],None))
                vs = voters(cs, None, votes)
                #print vs
                self.find_winners(vs)
                if self.rule1ws != self.rule2ws and self.rule1ws != self.rule3ws and \
                    self.rule2ws != self.rule3ws and len(self.rule1ws) == 1 and \
                    len(self.rule2ws) == 1 and len(self.rule3ws) == 1:
                    stri = 'experiments/%s_vs_%s_vs_%s.blt' % (self.rule1,self.rule2, self.rule3)
                    print "outputting %s!!!" % stri                    
                    vs.output_blt(stri)
                    break



    def find_winners(self, vs):
            if self.rule1 == 'plurality':
                p = plurality(vs)
                self.rule1ws = p.winner()
            if self.rule1 == 'borda':
                b = borda(vs)
                self.rule1ws = b.winner()
            if self.rule1 == 'copeland':
                co = copeland(vs)
                self.rule1ws = co.winner()
            if self.rule1 == 'stv':
                s = stv(vs)
                self.rule1ws = s.winner()
            if self.rule1 == 'approval':
                a = approval(vs)
                self.rule1ws = a.winner()
            if self.rule1 == 'even_and_equal':
                e = approval(vs, 'even_and_equal')
                self.rule1ws = e.winner()
            if self.rule1 == 'dodgson':
                d = dodgson(vs)
                self.rule1ws = d.winner()


            if self.rule2 == 'plurality':
                p = plurality(vs)
                self.rule2ws = p.winner()
            if self.rule2 == 'borda':
                b = borda(vs)
                self.rule2ws = b.winner()
            if self.rule2 == 'copeland':
                co = copeland(vs)
                self.rule2ws = co.winner()
            if self.rule2 == 'stv':
                s = stv(vs)
                self.rule2ws = s.winner()
            if self.rule2 == 'approval':
                a = approval(vs)
                self.rule2ws = a.winner()
            if self.rule2 == 'even_and_equal':
                e = approval(vs, 'even_and_equal')
                self.rule2ws = e.winner()
            if self.rule2 == 'dodgson':
                d = dodgson(vs)
                self.rule2ws = d.winner()


            if self.rule3 == 'plurality':
                p = plurality(vs)
                self.rule3ws = p.winner()
            if self.rule3 == 'borda':
                b = borda(vs)
                self.rule3ws = b.winner()
            if self.rule3 == 'copeland':
                co = copeland(vs)
                self.rule3ws = co.winner()
            if self.rule3 == 'stv':
                s = stv(vs)
                self.rule3ws = s.winner()
            if self.rule3 == 'approval':
                a = approval(vs)
                self.rule3ws = a.winner()
            if self.rule3 == 'even_and_equal':
                e = approval(vs, 'even_and_equal')
                self.rule3ws = e.winner()
            if self.rule3 == 'dodgson':
                d = dodgson(vs)
                self.rule3ws = d.winner()


