from tkinter import *
from random import randint
damtable = [[0,0,0,0,0,5,10,20,30,40,60,100],[0,0,0,0,0,15,20,30,40,50,70,100],[0,0,0,0,5,25,30,40,50,70,80,100],[0,0,0,0,10,30,40,50,60,80,90,100],[0,0,0,5,15,35,50,60,70,90,100,100],[0,0,5,10,25,40,60,70,90,100,100,100],[0,5,10,20,30,50,70,80,100,100,100,100],[5,10,15,25,35,60,80,90,100,100,100,100],[10,15,20,30,45,70,90,100,100,100,100,100],[15,20,20,35,55,80,100,100,100,100,100,100]]
stacklist = []
def ordinal(x):
if x%10 == 1:
return str(x) + "st"
elif x%10 == 2:
return str(x) + "nd"
elif x%10 == 3:
return str(x) + "rd"
else:
return str(x) + "th"
class Unit(object):
def __init__(self, profile, *name):
self.active = "nothing"
self.health = 100
self.armor = profiles[profile][0]
self.weapons = profiles[profile][1]
self.target = -1
if len(name)== 1:
self.name = name
else:
self.name = ordinal(profiles[profile][3])+ " " + profiles[profile][2]
profiles[profile][3] += 1
def unitreport(self):
return str(self.name) + "; Armor:" + str(self.armor) + "; Weapons:" + str(self.weapons) + "; Target: " + str(self.target+1) + "; Health: " + str(self.health)
profiles = {
"Guard" : [20, ["Rayguns", "Raypistols"], "Guards", 1], "Rebel" : [20, ["Rayguns", "Raypistols"], "Rebels", 1], "Militia" : [10, ["Squad AA", "Militia Rifles"], "Militia", 1]
}#profile order is armor, weapons, name, and the number 1 (used in the counting function for names)
arms = {
"Rayguns": [10, 10, 1, 1], "Raypistols": [5, 5, 2, 2], "Squad AA": [1, 5, -1, -1], "Militia Rifles": [2, 20, 12, 16]
#hitroll, damroll, distance it starts shooting at, distance it keeps shooting for
}
namelist = []
for name in profiles:
namelist.append(name)
class Stack(object):
def __init__(self, x_pos, y_pos, *units):
self.destroyed = []
self.units = []
self.x_pos = x_pos
self.y_pos = y_pos
self.x_gfx = (self.x_pos-1)*mygrid.size*3/2+mygrid.offsetx
if self.x_pos%2 == 1:
self.y_gfx = (self.y_pos-1)*mygrid.size*.86+mygrid.offsety
else:
self.y_gfx = (self.y_pos-1)*mygrid.size*.86+mygrid.offsety-mygrid.size*.86
for unit in units:
self.units.append(unit)
stacklist.append(self)
def showunits(self):
for unit in self.units:
print(unit.unitreport())
def find_gfx_pos(self):
self.x_gfx = (self.x_pos-1)*mygrid.size*3/2+mygrid.offsetx
if self.y_pos%2 == 1:
self.y_gfx = (self.y_pos-1)*mygrid.size*.86+mygrid.offsety
else:
self.y_gfx = (stack2.y_pos-1)*mygrid.size*.86+mygrid.offsety-mygrid.size*.86*evenoddrow
def clearunits(self):
for unit in self.units:
if unit.health <= 0:
self.destroyed.append(unit)
self.units.remove(unit)
def addunit(self, unittype):
self.units.append(Unit(unittype))
class Grid(object): #to be used in map creation
def __init__(self, width, height):
self.width = width
self.height = height
self.hexes = []
self.size = 30
self.offsetx = 40
self.offsety = 40
self.offset = 40
def draw(self):
for x in range(self.width):
for y in range(self.height):
for evenoddrow in [0, 1]:
self.hexes.append([x*2+evenoddrow, y*2+evenoddrow,
self.offsetx-self.size+self.size*x*3+3/2*self.size*evenoddrow
,self.offsety+self.size*y*1.72-self.size*.86*evenoddrow
,self.offsetx-self.size/2+self.size*x*3+3/2*self.size*evenoddrow
,self.offsety+self.size*.86+self.size*y*1.72-self.size*.86*evenoddrow
,self.offsetx+self.size/2+self.size*x*3+3/2*self.size*evenoddrow
,self.offsety+self.size*.86+self.size*y*1.72-self.size*.86*evenoddrow
,self.offsetx+self.size+self.size*x*3+3/2*self.size*evenoddrow
,self.offsety+self.size*y*1.72-self.size*.86*evenoddrow
,self.offsetx+self.size/2+self.size*x*3+3/2*self.size*evenoddrow
,self.offsety-self.size*.86+self.size*y*1.72-self.size*.86*evenoddrow
,self.offsetx-self.size/2+self.size*x*3+3/2*self.size*evenoddrow
,self.offsety-self.size*.86+self.size*y*1.72-self.size*.86*evenoddrow
])
mygrid = Grid(10,15)
mygrid.draw()
stack1 = Stack(1, 1, Unit("Militia"), Unit("Militia"))
stack2 = Stack(2, 3, Unit("Militia"), Unit("Militia"))
stack3 = Stack(5, 5, Unit("Militia"), Unit("Militia"))
def settargets(stack1, stack2, distance):
count = (len(stack1.units))%(len(stack2.units))
for unit in stack1.units:
unit.target = -1
for weapon in unit.weapons:
if (arms[weapon][2]<=distance) and (arms[weapon][2] + arms[weapon][3] > distance):
unit.target = (len(stack1.units)+count)%len(stack2.units)
unit.active = weapon
count +=1
else:
pass
def tohit(unit1, unit2):
hitroll = randint(1, 20)
if (hitroll + arms[unit1.active][0] >= unit2.armor):
return True
else:
return False
def damage(unit1, unit2):
if arms[unit1.weapons[0]][1] >= unit2.armor:
rat = (arms[unit1.active][1]-arms[active][1]%unit2.armor)/unit2.armor
unit2.health -= damtable[int(5-rat)][randint(0,9)]
else:
rat = (unit2.armor-unit2.armor% arms[unit1.active][1])/ arms[unit1.active][1]
unit2.dam = damtable[int(5+rat)][randint(0,9)]
unit2.health -= unit2.dam
if unit2.health > 0:
print( unit1.name + " shoot " + unit1.active + " and deals " + str(unit2.dam) + " damage to " + unit2.name + " HP: " + str(unit2.health))
else:
print( unit1.name + " shoot " + unit1.active + " and deals " + str(unit2.dam) + " damage to " + unit2.name + " HP: " + str(unit2.health) + " " + unit2.name + " DESTROYED")
def fight(stack1, stack2):
if len(stack2.units)>0 and len(stack1.units)>0:
for distance in range(20):
if len(stack2.units)>0 and len(stack1.units)>0:
#print("Range: " + str(distance))
settargets(stack1, stack2, distance)
settargets(stack2, stack1, distance)
for shooter in stack1.units:
if shooter.target != -1:
if tohit(shooter, stack2.units[shooter.target]):
damage(shooter, stack2.units[shooter.target])
else:
print(shooter.name + " shoots " + shooter.active + " and misses " + stack1.units[shooter.target].name)
for shooter in stack2.units:
if shooter.target != -1:
if tohit(shooter, stack1.units[shooter.target]):
damage(shooter, stack1.units[shooter.target])
else:
print(shooter.name + " shoots " + shooter.active + " and misses " + stack1.units[shooter.target].name)
shooter.target = -1
stack1.clearunits()
stack2.clearunits()
print("")
else:
pass
elif len(stack1.units)>0:
print("stack 2 is empty")
elif len(stack2.units)>0:
print("stack 1 is empty")
else:
print("they're all dead, jim.")
def drawunit(self, unit_to_draw):
self.can.create_image(((unit_to_draw.x_pos-1)*mygrid.size*3/2+mygrid.offsetx,(unit_to_draw.y_pos-1)*mygrid.size*.86+mygrid.offsety),image = unit.image)
class App:
def __init__(self, master):
self.unitimage = PhotoImage(file="unit.gif")
frame = Frame(master)
frame.pack()
self.pickedstack = 1
self.active_stack = stack1
self.button = Button(frame, text="QUIT", fg="red", command=frame.quit)
self.button.pack(side=LEFT)
self.fight = Button(frame, text="Fight", command=self.fight)
self.fight.pack(side=LEFT)
self.show_units = Button(frame, text="Show Units", command=self.show_units)
self.show_units.pack(side=LEFT)
self.selectfirst = Button(frame, text="Stack One", command=self.selectfirst)
self.selectfirst.pack(side=LEFT)
self.selectsecond = Button(frame, text="Stack Two", command=self.selectsecond)
self.selectsecond.pack(side=LEFT)
self.can = Canvas(width=1000, height=700)
self.can.pack(side = LEFT)
for hex in mygrid.hexes:
self.can.create_polygon([hex[2],hex[3],hex[4],hex[5],hex[6],hex[7],hex[8],hex[9],hex[10],hex[11],hex[12],hex[13]], outline = "black", fill = "white", width = 1)
#self.can.create_image(self.can.create_image((43,43), image = self.unitimage)
#self.can.create_image((129,146), image = self.unitimage)
self.can.create_image((stack1.x_gfx, stack1.y_gfx), image = self.unitimage)
self.can.create_image((stack2.x_gfx, stack2.y_gfx), image = self.unitimage)
self.can.create_image((stack3.x_gfx, stack3.y_gfx), image = self.unitimage)
def findhex(event):
clickx = (event.x-mygrid.offset+mygrid.size)/mygrid.size/3*2
clicky = (event.y-mygrid.offset)/(mygrid.size*.86)/2
if int(round(.5+clickx))%2==0:
clicky += .5
if round(clickx+1/6)<round(.5+clickx):
tri_x = clickx-round(clickx-.5)
tri_y = clicky-round(clicky-.5)
if round(tri_y)==0:
#print("above")
if tri_x*1.73<tri_y:
clicky+=1
clickx-=1
else:
#triangle below halfway on left hexagon of the junction
if (.3-tri_x>(tri_y-.5)/1.73):
clickx-=1
if round(.5+clickx)%2==1:
clicky-=1
#print(round(.5+clickx), round(clicky+1))
for item in stacklist:
if item.x_pos == round(.5+clickx) and item.y_pos == round(clicky+1):
self.active_stack = item
print(self.active_stack)
def rightclick(event):
clickx = (event.x-mygrid.offset+mygrid.size)/mygrid.size/3*2
clicky = (event.y-mygrid.offset)/(mygrid.size*.86)/2
if int(round(.5+clickx))%2==0:
clicky += .5
if round(clickx+1/6)<round(.5+clickx):
tri_x = clickx-round(clickx-.5)
tri_y = clicky-round(clicky-.5)
if round(tri_y)==0:
#print("above")
if tri_x*1.73<tri_y:
clicky+=1
clickx-=1
else:
#triangle below halfway on left hexagon of the junction
if (.3-tri_x>(tri_y-.5)/1.73):
clickx-=1
if round(.5+clickx)%2==1:
clicky-=1
print(round(.5+clickx), round(clicky+1))
print(self.active_stack.x_pos,self.active_stack.y_pos)
if self.active_stack.x_pos == round(.5+clickx) and (self.active_stack.y_pos == (1+clicky)):
self.active_stack.y_pos += 1
print(self.active_stack.x_pos,self.active_stack.y_pos)
elif self.active_stack.x_pos == round(.5+clickx) and self.active_stack.y_pos == (clicky-1):
self.active_stack.y_pos += -1
self.can.create_image((self.active_stack.x_gfx, self.active_stack.y_gfx), image = self.unitimage)
self.can.bind("<Button 1>",findhex)
self.can.bind("<Button 3>",rightclick)
def movecenter(event):
mygrid.offsetx += (event.x-280)
mygrid.offsety += (event.y-280)
mygrid.draw()
self.can.update_idletasks()
self.can.bind("<Button 3>",movecenter)
self.listbox = Listbox(master)
self.listbox.pack()
for item in namelist:
self.listbox.insert(END, item)
def unitadd(self):
print(namelist[int(self.listbox.curselection()[0])])
if self.pickedstack == 1:
stack1.units.append(Unit(namelist[int(self.listbox.curselection()[0])]))
else:
stack2.units.append(Unit(namelist[int(self.listbox.curselection()[0])]))
def fight(self):
fight(stack1, stack2)
def show_units(self):
print("Unit Report:")
stack1.showunits()
stack2.showunits()
def selectfirst(self):
self.selectfirst.config(relief=SUNKEN)
self.selectsecond.config(relief=RAISED)
self.pickedstack = 1
def selectsecond(self):
self.selectfirst.config(relief=RAISED)
self.selectsecond.config(relief=SUNKEN)
self.pickedstack = 2
root = Tk()
app = App(root)
root.mainloop()