Skip to content

Instantly share code, notes, and snippets.

@cascad-s
Created June 10, 2019 08:20
Show Gist options
  • Save cascad-s/d2b9d9f8a51091a867e1470cb8e4b4f0 to your computer and use it in GitHub Desktop.
Save cascad-s/d2b9d9f8a51091a867e1470cb8e4b4f0 to your computer and use it in GitHub Desktop.
__author__ = 'cascad'
import time
import logging
class Point:
defense_sort = 'df'
storm_sort = 'ef'
d_sort = 'dsf'
power = {'d': 3, 's': 2, 'f': 1, 'e': 3}
capacity = {'d': 3, 's': 2, 'f': 1}
regen_coefficients = {'d': 2, 's': 1, 'l': 1}
point_types = {'little': 40, 'small': 50, 'medium': 70, 'big': 80, 'large': 100, 'heavy': 110, 'huge': 140}
def __init__(self,
name='Unknown'+str(time.time()/10000),
claim=None,
forces=None,
pos=None,
size='little',
regen_coefficient=5):
self.pos = pos
self.claim = claim
self.name = name
self.forces = forces if forces else {'d': 0, 's': 0, 'f': 0}
self._regen_drone_type = 'd'
self.size = size
self._timestamp = round(time.time())
self.regen_coefficient = regen_coefficient # will doing this variable not protected
self.max_point_capacity = self.__class__.point_types[self.size]
logging.debug('Init Point({0}).'.format(self.name))
@property
def regen_time(self):
if round(time.time()) >= self._timestamp + self.__class__.regen_coefficients[self.regen_drone_type] * self.regen_coefficient:
self._timestamp = round(time.time())
return True
else:
#logging.debug('NO regen')
return False
@property
def regen_drone_type(self):
return self._regen_drone_type
@regen_drone_type.setter
def regen_drone_type(self, reg_type):
self._timestamp = round(time.time())
self._regen_drone_type = reg_type
@property
def regen_value(self):
return self.__class__.capacity[self.regen_drone_type]
@property
def point_capacity(self):
return sum([self.forces[i] * self.__class__.capacity[i] for i in self.forces])
def __str__(self):
return '{0}@{1}@{2}'.format(self.name, self.claim, str(self.forces))
def point_regen(self):
if self.claim:
if self.max_point_capacity > self.point_capacity:
if self.regen_value <= self.max_point_capacity - self.point_capacity:
if self.regen_time:
self.forces[self.regen_drone_type] += self.regen_coefficient
return True
return False
# -------------------------------------------------------------------------------------------------------------------
# -------------------------------------------------------------------------------------------------------------------
class Map:
def __init__(self, gamers, gcallback, dmap=None):
self._callback = gcallback
for gamer in gamers:
# set actions callBack
gamer.set_actions_callBack(self.action)
self.gamers = gamers
if not dmap:
self.map = {'x': Point('x', claim='g1', forces={'d': 0, 's': 0, 'f': 0}),
'y': Point('y', claim='g2', forces={'d': 0, 's': 0, 'f': 0})}
else:
for i in dmap:
if not i.get('claim', None):
dmap[dmap.index(i)]['claim'] = None
self.map = {i['name']: Point(i['name'],
claim=i['claim'],
pos=i['pos'],
forces={'d': 0, 's': 0, 'f': 0},
size=i['size']) for i in dmap}
self._callback('send_map_state', self)
def dump(self):
return [{'claim': self.map[i].claim,
'name': self.map[i].name,
'regen_drone_type': self.map[i].regen_drone_type,
'size': self.map[i].size,
'point_capacity': self.map[i].point_capacity,
'max_point_capacity': self.map[i].max_point_capacity,
'forces': self.map[i].forces,
'pos':self.map[i].pos} for i in self.map]
def regen_map(self):
is_change = False
for i in self.map:
if self.map[i].point_regen():
is_change = True
if is_change:
self._callback('send_map_state', self)
def final(self):
self._callback('close', self)
def action(self, act, parameters):
if act == 'set_regeneration':
self.set_regeneration(*parameters)
elif act == 'move':
self.move(*parameters)
elif act == 'close':
self.gamers.remove(parameters)
if len(self.gamers) <= 0:
self.final()
def set_regeneration(self, gamer, point, regen_type):
if self.check_own_gamer(gamer, point):
self.map[point].regen_drone_type = regen_type
else:
logging.debug('Restricted operation. Point {0} is not owned by {1}.'.format(point, gamer))
def move(self, gamer, point, destination, force): # force = int
if not force > 0:
print('Empty forces in move.')
return False
s_e = min(force, self.map[point].forces['s'])
force -= s_e
s_f = force
s = {'e': s_e, 'f': s_f}
self.map[point].forces['f'] -= s['f']
self.map[point].forces['f'] -= s['e']
self.map[point].forces['s'] -= s['e']
d = {'d': self.map[destination].forces['d'], 'f': self.map[destination].forces['f']}
print('S_start: {0}'.format(s))
print('D_start: {0}'.format(d))
_action = self.check_action_type(point, destination)
_checks = [self.check_exist_action_gamer(gamer),
self.check_exist_point(point),
self.check_own_gamer(gamer, point)] # self.check_required_quantity_drones_on_point(point, force)
if all(_checks):
if _action == 'support':
print('Support.')
old_drones_on_dest = self.map[destination].forces
self.map[destination].forces['f'] += s['f']
if s['e']:
self.map[destination].forces['f'] += s['e']
self.map[destination].forces['s'] += s['e']
logging.debug('Support {0}. Been: {1}. Now: {2}. Supply forces: {1}'.format(destination,
str(old_drones_on_dest),
str(self.map[destination].forces),
str(s)))
elif _action == 'battle':
print('Battle.')
tmp = {}
while sum(s.values()) and sum(d.values()):
tmp_storm = Map.next_drone_type('s', s)
tmp_defense = Map.next_drone_type('d', d)
tmp = d[tmp_defense] * Point.power[tmp_defense] - s[tmp_storm] * Point.power[tmp_storm]
print(tmp)
if tmp > 0:
s[tmp_storm] = 0
d[tmp_defense] = tmp // Point.power[tmp_defense]
else:
d[tmp_defense] = 0
s[tmp_storm] = (abs(tmp)) // Point.power[tmp_storm]
print('S_end: {0}'.format(s))
print('D_end: {0}'.format(d))
if sum(s.values()):
self.map[destination].forces = {'d': 0, 's': 0, 'f': 0}
self.map[destination].claim = gamer
self.map[destination]._timestamp = round(time.time())
self.map[destination].forces['f'] = s['f']
if s['e']:
self.map[destination].forces['f'] += s['e']
self.map[destination].forces['s'] += s['e']
elif sum(d.values()):
self.map[destination].forces['d'] = d['d']
self.map[destination].forces['f'] = d['f']
else:
self.map[destination].claim = None
self.map[destination].forces = {'d': 0, 's': 0, 'f': 0}
count = set()
for i in self.map:
count.add(self.map[i].claim)
if len(count) < 2:
self.finish()
else:
print("NOT ALL CHECK'S IN ACTION")
self._callback('send_map_state', self)
def check_exist_action_gamer(self, gamer): # gamer == str
logging.debug('check_exist_action_gamer')
return True if gamer in self.gamers else False
def check_exist_point(self, point): # point == str
logging.debug('check_exist_point')
return True if self.map[point] else False
def check_action_type(self, point, destination):
logging.debug('check_action_type')
return 'battle' if self.map[point].claim != self.map[destination].claim else 'support'
def check_own_gamer(self, gamer, point): # gamer, point == str
logging.debug('check_own_gamer')
return True if gamer == self.map[point].claim else False
@staticmethod
def next_drone_type(tactic, value):
if tactic == 's':
for i in Point.storm_sort:
if value[i] > 0:
return i
elif tactic == 'd':
for i in Point.defense_sort:
if value[i] > 0:
return i
def finish(self):
for i in self.map:
if self.map[i].claim:
logging.debug("-----------------------ROUND COMPLETE-----------------------")
logging.debug("-----------------------WINNER:{0}-------------------------".format(self.map[i].claim))
logging.debug("-----------------------ROUND COMPLETE-----------------------")
break
if __name__ == "__main__":
logging.basicConfig(format=u'%(filename)s[LINE:%(lineno)d]# %(levelname)-8s [%(asctime)s] %(message)s',
level=logging.DEBUG)
gamers = ('g1', 'g2')
gcallback = 1
dmap = {'x': Point('x', claim='g1', forces={'d': 4, 's': 3, 'f': 8}),
'y': Point('y', claim='g2', forces={'d': 4, 's': 1, 'f': 1}),
'z': Point('z', claim='g1', forces={'d': 3, 's': 2, 'f': 2})}
z = Map(gamers, gcallback, dmap)
z.move('g1', 'x', 'z', 5)
print(z.map['x'])
print(z.map['z'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment