Skip to content

Commit

Permalink
big refactor to Stepper class (#737)
Browse files Browse the repository at this point in the history
* big refactor to Stepper class

We now have a:

- StepWalker class, responsible for walking a small distance towards a
final destination.

- SpiralNavigator class, which around an area in a spiral. It
determines points to walk to and uses to StepWalker to slowly go from
one point to another.

This architecture enables us to have different Navigators, although it
doesn’t implement a nice Navigator configuration YET.

* small fixes to workers

* Merging

* Fixing arguments

* Moving the distance log line
  • Loading branch information
douglascamata authored and ProjectBarks committed Jul 25, 2016
1 parent c4d589a commit 586a0dc
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 168 deletions.
49 changes: 42 additions & 7 deletions pokemongo_bot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
import logger
import re
from pgoapi import PGoApi
from pgoapi.utilities import f2i, h2f
from cell_workers import PokemonCatchWorker, SeenFortWorker, MoveToFortWorker, InitialTransferWorker, EvolveAllWorker
from cell_workers.utils import distance
from cell_workers.utils import distance, get_cellid, encode
from step_walker import StepWalker
from human_behaviour import sleep
from stepper import Stepper
from spiral_navigator import SpiralNavigator
from geopy.geocoders import GoogleV3
from math import radians, sqrt, sin, cos, atan2
from item_list import Item
Expand All @@ -30,13 +32,45 @@ def __init__(self, config):
def start(self):
self._setup_logging()
self._setup_api()
self.stepper = Stepper(self)
self.step_walker = StepWalker(self)
self.navigator = SpiralNavigator(self)
random.seed()

def take_step(self):
self.stepper.take_step()

def work_on_cell(self, cell, position, include_fort_on_path):
location = self.navigator.take_step()
cells = self.find_close_cells(*location)

for cell in cells:
self.work_on_cell(cell, location)

def find_close_cells(self, lat, lng):
cellid = get_cellid(lat, lng)
timestamp = [0, ] * len(cellid)

self.api.get_map_objects(
latitude=f2i(lat),
longitude=f2i(lng),
since_timestamp_ms=timestamp,
cell_id=cellid
)
response_dict = self.api.call()
map_objects = response_dict.get('responses', {}).get('GET_MAP_OBJECTS', {})
status = map_objects.get('status', None)

map_cells = []
if status and status == 1:
map_cells = map_objects['map_cells']
position = (lat, lng, 0)
map_cells.sort(
key=lambda x: distance(
lat,
lng,
x['forts'][0]['latitude'],
x['forts'][0]['longitude']) if x.get('forts', []) else 1e6
)
return map_cells

def work_on_cell(self, cell, position):
if self.config.evolve_all:
# Run evolve all once. Flip the bit.
print('[#] Attempting to evolve all pokemons ...')
Expand Down Expand Up @@ -78,7 +112,7 @@ def work_on_cell(self, cell, position, include_fort_on_path):
if self.catch_pokemon(pokemon) == PokemonCatchWorker.NO_POKEBALLS:
break
if (self.config.mode == "all" or
self.config.mode == "farm") and include_fort_on_path:
self.config.mode == "farm"):
if 'forts' in cell:
# Only include those with a lat/long
forts = [fort
Expand All @@ -90,6 +124,7 @@ def work_on_cell(self, cell, position, include_fort_on_path):
# build graph & A* it
forts.sort(key=lambda x: distance(self.position[
0], self.position[1], x['latitude'], x['longitude']))

for fort in forts:
worker = MoveToFortWorker(fort, self)
worker.work()
Expand Down
5 changes: 3 additions & 2 deletions pokemongo_bot/cell_workers/move_to_fort_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ def __init__(self, fort, bot):
self.fort = fort
self.api = bot.api
self.config = bot.config
self.stepper = bot.stepper
self.navigator = bot.navigator
self.step_walker = bot.step_walker
self.position = bot.position

def work(self):
Expand All @@ -27,7 +28,7 @@ def work(self):
position = (lat, lng, 0.0)

if self.config.walk > 0:
self.stepper._walk_to(self.config.walk, *position)
self.step_walker.step(self.config.walk, *position[0:2])
else:
self.api.set_position(*position)

Expand Down
1 change: 0 additions & 1 deletion pokemongo_bot/cell_workers/seen_fort_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ def __init__(self, fort, bot):
self.config = bot.config
self.item_list = bot.item_list
self.rest_time = 50
self.stepper = bot.stepper

def work(self):
lat = self.fort['latitude']
Expand Down
20 changes: 20 additions & 0 deletions pokemongo_bot/cell_workers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,29 @@
import struct
from math import cos, asin, sqrt
from colorama import init
from s2sphere import CellId, LatLng
init()


def get_cellid(lat, long, radius=10):
origin = CellId.from_lat_lng(LatLng.from_degrees(lat, long)).parent(15)
walk = [origin.id()]

# 10 before and 10 after
next = origin.next()
prev = origin.prev()
for i in range(radius):
walk.append(prev.id())
walk.append(next.id())
next = next.next()
prev = prev.prev()
return sorted(walk)

def encode(cellid):
output = []
encoder._VarintEncoder()(output.append, cellid)
return ''.join(output)

def distance(lat1, lon1, lat2, lon2):
p = 0.017453292519943295
a = 0.5 - cos((lat2 - lat1) * p) / 2 + cos(lat1 * p) * \
Expand Down
70 changes: 70 additions & 0 deletions pokemongo_bot/spiral_navigator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-

import os
import json
import time
import pprint

from math import ceil
from s2sphere import CellId, LatLng
from google.protobuf.internal import encoder

from human_behaviour import sleep, random_lat_long_delta
from cell_workers.utils import distance, i2f, format_time, format_dist

from pgoapi.utilities import f2i, h2f
import logger


class SpiralNavigator(object):
def __init__(self, bot):
self.bot = bot
self.api = bot.api
self.config = bot.config

self.pos = 1
self.x = 0
self.y = 0
self.dx = 0
self.dy = -1
self.steplimit = self.config.max_steps
self.steplimit2 = self.steplimit**2
self.origin_lat = self.bot.position[0]
self.origin_lon = self.bot.position[1]

def take_step(self):
position = (self.origin_lat, self.origin_lon, 0.0)

logger.log('[#] Scanning area for objects....')
# logger.log('[#] Scanning area for objects ({} / {})'.format(
# (step + 1), self.steplimit**2))
if self.config.debug:
logger.log(
'steplimit: {} x: {} y: {} pos: {} dx: {} dy {}'.format(
self.steplimit2, self.x, self.y, self.pos, self.dx,
self.dy))
# Scan location math

if -self.steplimit2 / 2 < self.x <= self.steplimit2 / 2 and -self.steplimit2 / 2 < self.y <= self.steplimit2 / 2:
position = (self.x * 0.0025 + self.origin_lat,
self.y * 0.0025 + self.origin_lon, 0)
if self.config.walk > 0:

dist = distance(
i2f(self.api._position_lat),
i2f(self.api._position_lng),
position[0],
position[1]
)

logger.log('[#] Walking from ' + str((i2f(self.api._position_lat), i2f(
self.api._position_lng))) + " to " + str((str(position[0:2]))) + " " + format_dist(dist, self.config.distance_unit))
self.bot.step_walker.step(self.config.walk, *position[0:2])
else:
self.api.set_position(*position)
if self.x == self.y or self.x < 0 and self.x == -self.y or self.x > 0 and self.x == 1 - self.y:
(self.dx, self.dy) = (-self.dy, self.dx)

(self.x, self.y) = (self.x + self.dx, self.y + self.dy)
sleep(10)
return position[0:2]
29 changes: 29 additions & 0 deletions pokemongo_bot/step_walker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import logger

from cell_workers.utils import distance, i2f, format_time
from human_behaviour import random_lat_long_delta, sleep
from math import ceil


class StepWalker(object):

def __init__(self, bot):
self.bot = bot
self.api = bot.api

def step(self, speed, lat, lng):
if self.api._position_lat == lat and self.api._position_lng == lng:
return True

dLat = (lat - i2f(self.api._position_lat))
dLng = (lng - i2f(self.api._position_lng))

cLat = i2f(self.api._position_lat) + dLat + random_lat_long_delta()
cLng = i2f(self.api._position_lng) + dLng + random_lat_long_delta()

self.api.set_position(cLat, cLng, 0)
self.bot.heartbeat()
sleep(1) # sleep one second plus a random delta
# self._work_at_position(
# i2f(self.api._position_lat), i2f(self.api._position_lng),
# alt, False)
158 changes: 0 additions & 158 deletions pokemongo_bot/stepper.py

This file was deleted.

0 comments on commit 586a0dc

Please sign in to comment.