import wx
import math
class SketchFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, "Catan Simulator",size=(560,640))
self.sketch = SketchWindow(self, -1)
class SketchWindow(wx.Window):
def __init__ (self, parent,ID):
wx.Window.__init__(self, parent, ID)
self.Buffer = None
#Create Array of starting indexes
self.linelen = 50
rowlens=[4,5,6,7,6,5,4]
index=0
self.hexes={}
for x in range(0,38):
self.hexes[x]={}
self.hexes[x]["number"]=x
#seed
self.hexes[0]["xpos"]=0
self.hexes[0]["ypos"]=175
#Row Starts
self.hexes[1]["xpos"]=self.hexes[0]["xpos"]
self.hexes[1]["ypos"]=self.hexes[0]["ypos"]
self.hexes[5]["xpos"]=self.hexes[0]["xpos"]
self.hexes[5]["ypos"]=self.hexes[0]["ypos"]+math.sin(math.radians(60))*self.linelen*2
self.hexes[10]["xpos"]=self.hexes[0]["xpos"]
self.hexes[10]["ypos"]=self.hexes[5]["ypos"]+math.sin(math.radians(60))*self.linelen*2
self.hexes[16]["xpos"]=self.hexes[0]["xpos"]
self.hexes[16]["ypos"]=self.hexes[10]["ypos"]+math.sin(math.radians(60))*self.linelen*2
self.hexes[23]["xpos"]=self.hexes[16]["xpos"]+math.cos(math.radians(60))*self.linelen+self.linelen
self.hexes[23]["ypos"]=self.hexes[16]["ypos"]+math.sin(math.radians(60))*self.linelen
self.hexes[29]["xpos"]=self.hexes[23]["xpos"]+math.cos(math.radians(60))*self.linelen+self.linelen
self.hexes[29]["ypos"]=self.hexes[23]["ypos"]+math.sin(math.radians(60))*self.linelen
self.hexes[34]["xpos"]=self.hexes[29]["xpos"]+math.cos(math.radians(60))*self.linelen+self.linelen
self.hexes[34]["ypos"]=self.hexes[29]["ypos"]+math.sin(math.radians(60))*self.linelen
for z in range(1,38):
try:
self.hexes[z]["xpos"] = self.hexes[z]["xpos"]
except KeyError:
self.hexes[z]["xpos"] = self.hexes[z-1]["xpos"]+math.cos(math.radians(60))*self.linelen+self.linelen
self.hexes[z]["ypos"] = self.hexes[z-1]["ypos"]-math.sin(math.radians(60))*self.linelen
for i in [1,2,3,4,5,9,10,15,16,22,23,28,29,33,34,35,36,37]:
self.hexes[i]["landtype"]="water"
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBack)
self.Bind(wx.EVT_LEFT_UP, self.OnLeftClick)
self.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
def OnRightClick(self, event):
pos=event.GetPosition()
clicked=self.hexidentifier(pos[0],pos[1])
if len(clicked) != 1:
return
else:
self.cycledice(clicked[0])
event.Skip()
def cycledice(self, hexnum):
if "diceval" not in self.hexes[hexnum]:
self.hexes[hexnum]['diceval'] = "2"
elif self.hexes[hexnum]['diceval'] == "2":
self.hexes[hexnum]['diceval'] = "3"
elif self.hexes[hexnum]['diceval'] == "3":
self.hexes[hexnum]['diceval'] = "4"
elif self.hexes[hexnum]['diceval'] == "4":
self.hexes[hexnum]['diceval'] = "5"
elif self.hexes[hexnum]['diceval'] == "5":
self.hexes[hexnum]['diceval'] = "6"
elif self.hexes[hexnum]['diceval'] == "6":
self.hexes[hexnum]['diceval'] = "8"
elif self.hexes[hexnum]['diceval'] == "8":
self.hexes[hexnum]['diceval'] = "9"
elif self.hexes[hexnum]['diceval'] == "9":
self.hexes[hexnum]['diceval'] = "10"
elif self.hexes[hexnum]['diceval'] == "10":
self.hexes[hexnum]['diceval'] = "11"
elif self.hexes[hexnum]['diceval'] == "11":
self.hexes[hexnum]['diceval'] = "12"
elif self.hexes[hexnum]['diceval'] == "12":
del self.hexes[hexnum]['diceval']
dc = wx.ClientDC(self)
self.DrawDiceCircles(dc)
def OnLeftClick(self, event):
pos=event.GetPosition()
clicked=self.hexidentifier(pos[0],pos[1])
if len(clicked) != 1:
return
else:
self.cycleland(clicked[0])
event.Skip()
def cycleland(self, hexnum):
if "landtype" not in self.hexes[hexnum]:
self.hexes[hexnum]['landtype'] = "mountain"
elif self.hexes[hexnum]['landtype'] == "mountain":
self.hexes[hexnum]['landtype'] = "forest"
elif self.hexes[hexnum]['landtype'] == "forest":
self.hexes[hexnum]['landtype'] = "yellow plain"
elif self.hexes[hexnum]['landtype'] == "yellow plain":
self.hexes[hexnum]['landtype'] = "green meadow"
elif self.hexes[hexnum]['landtype'] == "green meadow":
self.hexes[hexnum]['landtype'] = "clay"
elif self.hexes[hexnum]['landtype'] == "clay":
self.hexes[hexnum]['landtype'] = "desert"
elif self.hexes[hexnum]['landtype'] == "desert":
self.hexes[hexnum]['landtype'] = "water"
elif self.hexes[hexnum]['landtype'] == "water":
del self.hexes[hexnum]['landtype']
dc = wx.ClientDC(self)
self.fillhex(dc, hexnum, "black")
self.DrawDiceCircles(dc)
def hexidentifier(self, xpos, ypos):
valids=[]
for hexnum in range(1, 38):
points=[]
points.append([self.hexes[hexnum]["xpos"],self.hexes[hexnum]["ypos"]])
points.append([points[0][0]+math.cos(math.radians(-60))*self.linelen, points[0][1]+math.sin(math.radians(-60))*self.linelen])
points.append([points[1][0]+math.cos(math.radians(0))*self.linelen, points[1][1]+math.sin(math.radians(0))*self.linelen])
points.append([points[2][0]+math.cos(math.radians(60))*self.linelen, points[2][1]+math.sin(math.radians(60))*self.linelen])
points.append([points[3][0]+math.cos(math.radians(120))*self.linelen, points[3][1]+math.sin(math.radians(120))*self.linelen])
points.append([points[4][0]+math.cos(math.radians(180))*self.linelen, points[4][1]+math.sin(math.radians(180))*self.linelen])
points.append([points[5][0]+math.cos(math.radians(240))*self.linelen, points[5][1]+math.sin(math.radians(240))*self.linelen])
n = len(points)
inside = False
p1x,p1y = points[0]
for i in range(n+1):
p2x,p2y = points[i % n]
if ypos > min(p1y,p2y):
if ypos <= max(p1y,p2y):
if xpos <= max(p1x,p2x):
if p1y != p2y:
xinters = (ypos-p1y)*(p2x-p1x)/(p2y-p1y)+p1x
if p1x == p2x or xpos <= xinters:
inside = not inside
p1x,p1y = p2x,p2y
if inside == True:
valids.append(hexnum)
return valids
def InitBuffer(self):
size=self.GetClientSize()
# if buffer exists and size hasn't changed do nothing
if self.Buffer is not None and self.Buffer.GetWidth() == size.width and self.Buffer.GetHeight() == size.height:
return False
self.Buffer=wx.EmptyBitmap(size.width,size.height)
dc=wx.MemoryDC()
dc.SelectObject(self.Buffer)
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
dc.Clear()
self.DrawBoard(dc)
self.fillall(dc)
self.DrawDiceCircles(dc)
dc.SelectObject(wx.NullBitmap)
return True
def DrawBoard(self, dc):
degs=[-60,0,60,120,180,240]
for z in range(1,38):
xpos=self.hexes[z]["xpos"]
ypos=self.hexes[z]["ypos"]
for d in degs:
destx=xpos+math.cos(math.radians(d))*self.linelen
desty=ypos+math.sin(math.radians(d))*self.linelen
dc.DrawLine(xpos, ypos, destx, desty)
xpos=destx
ypos=desty
def DrawDiceCircles(self,dc):
for i in range(1,38):
if "landtype" not in self.hexes[i]:
continue
if "diceval" not in self.hexes[i]:
self.fillhex(dc, i, "black")
continue
if self.hexes[i]["landtype"] in ["water", "desert"]:
continue
xstart = self.hexes[i]["xpos"]+math.cos(math.radians(60))*self.linelen+.5*self.linelen
ystart = self.hexes[i]["ypos"]
dc.SetPen(wx.Pen("black", 2))
dc.SetBrush(wx.Brush("White"))
dc.DrawCircle(xstart, ystart, 10)
if "diceval" not in self.hexes[i]:
continue
xoff=4
if self.hexes[i]["diceval"] in ["10", "11", "12"]:
xoff = xoff + 4
dc.SetPen(wx.Pen("black", 2))
dc.SetBrush(wx.Brush("White"))
dc.DrawText(self.hexes[i]["diceval"], xstart-xoff, ystart-7)
def OnEraseBack(self, event):
pass # do nothing to avoid flicker
def OnPaint(self, event):
if self.InitBuffer():
self.Refresh() # buffer changed paint in next event, this paint event may be old
return
dc = wx.PaintDC(self)
dc.DrawBitmap(self.Buffer, 0, 0)
self.DrawBoard(dc)
self.fillall(dc)
self.DrawDiceCircles(dc)
#self.Drawcircle(dc)
def fillall(self, dc, color="black"):
for i in range(1,38):
self.fillhex(dc, i, color)
def fillhex(self, dc, hexnum, color="black"):
degs=[-60,0,60,120,180,240]
dc.SetPen(wx.Pen(color, 2))
if "landtype" not in self.hexes[hexnum]:
dc.SetBrush(wx.Brush("Gray"))
elif self.hexes[hexnum]["landtype"]=="water":
dc.SetBrush(wx.Brush("Cyan"))
elif self.hexes[hexnum]["landtype"]=="forest":
dc.SetBrush(wx.Brush("FOREST GREEN"))
elif self.hexes[hexnum]["landtype"]=="yellow plain":
dc.SetBrush(wx.Brush("Yellow"))
elif self.hexes[hexnum]["landtype"]=="clay":
dc.SetBrush(wx.Brush("Red"))
elif self.hexes[hexnum]["landtype"]=="mountain":
dc.SetBrush(wx.Brush("Dark Slate Gray"))
elif self.hexes[hexnum]["landtype"]=="green meadow":
dc.SetBrush(wx.Brush("Lime Green"))
elif self.hexes[hexnum]["landtype"]=="desert":
dc.SetBrush(wx.Brush("Wheat"))
points=[]
points.append([self.hexes[hexnum]["xpos"],self.hexes[hexnum]["ypos"]])
points.append([points[0][0]+math.cos(math.radians(-60))*self.linelen, points[0][1]+math.sin(math.radians(-60))*self.linelen])
points.append([points[1][0]+math.cos(math.radians(0))*self.linelen, points[1][1]+math.sin(math.radians(0))*self.linelen])
points.append([points[2][0]+math.cos(math.radians(60))*self.linelen, points[2][1]+math.sin(math.radians(60))*self.linelen])
points.append([points[3][0]+math.cos(math.radians(120))*self.linelen, points[3][1]+math.sin(math.radians(120))*self.linelen])
points.append([points[4][0]+math.cos(math.radians(180))*self.linelen, points[4][1]+math.sin(math.radians(180))*self.linelen])
points.append([points[5][0]+math.cos(math.radians(240))*self.linelen, points[5][1]+math.sin(math.radians(240))*self.linelen])
#print points
dc.DrawPolygon(points)
if __name__=='__main__':
app=wx.PySimpleApp()
frame=SketchFrame(None)
frame.Show(True)
app.MainLoop()