Skip to content

Commit

Permalink
add some typing (#1612)
Browse files Browse the repository at this point in the history
* add some tpying

* format
  • Loading branch information
Killklli authored Sep 16, 2023
1 parent 1c07a58 commit 070cf13
Show file tree
Hide file tree
Showing 13 changed files with 85 additions and 69 deletions.
2 changes: 1 addition & 1 deletion js.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import json


def postMessage(message):
def postMessage(message: str) -> None:
"""Fake function for printing messages with JS."""
print(message)

Expand Down
3 changes: 2 additions & 1 deletion randomizer/Enums/Kongs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Kong enum."""
from enum import IntEnum, auto
from typing import List


class Kongs(IntEnum):
Expand All @@ -13,6 +14,6 @@ class Kongs(IntEnum):
any = auto()


def GetKongs():
def GetKongs() -> List[Kongs]:
"""Return list of kongs without any."""
return [Kongs.donkey, Kongs.diddy, Kongs.lanky, Kongs.tiny, Kongs.chunky]
58 changes: 31 additions & 27 deletions randomizer/Fill.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
from randomizer.ShuffleShopLocations import ShuffleShopLocations
from randomizer.ShuffleWarps import LinkWarps, ShuffleWarps, ShuffleWarpsCrossMap
from randomizer.Patching.EnemyRando import randomize_enemies_0
from randomizer.Spoiler import Spoiler
from typing import Any, List, Optional, Set, Tuple, Union


def GetExitLevelExit(region):
Expand Down Expand Up @@ -106,7 +108,9 @@ def GetLobbyOfRegion(region):
return None


def GetAccessibleLocations(spoiler, startingOwnedItems, searchType, purchaseList=None, targetItemId=None):
def GetAccessibleLocations(
spoiler: Spoiler, startingOwnedItems: List[Union[Items, Any]], searchType: SearchMode, purchaseList: Optional[List[Locations]] = None, targetItemId: None = None
) -> Union[Set[Locations], List[Sphere], bool]:
"""Search to find all reachable locations given owned items."""
settings = spoiler.settings
# No logic? Calls to this method that are checking things just return True
Expand Down Expand Up @@ -378,7 +382,7 @@ def GetAccessibleLocations(spoiler, startingOwnedItems, searchType, purchaseList
return [x for x in spoiler.LocationList if x not in accessible and not spoiler.LocationList[x].inaccessible]


def VerifyWorld(spoiler):
def VerifyWorld(spoiler: Spoiler) -> bool:
"""Make sure all item locations are reachable on current world graph with constant items placed and all other items owned."""
settings = spoiler.settings
if settings.logic_type == LogicType.nologic:
Expand All @@ -399,7 +403,7 @@ def VerifyWorld(spoiler):
return allLocationsReached and allCBsFound


def VerifyWorldWithWorstCoinUsage(spoiler):
def VerifyWorldWithWorstCoinUsage(spoiler: Spoiler) -> bool:
"""Make sure the game is beatable without it being possible to run out of coins for required moves."""
settings = spoiler.settings
if settings.logic_type == LogicType.nologic:
Expand Down Expand Up @@ -595,7 +599,7 @@ def VerifyWorldWithWorstCoinUsage(spoiler):
locationsToPurchase.append(locationToBuy)


def ParePlaythrough(spoiler, PlaythroughLocations):
def ParePlaythrough(spoiler: Spoiler, PlaythroughLocations: List[Sphere]) -> None:
"""Pare playthrough down to only the essential elements."""
settings = spoiler.settings
locationsToAddBack = []
Expand Down Expand Up @@ -648,7 +652,7 @@ def ParePlaythrough(spoiler, PlaythroughLocations):
spoiler.LocationList[locationId].PlaceDelayedItem(spoiler)


def PareWoth(spoiler, PlaythroughLocations):
def PareWoth(spoiler: Spoiler, PlaythroughLocations: List[Sphere]) -> List[Locations]:
"""Pare playthrough to locations which are Way of the Hoard (hard required by logic)."""
# The functionality is similar to ParePlaythrough, but we want to see if individual locations are
# hard required, so items are added back after checking regardless of the outcome.
Expand Down Expand Up @@ -695,7 +699,7 @@ def PareWoth(spoiler, PlaythroughLocations):
return WothLocations


def CalculateWothPaths(spoiler, WothLocations):
def CalculateWothPaths(spoiler: Spoiler, WothLocations: List[Locations]) -> None:
"""Calculate the Paths (dependencies) for each Way of the Hoard item."""
# Helps get more accurate paths by removing important obstacles to level entry
# Removes the following:
Expand Down Expand Up @@ -796,7 +800,7 @@ def CalculateWothPaths(spoiler, WothLocations):
spoiler.settings.open_lobbies = old_open_lobbies_temp # Undo the open lobbies setting change as needed


def CalculateFoolish(spoiler, WothLocations):
def CalculateFoolish(spoiler: Spoiler, WothLocations: List[Locations]) -> None:
"""Calculate the items and regions that are foolish (blocking no major items)."""
# FOOLISH MOVES - unable to verify the accuracy of foolish moves, so these have to go :(
# The problem that needs to be solved: How do you guarantee neither part of a required either/or is foolish?
Expand Down Expand Up @@ -925,7 +929,7 @@ def CalculateFoolish(spoiler, WothLocations):
spoiler.foolish_region_names = list(set([region.hint_name for id, region in spoiler.RegionList.items() if any(region.locations) and region.hint_name not in nonHintableNames]))


def RandomFill(spoiler, itemsToPlace, inOrder=False):
def RandomFill(spoiler: Spoiler, itemsToPlace: List[Items], inOrder: bool = False) -> int:
"""Randomly place given items in any location disregarding logic."""
settings = spoiler.settings
if not inOrder:
Expand Down Expand Up @@ -964,7 +968,7 @@ def RandomFill(spoiler, itemsToPlace, inOrder=False):
return 0


def CarefulRandomFill(spoiler, itemsToPlace, ownedItems=None):
def CarefulRandomFill(spoiler: Spoiler, itemsToPlace: List[Items], ownedItems: Optional[List[Union[Items, Any]]] = None) -> int:
"""Randomly place items, but try to keep shops in mind. Expected to be faster than forward fill for large quantities of items but slower than random fill."""
spoiler.Reset()
settings = spoiler.settings
Expand Down Expand Up @@ -1027,7 +1031,7 @@ def CarefulRandomFill(spoiler, itemsToPlace, ownedItems=None):
return 0


def ForwardFill(spoiler, itemsToPlace, ownedItems=None, inOrder=False, doubleTime=False):
def ForwardFill(spoiler: Spoiler, itemsToPlace: List[Items], ownedItems: Optional[List[Items]] = None, inOrder: bool = False, doubleTime: bool = False) -> int:
"""Forward fill algorithm for item placement."""
settings = spoiler.settings
if ownedItems is None:
Expand Down Expand Up @@ -1109,7 +1113,7 @@ def GetItemValidLocations(spoiler, validLocations, item):
return itemValidLocations


def AssumedFill(spoiler, itemsToPlace, ownedItems=None, inOrder=False):
def AssumedFill(spoiler: Spoiler, itemsToPlace: List[Items], ownedItems: Optional[List[Items]] = None, inOrder: bool = False) -> int:
"""Assumed fill algorithm for item placement."""
settings = spoiler.settings
if ownedItems is None:
Expand Down Expand Up @@ -1199,7 +1203,7 @@ def BanAllRemainingSharedShops(spoiler):
spoiler.LocationList[location].PlaceItem(spoiler, Items.NoItem)


def GetMaxCoinsSpent(spoiler, purchasedShops):
def GetMaxCoinsSpent(spoiler: Spoiler, purchasedShops: List[Union[Any, Locations]]) -> List[int]:
"""Calculate the max number of coins each kong could have spent given the ownedItems and the price settings."""
settings = spoiler.settings
MaxCoinsSpent = [0, 0, 0, 0, 0, 0]
Expand Down Expand Up @@ -1303,7 +1307,7 @@ def GetUnplacedItemPrerequisites(spoiler, targetItemId, placedMoves, ownedKongs=
return requiredMoves


def PlaceItems(spoiler, algorithm, itemsToPlace, ownedItems=None, inOrder=False, doubleTime=False):
def PlaceItems(spoiler: Spoiler, algorithm: FillAlgorithm, itemsToPlace: List[Items], ownedItems: Optional[List[Union[Items, Any]]] = None, inOrder: bool = False, doubleTime: bool = False) -> int:
"""Places items using given algorithm."""
if ownedItems is None:
ownedItems = []
Expand All @@ -1320,7 +1324,7 @@ def PlaceItems(spoiler, algorithm, itemsToPlace, ownedItems=None, inOrder=False,
return CarefulRandomFill(spoiler, itemsToPlace, ownedItems)


def FillShuffledKeys(spoiler, placed_types):
def FillShuffledKeys(spoiler: Spoiler, placed_types: List[Types]) -> None:
"""Fill Keys in shuffled locations based on the settings."""
keysToPlace = []
for keyEvent in spoiler.settings.krool_keys_required:
Expand Down Expand Up @@ -1364,7 +1368,7 @@ def FillShuffledKeys(spoiler, placed_types):
raise Ex.ItemPlacementException(str(keysUnplaced) + " unplaced keys.")


def FillHelmLocations(spoiler, placed_types):
def FillHelmLocations(spoiler: Spoiler, placed_types: List[Types]) -> List[Items]:
"""Fill all currently empty Helm locations with eligible non-logic-critical items."""
placed_in_helm = []
# Get all the empty Helm locations
Expand Down Expand Up @@ -1421,7 +1425,7 @@ def FillHelmLocations(spoiler, placed_types):
return placed_in_helm


def Fill(spoiler):
def Fill(spoiler: Spoiler) -> None:
"""Fully randomizes and places all items."""
placed_types = []
spoiler.settings.debug_fill = {}
Expand Down Expand Up @@ -1618,7 +1622,7 @@ def Fill(spoiler):
return


def ShuffleSharedMoves(spoiler, placedMoves, placedTypes):
def ShuffleSharedMoves(spoiler: Spoiler, placedMoves: List[Items], placedTypes: List[Types]) -> None:
"""Shuffles shared kong moves into shops and then returns the remaining ones and their valid locations."""
# Confirm there are enough locations available for each remaining shared move
availableSharedShops = [location for location in SharedMoveLocations if spoiler.LocationList[location].item is None]
Expand Down Expand Up @@ -1709,7 +1713,7 @@ def FillKongsAndMovesGeneric(spoiler):
js.postMessage("Retrying fill. Tries: " + str(retries))


def GeneratePlaythrough(spoiler):
def GeneratePlaythrough(spoiler: Spoiler) -> None:
"""Generate playthrough and way of the hoard and update spoiler."""
js.postMessage("Seed generated! Finalizing spoiler...")
spoiler.LogicVariables.assumeFillSuccess = True # Now that we know the seed is valid, we can assume fill success for the sake of generating the playthrough and WotH
Expand Down Expand Up @@ -1903,7 +1907,7 @@ def PlaceKongsInKongLocations(spoiler, kongItems, kongLocations):
spoiler.settings.update_valid_locations(spoiler)


def FillKongs(spoiler, placedTypes):
def FillKongs(spoiler: Spoiler, placedTypes: List[Types]) -> None:
"""Place Kongs in valid locations."""
placedTypes.append(Types.Kong)
# Determine what kong items need to be placed
Expand Down Expand Up @@ -1956,7 +1960,7 @@ def FillKongs(spoiler, placedTypes):
PlaceKongsInKongLocations(spoiler, kongItems, spoiler.settings.kong_locations.copy())


def FillKongsAndMoves(spoiler, placedTypes):
def FillKongsAndMoves(spoiler: Spoiler, placedTypes: List[Types]) -> None:
"""Fill kongs, then progression moves, then shared moves, then rest of moves."""
itemsToPlace = []

Expand Down Expand Up @@ -2055,7 +2059,7 @@ def FillKongsAndMoves(spoiler, placedTypes):
raise Ex.ItemPlacementException(str(unplaced) + " unplaced items.")


def FillKongsAndMovesForLevelOrder(spoiler):
def FillKongsAndMovesForLevelOrder(spoiler: Spoiler) -> None:
"""Shuffle Kongs and Moves accounting for level order restrictions."""
# All methods here follow this Kongs vs level progression rule:
# Must be able to have 2 kongs no later than level 2
Expand Down Expand Up @@ -2137,7 +2141,7 @@ def GetAccessibleKongLocations(levels: list, ownedKongs: list):
return kongLocations


def WipeProgressionRequirements(settings: Settings):
def WipeProgressionRequirements(settings: Settings) -> None:
"""Wipe out progression requirements to assume access through main 7 levels."""
for i in range(0, 7):
# Assume T&S and B.Locker amounts will be attainable for now
Expand All @@ -2154,7 +2158,7 @@ def WipeProgressionRequirements(settings: Settings):
settings.chunky_freeing_kong = Kongs.any


def SetNewProgressionRequirements(spoiler):
def SetNewProgressionRequirements(spoiler: Spoiler) -> None:
"""Set new progression requirements based on what is owned or accessible heading into each level."""
# Find for each level: # of accessible bananas, total GBs, owned kongs & owned moves
settings = spoiler.settings
Expand Down Expand Up @@ -2542,7 +2546,7 @@ def GetAccessibleOpenLevels(spoiler):
return accessibleOpenLevels


def BlockAccessToLevel(settings: Settings, level):
def BlockAccessToLevel(settings: Settings, level: int) -> None:
"""Assume the level index passed in is the furthest level you have access to in the level order."""
for i in range(0, 8):
if i >= level - 1:
Expand All @@ -2567,7 +2571,7 @@ def BlockCompletionOfLevelSet(settings: Settings, lockedLevels):
settings.BossBananas[i] = 1000


def Generate_Spoiler(spoiler):
def Generate_Spoiler(spoiler: Spoiler) -> Tuple[None, Spoiler]:
"""Generate a complete spoiler based on input settings."""
# Init logic vars with settings
if spoiler.settings.wrinkly_hints == WrinklyHints.fixed_racing:
Expand Down Expand Up @@ -2618,7 +2622,7 @@ def Generate_Spoiler(spoiler):
return patch_data, spoiler


def ShuffleMisc(spoiler):
def ShuffleMisc(spoiler: Spoiler) -> None:
"""Shuffle miscellaneous objects outside of main fill algorithm, including Kasplats, Bonus barrels, and bananaport warps."""
resetCustomLocations()
# T&S and Wrinkly Door Shuffle
Expand Down Expand Up @@ -2683,7 +2687,7 @@ def ShuffleMisc(spoiler):
spoiler.settings.update_valid_locations(spoiler)


def ValidateFixedHints(settings):
def ValidateFixedHints(settings: Settings) -> None:
"""Check for some known incompatibilities with the Fixed hint system ASAP so we don't waste time genning this seed."""
if settings.win_condition != WinCondition.beat_krool:
raise Ex.SettingsIncompatibleException("Alternate win conditions will not work with Fixed hints.")
Expand Down
11 changes: 7 additions & 4 deletions randomizer/Lists/Item.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
from randomizer.Enums.Levels import Levels
from randomizer.Enums.MoveTypes import MoveTypes
from randomizer.Enums.Types import Types
from typing import List, Optional, Union


class Item:
"""Stores information about an item."""

def __init__(self, name, playthrough, type, kong, data=None):
def __init__(
self, name: str, playthrough: bool, type: Types, kong: Kongs, data: Optional[Union[List[Levels], List[Union[MoveTypes, int]], List[Union[MoveTypes, str, int]], List[int]]] = None
) -> None:
"""Initialize with given parameters."""
if data is None:
data = []
Expand Down Expand Up @@ -39,7 +42,7 @@ def __init__(self, name, playthrough, type, kong, data=None):
self.flag = data[0]


def ItemFromKong(kong):
def ItemFromKong(kong: Kongs) -> Items:
"""Get the item representation of a Kong enum."""
if kong == Kongs.donkey:
return Items.Donkey
Expand All @@ -55,7 +58,7 @@ def ItemFromKong(kong):
return Items.NoItem


def NameFromKong(kong):
def NameFromKong(kong: Kongs) -> str:
"""Get the name of a kong from its Kong enum value."""
if kong == Kongs.donkey:
return "Donkey"
Expand All @@ -71,7 +74,7 @@ def NameFromKong(kong):
return "No Kong"


def KongFromItem(item):
def KongFromItem(item: Items) -> Kongs:
"""Get the Kong enum representation of a kong item."""
if item == Items.Donkey:
return Kongs.donkey
Expand Down
2 changes: 1 addition & 1 deletion randomizer/Lists/LevelInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class LevelInfo:
"""Class which stores some information about levels."""

def __init__(self, TransitionTo, TransitionFrom, KeyLocation, KeyItem):
def __init__(self, TransitionTo: Transitions, TransitionFrom: Transitions, KeyLocation: Locations, KeyItem: Items) -> None:
"""Initialize with given parameters."""
self.TransitionTo = TransitionTo
self.TransitionsFrom = TransitionFrom
Expand Down
2 changes: 1 addition & 1 deletion randomizer/Lists/Logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
class GlitchLogicItem:
"""Glitch Logic multiselector information."""

def __init__(self, name, tooltip=""):
def __init__(self, name: str, tooltip: str = "") -> None:
"""Initialize with given data."""
self.name = name
self.shorthand = name.lower().replace(" ", "_")
Expand Down
2 changes: 1 addition & 1 deletion randomizer/Lists/QoL.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
class QoLItem:
"""Quality of life multiselector information."""

def __init__(self, name, shift, tooltip=""):
def __init__(self, name: str, shift: int, tooltip: str = "") -> None:
"""Initialize with given data."""
self.name = name
self.shift = shift
Expand Down
5 changes: 3 additions & 2 deletions randomizer/Lists/WrinklyHints.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
from randomizer.Enums.Kongs import Kongs
from randomizer.Enums.Levels import Levels
from randomizer.Enums.WrinklyKong import WrinklyLocation
from typing import Any, List, Union


class HintLocation:
"""Hint object for Wrinkly hint data locations."""

def __init__(self, name, kong: Kongs, location: WrinklyLocation, hint, level: Levels, banned_keywords=[]):
def __init__(self, name: str, kong: Kongs, location: WrinklyLocation, hint: str, level: Levels, banned_keywords: List[Union[Any, str]] = []) -> None:
"""Create wrinkly hint object.
Args:
Expand Down Expand Up @@ -67,7 +68,7 @@ def __init__(self, name, kong: Kongs, location: WrinklyLocation, hint, level: Le
]


def ClearHintMessages():
def ClearHintMessages() -> None:
"""Reset the hint message for all hints."""
for hint in hints:
if hint.name != "First Time Talk":
Expand Down
Loading

0 comments on commit 070cf13

Please sign in to comment.