// Note: We keep the data and the states in this component class CoinTossPanel extends React.Component { constructor(props) { super(props); this.state = { // Check whether all nodes are clicked isClicked: [ true, true, true, ], // Save continuation decision in percent continuation: [ 100, ], // Save outcome path drawn: -1, coinTossCounter: 0, // Keep track of clicks enableCoinToss: false, // Enable Coin Toss imagePathGuess: '/static/img/coin.png', imagePath: '/static/img/coin_questionmark.png', winningSide: "", lastRiskWon: "", nextCoin: false, riskOutcome: [], coinTossOutcome: [], } this.tryCoin = this.tryCoin.bind(this); this.coin = this.coin.bind(this); this.tossCoin = this.tossCoin.bind(this); this.nextCoin = this.nextCoin.bind(this); this.winningSideUpdate = this.winningSideUpdate.bind(this); this.fastCoinTosses = this.fastCoinTosses.bind(this); this.submitData = this.submitData.bind(this); } tryCoin() { this.setState({enableCoinToss: true}, () => { document.getElementById("tryCoinBtn").classList.add("d-none") document.getElementById("pickWinningSide").classList.remove("d-none") }) } winningSideUpdate(chosenSide) { if (chosenSide == "H") { this.setState({ winningSide: chosenSide, imagePathGuess: '/static/img/coin_h.png' }) } else if (chosenSide == "T") { this.setState({ winningSide: chosenSide, imagePathGuess: '/static/img/coin_t.png' }) } if (this.state.coinTossCounter >= 2) { setTimeout(this.tossCoin, 500) } else { document.getElementById("explainDiv").classList.remove("d-none") document.getElementById("explainText").innerHTML = ` You entered ${chosenSide == "H" ? "Heads" : "Tails"} as your coin toss outcome. Therefore, the left coin shows ''${chosenSide}''. Next, you will see the winning side. ` document.getElementById("nextCoinBtn").classList.remove("d-none"); } } tossCoin() { const userInput = this.state.winningSide const lastRiskWon = this.state.lastRiskWon let {coinTossCounter, riskOutcome, coinTossOutcome} = this.state coinTossOutcome.push(userInput) // Grey background for selection section document.getElementById("pickWinningSide").classList.remove("alert-warning"); document.getElementById("pickWinningSide").classList.add("alert-secondary"); // Disable winniing side buttons var ele = document.getElementsByName("winningSideInput"); for(var i=0;iFrom now on, we omit the explanations." : "" } ` } else { riskOutcome.push("L") document.getElementById("coinTossLost").classList.remove("d-none") document.getElementById("moveDown").classList.remove("d-none") document.getElementById("ball_2_text").classList.add("alert-danger") this.setState({drawn: 2}) document.getElementById("explainText").innerHTML = ` The coin toss outcome does not equal the winning side! Therefore, you lose this single risk and pay £${js_vars.upTick.toFixed(2)}. ${(coinTossCounter + 1 == 2) ? "From now on, we omit the explanations." : "" } ` } this.setState({ nextCoin: true, coinTossCounter: coinTossCounter + 1, lastRiskWon: (userInput == coinOutcome), riskOutcome: riskOutcome, coinTossOutcome : coinTossOutcome, }, () => { if (this.state.coinTossCounter >= 4) { this.props.fourCoinTosses() // Callback function for HTML page } else if (this.state.coinTossCounter > 2) { document.getElementById("explainText").classList.add("d-none") } }) } coin() { let coinSide = "" let outcome = Math.round(Math.random()) if (outcome === 0){ coinSide = "H" this.setState({ imagePath: '/static/img/coin_h.png', }) } else { coinSide = "T" this.setState({ imagePath: '/static/img/coin_t.png', }) } return coinSide } nextCoin() { this.setState({ imagePath: '/static/img/coin_questionmark.png', imagePathGuess: '/static/img/coin.png', winningSide: '', nextCoin: false, drawn: -1, }) document.getElementById("ball_1_text").classList.remove("alert-success") document.getElementById("ball_2_text").classList.remove("alert-danger") document.getElementById("coinTossWon").classList.add("d-none") document.getElementById("coinTossLost").classList.add("d-none") document.getElementById("moveUp").classList.add("d-none") document.getElementById("moveDown").classList.add("d-none") document.getElementById("explainDiv").classList.add("d-none") if (document.getElementById("nextCoinBtn")) { document.getElementById("nextCoinBtn").classList.add("d-none") } //document.getElementById("pickWinningSide").classList.remove("d-none") // Yellow background for selection section document.getElementById("pickWinningSide").classList.remove("alert-secondary"); document.getElementById("pickWinningSide").classList.add("alert-warning"); var ele = document.getElementsByName("winningSideInput"); for(var i=0;i{ let data = { riskOutcome: this.state.riskOutcome, coinToss: this.state.coinTossOutcome, } liveSend(data) // Sends state to oTree backend } render () { return ( <> {/* Left column */} {this.state.enableCoinToss ? Coin toss: Win or lose? Coin toss outcome The winning side Heads Tails this.winningSideUpdate("H")} className="largerRadio"/> this.winningSideUpdate("T")} className="largerRadio"/> You won this single risk. You lost this single risk. : {/* Starting picture showing coin*/ } Coin toss } {/* Right column */} {((this.state.winningSide != "") && (this.state.nextCoin)) ? "Single risk outcome" : "Single risk" } You moved up. { (this.state.coinTossCounter > 2) ? Next single risk : <>>} You moved down. { (this.state.coinTossCounter > 2) ? Next single risk : <>>} {((this.state.winningSide != "") && (this.state.nextCoin) && (this.state.coinTossCounter <= 2)) ? Resolve another single risk : (this.state.coinTossCounter < 2) ? Show the winning side : <>> } Start resolving single risks > ) } }