pykworldsim 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pykworldsim-0.1.0/LICENSE +21 -0
- pykworldsim-0.1.0/PKG-INFO +153 -0
- pykworldsim-0.1.0/README.md +117 -0
- pykworldsim-0.1.0/pykworldsim/__init__.py +10 -0
- pykworldsim-0.1.0/pykworldsim/event.py +28 -0
- pykworldsim-0.1.0/pykworldsim/goal.py +34 -0
- pykworldsim-0.1.0/pykworldsim/job.py +34 -0
- pykworldsim-0.1.0/pykworldsim/location.py +31 -0
- pykworldsim-0.1.0/pykworldsim/person.py +468 -0
- pykworldsim-0.1.0/pykworldsim/relationship.py +97 -0
- pykworldsim-0.1.0/pykworldsim/report.py +101 -0
- pykworldsim-0.1.0/pykworldsim/world.py +391 -0
- pykworldsim-0.1.0/pykworldsim.egg-info/PKG-INFO +153 -0
- pykworldsim-0.1.0/pykworldsim.egg-info/SOURCES.txt +16 -0
- pykworldsim-0.1.0/pykworldsim.egg-info/dependency_links.txt +1 -0
- pykworldsim-0.1.0/pykworldsim.egg-info/top_level.txt +3 -0
- pykworldsim-0.1.0/pyproject.toml +30 -0
- pykworldsim-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kairav Dutta
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pykworldsim
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A python library that simulates a world with people, relationships, and cities
|
|
5
|
+
Author-email: Kairav Dutta <kairavdutta@gmail.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Kairav Dutta
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
Project-URL: Homepage, https://github.com/yourusername/pykworldsim
|
|
28
|
+
Keywords: simulation,world,ai,people,relationships
|
|
29
|
+
Classifier: Programming Language :: Python :: 3
|
|
30
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
31
|
+
Classifier: Operating System :: OS Independent
|
|
32
|
+
Requires-Python: >=3.8
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
License-File: LICENSE
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# 🌍 PyKWorldSim
|
|
38
|
+
|
|
39
|
+
> A lightweight Python simulation engine for modeling **people, relationships, cities, and dynamic worlds**.
|
|
40
|
+
|
|
41
|
+
PyKWorldSim provides a modular framework to simulate interactions between entities such as individuals, locations, jobs, and events — making it useful for experiments in **AI, social simulations, and system modeling**.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 🚀 Features
|
|
46
|
+
|
|
47
|
+
- 👤 **Person system** — create and manage individuals
|
|
48
|
+
- 🤝 **Relationships** — model connections between people
|
|
49
|
+
- 🏙️ **Locations & cities** — simulate environments
|
|
50
|
+
- 💼 **Jobs & roles** — assign occupations
|
|
51
|
+
- 🎯 **Goals** — define motivations and behaviors
|
|
52
|
+
- 📅 **Events** — simulate time-based interactions
|
|
53
|
+
- 📊 **Reports** — analyze simulation outcomes
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 📦 Installation
|
|
58
|
+
|
|
59
|
+
### From PyPI (after publishing)
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install pykworldsim
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### For local development
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install .
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 🧠 Basic Usage
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from pykworldsim.world import World
|
|
77
|
+
from pykworldsim.person import Person
|
|
78
|
+
|
|
79
|
+
# Create world
|
|
80
|
+
world = World()
|
|
81
|
+
|
|
82
|
+
# Create people
|
|
83
|
+
alice = Person(Name="Alice")
|
|
84
|
+
bob = Person(Name="Bob")
|
|
85
|
+
|
|
86
|
+
# Add people to the world
|
|
87
|
+
world.addPerson(alice)
|
|
88
|
+
world.addPerson(bob)
|
|
89
|
+
|
|
90
|
+
# Run simulation step (example)
|
|
91
|
+
world.Simulate()
|
|
92
|
+
|
|
93
|
+
# Generate report
|
|
94
|
+
report = world.generate_report()
|
|
95
|
+
print(report)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 📁 Project Structure
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
pykworldsim/
|
|
104
|
+
│
|
|
105
|
+
├── pykworldsim/
|
|
106
|
+
│ ├── world.py
|
|
107
|
+
│ ├── person.py
|
|
108
|
+
│ ├── relationship.py
|
|
109
|
+
│ ├── goal.py
|
|
110
|
+
│ ├── event.py
|
|
111
|
+
│ ├── job.py
|
|
112
|
+
│ ├── location.py
|
|
113
|
+
│ └── report.py
|
|
114
|
+
│
|
|
115
|
+
├── pyproject.toml
|
|
116
|
+
├── README.md
|
|
117
|
+
└── LICENSE
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## ⚙️ Requirements
|
|
123
|
+
|
|
124
|
+
- Python 3.8+
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
## 📌 Use Cases
|
|
130
|
+
|
|
131
|
+
- AI simulations
|
|
132
|
+
- Social behavior modeling
|
|
133
|
+
- Game prototyping
|
|
134
|
+
- Agent-based systems
|
|
135
|
+
- Experimental world-building
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 📜 License
|
|
140
|
+
|
|
141
|
+
This project is licensed under the MIT License.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 👤 Author
|
|
146
|
+
|
|
147
|
+
**Kairav Dutta**
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## ⭐ Contributing
|
|
152
|
+
|
|
153
|
+
Contributions, issues, and feature requests are welcome and appreciated!
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# 🌍 PyKWorldSim
|
|
2
|
+
|
|
3
|
+
> A lightweight Python simulation engine for modeling **people, relationships, cities, and dynamic worlds**.
|
|
4
|
+
|
|
5
|
+
PyKWorldSim provides a modular framework to simulate interactions between entities such as individuals, locations, jobs, and events — making it useful for experiments in **AI, social simulations, and system modeling**.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🚀 Features
|
|
10
|
+
|
|
11
|
+
- 👤 **Person system** — create and manage individuals
|
|
12
|
+
- 🤝 **Relationships** — model connections between people
|
|
13
|
+
- 🏙️ **Locations & cities** — simulate environments
|
|
14
|
+
- 💼 **Jobs & roles** — assign occupations
|
|
15
|
+
- 🎯 **Goals** — define motivations and behaviors
|
|
16
|
+
- 📅 **Events** — simulate time-based interactions
|
|
17
|
+
- 📊 **Reports** — analyze simulation outcomes
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 📦 Installation
|
|
22
|
+
|
|
23
|
+
### From PyPI (after publishing)
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install pykworldsim
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### For local development
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install .
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 🧠 Basic Usage
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from pykworldsim.world import World
|
|
41
|
+
from pykworldsim.person import Person
|
|
42
|
+
|
|
43
|
+
# Create world
|
|
44
|
+
world = World()
|
|
45
|
+
|
|
46
|
+
# Create people
|
|
47
|
+
alice = Person(Name="Alice")
|
|
48
|
+
bob = Person(Name="Bob")
|
|
49
|
+
|
|
50
|
+
# Add people to the world
|
|
51
|
+
world.addPerson(alice)
|
|
52
|
+
world.addPerson(bob)
|
|
53
|
+
|
|
54
|
+
# Run simulation step (example)
|
|
55
|
+
world.Simulate()
|
|
56
|
+
|
|
57
|
+
# Generate report
|
|
58
|
+
report = world.generate_report()
|
|
59
|
+
print(report)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 📁 Project Structure
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
pykworldsim/
|
|
68
|
+
│
|
|
69
|
+
├── pykworldsim/
|
|
70
|
+
│ ├── world.py
|
|
71
|
+
│ ├── person.py
|
|
72
|
+
│ ├── relationship.py
|
|
73
|
+
│ ├── goal.py
|
|
74
|
+
│ ├── event.py
|
|
75
|
+
│ ├── job.py
|
|
76
|
+
│ ├── location.py
|
|
77
|
+
│ └── report.py
|
|
78
|
+
│
|
|
79
|
+
├── pyproject.toml
|
|
80
|
+
├── README.md
|
|
81
|
+
└── LICENSE
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## ⚙️ Requirements
|
|
87
|
+
|
|
88
|
+
- Python 3.8+
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## 📌 Use Cases
|
|
94
|
+
|
|
95
|
+
- AI simulations
|
|
96
|
+
- Social behavior modeling
|
|
97
|
+
- Game prototyping
|
|
98
|
+
- Agent-based systems
|
|
99
|
+
- Experimental world-building
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 📜 License
|
|
104
|
+
|
|
105
|
+
This project is licensed under the MIT License.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 👤 Author
|
|
110
|
+
|
|
111
|
+
**Kairav Dutta**
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## ⭐ Contributing
|
|
116
|
+
|
|
117
|
+
Contributions, issues, and feature requests are welcome and appreciated!
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from .world import World
|
|
2
|
+
from .person import Person
|
|
3
|
+
from .relationship import Relationship
|
|
4
|
+
from .goal import Goal
|
|
5
|
+
from .event import Event
|
|
6
|
+
from .location import Location
|
|
7
|
+
from .job import Job
|
|
8
|
+
|
|
9
|
+
__all__ = ["World", "Person", "Relationship", "Goal", "Event", "Location", "Job"]
|
|
10
|
+
__version__ = "1.0.0"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import random
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import Optional, Callable
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass
|
|
7
|
+
class Event:
|
|
8
|
+
"""A world event that fires probabilistically or on demand."""
|
|
9
|
+
Name: str
|
|
10
|
+
Probability: float = 0.05 # per-year probability
|
|
11
|
+
Effect: Optional[Callable] = None # fn(world, year) → None
|
|
12
|
+
Description: str = ""
|
|
13
|
+
IsGlobal: bool = True # True = affects everyone; False = individual
|
|
14
|
+
|
|
15
|
+
def ShouldTrigger(self) -> bool:
|
|
16
|
+
return random.random() < self.Probability
|
|
17
|
+
|
|
18
|
+
def Fire(self, World, Year: int):
|
|
19
|
+
Msg = f"[Year {Year}] EVENT: {self.Name}"
|
|
20
|
+
if self.Description:
|
|
21
|
+
Msg += f" — {self.Description}"
|
|
22
|
+
World.Log.append(Msg)
|
|
23
|
+
if self.Effect:
|
|
24
|
+
self.Effect(World, Year)
|
|
25
|
+
|
|
26
|
+
def __str__(self):
|
|
27
|
+
Scope = "Global" if self.IsGlobal else "Local"
|
|
28
|
+
return f"Event: {self.Name} ({self.Probability*100:.1f}%) - {Scope}"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class Goal:
|
|
2
|
+
"""Represents a personal goal with a type and priority."""
|
|
3
|
+
|
|
4
|
+
ValidGoalTypes = {
|
|
5
|
+
"GetJob", "GetPromotion", "MakeFriends", "FindPartner",
|
|
6
|
+
"ImproveSkills", "EarnMoney", "IncreaseStatus", "MoveCity",
|
|
7
|
+
"StartFamily", "BuildBusiness", "SocializeMore", "FindPurpose"
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
def __init__(self, GoalType: str, Priority: float = 0.5):
|
|
11
|
+
if GoalType not in self.ValidGoalTypes:
|
|
12
|
+
raise ValueError(f"GoalType '{GoalType}' is not valid. Choose from: {sorted(self.ValidGoalTypes)}")
|
|
13
|
+
if not (0.0 <= Priority <= 1.0):
|
|
14
|
+
raise ValueError("Priority must be between 0.0 and 1.0")
|
|
15
|
+
self.GoalType = GoalType
|
|
16
|
+
self.Priority = Priority
|
|
17
|
+
self.Progress = 0.0
|
|
18
|
+
self.Achieved = False
|
|
19
|
+
self.YearAchieved = None
|
|
20
|
+
|
|
21
|
+
def UpdateProgress(self, Delta: float):
|
|
22
|
+
self.Progress = max(0.0, min(1.0, self.Progress + Delta))
|
|
23
|
+
if self.Progress >= 1.0 and not self.Achieved:
|
|
24
|
+
self.Achieved = True
|
|
25
|
+
return True
|
|
26
|
+
return False
|
|
27
|
+
|
|
28
|
+
def __repr__(self):
|
|
29
|
+
Status = "✓" if self.Achieved else f"{self.Progress:.0%}"
|
|
30
|
+
return f"Goal({self.GoalType}, priority={self.Priority:.1f}, progress={Status})"
|
|
31
|
+
|
|
32
|
+
def __str__(self):
|
|
33
|
+
Status = "Achieved" if self.Achieved else f"{self.Progress:.0%} Complete"
|
|
34
|
+
return f"Goal: {self.GoalType} ({Status})"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class Job:
|
|
2
|
+
"""A job that can be held by a person."""
|
|
3
|
+
|
|
4
|
+
def __init__(self, Role: str, Salary: float = 50000,
|
|
5
|
+
Prestige: float = 0.5, StressLevel: float = 0.4,
|
|
6
|
+
SkillRequired: float = 0.3, Industry: str = "general"):
|
|
7
|
+
self.Role = Role
|
|
8
|
+
self.Salary = Salary
|
|
9
|
+
self.Prestige = max(0.0, min(1.0, Prestige))
|
|
10
|
+
self.StressLevel = max(0.0, min(1.0, StressLevel))
|
|
11
|
+
self.SkillRequired = max(0.0, min(1.0, SkillRequired))
|
|
12
|
+
self.Industry = Industry
|
|
13
|
+
self.Holder = None
|
|
14
|
+
self.Location = None
|
|
15
|
+
|
|
16
|
+
def IsAvailable(self) -> bool:
|
|
17
|
+
return self.Holder is None
|
|
18
|
+
|
|
19
|
+
def Assign(self, Person):
|
|
20
|
+
self.Holder = Person
|
|
21
|
+
|
|
22
|
+
def Vacate(self):
|
|
23
|
+
self.Holder = None
|
|
24
|
+
|
|
25
|
+
def AnnualSalary(self, Year: int = 0) -> float:
|
|
26
|
+
"""Salary grows slightly with experience."""
|
|
27
|
+
return self.Salary * (1.02 ** Year)
|
|
28
|
+
|
|
29
|
+
def __repr__(self):
|
|
30
|
+
Status = f"held by {self.Holder.Name}" if self.Holder else "available"
|
|
31
|
+
return f"Job({self.Role}, salary={self.Salary:,.0f}, {Status})"
|
|
32
|
+
|
|
33
|
+
def __str__(self):
|
|
34
|
+
return f"{self.Role} (${self.Salary:,.0f}/yr) - {'Available' if not self.Holder else f'Held by {self.Holder.Name}'}"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class Location:
|
|
2
|
+
"""A place in the world where people live, work, and interact."""
|
|
3
|
+
|
|
4
|
+
def __init__(self, Name: str, LocationType: str = "city",
|
|
5
|
+
OpportunityLevel: float = 0.5,
|
|
6
|
+
CostOfLiving: float = 0.5,
|
|
7
|
+
PopulationDensity: float = 0.5):
|
|
8
|
+
self.Name = Name
|
|
9
|
+
self.LocationType = LocationType # city, suburb, rural, campus
|
|
10
|
+
self.OpportunityLevel = max(0.0, min(1.0, OpportunityLevel))
|
|
11
|
+
self.CostOfLiving = max(0.0, min(1.0, CostOfLiving))
|
|
12
|
+
self.PopulationDensity = max(0.0, min(1.0, PopulationDensity))
|
|
13
|
+
self.Residents: list = []
|
|
14
|
+
self.Jobs: list = []
|
|
15
|
+
|
|
16
|
+
def AddResident(self, Person):
|
|
17
|
+
if Person not in self.Residents:
|
|
18
|
+
self.Residents.append(Person)
|
|
19
|
+
|
|
20
|
+
def RemoveResident(self, Person):
|
|
21
|
+
if Person in self.Residents:
|
|
22
|
+
self.Residents.remove(Person)
|
|
23
|
+
|
|
24
|
+
def AddJob(self, Job):
|
|
25
|
+
self.Jobs.append(Job)
|
|
26
|
+
|
|
27
|
+
def __repr__(self):
|
|
28
|
+
return f"Location({self.Name}, type={self.LocationType}, residents={len(self.Residents)})"
|
|
29
|
+
|
|
30
|
+
def __str__(self):
|
|
31
|
+
return f"{self.Name} ({self.LocationType.title()}) - Population: {len(self.Residents)}"
|