###### tags: `Block Chain` # Solidity練習 - 猜數字遊戲 ## 簡介 猜數字遊戲,玩法跟終極密碼一樣, 猜的數字只要沒有答對都會縮小數字範圍, 比較不同的是猜數字的方式, 每次猜數字都須支付1 finney, 所以猜中的人可以拿到contract裡面所有參與者投入的錢 ```solidity= // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.14; contract GuessNumber{ /* Feature 猜數字遊戲,玩法其實就跟終極密碼一樣, 猜的數字只要沒有答對都會縮小數字範圍, 比較不同的是猜數字的方式, 每次猜數字都須支付1 finney, 所以猜中的人可以拿到contract裡面所有參與者投入的錢 */ // 答案 uint256 answer; // 上限 uint256 public MaxRange; // 下限 uint256 public MinRange; // 擁有者 address owner; // 猜中事件 event Winner(address indexed _winner, uint256 _answer); constructor () { // 產生數字 genrate(); // 設定合約擁有者 owner = msg.sender; // 設定上下限 MaxRange = 100; MinRange = 1; } // 檢查數字須在區間內 modifier checkNum(uint num){ require(num > MinRange,"you have to guess higher"); require(num < MaxRange,"you have to guess lower"); _; } // 檢查是否有投入適當的eth modifier checkValue() { require(msg.value == 1 * 10**15,"need more eth"); _; } // 產生數字 function genrate() private { answer = uint(sha256(abi.encodePacked(block.difficulty, block.timestamp))) % 100; } // 合約擁有者可以查看答案 function giveMeAnswer() public view returns(uint){ require(msg.sender == owner,"you are not owner!"); return answer; } // 查看目前獎金總數 function award() public view returns(uint){ return address(this).balance; } // 猜數字 function guess(uint num) public checkNum(num) checkValue() payable{ // 猜的數字 > answer if (num > answer) { MaxRange = num; return; } // 猜的數字 < answer if (num < answer) { MinRange = num; return; } // 猜中 if (num == answer) { winner(num); } } // 贏家可獲得所有獎金 function winner(uint num) private { // 轉帳的語法 payable(msg.sender).transfer(address(this).balance); // 重新開始 restart(); emit Winner(msg.sender,num); } // 重新開始 function restart() private { // 產生數字 genrate(); // 設定上下限 MaxRange = 100; MinRange = 1; } } ``` {%hackmd theme-dark %}