Git Product home page Git Product logo

epicwar's Introduction

StackOverflow Python Package Index crates.io LinkedIn Facebook Instagram Telegram ВКонтакте YouTube Discord

epicwar's People

Contributors

eigenein avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

epicwar's Issues

Requests pipelining

Epic War supports requests pipelining (i.e. making several calls within one HTTP request). Might be a good idea to use it.

💻 Get rid of LookupEnum.has_value

Problems

  • When new game event starts I need to add new unit types because some logic depends on them.
  • try … catch ValueError and has_value(…) are weird.

Need to subclass enum.Enum so that unknown values will be automatically added in runtime (with names like unknown_123).

Summary log line

Instead of just:

2016-08-10 00:10:18 [I] Made 22 requests. Bye!

I'd like to see:

  • Request count.
  • Last known resource amounts.
  • Busy builder count.

This will help to broadcast main information to the Telegram channel.

Get rid of initial vk.com requests

Need to investigate which tokens are passed to i-epicwar-vk.progrestar.net.

For sure secret is a constant for each user that can be obtained from a browser manually.

The another one is still unknown.

👷 Optimize building upgrade

Bot makes additional getBuildings call after upgradeBuilding but it can be avoided. I just need to update Building.is_completed and self.incomplete_buildings.

📈 Get rid of create_enum

create_enum looks very ugly and doesn't allow me to use static code analysis tools.

It's much prettier to use NewType so that I'll be ready for any IDs. For some predefined constants introduce usual class attributes.

Remember that Library will be broken since it relies on the fact that instances of different enum types are different.

Make use of state call

Looks like state call returns some state that is corresponding to a main call. I can try to use it when I need to refresh resources and buildings. Example:

{
  "date": 1471644485.9929,
  "results": [
    {
      "ident": "group_0_body",
      "result": {
        "buildingId": 1144,
        "reward": {
          "resource": [
            {
              "id": 26,
              "amount": 209
            }
          ]
        },
        "available": {
          "resource": [
            {
              "id": 26,
              "amount": 209
            }
          ]
        }
      }
    },
    {
      "ident": "group_1_body",
      "result": {
        "resource": [
          {
            "id": 1,
            "amount": 2416207
          },
          {
            "id": 2,
            "amount": 15303182
          },
          {
            "id": 5,
            "amount": 28
          },
          {
            "id": 26,
            "amount": 42641
          },
          {
            "id": 4,
            "amount": 41
          },
          {
            "id": 6,
            "amount": 13
          },
          {
            "id": 20,
            "amount": 0
          },
          {
            "id": 3,
            "amount": 13
          },
          {
            "id": 8,
            "amount": 35
          },
          {
            "id": 7,
            "amount": 0
          },
          {
            "id": 9,
            "amount": 34
          },
          {
            "id": 27,
            "amount": 2976
          },
          {
            "id": 29,
            "amount": 172
          },
          {
            "id": 34,
            "amount": 0
          },
          {
            "id": 40,
            "amount": 188
          },
          {
            "id": 38,
            "amount": 0
          },
          {
            "id": 39,
            "amount": 0
          },
          {
            "id": 51,
            "amount": 0
          },
          {
            "id": 21,
            "amount": 50
          },
          {
            "id": 50,
            "amount": 84
          },
          {
            "id": 52,
            "amount": 10
          },
          {
            "id": 57,
            "amount": 0
          },
          {
            "id": 55,
            "amount": 0
          },
          {
            "id": 104,
            "amount": 245
          },
          {
            "id": 59,
            "amount": 3
          },
          {
            "id": 89,
            "amount": 1
          },
          {
            "id": 79,
            "amount": 2
          },
          {
            "id": 69,
            "amount": 2
          },
          {
            "id": 88,
            "amount": 1
          },
          {
            "id": 78,
            "amount": 1
          },
          {
            "id": 68,
            "amount": 2
          },
          {
            "id": 70,
            "amount": 0
          },
          {
            "id": 111,
            "amount": 11
          },
          {
            "id": 41,
            "amount": 0
          },
          {
            "id": 126,
            "amount": 117
          },
          {
            "id": 127,
            "amount": 0
          },
          {
            "id": 123,
            "amount": 0
          },
          {
            "id": 128,
            "amount": 0
          },
          {
            "id": 58,
            "amount": 1
          },
          {
            "id": 131,
            "amount": 132
          },
          {
            "id": 130,
            "amount": 0
          },
          {
            "id": 132,
            "amount": 0
          },
          {
            "id": 145,
            "amount": 23
          },
          {
            "id": 147,
            "amount": 0
          },
          {
            "id": 146,
            "amount": 0
          },
          {
            "id": 80,
            "amount": 1
          },
          {
            "id": 90,
            "amount": 0
          },
          {
            "id": 60,
            "amount": 1
          },
          {
            "id": 153,
            "amount": 298
          },
          {
            "id": 155,
            "amount": 0
          },
          {
            "id": 154,
            "amount": 0
          },
          {
            "id": 156,
            "amount": 0
          },
          {
            "id": 81,
            "amount": 0
          },
          {
            "id": 162,
            "amount": 57
          },
          {
            "id": 164,
            "amount": 0
          },
          {
            "id": 163,
            "amount": 0
          },
          {
            "id": 169,
            "amount": 0
          },
          {
            "id": 161,
            "amount": 141
          },
          {
            "id": 167,
            "amount": 0
          },
          {
            "id": 91,
            "amount": 1
          },
          {
            "id": 172,
            "amount": 0
          },
          {
            "id": 171,
            "amount": 1
          }
        ],
        "buildingChanged": [
          {
            "id": 1144,
            "typeId": 31,
            "flip": false,
            "level": 1,
            "x": 23,
            "y": 21,
            "completed": true,
            "volume": 0,
            "stateTimestamp": 1471644485,
            "hitpoints": 920,
            "disabled": false,
            "speedMultiplier": 1.1000001,
            "boosts": [
              673,
              673
            ],
            "completeTime": 0
          }
        ]
      }
    }
  ]
}

