Advertisement
Guest User

trek.py

a guest
Jul 26th, 2014
309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.26 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. #from threading import Thread
  4. #import subprocess
  5. #import Queue
  6. import pexpect
  7. import ships
  8. import re
  9. import math
  10.  
  11. class CLIGame:
  12.     def __init__(self, command):
  13.         self.game = pexpect.spawn(command)
  14.  
  15.     def readall(self):
  16.         data = ''
  17.         while True:
  18.             try:
  19.                 char = self.game.read_nonblocking(timeout=0.05)
  20.             except pexpect.TIMEOUT:
  21.                 return data
  22.             else:
  23.                 data += char
  24.  
  25.     def send_cmd(self, cmd):
  26.         data = ''
  27.         self.game.sendline(cmd)
  28.         return self.readall()
  29.  
  30. class Trek(CLIGame):
  31.     def __init__(self, length=0, difficulty=0, password='hunter2'):
  32.         lengths = ['short', 'medium', 'long']
  33.         difficulties = ['novice', 'fair', 'good', 'expert', 'commodore', 'impossible']
  34.  
  35.         if length >= len(lengths) or difficulty >= len(difficulties):
  36.             raise ValueError
  37.  
  38.         CLIGame.__init__(self, 'trek')
  39.         print self.send_cmd('\n'.join([
  40.             '', # There's a "press return to continue" bit
  41.             lengths[length],
  42.             difficulties[difficulty],
  43.             password
  44.         ]))
  45.  
  46.         self.enterprise = ships.Enterprise([0, 0])
  47.         self.update_pos()
  48.  
  49.     def coords_to_pos(self, coords):
  50.         # y1,x1/y2,x2
  51.         print coords
  52.         coords = coords.split('/')
  53.         print coords
  54.         coords = [[int(j) for j in i.split(',')] for i in coords]
  55.         print coords
  56.         pos = (coords[0][0]+coords[1][1]*0.1, coords[0][1]+coords[1][0]*0.1)
  57.         print pos
  58.         return pos
  59.  
  60.     def update_pos(self):
  61.         print 'Updating position data...'
  62.         srscan = self.send_cmd('srscan')
  63.         pos = re.search(
  64.             r'position\s+?(\d+,\d+/\d+,\d+)',
  65.             srscan
  66.         )
  67.         pos = pos.group(1)
  68.         print 'Found pos string',pos
  69.         pos = self.coords_to_pos(pos)
  70.         print 'Converted to', pos
  71.         self.enterprise.pos = pos
  72.  
  73.     def move_angle(self, angle, distance):
  74.         self.send_cmd('m {} {}'.format(angle, distance))
  75.         self.update_pos()
  76.  
  77. class UserCommands:
  78.     commands = []
  79.    
  80.     def string_to_code(self, string):
  81.         for i, command in enumerate(self.commands):
  82.             if string in string_list[0]:
  83.                 return command_code[i]
  84.         return False
  85.  
  86. class AutoTrek(Trek):
  87.     user_commands = UserCommands()
  88.     user_commands.commands = [
  89.         [['attack', 'a'], 'self.send_cmd(self.generate_attack_command())']
  90.     ]
  91.  
  92.     klingons = []
  93.  
  94.     def get_offset(self, target_pos):
  95.         return (target_pos[0]-self.pos[0], target_pos[1]-self.enterprise.pos[1])
  96.  
  97.     def get_distance(self, target_pos):
  98.         return math.hypot( *self.get_offset(target_pos) )
  99.  
  100.     def get_heading(self, target_pos):
  101.         target_offset = self.get_offset(target_pos)
  102.         heading = math.atan2(*target_offset)
  103.         print 'heading (unconverted):',heading
  104.         heading = math.degrees(heading)
  105.         print 'heading (converted):  ',heading
  106.         # converted to int so that str(heading) doesn't have a .0 and mess up commands
  107.         heading = int(round(heading))
  108.         print 'heading (rounded):    ',heading
  109.         # this doesn't seem to work. It once output 360.
  110.         while heading < 0:
  111.             print 'heading is < 0'
  112.             heading += 360
  113.             print 'new heading:      ',heading
  114.         return heading
  115.  
  116.     def get_phaser_efficiency(self, distance):
  117.         return ( 0.9**float(distance*10) * 98 + 0.5 ) / 100
  118.  
  119.     def generate_attack_command(self, *klingons):
  120.         command = 'phaser manual'
  121.         for klingon in klingons:
  122.             command += '\n'
  123.             efficiency = self.get_phaser_efficiency(
  124.                 self.get_distance(
  125.                     klingon.pos
  126.                 )
  127.             )
  128.             command += str(int(round(klingon.hp/efficiency)))+' '
  129.             command += str(int(round(self.get_heading(klingon.pos))))+' '
  130.             command += '0'
  131.         command += '\n0'
  132.         return command
  133.  
  134.     def user_input(self, cmd):
  135.         if cmd[0] == '/':
  136.             exec cmd[1:]
  137.         else:
  138.             print self.send_cmd(cmd)
  139.  
  140. while True:
  141.     ai = AutoTrek()
  142.     while True:
  143.         ai.user_input(raw_input('$'))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement