Hey all! I’m again with one other aspect venture I wished to make to apply lessons and attributes on Python by simulating Monopoly, my favourite board sport. I knew that if I wished to coach a neural internet to play it, I wanted a number of information simulating the sport’s state on every participant’s flip, so I did it.
I’ll drive you thru the code within the order it’s executed, however if you wish to see the order through which it was written, you possibly can see the complete code here.
First, there’s a fundamental perform that runs 3000 instances and whose solely attribute is the variety of gamers the sport can have. This perform:
def fundamental(n_players):#Creating gamers
gamers = []
for i in vary(n_players):
gamers.append(Participant(i,[]))
#Monopoly creating
monopoly = Monopoly(gamers)
whereas min([p.money for p in monopoly.players]) > 0:
monopoly.spherical(gamers)
winner = monopoly.outcomes.tail(n_players).groupby('player_number').max()['money'].sort_values(ascending=False).index[0]
return monopoly.outcomes.loc[(monopoly.results['player_number'] == winner) & (monopoly.outcomes["is_special_position"] == False)]
if __name__ == '__main__':
df = pd.DataFrame(
columns = ["player_number","last_position","dice","current_position","jail","is_special_position","money","properties","networth"
,"owned_properties_price","owned_properties_houses","rent_to_charge","percentage_of_owned_properties","railroads_owned"
,"properties_available","buy","money2","properties2","networth2","owned_properties_price2","owned_properties_houses2"
,"rent_to_charge2","percentage_of_owned_properties2","railroads_owned2","properties_available2"])
begin = time.time()
for _ in vary(3000):
df = pd.concat([df, main(3)], axis=0)
print(time.time() - begin)
print(len(df))
df.to_csv("outcomes.csv")
- Creates n Participant objects, with the identical attributes for all of them.
class Participant():def __init__(self, playerNumber: int, properties: checklist["Property"]) -> None:
self.playerNumber = playerNumber
self.properties = properties
self.cash = 2500
self.land_value = 0
self.place = 0
self.jail = False
self.railroads = 0
self.homes = 0
self.rent_to_charge = 0
- Creates a Monopoly object primarily based on the Participant objects. The init methodology of this class assigns the array of Gamers to a variable, creates a outcomes variable that will later assist us retailer the winner’s choice document, and converts all JSONs from the utils folder into Property objects
properties = [Property(**pm) for pm in getSquaresInfo()]
def getSquaresInfo():squaresInfo = [
{'squareId': 0, 'isSpecialSquare': True, 'owner': None, 'name': None, 'price': None, 'rent': None, 'rentWithHouses': None, 'costPerHouse': None, 'houses': 0}
,{'squareId': 1, 'isSpecialSquare': False, 'owner': None, 'name': 'Mexico', 'price': 50.0, 'rent': 5.0, 'rentWithHouses': [13.0, 26.0, 39.0, 52.0, 65.0], 'costPerHouse': 10.0, 'homes': 0}
]
class Property():
def __init__(self, **kwargs) -> None:
for ok,v in kwargs.gadgets():
setattr(self, ok, v)
- Calls the Monopoly.spherical() methodology till one participant will get out of cash
- Will get a winner primarily based on the utmost sum of money
- Returns a df csv with the earlier and precise state of the winner after a sure choice on every of their turns. This may assist to coach the NN by measuring the impression of their choice, a binary worth.
Now that we all know what occurs with the primary perform, it’s time to know what the .spherical() methodology does. Principally, the .spherical() methodology solely loops the .flip() methodology n(gamers) instances for every spherical, which does the next:
- Evaluates if the participant is in jail, whether it is, the flip is skipped and a document is added to the outcomes df. Every flip of the participant returns a df row that incorporates a Q desk, a binary choice, and a Q+1 desk. I’ll later present the desk and what it means. Every flip may mutate the sum of money, quantity of properties, homes of every property, hire, and many others.
- Rolls the cube and evaluates the brand new board place
cube = self.roll_dice()
participant.place = (participant.place + cube) % 40
3. Checks if the participant has accomplished a spherical and provides them $200 if they’ve.
if participant.place < lastPosition:
participant.cash += 200
4. Evaluates shock situations if they’ve fallen in a particular sq. of the board
if self.properties[player.position].isSpecialSquare == True: #Particular squares logic
#Jail ------------------------------->
if participant.place == 10:
participant.jail = Trueelif participant.place == 30:
participant.jail = True
participant.place = 10
#Probability Playing cards ----------------------->
if participant.place in (2,7,17,22,33,36):
participant.cash += random.selection(self.chanceCards)
#Taxes ------------------------------>
if participant.place == 4:
participant.cash -= 200
if participant.place in (12,29):
participant.cash -= 150
if participant.place == 38:
participant.cash -= 100
5. Checks if the participant is in a railroad sq., if they should pay, or in the event that they need to purchase it.
if participant.place in (5,15,25,35): #If place is a railroadif currentProperty.proprietor != participant: #If the proprietor of the railroad isn't the participant
if currentProperty.proprietor == None: #if nobody is the proprietor
if participant.cash > currentProperty.worth and selection:
currentProperty.proprietor = participant
participant.cash -= currentProperty.worth
participant.railroads += 1
else:
rentToPay = currentProperty.proprietor.railroads*50
currentProperty.proprietor.cash += rentToPay
participant.cash -= rentToPay
6. Checks if the participant is on their very own Property and desires so as to add a home to it.
if currentProperty.proprietor == participant: #Simulating the participant choice so as to add a home or many to the property
#For properties with lower than 5 home
#Solely is your simulated descition to purchase a home is True
#In case you have sufficient cash for homes
propertyHouses = currentProperty.homes
if (5 - propertyHouses) > 0 and (participant.cash > currentProperty.costPerHouse) and selection: currentProperty.homes += 1 #Replace quantity of homes on property
participant.cash -= currentProperty.costPerHouse #Pay for the homes
currentProperty.hire = currentProperty.rentWithHouses[currentProperty.houses -1] #Set hire to the value with n homes
7. If nobody is the proprietor, you should purchase the property.
if currentProperty.proprietor == None: #shopping for the property
if selection:
participant.cash -= currentProperty.worth #Pay for the property
currentProperty.proprietor = participant #Replace property proprietor
participant.properties.append(currentProperty) #Add property to participant's properties
8. Lastly, if the Property has an proprietor, you pay for the hire
else: #Paying hire to the proprietor
rentToPay = currentProperty.hire
participant.cash -= rentToPay
currentProperty.proprietor.cash += rentToPay
9. After every flip, a row is added to the ultimate df, in order that we are able to observe:
S(t) + A(t) = S(t+1)
Because of this for every flip I’m monitoring the precise state of the sport, their choice, and the state of the sport after their choice, hoping this could possibly be sufficient to coach the neural internet.
Keep tuned for half 2 and you’ll attain me by Medium, Github, or Linkedin you probably have any options/questions