TypeError when PvP is not started

❌ Critical error:

Traceback (most recent call last):
  File "/home/eigenein/epicwar/epicbot/__main__.py", line 88, in step
    epicbot.bot.Bot(obj, api, library).step()
  File "/home/eigenein/epicwar/epicbot/bot.py", line 120, in step
    self.play_pvp()
  File "/home/eigenein/epicwar/epicbot/bot.py", line 440, in play_pvp
    battle_result, new_resources = self.api.finish_battle(battle.battle_id, commands)
AttributeError: 'NoneType' object has no attribute 'battle_id'

Move lib.json to a Python module

After #28.

I'd like to remove the binary asset, simplify library loading and use git diff to see changes in library.

Write a script to download the library from the specified URL, unzip it and put into an auto-generated Python module with sort_keys=True.

🏆 Pick defender in PvP battles

Currently bot accepts the very first defender fights against it.

Bot could try to evaluate some defenders before accepting a battle.

👷 Building manager

Prior to #10 and #24.

I will need to track a lot of values linked to the buildings. It's better to encapsulate this behavior into a separate building manager class.

👷 Construct new buildings

Max amount stored in lib.json:

"unlocks": {
  "building": [
    {
      "typeId": 631,
      "maxLevel": 10,
      "maxAmount": 1
    }
  ]
}

📈 Optimize unit upgrade

Bot doesn't check if there is already a research in progress that leads to the useless upgrade requests.

2016-08-18 17:24:19 [I] Trying to upgrade units…
2016-08-18 17:24:19 [I] Upgrading unit goblin to level 4…
2016-08-18 17:24:20 [E] Failed to upgrade: not_available.
2016-08-18 17:24:20 [I] Upgrading unit knight to level 4…
2016-08-18 17:24:21 [E] Failed to upgrade: not_available.
2016-08-18 17:24:21 [I] Upgrading unit troll to level 3…
2016-08-18 17:24:22 [E] Failed to upgrade: not_available.
2016-08-18 17:24:22 [I] Upgrading unit orc to level 3…
2016-08-18 17:24:23 [E] Failed to upgrade: not_available.

🚀 Bot 2.0

This is a meta-issue to develop the 2nd version of the bot that will be able to run continuously and react on events (e.g. upgrade finished, bastion is available, units hired etc) immediately.

  • Add new CLI command
  • Move options to configuration file
  • Move from requests to aiohttp
  • Multiple accounts
  • Add top-level event handling loop
  • Print average requests per minute per account
  • Use typing.NewType for game enums
  • Re-write library converter because of typing.NewType
  • Move task queue to SQLite database: everyday, regular and irregular tasks
  • Collect resources
  • Farm alliance help
  • Send mana
  • Farm mana
  • Proxy support (to use Tor)
  • Translations for resource, unit and spell types
  • Move state (buildings, resources and etc) to the database
  • Spin roulette
  • Farm random war tasks
  • Activate alliance daily gift
  • Collect alliance daily gift
  • Farm cemetery
  • Upgrade buildings
  • Upgrade units
  • Destruct extended areas
  • Play PvP
  • Play bastion
  • Collect bastion gift

📈 Optimize random war task farm

Now the bot tries to farm every task regardless of its completion status.

Need to check a task progress before trying to complete it.

alliance_randomWar_cycle_get

{
  "state": [],
  "result": {
    "timestampStart": 1473260400,
    "id": 1473260400,
    "timestampEnd": 1473865200
  }
}

alliance_randomWar_status

{
  "result": {
    "war": {
      "timestampEnd": 1473346800,
      "id": 1473260404257675978,
      "randomWarCycleId": 1,
      "timestampStart": 1473260400
    },
    "opponent": {
      "warId": 1473260404257675978,
      "allianceId": 549928,
      "score": 415
    },
    "alliance": {
      "warId": 1473260404257675978,
      "allianceId": 334586,
      "score": 230
    }
  },
  "state": []
}

🍔 Track resources manually

Current problems

  1. Bot requests resource info after each building upgrade that leads to a lot of requests.
  2. Bot does not refresh resource info after unit upgrade, cleaning territory and resource collection.
  3. Summary contains invalid resource amounts.

Now I'm able to track all the resources spent. Thus, it makes sense to refresh current resource amount "online" without making any requests to API.

Implementation details

It makes sense to use collections.Counter to store resource amounts.

👷 Destroy extended areas

Conditions for extended areas are listed in lib.json. Example:

"destroyConditions": {
  "building": [
    {
      "typeId": 1,
      "level": 9,
      "amount": 1
    }
  ]
}

The relevant part of the code:

if (
    building.type in BuildingType.extended_areas() and
    self.can_upgrade(building.type, building.level, building_levels) and
    building.is_completed
):
    logging.info("Cleaning %s #%s…", building.type.name, building.id)
    error = self.epic_war.destruct_building(building.id, False)
    if error == Error.ok:
        self.update_self_info()
        self.audit_log.append("Clean *{}*.".format(building.type.name))
    else:
        logging.error("Failed to clean extended area.")

Split into modules

The bot is getting bigger and bigger. Now is good time to split into separate modules.

Keep bot.py script to import the package and call __main__.main().

🍔 Improve resource collection

Traverse resource buildings at the very end. Thanks to this I will be able to stop collecting from a certain building type once zero amount is collected.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.