"""
Player.py - File for defining a Game class.
"""

import copy
import logging
import datetime
import textwrap
import pandas as pd
import numpy as np

from monopoly.Constants import TOTAL_MONEY, CARD_WIDTH, PROPERTY_INDX, PROPERTY_DEFS, INIT_CASH
from monopoly.Constants import GO, JAIL
from monopoly.Constants import ILLINOIS, ST_CHARLES, UTILITIES, RAILROADS, READING, BOARDWALK

from monopoly.Card import Card
from monopoly.Property import Property
from monopoly.Player import Player
from monopoly.Bank import Bank, FreeParking

# Create list of Property objects
PROPERTIES = [Property(**dict(zip(PROPERTY_INDX, p))) for p in PROPERTY_DEFS]

# Game Chance and Community Chest Cards
# Rule functin is called with a tuple of (player, game)
# pylint:disable=bad-whitespace
CHANCE_CARDS = [
    Card('Chance',                               'Advance to Go', lambda p, g, c: p.go_to_space(GO)),
    Card('Chance',                         'Advance to Illinois', lambda p, g, c: p.go_to_space(ILLINOIS)),
    Card('Chance',                'Advance to St. Charles Place', lambda p, g, c: p.go_to_space(ST_CHARLES)),
    Card('Chance',                  'Advance to Nearest Utility', lambda p, g, c: p.go_to_nearest(UTILITIES)),
    Card('Chance',                 'Advance to Nearest Railroad', lambda p, g, c: p.go_to_nearest(RAILROADS)),
    Card('Chance',                      'Bank pays you dividend', lambda p, g, c: p.add(50.0, g.bank)),
    Card('Chance',                        'Get out of Jail Free', lambda p, g, c: p.cards.append(c)),
    Card('Chance',                            'Go Back 3 Spaces', lambda p, g, c: p.go_to_space(p.position - 3)),
    Card('Chance',                                  'Go To Jail', lambda p, g, c: p.go_to_space(JAIL, pass_go=False, just_visiting=False)),
    Card('Chance',                        'Make General Repairs', lambda p, g, c: p.pay(25.0 * p.num_houses + 100.0 * p.num_hotels, g.freeparking)),
    Card('Chance',                                'Pay Poor Tax', lambda p, g, c: p.pay(15.0, g.freeparking)),
    Card('Chance',                 'Advance to Reading Railroad', lambda p, g, c: p.go_to_space(READING)),
    Card('Chance',                        'Advance to Boardwalk', lambda p, g, c: p.go_to_space(BOARDWALK)),
    Card('Chance', 'You have been elected Chairman of the Board', lambda p, g, c: map(p.pay, [50.0] * len(g.others(p)), g.others(p))),
    Card('Chance',                  'Your building loan matures', lambda p, g, c: p.add(150.0, g.bank)),
    Card('Chance',        'You have won a crossword competition', lambda p, g, c: p.add(100.0, g.bank))
]
COMMUNITY_CHEST_CARDS = [
    Card('Chest',                                 'Advance to Go', lambda p, g, c: p.go_to_space(GO)),
    Card('Chest',                      'Bank Error in Your Favor', lambda p, g, c: p.add(200.0, g.bank)),
    Card('Chest',                                'Doctor\'s fees', lambda p, g, c: p.pay(50.0, g.freeparking)),
    Card('Chest',                    'From Sale of Stock You Get', lambda p, g, c: p.add(50.0, g.bank)),
    Card('Chest',                          'Get out of Jail Free', lambda p, g, c: p.cards.append(c)),
    Card('Chest',                                    'Go To Jail', lambda p, g, c: p.go_to_space(JAIL, pass_go=False, just_visiting=False)),
    Card('Chest',                             'Grand Opera Night', lambda p, g, c: map(p.add, [50.0] * len(g.others(p)), g.others(p))),
    Card('Chest',                          'Holiday Fund Matures', lambda p, g, c: p.add(100.0, g.bank)),
    Card('Chest',                             'Income Tax Refund', lambda p, g, c: p.add(20.0, g.bank)),
    Card('Chest',                           'It is Your Birthday', lambda p, g, c: map(p.add, [10.0] * len(g.others(p)), g.others(p))),
    Card('Chest',                        'Life Insurance Matures', lambda p, g, c: p.add(100.0, g.bank)),