Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/mukybaby/Simple-Shop-Sim/llms.txt

Use this file to discover all available pages before exploring further.

All game logic lives in res/shop.py. This page documents the public interface of each class and the make_customers() helper function that seeds every in-game day with a fresh roster of customers.

Class: Item

Represents a single product stocked in the shop.
Item(name: str, price: int, stock: int)
name
string
required
The display name of the item — for example "Apple", "Bread", or "Potion". Used in all printed output and customer-want matching.
price
int
required
The base sale price in game currency. This value is mutable — bargaining mechanics in main.py can increase or decrease it during a customer interaction.
stock
int
required
The quantity currently available in the shop. Decremented by Customer.buy() on a successful purchase and incremented by Shop.restock().

Attributes

AttributeTypeDescription
namestrDisplay name of the item.
priceintBase sale price in game currency (mutable).
stockintNumber of units currently available in the shop.

Class: Customer

Represents a customer who visits the shop on a given day. On construction the customer immediately scans the shop’s inventory to locate their desired item via select_item().
Customer(name: str, budget: int, wants: Item, bargin: float, shop: Shop)
name
string
required
The customer’s display name. Printed throughout the shopping interaction (e.g. "Liam Johnson wants to buy Apple for 5").
budget
int
required
The maximum amount the customer is willing to spend. Generated randomly between 17 and 286 by make_customers(). A customer will not buy an item priced above their budget.
wants
Item
required
The specific Item instance the customer is trying to purchase. Chosen randomly from the shop’s inventory by make_customers().
bargin
float
required
The customer’s bargain threshold, in the range 0.0100.0. A lower value means the customer is harder to bargain with — see bargin_with() for details.
shop
Shop
required
The Shop instance. Passed to select_item() at construction time so the customer can verify their desired item is actually in stock and affordable before their turn begins.

Methods

buy(i: Item, shop: Shop) -> None

Attempts to complete a purchase. The transaction succeeds only when all of the following conditions are met:
  • i == self.wants — the item offered matches what the customer wants.
  • i.stock > 0 — at least one unit is in stock.
  • self.budget >= i.price — the customer can afford the current price.
  • i in shop.inventory — the item is listed in the shop’s inventory.
On success, i.stock is decremented by 1 and self.budget is decremented by i.price. self.selected_item is set to None. On failure, an error message is printed:
Error: <name> cannot buy <item>.

bargin_with(chance: float) -> bool

Returns True if self.bargin <= chance, otherwise False. The caller (main.py) passes a random.uniform(0, 100) value as chance. Customers with a lower bargin value are easier to successfully bargain with — their threshold is met more often by a random roll.
chance = random.uniform(0, 100)
if customer.bargin_with(chance):
    # Bargain succeeded — apply price markup

Class: Shop

The central game object. Tracks inventory, cash, day number, and the queue of customers currently in the store.
Shop(name: str, inventory: list[tuple[Item, int]], cash: int)
The inventory parameter type hint in source is list[tuple[Item, int]], but the constructor immediately reassigns it as self.inventory: list[Item]. In practice, main.py always passes an empty list [] and appends plain Item objects afterwards — so the tuple hint is misleading. Treat inventory as list[Item] at runtime.
name
string
required
The display name of the shop, entered by the player at game start.
inventory
list[tuple[Item, int]]
required
The starting inventory. The type hint in source is list[tuple[Item, int]], but at runtime main.py passes [] and appends Item objects directly — see the note above.
cash
int
required
Starting cash balance in game currency. main.py initialises this to 100.

Attributes

AttributeTypeDescription
namestrDisplay name of the shop.
inventorylist[Item]All Item objects currently stocked.
cashintCurrent cash balance. Reduced by rent each day and by restock costs.
dayintCurrent day number. Starts at 1, incremented by end_day().
openboolWhether the shop is currently open. Starts False.
customers_in_storelist[Customer]Queue of customers waiting to be served today.

Methods

restock(item: Item, quantity: int) -> None

Finds item in self.inventory and adds quantity to its stock. If the item is not present in inventory, a warning is printed:
"<item.name>" is not in invotory
The caller is responsible for deducting the restock cost from shop.cash before calling this method. In main.py, the deduction is performed as:
shop.cash -= stock_choice * item.price
shop.restock(shop.inventory[int(choice) - 1], stock_choice)

open_for_day(customers: list[Customer]) -> None

Sets self.open = True and appends every Customer in customers to self.customers_in_store. Called automatically when the player chooses to open the shop from the main menu.

end_day(rent: int) -> None

Closes the shop for the current day:
  1. Sets self.open = False.
  2. Deducts rent from self.cash.
  3. Increments self.day by 1.
The rent value is calculated by main.py as shop.day * 10, so rent increases with each passing day.

Function: make_customers

Factory function that generates the full roster of customers for a given day.
make_customers(day: int, shop: Shop, customers_name: list[str]) -> list[Customer]
day
int
The current day number (from shop.day). Determines customer count: day × 3. Day 1 produces 3 customers, Day 2 produces 6, and so on.
shop
Shop
The active Shop instance. Used to select a random Item from shop.inventory for each customer’s wants attribute.
customers_name
list[str]
The full pool of candidate names loaded from res/customer_names.json. Names are sampled randomly to assign to each new customer.

Return value

A list[Customer] of length day × 3. Each customer is created with:
  • A name sampled from customers_name via random.choice(). The loop contains a uniqueness guard, but due to a bug the guard never triggers — see the Customization page for details. Duplicate names are possible.
  • A random budget between 17 and 286 (inclusive), via random.randint(17, 286).
  • A random wanted item chosen from shop.inventory via random.choice().
  • A random bargain threshold between 0.0 and 100.0 via random.uniform(0, 100).

Usage

main.py calls make_customers() inline when the player opens the shop for the day, passing the result directly to open_for_day():
shop.open_for_day(make_customers(shop.day, shop, customer_names))

Build docs developers (and LLMs) love