├── extensions.json ├── setup.cfg ├── images ├── cancel.PNG ├── skip.png ├── spin.png ├── spin2.PNG ├── Capture.PNG ├── Capture2.PNG ├── jail-roll.png ├── megaheist.PNG ├── quickwins.PNG ├── taptoclaim.PNG ├── dailycollect.PNG ├── bank-heist-door.png ├── shutdown-marker.png ├── advertisement-close.png ├── community-chest-start.png ├── zz__quick-wins-exit.png ├── community-chest-collect.png └── quick-wins-tap-to-claim.png ├── requirements.txt ├── .github └── ISSUE_TEMPLATE │ ├── custom.md │ ├── feature_request.md │ └── bug_report.md ├── settings.json ├── CHANGELOG.md ├── main.py ├── mainV2.py └── README.md /extensions.json: -------------------------------------------------------------------------------- 1 | { "recommendations": ["ms-python.autopep8"] } 2 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [pep8] 2 | ignore = E402 3 | max-line-length = 180 4 | -------------------------------------------------------------------------------- /images/cancel.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/cancel.PNG -------------------------------------------------------------------------------- /images/skip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/skip.png -------------------------------------------------------------------------------- /images/spin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/spin.png -------------------------------------------------------------------------------- /images/spin2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/spin2.PNG -------------------------------------------------------------------------------- /images/Capture.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/Capture.PNG -------------------------------------------------------------------------------- /images/Capture2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/Capture2.PNG -------------------------------------------------------------------------------- /images/jail-roll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/jail-roll.png -------------------------------------------------------------------------------- /images/megaheist.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/megaheist.PNG -------------------------------------------------------------------------------- /images/quickwins.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/quickwins.PNG -------------------------------------------------------------------------------- /images/taptoclaim.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/taptoclaim.PNG -------------------------------------------------------------------------------- /images/dailycollect.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/dailycollect.PNG -------------------------------------------------------------------------------- /images/bank-heist-door.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/bank-heist-door.png -------------------------------------------------------------------------------- /images/shutdown-marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/shutdown-marker.png -------------------------------------------------------------------------------- /images/advertisement-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/advertisement-close.png -------------------------------------------------------------------------------- /images/community-chest-start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/community-chest-start.png -------------------------------------------------------------------------------- /images/zz__quick-wins-exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/zz__quick-wins-exit.png -------------------------------------------------------------------------------- /images/community-chest-collect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/community-chest-collect.png -------------------------------------------------------------------------------- /images/quick-wins-tap-to-claim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Krazalm/MonopolyGoBotCustomedited/HEAD/images/quick-wins-tap-to-claim.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pillow==9.3.0 2 | pyautogui==0.9.54 3 | pydirectinput==1.0.4 4 | pynput==1.7.6 5 | pyscreeze==0.1.29 6 | opencv-python==4.8.0.74 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.analysis.typeCheckingMode": "basic", 3 | "python.formatting.provider": "none", 4 | "[python]": { 5 | "editor.formatOnSave": true, 6 | "editor.defaultFormatter": "ms-python.autopep8" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ### Added 6 | mainV2.py 7 | - Customizable keybind functionality for toggling the bot on and off. 8 | - Support for inputting any character as the toggle key. 9 | 10 | ### Changed 11 | - Improved user input validation for toggle key. 12 | 13 | ## [1.0.0] - 2023-08-09 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import time 2 | import glob 3 | import pyscreeze 4 | import PIL.Image 5 | import pynput 6 | import pyautogui 7 | import logging 8 | 9 | # Configurable Parameters 10 | DELAY = 0 11 | CONFIDENCE = 0.75 12 | TOGGLE_KEY = pynput.keyboard.Key.f2 # Don't Change 13 | 14 | # Configure logging 15 | logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") 16 | logger = logging.getLogger(__name__) 17 | 18 | class MonopolyBot: 19 | def __init__(self) -> None: 20 | self.images_path = "images" 21 | self.cache = {} 22 | self.running = False 23 | 24 | # Initialize keyboard listener 25 | self.keyboard_listener = pynput.keyboard.Listener(on_press=self.on_key_press) 26 | self.keyboard_listener.start() 27 | 28 | self.print_banner() 29 | 30 | while True: 31 | if self.running: 32 | self.process_images() 33 | time.sleep(DELAY) 34 | 35 | def print_banner(self) -> None: 36 | print("Monopoly Go! Bot") 37 | print(f"\nPress {TOGGLE_KEY} to toggle running.\n") 38 | 39 | def on_key_press(self, key) -> None: 40 | if key == TOGGLE_KEY: 41 | self.toggle_running() 42 | 43 | def toggle_running(self) -> None: 44 | self.running = not self.running 45 | status = "Started" if self.running else "Stopped" 46 | print(f"{status}\n") 47 | logger.info(f"Bot {status.lower()}.") 48 | 49 | def process_images(self) -> None: 50 | for path in self.get_sorted_images(): 51 | if not self.running: 52 | break 53 | if self.process_image(path): 54 | break 55 | 56 | def get_sorted_images(self) -> list: 57 | return sorted(glob.glob(f"{self.images_path}/*.png")) 58 | 59 | def load_image(self, path: str) -> PIL.Image.Image: 60 | if path not in self.cache: 61 | self.cache[path] = PIL.Image.open(path) 62 | return self.cache[path] 63 | 64 | def find(self, image: PIL.Image.Image) -> pyscreeze.Point | None: 65 | result = pyautogui.locateCenterOnScreen(image, grayscale=True, confidence=CONFIDENCE) 66 | return result 67 | 68 | def process_image(self, path: str) -> bool: 69 | image = self.load_image(path) 70 | point = self.find(image) 71 | 72 | if point: 73 | print(f"Scanning for {path} -> ({point.x}, {point.y})") 74 | pyautogui.click(point) 75 | logger.info(f"Clicked on {path} at ({point.x}, {point.y}).") 76 | return True 77 | 78 | print(f"Scanning for {path}") 79 | return False 80 | 81 | def main(): 82 | MonopolyBot() 83 | 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /mainV2.py: -------------------------------------------------------------------------------- 1 | import time 2 | import glob 3 | import pyscreeze 4 | import PIL.Image 5 | import pynput 6 | import pyautogui 7 | import logging 8 | 9 | # Configurable Parameters 10 | DELAY = 0 11 | CONFIDENCE = 0.75 12 | 13 | # Configure logging 14 | logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") 15 | logger = logging.getLogger(__name__) 16 | 17 | class MonopolyBot: 18 | def __init__(self, toggle_key) -> None: 19 | self.images_path = "images" 20 | self.cache = {} 21 | self.running = False 22 | 23 | if len(toggle_key) == 1: 24 | self.toggle_key = toggle_key 25 | else: 26 | raise ValueError("Toggle key must be a single character.") 27 | 28 | self.keyboard_listener = pynput.keyboard.Listener(on_press=self.on_key_press) 29 | self.keyboard_listener.start() 30 | 31 | self.print_banner() 32 | 33 | while True: 34 | if self.running: 35 | self.process_images() 36 | time.sleep(DELAY) 37 | 38 | def print_banner(self) -> None: 39 | print("Monopoly Go! Bot") 40 | print(f"\nPress '{self.toggle_key}' to toggle running.\n") 41 | 42 | def on_key_press(self, key) -> None: 43 | if hasattr(key, 'char') and key.char == self.toggle_key: 44 | self.toggle_running() 45 | 46 | def toggle_running(self) -> None: 47 | self.running = not self.running 48 | status = "Started" if self.running else "Stopped" 49 | print(f"{status}\n") 50 | logger.info(f"Bot {status.lower()}.") 51 | 52 | def process_images(self) -> None: 53 | for path in self.get_sorted_images(): 54 | if not self.running: 55 | break 56 | if self.process_image(path): 57 | break 58 | 59 | def get_sorted_images(self) -> list: 60 | return sorted(glob.glob(f"{self.images_path}/*.png")) 61 | 62 | def load_image(self, path: str) -> PIL.Image.Image: 63 | if path not in self.cache: 64 | self.cache[path] = PIL.Image.open(path) 65 | return self.cache[path] 66 | 67 | def find(self, image: PIL.Image.Image) -> pyscreeze.Point | None: 68 | result = pyautogui.locateCenterOnScreen(image, grayscale=True, confidence=CONFIDENCE) 69 | return result 70 | 71 | def process_image(self, path: str) -> bool: 72 | image = self.load_image(path) 73 | point = self.find(image) 74 | 75 | if point: 76 | print(f"Scanning for {path} -> ({point.x}, {point.y})") 77 | pyautogui.click(point) 78 | logger.info(f"Clicked on {path} at ({point.x}, {point.y}).") 79 | return True 80 | 81 | print(f"Scanning for {path}") 82 | return False 83 | 84 | def main(): 85 | while True: 86 | toggle_key = input("Enter the single character you want to use as the toggle key: ") 87 | if len(toggle_key) == 1: 88 | break 89 | else: 90 | print("Invalid input. Please enter a single character.") 91 | 92 | MonopolyBot(toggle_key) 93 | 94 | if __name__ == "__main__": 95 | main() 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Monopoly Go! Bot 2 | 3 | **Automate gameplay in the Monopoly Go! online game using this Python bot with image recognition capabilities.** 4 | 5 | [DEMO](https://youtu.be/-MjjCc4hriI) 6 | 7 | 8 | 9 | ## Table of Contents 10 | 11 | - [Features](#features) 12 | - [Usage](#usage) 13 | - [Configuration](#configuration) 14 | - [Disclaimer](#disclaimer) 15 | - [Credits](#credits) 16 | - [Differences](#differences) 17 | - [ChangeLog](#changeLog) 18 | 19 | ## Features 20 | 21 | - Toggle bot operation using a designated toggle key (default: F2). 22 | - Automatically scan and interact with predefined in-game elements. 23 | - Utilizes PyScreeze and PyAutoGUI for image recognition and interaction. 24 | - mainV2.py Customizable keybind functionality for toggling the bot on and off. Support for inputting any character as the toggle key. 25 | 26 | 27 | ## Usage 28 | 29 | 1. **Clone or Download:** 30 | Clone or download this repository to your local machine. 31 | 32 | 2. **Install Dependencies:** 33 | Install the required Python libraries if not already installed: 34 | 35 | ```sh 36 | pip install pynput pyautogui pillow pyscreeze opencv-python 37 | ``` 38 | Prepare Screenshots: 39 | Place screenshots of the game elements in the images folder. 40 | 41 | Configure: 42 | Adjust configurable parameters in the script, if needed (e.g., DELAY, CONFIDENCE, TOGGLE_KEY). 43 | 44 | Run the Bot: 45 | Open a terminal and navigate to the repository folder. Run the script: 46 | 47 | ```sh 48 | python main.py 49 | ``` 50 | Toggle Bot: 51 | Press the toggle key (F2) to start or stop the bot. 52 | 53 | ## Configuration 54 | DELAY: The delay (in seconds) between bot cycles. 55 | CONFIDENCE: The confidence level for image recognition. 56 | TOGGLE_KEY: The key used to start and stop the bot (default: F2). 57 | 58 | ## Disclaimer: 59 | Use responsibly. Please be aware that automating gameplay using this bot may violate the terms of service of the game. This bot is intended for educational and personal use. The developer of this bot assumes no responsibility for any consequences arising from its usage. 60 | 61 | 62 | 63 | ## Credits: 64 | This project is based on the original work by Lewis Gibson. We express our gratitude for their contribution. 65 | https://github.com/lewisgibson 66 | https://github.com/lewisgibson/monopoly-go-bot 67 | 68 | 69 | 70 | 71 | ## Differences from the original work by Lewis Gibson: 72 | 73 | - Implements a class named `MonopolyBot`. 74 | - Uses a continuous loop to process images only when the bot is running. 75 | - Toggles the bot's running status using a specified key (F2) and `pynput.keyboard`. 76 | - Utilizes structured logging to print status messages. 77 | - Obtains sorted image files using a method for image searching. 78 | - Processes images only when the bot is running. 79 | - Uses a class-wide cache for loaded images. 80 | - Offers a more organized and modular design for enhanced maintainability. 81 | 82 | ## ChangeLog 83 | 84 | All notable changes to this project will be documented in this file. 85 | 86 | Added mainV2.py 87 | - Customizable keybind functionality for toggling the bot on and off. 88 | - Support for inputting any character as the toggle key. 89 | 90 | Changed 91 | - Improved user input validation for toggle key. 92 | [1.0.0] - 2023-08-09 93 | --------------------------------------------------------------------------------