Last version of my monopoly code, not finished and works only on devices with OS such as Upsilon or Omega
from kandinsky import fill_rect as rect,draw_string as txt,set_pixel as pix from random import randint,choice from ion import keydown as k import time SKY=(0,0,0) TXT=(255,)*3 IMP=(0,0,255) SEL=(255,255,0) PC=[(200,0,200),(0,255,255),(255,0,255),(255,200,0),(255,0,0),(255,255,0),(0,150,0),(0,0,255)] savefile="monopoly.sav" CASES=[#["name",type,id/amount,group-if-property,price,rent,house1,house2,house3,house4,hotel] ["Start",1,200], ["Mediterranean Avenue",0,0,0,60,2,10,30,90,160,250], ["Community Chest",5], ["Baltic Avenue",0,1,0,60,4,20,60,180,320,450], ["Income Tax",1,-200], ["Reading Railroad",0,22,1,200,25], ["Oriental Avenue",0,2,1,100,6,30,90,270,400,550], ["Chance",4], ["Vermont Avenue",0,3,1,100,6,30,90,270,400,550], ["Connecticut Avenue",0,4,1,120,8,40,100,300,450,600], ["Jail",6], ["St. Charles Place",0,5,2,140,10,50,150,450,625,750], ["Electric Company",0,26,5,150], ["States Avenue",0,6,2,140,10,50,150,450,625,750], ["Virginia Avenue",0,7,2,160,12,60,180,500,700,900], ["Pennsylvania Railroad",0,23,1,200,25], ["St. James Place",0,8,3,180,14,70,200,550,750,950], ["Community Chest",5], ["Tennessee Avenue",0,9,3,180,14,70,200,550,750,950], ["New York Avenue",0,10,3,200,16,80,220,600,800,1000], ["Free Parking",8], ["Kentucky Avenue",0,11,4,220,18,90,250,700,875,1050], ["Chance",4], ["Indiana Avenue",0,12,4,220,18,90,250,700,875,1050], ["Illinois Avenue",0,13,4,240,20,100,300,750,925,1100], ["B&O Railroad",0,24,1,200,25], ["Atlantic Avenue",0,14,5,260,22,110,330,800,975,1150], ["Ventnor Avenue",0,15,5,260,22,110,330,800,975,1150], ["Water Works",0,27,5,150], ["Marvin Gardens",0,16,5,280,24,120,360,850,1025,1200], ["Go to Jail",7], ["Pacific Avenue",0,17,6,300,26,130,390,900,1100,1275], ["North Carolina Avenue",0,18,6,300,26,130,390,900,1100,1275], ["Community Chest",5], ["Pennsylvania Avenue",0,19,6,320,28,150,450,1000,1200,1400], ["Short Line",0,25,1,200,25], ["Chance",4], ["Park Place",0,20,7,350,35,175,500,1100,1300,1500], ["Luxury Tax",1,-100], ["Boardwalk",0,21,7,400,50,200,600,1400,1700,2000]] CHANCES=[ [["Go to jail!"],5], [["Free from jail"],0], [["Advance to Boardwalk"],2,21], [["Advance to Go","(Collect 200)"],2,0], #[["Advance to Illinois","Avenue"],2,19], #[["Advance to St. Charles","Place"],2,5], #[["Bank pays you a","dividend of 50"],1,50], #[["Get out of jail","free"],0], #[["Go back 3 spaces"],4], #[["Go to Reading","Railroad"],2,22], #[["Make general repairs","on all property"],3,[25,100]], #[["Pay poor tax of","150"],1,-150], #[["Take a trip to","Pennsylvania Railroad"],2,24], #[["Your building and","loan matures,","Collect 150"],1,150], #[["You have won a","crossword competition.","Collect 100"],1,100] ] CHESTS=[ [["Go to jail!"],5], [["Free from jail"],0], [["Advance to Go","(Collect 200)"],2,0], #[["Bank error in your","favor, Collect 200"],1,200], #[["Doctor's fees,","Pay 100"],1,-100], #[["From sale of stock","you get 50"],1,50], #[["Get out of jail","free"],0], #[["Grand Opera Night.","Collect 50","from each player"],1,50], #[["Holiday fund matures.","Receive 100"],1,100], #[["Income tax refund.","Collect 20"],1,20], #[["It is your birthday.","Collect 10","from each player"],6,10], #[["Life insurance matures.","Collect 100"],1,100], #[["Pay hospital fees","of 100"],1,-100], #[["Pay school fees","of 50"],1,-50], #[["Receive consultancy","fee of 250"],1,250], #[["You inherit 100"],1,100] ] def shuffle(l): n=len(l) for i in range(len(l)-1,0,-1): j=randint(0,i) l[i],l[j]=l[j],l[i] return l try: import os OS=True except:OS=False clean=lambda:rect(0,0,320,222,SKY) txtc=lambda t,y,fc,bc:txt(t,160-len(t)*5,y,fc,bc) s=lambda:k(0)|k(1)|k(2)|k(3) v=lambda:k(4)|k(52) def popup(x,y,w,h,xso,yso,c,title,opt,types,result=[],frame=True,padding=2,back=False,retname=False): if frame: rect(x,y,w,h,c[0]) rect(x+3,y+3,w-6,h-6,SKY) y+=2 else:rect(x,y,w,h,SKY) for i,j in enumerate(title): txtc(j,y+2+(18+padding)*i,c[1],SKY) ntv=False for i,o in enumerate(opt): txt(o,xso,yso+(18+padding)*i,c[2],SKY) if types[i][0]==0: switch(types[i][1],yso+(18+padding)*i,result[i]) ntv=True elif types[i][0]==1: rect(types[i][1],yso+(18+padding)*i+17,10*types[i][2],1,IMP) ntv=True elif types[i][0]==2: txt("< >",types[i][1]-20,yso+(18+padding)*i,IMP,SKY) if ntv: txt("VALIDATE",xso,yso+(18+padding)*(i+1),(0,255,0),SKY) types.append([3]) r=0 first=True lastAct=-1 while v():1 while 1: if s()|first: lastAct=r r=(r-k(1)+k(2))%len(types) if types[r][0]==2: result[r]=(result[r]-k(0)+k(3))%(types[r][3]-types[r][2]+1) txt(str(result[r]+types[r][2]),types[r][1],yso+(18+padding)*r,IMP,SKY) rect(xso-20,yso+(18+padding)*lastAct,10,18,SKY) txt("→",xso-20,yso+(18+padding)*r,SEL,SKY) if first:first=False while s():1 elif v(): if not ntv: if retname:return opt[r] return r if types[r][0]==0: result[r]=not result[r] switch(types[r][1],yso+(18+padding)*r,result[r]) while v():1 elif types[r][0]==1: result[r]=kinput(types[r][1],yso+(18+padding)*r,types[r][2],types[r][3],types[r][4]) elif types[r][0]==3: if retname: return opt[r] return tuple(result) elif k(17)&back:return -1 def switch(x,y,on): rect(x,y,18,18,(200,)*3) rect(x+1,y+1,16,16,SKY) if on:c=(0,255,0) else:c=(100,)*3 rect(x+3,y+3,12,12,c) def kinput(x,y,maxLenght=4,minLenght=4,onlynumbers=True,ct=TXT): letters={29: 'l', 30: 'm', 31: 'n', 32: 'o', 33: 'p', 34: 'q', 36: 'r', 37: 's', 38: 't', 39: 'u', 40: 'v', 42: 'w', 43: 'x', 44: 'y', 45: 'z', 18: 'a', 19: 'b', 20: 'c', 21: 'd', 22: 'e', 23: 'f', 24: 'g', 25: 'h', 26: 'i', 27: 'j', 28: 'k'} numbers={30: '7', 31: '8', 32: '9', 42: '1', 43: '2', 44: '3', 36: '4', 37: '5', 38: '6', 48: '0'} Input="" rect(x,y,10*maxLenght,18,SKY) rect(x,y+17,10*maxLenght,1,IMP) rect(x,y+2,1,14,TXT) while v():1 while 1: for i in range(17,49): if k(i): if onlynumbers: if(i in numbers.keys())&(len(Input)<maxLenght): Input+=numbers[i] else: if(i in letters.keys())&(len(Input)<maxLenght): Input+=letters[i] if (i==17)&(len(Input)>0): Input=Input[:-1] rect(x+len(Input)*10,y,12,18,SKY) rect(x,y+17,10*maxLenght,1,IMP) rect(x+len(Input)*10+1,y+2,1,14,TXT) txt(Input,x,y,ct,SKY) while k(i):1 if v(): if len(Input)>=minLenght: rect(x+len(Input)*10+1,y+2,1,14,SKY) return Input else: txt(Input,x,y,(255,0,0),SKY) time.sleep(0.5) txt(Input,x,y,ct,SKY) def draw_case(x,y,id,rot=0): t=CASES[id][1] rect(x,y,20,20,TXT) rect(x+1,y+1,18,18,SKY) if t==0: if 21<CASES[id][2]<26: #Train stations rect(x+2,y+2,16,16,(50,)*3) rect(x+4,y+4,12,12,SKY) rect(x+6,y+6,8,8,(50,)*3) elif CASES[id][2]>25: # Services if CASES[id][2]==0:c=(0,0,200) else:c=SEL txt("S",x+5,y+1,c,SKY) else: # Propreties xs1,ys1,w1,h1,xs2,ys2,w2,h2=x+1,y+1,18,5,x+1,y+7,18,12 if rot==1:xs1,w1,h1,ys2,w2,h2=x+14,5,18,y+1,12,18 elif rot==2:ys1,ys2=y+14,y+1 elif rot==3:w1,h1,xs2,ys2,w2,h2=5,18,x+7,y+1,12,18 rect(xs1,ys1,w1,h1,PC[CASES[id][3]]) for i in range(N): if id in A[i]["terrains"]: rect(xs2,ys2,w2,h2,PC[i]) if 0<A[-2][CASES[id][2]]<5: xi,yi=0,0 if w1>h1:xi=4 else:yi=4 for i in range(A[-2][CASES[id][2]]): rect(xs1+1+xi*i,ys1+1+yi*i,3,3,SKY) elif A[-2][CASES[id][2]]==5: rect(xs1+1,ys1+1,3,3,TXT) elif t==1: # Start/Taxes if CASES[id][2]>0:c=(0,200,0) else:c=(200,0,0) rect(x+2,y+2,16,16,c) elif 3<t<6: # Chance/Community Chest if t==4:c=(0,0,255) else:c=(255,0,0) txt("C",x+5,y+1,c,SKY) elif t==6: # Jail rect(x+1,y+1,18,18,(255,100,0)) rect(x+1,y+7,12,12,(70,)*3) elif t==7:rect(x+3,y+3,14,14,(255,100,0)) # Go to jail elif t==8: # Free park rect(x+2,y+2,16,16,(0,255,0)) rect(x+4,y+4,12,12,(0,180,0)) # Draw players np=[] for i in range(N): if A[i]["case"]==id: np.append(i) if len(np)>0: rect(x+5,y+7,10,6,SKY) for _ in range(2): for __ in range(4): if _*4+__ in np:rect(x+6+__*2,y+8+_*2,2,2,PC[_*4+__]) def getHousePrice(id): if id<10:return 5000 elif id<20:return 10000 elif id<30:return 15000 else:return 20000 def draw_terrain(): id=0 for i in range(10): draw_case(1+i*20,1,id,0) id+=1 for i in range(10): draw_case(201,1+i*20,id,1) id+=1 for i in range(10): draw_case(201-i*20,201,id,2) id+=1 for i in range(10): draw_case(1,201-i*20,id,3) id+=1 txt("Total in",70,50,IMP,SKY) txt("Free park:",60,70,IMP,SKY) txt(str(A[-1]),110-len(str(A[-1]))*5,90,IMP,SKY) def calc_rent(id,All=False,owner=None): p=[5000,2500,5000,10000,20000] if CASES[id][2]<26: if All: if CASES[id][2]<22:return CASES[id][4:] # # p=[CASES[id][4]] #Case price # for i in range(7): # p.append(CASES[id][4+i]) # CasePrice/Greenfield/houses/hotel return p else: if CASES[id][2]<22: return CASES[id][4+A[-2][CASES[id][2]]] else: nbts=0 for i in range(22,26): if i in A[owner]["terrains"]:nbts+=1 return p[nbts+1] else: if All:return nbs=0 if 28 in A[owner]["terrains"]:nbs+=1 if 27 in A[owner]["terrains"]:nbs+=1 if nbs==1:return 400*DR return 1000*DR def draw_rent(x,y,id): r=calc_rent(id,True) if CASES[id][2]<26: for i,j in enumerate(r): if i==0:txt("Base Price:",x,y,TXT,SKY) if CASES[id][2]<22: if i==1:txt("Terrain:",x,y+20,TXT,SKY) elif i==6:txt("Hotel:",x,y+120,TXT,SKY) elif i>0:txt(str(i-1)+" houses",x,y+20*i,TXT,SKY) txt(str(j),x+120,y+20*i,PC[4],SKY) else: if i>0:txt(str(i)+" stations:",x,y+20*i,TXT,SKY) txt(str(j),x+120,y+20*i,PC[4],SKY) else: txt("1 serv: 400*Dices",x,y,TXT,SKY) txt("2 serv: 1000*Dices",x,y+20,TXT,SKY) def selectP(l): clean() txtc("Select a propriety:",10,IMP,SKY) act=0 first=True while v():1 while not v(): if s()|first: act=(act-k(0)+k(3))%len(l) clean() rect(0,40,320,18,SKY) txtc("< "+CASES[l[act]][0]+" >",40,TXT,SKY) draw_case(20,100,l[act]) draw_rent(110,75,l[act]) if first:first=False while s():1 elif k(17): return -1 return l[act] def drawC(P,t): clean() # print(P,A[P]) rp=0 if t: id=-5 c=CHANCES[A[id][0]][1] txtc("CHANCE",10,IMP,SKY) else: id=-4 c=CHESTS[A[id][0]][1] txtc("COMMUNITY CHEST",10,IMP,SKY) for i,j in enumerate(CHANCES[A[id][0]][0]): txtc(j,35+i*20,TXT,SKY) if c==0: # Free from jail A[P]["free"]=True elif c==1: # Pay/gain amount if t:amount=CHANCES[A[-5][0]][2] else:amount=CHESTS[A[-4][0]][2] if amount>0:A[P]["money"]+=amount else:pay(P,-1,amount,True) elif c==2: # Move to pass elif c==3: #Pay houses nbhouses=0 nbhotels=0 for i in A[P]["terrains"]: n=A[-2][CASES[i][2]] if 0<n<5:nbhouses+=n else:nbhotels=+n amount=nbhouses*CHANCES[A[-5][0]][2]+nbhotels*CHANCES[A[-5][0]][3] rp=pay(P,-1,amount) elif c==4: # move backwards pass elif c==5: # Go jail pass if c:A[id].append(A[id][0]) del [id][0] return rp #-1:cancel,0:fine,1:one lost, 2:game ends def pay(p,r,amount,middle=False,canCancel=False): while A[p]["money"]<amount: opt=[] houses={} for i in A[p]["terrains"]: if CASES[i][2]<22:houses[i]=A[-2][CASES[i][2]] else: houses[i]=0 if sum(houses.values())>0: opt.append("Sell houses") if 0 in houses.values():opt.append("Mortgage") if len(opt)==0: if lose(p):return 1 else:return 2 code=popup(10,10,300,202,40,90,[PC[4],PC[4],IMP],["Warning! Not enough money!","Your money: "+str(A[p]["money"]),"To pay: "+str(amount)],opt,[[3] for i in range(len(opt))],back=canCancel,retname=True) if code=="Sell houses": htcbs=[i for i,j in houses.items() if j>0] s=selectP(htcbs) if s==-1:continue else: A[-2][CASES[s][2]]-=1 A[p]["money"]+=getHousePrice(s)//2 continue elif code=="Mortgage": htcbs=[i for i,j in houses.items() if j==0] s=selectP(htcbs) if s==-1:continue else: A[p]["terrains"].remove(s) A[p]["hyp"].append(s) A[p]["money"]+=CASES[s][4]//2 else:return -1 # Cancel A[p]["money"]-=amount if middle:A[-1]+=amount if r!=-1:A[r]["money"]+=amount return 0 def lose(p): N-=1 for i in A[p]["hyp"]: A[-3].append(i) rect(20,20,280,182,PC[p]) rect(23,23,274,176,SKY) if N>1: txtc(A[p]["name"]+" lose!",70,PC[p],SKY) txtc("BUT THE GAME CONTINUE!",110,TXT,SKY) del A[p] if N==1: txtc("Congrat to "+A[0]["name"],70,PC[p],SKY) txtc("For winning this game!",110,TXT,SKY) while v():1 while not v():1 return False else: while v():1 while not v():1 return True while 1: clean() c=0 m=True if OS: if savefile in os.listdir(): c=popup(0,0,320,222,135,150,[PC[0],PC[3],IMP],["Savefile found!","Do you want to","continue the game?"],["YES","NO"],[[3],[3]]) if c==0: with open(savefile,"r")as f: A=eval(f.read()) if"code"in A[0].keys():Password=True else:Password=False N=len(A[-6]) Save=True m=False if m==True: opt=["Number of players:","Password protection:"] types=[[2,260,2,8],[0,260]] if OS: opt.append("Enable saving:") types.append([0,260]) params=popup(0,0,320,222,30,70,[PC[1],PC[3],IMP],["MONOPOLY - Made by Elnix"],opt,types,[0,False,False],padding=22) N,Password,Save=params[0]+2,params[1],params[2] del params A=[{"name":"","money":1500,"terrains":[],"hyp":[],"case":0,"free":False} for i in range(N)] for i in range(N): clean() txt("Player "+str(i+1),30,20,PC[i],SKY) txt(", enter your name:",110,20,TXT,SKY) A[i]["name"]=kinput(110,70,10,False) if Password: txt("Please set a up a pin code:",25,110,TXT,SKY) while 1: code=kinput(140,140) if len(code)<4:txt("Too short!",110,170,(255,0,0),SKY) else: A[i]["code"]=code break A.append([33,11]) A.append(shuffle([i for i in range(18)])) A.append(shuffle([i for i in range(18)])) A.append([i for i in range(22)]) A.append([0 for i in range(22)]) A.append(0) T=randint(0,N-1) DR=randint(1,6)+randint(1,6) clean() # Tests A[0]["terrains"].append(1) A[0]["terrains"].append(3) A[0]["terrains"].append(5) A[0]["terrains"].append(6) A[0]["terrains"].append(12) for i in range(22): A[-2][i]=randint(1,5) draw_terrain() # print(pay(0,1,9899999,canCancel=True)) ### while 1: if Password: clean() txtc(A[T]["name"]+", enter your password:",50,TXT,SKY) while kinput(140,110)!=A[T]["code"]: txtc("Wrong password, retry in 3s...",130,PC[4],SKY) time.sleep(3) wasRewarded=0 d1,d2=randint(1,6),randint(1,6) txt(str(d1),85,150,PC[5],SKY) txt(str(d2),120,150,PC[5],SKY) DR=d1+d2 A[T]["case"]=(A[T]["case"]+DR)%40 if A[T]["case"]-DR<0:wasRewarded=200 elif A[T]["case"]==0: wasRewarded=400 A[T]["money"]+=wasRewarded clean() rp=0 a=CASES[A[T]["case"]][1] draw_terrain() while v():1 while not v():1 txt("Landed on "+CASES[A[T]["case"]][0],5,5,TXT,SKY) if wasRewarded:txtc("You were rewarded by "+str(wasRewarded),202,(0,255,0),SKY) draw_case(10,30,A[T]["case"]) if a==0: # Pay rent/Buy propriety draw_rent(110,60,A[T]["case"]) txt("Your money:",0,70,TXT,SKY) txt(str(A[T]["money"]),0,90,IMP,SKY) if A[T]["case"] in A[-3]: c=popup(-1,30,0,0,20,140,[0,(0,255,0),IMP],["Want you buy this propriety?"],["YES","NO"],[[3],[3]],frame=False) if c==0: rp=pay(T,-1,CASES[A[T]["case"]][4],canCancel=True) if rp==0: A[-3].remove(A[T]["case"]) A[T]["terrains"].append(A[T]["case"]) elif A[T]["case"] not in A[T]["terrains"]: # find who own the case for i in range(N): if A[T]["case"] in A[i]["terrains"]: amount=calc_rent(A[T]["case"],owner=i) txtc("You have to pay "+A[i]["name"],30,(255,150,0),SKY) txtc(str(amount),50,(255,150,0),SKY) txtc("[OK]",50,IMP,SKY) while v():1 while not v():1 rp=pay(T,i,amount) break if rp!=0:continue elif a==1: # Gain/pay taxe amount=CASES[A[T]["case"]][2] if amount>0: txtc("You have been rewarded by",30,IMP,SKY) txtc(str(amount),50,(0,255,0),SKY) A[T]["money"]+=amount else: txtc("You have to pay",30,IMP,SKY) txtc(str(amount),50,(255,0,0),SKY) rp=pay(T,-1,amount,True) if rp!=0:continue elif 4: # Chance # txtc("You draw a chance",30,IMP,SKY) drawC(T,1) elif 5: # Chest # txtc("You draw a community chest",30,IMP,SKY) drawC(T,0) elif a==6: # Jail pass elif a==7: # Go to jail pass elif a==8: # Free park txtc("Congrats, you won the middle!") A[T]["money"]+=A[-1] A[-1]=0 # Options that you can do here opt=[] if Save: with open(savefile,"w")as f: f.write(str(A)) T=(T+1)%N if OS:os.remove(savefile)