【解決方法】プレーヤーに選択式の質問に答えてもらいたいのですが、プレーヤーが質問に正しく答えた場合、残高に 100 ドルを受け取り、そうでない場合は 200 ドルを失います。


class LoaderSettings {
    constructor(param = {}) {
        this.loadTarget = param.loadTarget === undefined ? 'body' : param.loadTarget;
        this.gameDataURL = param.gameDataURL === undefined ? 'https://cdn.jsdelivr.net/gh/piriys/Monopoly.js@v1.0.1/gamedata.js' : param.gameDataURL;
        this.styleURL = param.styleURL === undefined ? 'https://cdn.jsdelivr.net/gh/piriys/Monopoly.js@v1.0.1/style.css' : param.styleURL;
    }
}
const Monopoly = {
    load: (param = {}) => {
        const loaderSettings = new LoaderSettings(param);
        console.clear();
        console.log(loaderSettings);

        // Load external files
        const styleDOM = document.createElement('link');
        styleDOM.setAttribute('rel', 'stylesheet');
        styleDOM.setAttribute('href', loaderSettings.styleURL);
        document.head.append(styleDOM);


        // TO DO: 
        // *Load game data here

        // Constants
        const settings = {
            goCollectAmount: 10,
            dieCount: 2,
            startingAmount: 500,
            movementStepDelay: 500,
            jailedTurn: 3,
            rentMultiplier: 2000, //For faster game
            taxMultiplier: 30 //For faster game
        };


        // Global
        let game;
        let board;
        let gameLoaderDOM;
        let gameDOM;

        document.addEventListener('DOMContentLoaded', () => {
            gameLoaderDOM = document.querySelector(loaderSettings.loadTarget);
            gameLoaderDOM.id = 'gameLoader';
            gameLoaderDOM.innerHTML = '';

            gameDOM = document.createElement('div');
            gameDOM.id = 'game';
            gameDOM.style.opacity = 0.0;

            const gameDataDOM = document.createElement('script');
            gameDataDOM.setAttribute('src', loaderSettings.gameDataURL);
            document.head.append(gameDataDOM);

            //Wait until data script is loaded
            gameDataDOM.addEventListener('load', () => {
                gameLoaderDOM.append(gameDOM);
                if (typeof (gameLoaderDOM) !== 'undefined' && gameLoaderDOM !== null) {
                    if (typeof (GameData) !== 'undefined' && GameData !== null) {
                        GameHelpers.setupGame();
                        GameHelpers.setupPlayers();
                        GameHelpers.setupEventListeners();
                        game.start();
                        game.currentPlayer.currentSpace.updateSpaceDetailDisplay();

                        window.setTimeout(() => {
                            GameHelpers.resizeBoard();
                            gameDOM.style.opacity = '';
                        }, 1000);
                    } else {
                        throw 'Game data not found.';
                    }
                } else {
                    throw 'Load target not found.';
                }
            });
        }, false);


        // Classes for helpers
        class Vector3D {
            constructor(x = 0, y = 0, z = 0) {
                this.x = x;
                this.y = y;
                this.z = z;
            }
        }

        class Option {
            constructor(name = 'accept', text = 'Ok') {
                this.name = name;
                this.text = text;
            }
        }

        // Helpers
        class MathHelpers {
            static randomInt(min, max) {
                return Math.floor(Math.random() * (max - min + 1)) + min;
            }
        }

        class UIHelpers {
            static menu(player, message, options = [new Option()], icon = '') {
                const buttons = new Map();
                return buttons;
            }
            static notice(player, message, icon) {
                board.inputDisplay.innerHTML = '';
                const header = document.createElement('h2');
                header.innerText = `${player.name}: ${message}`;
                board.inputDisplay.append(header);

                if (icon !== undefined) {
                    const dialogIcon = document.createElement('div');
                    dialogIcon.className = 'dialogIcon';
                    dialogIcon.innerText = icon;
                    board.inputDisplay.append(dialogIcon);
                }
            }
            static dialog(player, message, options = [new Option()], icon = '') {
                const buttons = new Map();

                if (icon === '') {
                    icon = player.icon;
                }

                board.inputDisplay.innerHTML = '';
                const header = document.createElement('h2');
                header.innerText = `${player.name}: ${message}`;
                board.inputDisplay.append(header);

                const dialogIcon = document.createElement('div');
                dialogIcon.className = 'dialogIcon';
                dialogIcon.innerText = icon;
                board.inputDisplay.append(dialogIcon);

                options.forEach((option) => {
                    const button = document.createElement('button');
                    button.innerText = option.text;
                    board.inputDisplay.append(button);
                    buttons.set(option.name, button);
                });

                return buttons;
            }
            static spaceDetail(space) {
                board.spaceDetailDisplay.innerHTML = '';

                const header = document.createElement('h2');
                if (space !== undefined) {
                    header.innerText = `${space.name}`;
                } else {
                    header.innerText = '[HOVER SPACE TO SEE DETAILS]';
                }
                board.spaceDetailDisplay.append(header);
            }
           
            static rollDice(player) {
                
                const message = `${player.name}'s Turn`;
                const button = this.dialog(player, message, [new Option('accept', 'Roll Dice')]).get('accept');

                return button;
            }

            static payTax(player, tax) {
                console.log(tax);
                const message = `Pay ${tax.name}`;
                const buttonText = `Pay \$${tax.amount}${settings.taxMultiplier !== 1 ? ` (x${settings.taxMultiplier})` : ''}`;
                const button = this.dialog(player, message, [new Option('accept', buttonText)], '').get('accept');

                return button;
            }

            static buyProperty(player, property) {
                const message = `Buy ${property.name}`;
                const options = [];
                options.push(new Option('accept', `Buy for \$${property.price}`));
                options.push(new Option('decline', 'Cancel'));

                const buttons = this.dialog(player, message, options);

                return buttons;
            }

            static upgradeProperty(player, property) {
                const message = `Upgrade ${property.name}`;
                const options = [];
                options.push(new Option('accept', `Upgrade for \$${property.currentUpgradeCost}`));
                options.push(new Option('decline', 'Cancel'));

                const buttons = this.dialog(player, message, options);

                return buttons;
            }

            static payRent(player, property) {
                const message = `Rent Due at ${property.name} to ${property.owner.name}`;
                const buttonText = `Pay \$${property.calculatedRent}${settings.rentMultiplier !== 1 ? ` ` : ''} to ${property.owner.name}`;
                const button = this.dialog(player, message, [new Option('accept', buttonText)]).get('accept');

                return button;
            }
        }


        // Game Assets
        class GameAsset {
            constructor(param) {
                this.transform = {
                    scale: 0,
                    rotate: new Vector3D(),
                    translate: new Vector3D(),
                };
            }
        }

        class Board extends GameAsset {
            constructor(param) {
                super(param);
                this.boardLayer;
                this.pieceLayer;
            }

            setup() {
                gameDOM.innerHTML = '';
                this.boardLayer = document.createElement('div');
                this.boardLayer.id = 'boardLayer';
                gameDOM.append(this.boardLayer);

                this.pieceLayer = document.createElement('div');
                this.pieceLayer.id = 'pieceLayer';
                gameDOM.append(this.pieceLayer);
            }
        }

        class MonopolyBoard extends Board {
            constructor(param) {
                super(param);

                this.statsDisplay;
                this.inputDisplay;
                this.spaceDetailDisplay;
            }
            setup() {
                super.setup();

                this.statsDisplay = document.createElement('div');
                this.statsDisplay.id = 'stats';
                this.statsDisplay.className = 'hud';
                this.boardLayer.append(this.statsDisplay);

                this.inputDisplay = document.createElement('div');
                this.inputDisplay.id = 'input';
                this.inputDisplay.className = 'hud';
                this.boardLayer.append(this.inputDisplay);

                this.spaceDetailDisplay = document.createElement('div');
                this.spaceDetailDisplay.id = 'spaceDetail';
                this.spaceDetailDisplay.className = 'hud';
                this.boardLayer.append(this.spaceDetailDisplay);

                this.settingsDisplay = document.createElement('div');
                this.settingsDisplay.id = 'settings';
                this.settingsDisplay.className = 'hud';

                const logo = document.createElement('h1');
                logo.className = 'logo';
                logo.innerText = 'MONOPOLY';
                this.settingsDisplay.append(logo);
                this.boardLayer.append(this.settingsDisplay);
            }
        }

        class Player extends GameAsset {
            constructor(param) {
                super(param);
                this.currentSpace = undefined;

                // Monopoly only
                this.name = param.name;
                this.icon = param.icon;
                this.money = param.money;
                this.state = 'playing';
                this.stateTurn = 0;

                this.playerStatsWrapper = document.createElement('div');
                this.playerStatsWrapper.className = 'playerStats';

                this.playerIconDOM = document.createElement('div');
                this.playerIconDOM.className = 'playerIcon';
                this.playerStatsWrapper.append(this.playerIconDOM);

                this.playerTextStatsWrapper = document.createElement('div');
                this.playerTextStatsWrapper.className = 'playerTextStats';
                this.playerStatsWrapper.append(this.playerTextStatsWrapper);

                this.playerNameDOM = document.createElement('h3');
                this.playerNameDOM.className = 'playerName';
                this.playerTextStatsWrapper.append(this.playerNameDOM);

                this.playerMoneyDOM = document.createElement('div');
                this.playerMoneyDOM.className = 'playerMoney';
                this.playerTextStatsWrapper.append(this.playerMoneyDOM);

                this.playerSpaceDOM = document.createElement('div');
                this.playerSpaceDOM.className = 'playerSpace';
                this.playerTextStatsWrapper.append(this.playerSpaceDOM);

                this.playerStateDOM = document.createElement('div');
                this.playerStateDOM.className = 'playerState';
                this.playerTextStatsWrapper.append(this.playerStateDOM);

                board.statsDisplay.append(this.playerStatsWrapper);

                this.playerPieceDOM = document.createElement('div');
                this.playerPieceDOM.className = 'piece';
                this.playerPieceDOM.innerText = this.icon;
                board.pieceLayer.append(this.playerPieceDOM);
            }

            updateDisplay() {
                this.updateStatsDisplay();
                this.updatePiece();
                this.currentSpace.updateSpaceDetailDisplay();
            }

            updateStatsDisplay() {
                this.playerIconDOM.innerText = `${this.icon}`;
                this.playerNameDOM.innerText = `Player: ${this.name}`;
                this.playerMoneyDOM.innerText = `Money: ${this.money}`;
                this.playerStateDOM.innerText = `[${this.state.toUpperCase()}${this.state === 'playing' || this.state === 'bankrupt' ? '' : ` (${this.stateTurn})`}]`;
                if (this.state === 'bankrupt') {
                    this.playerStatsWrapper.filter = 'grayscale(100%)';
                }
            }

            updatePiece() {
                this.playerPieceDOM.style.left = `${(this.currentSpace.column - 1) / 11 * 100}%`;
                this.playerPieceDOM.style.top = `${(this.currentSpace.row - 1) / 11 * 100}%`;
            }


            moveTo(nameId = 'start', resolveSpace = true, collectPassGo = false) {
                if (game.spaceMap.has(nameId)) {
                    UIHelpers.notice(this, 'Moving...');
                    this.currentSpace = game.spaceMap.get(nameId);

                    console.log(`${this.name} moves to [${this.currentSpace.name}]!`);

                    window.setTimeout(() => {
                        if (resolveSpace) {
                            this.currentSpace.resolve(this);
                        }

                        this.updateDisplay();
                    }, settings.movementStepDelay);
                } else {
                    throw 'nameId not found.';
                }
            }

            moveForward(steps = 1, resolveSpace = true, collectPassGo = true) {
                // Assume steps > 0
                UIHelpers.notice(this, 'Moving...');
                this.playerPieceDOM.style.animation = `bouncePlayerPiece ${(settings.movementStepDelay / 1000) / 2}s alternate infinite`;

                let i = 0;
                for (i = 0; i < steps; i++) {
                    window.setTimeout(() => {
                        this.currentSpace = game.spaceMap.get(this.currentSpace.nextId);
                        if (collectPassGo && this.currentSpace.nameId === 'start') {
                            console.log('collecting pass go');
                            this.deposit(settings.goCollectAmount);
                        }
                        this.updateDisplay();
                    }, settings.movementStepDelay * i);
                }

                window.setTimeout(() => {
                    console.log(`${this.name} landed on ${this.currentSpace.name}!`);
                    if (resolveSpace) {
                        this.currentSpace.resolve(this);
                    }
                    this.updateDisplay();
                    this.playerPieceDOM.style.animation = '';
                }, settings.movementStepDelay * i);
            }

            moveBackward(steps = 1, resolveSpace = true) {
                // Assume steps > 0
                UIHelpers.notice(this, 'Moving...');
                let i = 0;
                for (i = 0; i < steps; i++) {
                    window.setTimeout(() => {
                        this.currentSpace = game.spaceMap.get(this.currentSpace.prevId);
                        this.updateDisplay();
                    }, settings.movementStepDelay * i);
                }

                window.setTimeout(() => {
                    console.log(`${this.name} landed on ${this.currentSpace.name}!`);
                    if (resolveSpace) {
                        this.currentSpace.resolve(this);
                    }
                    this.updateDisplay();
                }, settings.movementStepDelay * i);
            }

            transfer(amount, player) {
                //Assume amount >= 0
                player.deposit(Math.min(amount, this.money));
                this.money -= amount;
                this.updateDisplay();
            }

            deposit(amount) {
                //Assume amount >= 0
                this.money += amount;
                this.updateDisplay();
            }

            withdraw(amount) {
                //Assume amount >= 0
                console.log(`withdrawing ${amount} from player[${this.name}]`);
                this.money -= amount;
                this.updateDisplay();
            }
        }

        class Space extends GameAsset {
            constructor(param) {
                super(param);
                this.name = param.name;

                this.nameId = param.nameId;
                this.nextId = param.nextId;
                this.prevId = param.prevId;

                this.type = param.type;
                this.column = param.column;
                this.row = param.row;
                this.icon = '';

                this.boardSpaceWrapper = document.createElement('div');
                this.boardSpaceWrapper.className = 'space';

                const spaceNumberDOM = document.createElement('div');
                spaceNumberDOM.className = 'spaceNumber';
                this.boardSpaceWrapper.append(spaceNumberDOM);

                this.spaceNameDOM = document.createElement('h3');
                this.spaceNameDOM.className = 'spaceName';
                this.boardSpaceWrapper.append(this.spaceNameDOM);

                this.boardSpaceWrapper.style['grid-column-start'] = this.column;
                this.boardSpaceWrapper.style['grid-row-start'] = this.row;
                this.boardSpaceWrapper.style.border = `1px solid yellowgreen`;

                board.boardLayer.append(this.boardSpaceWrapper);

                this.boardSpaceWrapper.addEventListener('mouseenter', () => {
                    this.updateSpaceDetailDisplay();
                });
                this.boardSpaceWrapper.addEventListener('mouseleave', () => {
                    game.currentPlayer.currentSpace.updateSpaceDetailDisplay();
                });
                this.updateSpaceDisplay();
            }

            updateSpaceDisplay() {
                this.spaceNameDOM.innerText = this.name;
            }

            updateSpaceDetailDisplay() {
                board.spaceDetailDisplay.innerHTML = '';

                const header = document.createElement('h2');
                header.innerText = `${this.name}`;
                board.spaceDetailDisplay.append(header);

                const iconContainer = document.createElement('div');
                iconContainer.className = 'detailIcon';
                iconContainer.style['border'] = `5px solid ${typeof (this.color) === 'undefined' ? 'white' : this.color}`;
                let detailIcon = '';

                switch (this.type.toLowerCase()) {
                    case 'start':
                        detailIcon = '';
                        break;
                    case 'property':
                        detailIcon = '';
                        break;
                    case 'tax':
                        detailIcon = '';
                        break;
                    case 'chest':
                        detailIcon = '';
                        break;
                    case 'chance':
                        detailIcon = '';
                        break;
                    case 'jail':
                        detailIcon = '';
                        break;
                    case 'gotojail':
                        detailIcon = '';
                        break;
                    default:
                        detailIcon = '';
                        break;
                }
                iconContainer.innerHTML = detailIcon;
                board.spaceDetailDisplay.append(iconContainer);
            }

            resolve() {
                console.log(`resolving action of ${this.name}`);
                game.finishTurn();
            }
        }

        class Tax extends Space {
            constructor(param) {
                super(param);
                this.amount = param.amount;
            }

            updateSpaceDetailDisplay() {
                super.updateSpaceDetailDisplay();
            }

            resolve(player) {
                const button = UIHelpers.payTax(player, this);
                button.addEventListener('click', () => {
                    player.withdraw(this.amount );
                    game.finishTurn();
                });
            }
        }
       
        class RandomAction extends Space {
            constructor(param) {
                super(param);
                this.deck = [];
                this.dialogMessage = '';
            }

            updateSpaceDetailDisplay() {
                super.updateSpaceDetailDisplay();
            }

            resolve(player) {
                console.log(`drawing card for ${player.name} from ${this.type}`);
                let message = '';
                switch (this.type.toLowerCase()) {
                    case 'chance':
                        this.deck = game.chanceCards;
                        message = 'Chance!';
                        this.icon = '';
                        break;
                    case 'chest':
                        this.deck = game.communityChestCards;
                        message = 'Community Chest';
                        this.icon = '';
                        break;
                }

                const button = UIHelpers.dialog(player, message, [new Option('accept', 'Draw')], this.icon).get('accept');
                button.addEventListener('click', () => {
                    if (this.deck.length > 0) {
                        const randomCardIndex = MathHelpers.randomInt(0, this.deck.length - 1);
                        const card = this.deck[randomCardIndex];

                        let resolveButtonText = 'Ok';
                        let resolveFunction = () => {
                            game.finishTurn();
                        };

                        switch (card.type.toLowerCase()) {
                            // Change this so it looks up nameId instead 
                            case 'moveto':
                                const space = game.spaceMap.get(card.nameId);
                                resolveButtonText = `Move to ${space.name}`;
                                resolveFunction = () => {
                                    player.moveTo(card.nameId, card.resolveSpace, card.collectPassGo);
                                    game.finishTurn();
                                };
                                break;
                            case 'withdraw':
                                resolveButtonText = `Pay \$${card.amount}`;
                                resolveFunction = () => {
                                    player.withdraw(card.amount * settings.taxMultiplier);
                                    game.finishTurn();
                                };
                                break;
                            case 'deposit':
                                resolveButtonText = `Receive \$${card.amount}`;
                                resolveFunction = () => {
                                    player.deposit(card.amount);
                                    game.finishTurn();
                                };
                                break;
                        }

                        const resolveButton = UIHelpers.dialog(player, card.description, [new Option('accept', resolveButtonText)], card.icon).get('accept');
                        resolveButton.addEventListener('click', resolveFunction);
                    } else {
                        game.finishTurn();
                    }
                });
            }
        }

        class GoToJail extends Space {
            constructor(param) {
                super(param);
            }

            updateSpaceDetailDisplay() {
                super.updateSpaceDetailDisplay();
            }

            resolve(player) {
                const message = 'Move to Jail';
                const button = UIHelpers.dialog(player, message).get('accept');
                button.addEventListener('click', () => {
                    player.moveTo('jail');
                });
            }
        }

        class Jail extends Space {
            constructor(param) {
                super(param);
            }

            updateSpaceDetailDisplay() {
                super.updateSpaceDetailDisplay();
            }

            resolve(player) {
                console.log(`${player.name} is in jail`);
                player.state = 'jailed';
                player.stateTurn = settings.jailedTurn;
                const message = 'is in Jail';
                const button = UIHelpers.dialog(player, message).get('accept');
                button.addEventListener('click', () => {
                    game.finishTurn();
                });
            }
        }

        class Property extends Space {
            constructor(param) {
                super(param);
                this.color = param.color;
                this.price = param.price;
                this.rent = param.rent;
                this.upgradeCost = param.upgradeCost;
                this.upgradeIcons = ['', '', '', '', ''];
                this.owner = undefined;
                this.upgradeLevel = 0;

                this.ownerDOM = document.createElement('span');
                this.ownerDOM.className = 'owner';
                this.boardSpaceWrapper.append(this.ownerDOM);

                this.upgradeDOM = document.createElement('span');
                this.upgradeDOM.className = 'upgrade';
                this.boardSpaceWrapper.append(this.upgradeDOM);

                this.priceDOM = document.createElement('span');
                this.priceDOM.className = 'price';
                this.boardSpaceWrapper.append(this.priceDOM);

                if (this.row === 1) {
                    this.boardSpaceWrapper.style['border-bottom'] = `5px solid ${this.color}`;
                }
                if (this.row === 11) {
                    this.boardSpaceWrapper.style['border-top'] = `5px solid ${this.color}`;
                }
                if (this.column === 1) {
                    this.boardSpaceWrapper.style['border-right'] = `5px solid ${this.color}`;
                }
                if (this.column === 11) {
                    this.boardSpaceWrapper.style['border-left'] = `5px solid ${this.color}`;
                }
                this.updatePropertyDisplay();
            }

            get calculatedRent() {
                return this.rent[this.upgradeLevel];
            }

            get currentUpgradeCost() {
                return this.upgradeCost[this.upgradeLevel];
            }

            updateDisplay() {
                this.updateSpaceDisplay();
                this.updatePropertyDisplay();
                this.updateSpaceDetailDisplay();
            }

            updatePropertyDisplay() {
                if (this.owner !== undefined) {
                    this.ownerDOM.innerText = `Owner: ${this.owner.icon}`;
                    this.priceDOM.innerText = `Rent: \$${this.calculatedRent}`;
                } else {
                    this.priceDOM.innerText = `Buy: \$${this.price}`;
                }
                if (this.upgradeLevel > 0) {
                    this.upgradeDOM.innerText = this.upgradeIcons[this.upgradeLevel - 1];
                }
            }

            updateSpaceDetailDisplay() {
                super.updateSpaceDetailDisplay();
                const detailsContainer = document.createElement('div');
                detailsContainer.className = 'details';
                detailsContainer.style.display = 'grid';
                detailsContainer.style['grid-template-columns'] = '5fr 2fr 2fr';

                ['Upgrade', 'Cost', 'Rent'].forEach((headerText) => {
                    const header = document.createElement('h3');
                    header.innerText = headerText;
                    detailsContainer.append(header);
                });

                for (let i = 0; i < this.rent.length; i++) {
                    const upgradeIconDOM = document.createElement('div');
                    const upgradeCostDOM = document.createElement('div');
                    const rentDOM = document.createElement('div');

                    if (i === 0) {
                        upgradeIconDOM.innerText = 'No Upgrade';
                        upgradeCostDOM.innerText = '-';

                    } else {
                        upgradeIconDOM.innerText = this.upgradeIcons[i - 1];
                        upgradeCostDOM.innerText = this.upgradeCost[i - 1];
                    }

                    rentDOM.innerHTML = this.rent[i];
                    detailsContainer.append(upgradeIconDOM);
                    detailsContainer.append(upgradeCostDOM);
                    detailsContainer.append(rentDOM);
                }

                board.spaceDetailDisplay.append(detailsContainer);
            }

            resolve(player) {
                
               
                // console.log('resolving action of property');
                if (typeof (this.owner) === 'undefined') {
                    console.log(`this property is not owned. prompt player to buy.`);
                    const buttons = UIHelpers.buyProperty(player, this);
                    buttons.get('accept').addEventListener('click', () => {
                        if (player.money >= this.price) {
                            player.withdraw(this.price);
                            this.owner = player;
                            console.log(`${this.name} is bought by ${player.name} for \$${this.price}`);
                            this.updateDisplay();
                        } else {
                            console.log(`insufficient funds!`);
                        }
                       
                        game.finishTurn();
                    });
                    buttons.get('decline').addEventListener('click', () => {
                        game.finishTurn();
                    });
                } else if (this.owner === player) {
                    console.log(`this property is owned by player. check if upgrade is available.`);
                    //check if player own all property in color group
                    let ownedAll = true;

                    for (const property of game.propertyGroups.get(this.color).value) {
                        if (property.owner !== player) {
                            ownedAll = false;
                            break;
                        }
                    }

                    //Utility property does not require ownership of all property in the group to upgrade
                    if ((this.color === 'black' || ownedAll) && this.upgradeLevel < this.rent.length - 1) {
                        const buttons = UIHelpers.upgradeProperty(player, this);
                        buttons.get('accept').addEventListener('click', () => {
                            if (player.money >= this.currentUpgradeCost) {
                                player.withdraw(this.currentUpgradeCost);
                                console.log(`${this.name} is upgraded by ${player.name} for \$${this.currentUpgradeCost}`);
                                this.upgradeLevel++;
                                this.updateDisplay();
                            } else {
                                console.log(`insufficient funds!`);
                            }
                            game.finishTurn();
                        });
                        buttons.get('decline').addEventListener('click', () => {
                            game.finishTurn();
                        });
                    } else {
                        console.log(`own all property in this color group to unlock upgrade.`);
                        game.finishTurn();
                    }
                } else {
                    console.log(`this property is owned by another player. transfer ${this.calculatedRent} to ${this.owner.name}`);
                    const button = UIHelpers.payRent(player, this);
                    button.addEventListener('click', () => {
                        player.transfer(this.calculatedRent, this.owner);
                        game.finishTurn();
                    });
                }
            }
        }

        class Game {
            constructor() {
                this.turnCount = 0;
                this.players = [];
                this.currentPlayerIndex = 0;

                this.spaceMap = new Map();
                this.startSpace = undefined;

                // Monopoly only
                this.propertyGroups = new Map();
                this.chanceCards = [];
                this.communityChestCards = [];
            }

            setup() {
                this.turnCount = 0;
                this.players = [];
                this.currentPlayerIndex = 0;

                this.spaceMap = new Map();

                this.chanceCards = [];
                this.communityChestCards = [];
            }

            addPlayer(param) {
                const newPlayer = new Player(param);
                this.players.push(newPlayer);
                newPlayer.moveTo('start');
                newPlayer.updateDisplay();
            }

            addSpace(param) {
                let newSpace;
                switch (param.type.toLowerCase()) {
                    case 'property':
                        newSpace = new Property(param);
                        if (!this.propertyGroups.has(newSpace.color)) {
                            this.propertyGroups.set(newSpace.color, { value: [] });
                        }
                        this.propertyGroups.get(newSpace.color).value.push(newSpace);
                        break;
                    case 'jail':
                        newSpace = new Jail(param);
                        break;
                    case 'gotojail':
                        newSpace = new GoToJail(param);
                        break;
                    case 'chance':
                        newSpace = new RandomAction(param);
                        break;
                    case 'chest':
                        newSpace = new RandomAction(param);
                        break;
                    case 'tax':
                        newSpace = new Tax(param);
                        break;
                    default:
                        newSpace = new Space(param);
                }
                this.spaceMap.set(newSpace.nameId, newSpace);
            }


            start() {
                this.play();
            }

            play() {
               
                  
                this.currentPlayer = this.players[this.currentPlayerIndex];
                const player = this.currentPlayer;
                
                if (player.state !== 'bankrupt') {
                    player.currentSpace.updateSpaceDetailDisplay();
                    if (player.state === 'playing') {
                        const button = UIHelpers.rollDice(player);
                        button.addEventListener('click', () => {
                            this.rollDice();

                        });
                    } else if (player.state === 'jailed') {
                        const message = player.stateTurn > 1 ? `${player.stateTurn} Turn${player.stateTurn > 1 ? 's' : ''} Remaining in Jail` : 'Last Turn in Jail';
                        const buttonText = player.stateTurn > 1 ? 'Skip Turn' : 'Get Out';
                        const button = UIHelpers.dialog(player, message, [new Option('accept', buttonText)]).get('accept');
                        
                        button.addEventListener('click', () => {
                            player.stateTurn--;
                            if (player.stateTurn === 0) {
                                player.state = 'playing';
                            }
                            

                            player.updateDisplay();
                            this.finishTurn();
                        });
                    }
                } else {
                    this.nextTurn();
                }
            }
            
           
            rollDice(count = settings.dieCount) {
               
               
                const player = this.players[this.currentPlayerIndex];
                const dieFaces = ['', '', '', '', '', ''];
                let totalRoll = 0;
                let icon = '';

                console.log(`roll dice, money: ${player.money}`);

                for (let i = 0; i < count; i++) {
                    const roll = MathHelpers.randomInt(1, 6);
                    console.log(`${player.name} rolls the dice! ${roll}!`);
                    totalRoll += roll;
                    icon += dieFaces[roll - 1];
                }

                const message = `Rolled ${totalRoll}`;
                const button = UIHelpers.dialog(player, message, [new Option('accept', 'Move')], icon).get('accept');
                button.addEventListener('click', () => {
                    player.moveForward(totalRoll);
                });
            }
              
           
            finishTurn() {
                const player = this.players[this.currentPlayerIndex];
                //Check if player is bankrupt
                if (player.money < 0) {
                    player.state = 'bankrupt';
                    player.playerStatsWrapper.style.filter = 'grayscale(100%)';
                    player.playerPieceDOM.style.filter = 'grayscale(100%)';
                    player.updateDisplay();
                    const message = 'GAME OVER';
                    const button = UIHelpers.dialog(player, message, [new Option('accept', 'Ok')]).get('accept');
                    button.addEventListener('click', () => {
                        this.nextTurn();
                    });
                } else {
                    this.nextTurn();
                }
            }

            nextTurn() {
                console.log(`turn ended for ${this.currentPlayer.name}`);
                console.log(`----------------`);

                const activePlayerCount = game.players.reduce((count, current) => count + ((current.state !== 'bankrupt') ? 1 : 0), 0);
                if (activePlayerCount > 1) {
                    this.currentPlayerIndex++;
                    this.currentPlayer = this.players[this.currentPlayerIndex];
                    if (this.currentPlayerIndex >= this.players.length) {
                        this.currentPlayerIndex = 0;
                    }

                    this.turnCount++;
                    this.play();
                } else {
                    this.end();
                }
            }

            end() {
                const player = game.players.find((current) => current.state !== 'bankrupt');
                const message = `${player.name} wins!`;
                const button = UIHelpers.dialog(player, message, [new Option('accept', 'Reset Game')], `${player.icon}`).get('accept');

                button.addEventListener('click', () => {
                    GameHelpers.setupGame();
                    GameHelpers.setupPlayers();
                    GameHelpers.setupEventListeners();
                    game.start();
                    game.currentPlayer.currentSpace.updateSpaceDetailDisplay();
                    window.setTimeout(1000, () => {
                        GameHelpers.resizeBoard();
                    });
                });
            }
        }

        class GameHelpers {
            static setupGame() {
                board = new MonopolyBoard();
                board.setup();
                game = new Game();
                game.setup();

                GameData.spaces().forEach((space) => game.addSpace(space));
                game.startSpace = game.spaceMap.get('start');
                game.chanceCards = GameData.chanceCards();
                game.communityChestCards = GameData.communityChestCards();
            }
            static setupPlayers() {
                game.addPlayer({ name: 'P1', money: 2000, icon: '' });
                game.addPlayer({ name: 'P2', money: 2000, icon: '' });
                game.addPlayer({ name: 'P3', money: 2000, icon: '' });
                game.addPlayer({ name: 'P4', money: 2000, icon: '' });
            }
            static setupEventListeners() {
                window.removeEventListener('resize', this.resizeBoard);
                window.addEventListener('resize', this.resizeBoard);
            }
            static resizeBoard() {
                const windowWidth = window.innerWidth;
                const windowHeight = window.innerHeight;
                // Get width and height of board then set transform scale
                const boardWidth = board.boardLayer.offsetWidth;
                const boardHeight = board.boardLayer.offsetHeight;
                board.transform.scale = Math.min(
                    windowWidth / boardWidth,
                    windowHeight / boardHeight
                ) * 0.99;
                gameDOM.style['transform-origin'] = `${boardHeight / 2}px ${boardWidth / 2}px`;

                const rotate = `rotateX(${board.transform.rotate.x}deg) rotateY(${board.transform.rotate.y}deg) rotateZ(${board.transform.rotate.z}deg)`;
                const scale = `scale(${board.transform.scale})`;
                const translate = `translateX(${board.transform.translate.x}px) translateY(${board.transform.translate.y}px) translateZ(${board.transform.translate.z}px)`;
                gameDOM.style.transform = `${rotate} ${scale} ${translate}`;
                return board.transform;
            }
        }
    }
}

私が試したこと:

class Question {
  constructor(question, options, correctAnswer) {
    this.question = question;
    this.options = options;
    this.correctAnswer = correctAnswer;
  }

  ask(player) {
    const button = UIHelpers.createButton(player, 'Ask question', () => {
      // Show the question to the player
      const userAnswer = prompt(`${this.question}\n\n${this.options.join('\n')}`);

      // Check if the player's answer is correct
      if (userAnswer === this.correctAnswer) {
        // Increase the player's money if the answer is correct
        player.money += 100;
        console.log("Correct! Your money has increased by 100.");
      } else {
        // Decrease the player's money if the answer is wrong
        player.money -= 200;
        console.log("Incorrect! Your money has decreased by 200.");
      }
    });
  }
}

const question = new Question("What is the capital of France?", ["Paris", "London", "New York"], "Paris");
question.ask(player);

“`
メソッドをどこに置くべきか、どこで呼び出すべきかがわかりませんでした。 これは、github でこのリポジトリを見つけた私のコードではありません。
質問は、プレーヤーがサイコロを振ってピスを動かした後に表示する必要があります。 ありがとう

解決策 1

最初にすべきことは、インターネットからランダムなコードを取得し、それが希望する方法で実行され、簡単に変更できると仮定することは、おそらく失敗する運命にあることを学ぶことです。

コードを使用したい場合は、現実的な方法でコードを変更する方法を理解するために、それがどのように機能するかを学ぶ必要があります。 そして、あなたに代わってあなたの課題をこなすためにそれほど多くの時間を費やしたいと思う人は誰もいないでしょう – 特に出発点が非常に質の低い学生レベルのコードであり、いつこの変更が必要になるかわかりません.

したがって、その多くを捨てて独自のコードを作成してみるか、変更を加える前に座ってその仕組みを学んでください。

コメント

タイトルとURLをコピーしました