编译器
0.8.25+commit.b61c2a91
文件 1 的 13:ABDKMath64x64.sol
pragma solidity ^0.8.0;
library ABDKMath64x64 {
int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;
int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
function fromInt (int256 x) internal pure returns (int128) {
unchecked {
require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF);
return int128 (x << 64);
}
}
function toInt (int128 x) internal pure returns (int64) {
unchecked {
return int64 (x >> 64);
}
}
function fromUInt (uint256 x) internal pure returns (int128) {
unchecked {
require (x <= 0x7FFFFFFFFFFFFFFF);
return int128 (int256 (x << 64));
}
}
function toUInt (int128 x) internal pure returns (uint64) {
unchecked {
require (x >= 0);
return uint64 (uint128 (x >> 64));
}
}
function from128x128 (int256 x) internal pure returns (int128) {
unchecked {
int256 result = x >> 64;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function to128x128 (int128 x) internal pure returns (int256) {
unchecked {
return int256 (x) << 64;
}
}
function add (int128 x, int128 y) internal pure returns (int128) {
unchecked {
int256 result = int256(x) + y;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function sub (int128 x, int128 y) internal pure returns (int128) {
unchecked {
int256 result = int256(x) - y;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function mul (int128 x, int128 y) internal pure returns (int128) {
unchecked {
int256 result = int256(x) * y >> 64;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function muli (int128 x, int256 y) internal pure returns (int256) {
unchecked {
if (x == MIN_64x64) {
require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF &&
y <= 0x1000000000000000000000000000000000000000000000000);
return -y << 63;
} else {
bool negativeResult = false;
if (x < 0) {
x = -x;
negativeResult = true;
}
if (y < 0) {
y = -y;
negativeResult = !negativeResult;
}
uint256 absoluteResult = mulu (x, uint256 (y));
if (negativeResult) {
require (absoluteResult <=
0x8000000000000000000000000000000000000000000000000000000000000000);
return -int256 (absoluteResult);
} else {
require (absoluteResult <=
0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return int256 (absoluteResult);
}
}
}
}
function mulu (int128 x, uint256 y) internal pure returns (uint256) {
unchecked {
if (y == 0) return 0;
require (x >= 0);
uint256 lo = (uint256 (int256 (x)) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;
uint256 hi = uint256 (int256 (x)) * (y >> 128);
require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
hi <<= 64;
require (hi <=
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo);
return hi + lo;
}
}
function div (int128 x, int128 y) internal pure returns (int128) {
unchecked {
require (y != 0);
int256 result = (int256 (x) << 64) / y;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function divi (int256 x, int256 y) internal pure returns (int128) {
unchecked {
require (y != 0);
bool negativeResult = false;
if (x < 0) {
x = -x;
negativeResult = true;
}
if (y < 0) {
y = -y;
negativeResult = !negativeResult;
}
uint128 absoluteResult = divuu (uint256 (x), uint256 (y));
if (negativeResult) {
require (absoluteResult <= 0x80000000000000000000000000000000);
return -int128 (absoluteResult);
} else {
require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return int128 (absoluteResult);
}
}
}
function divu (uint256 x, uint256 y) internal pure returns (int128) {
unchecked {
require (y != 0);
uint128 result = divuu (x, y);
require (result <= uint128 (MAX_64x64));
return int128 (result);
}
}
function neg (int128 x) internal pure returns (int128) {
unchecked {
require (x != MIN_64x64);
return -x;
}
}
function abs (int128 x) internal pure returns (int128) {
unchecked {
require (x != MIN_64x64);
return x < 0 ? -x : x;
}
}
function inv (int128 x) internal pure returns (int128) {
unchecked {
require (x != 0);
int256 result = int256 (0x100000000000000000000000000000000) / x;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function avg (int128 x, int128 y) internal pure returns (int128) {
unchecked {
return int128 ((int256 (x) + int256 (y)) >> 1);
}
}
function gavg (int128 x, int128 y) internal pure returns (int128) {
unchecked {
int256 m = int256 (x) * int256 (y);
require (m >= 0);
require (m <
0x4000000000000000000000000000000000000000000000000000000000000000);
return int128 (sqrtu (uint256 (m)));
}
}
function pow (int128 x, uint256 y) internal pure returns (int128) {
unchecked {
bool negative = x < 0 && y & 1 == 1;
uint256 absX = uint128 (x < 0 ? -x : x);
uint256 absResult;
absResult = 0x100000000000000000000000000000000;
if (absX <= 0x10000000000000000) {
absX <<= 63;
while (y != 0) {
if (y & 0x1 != 0) {
absResult = absResult * absX >> 127;
}
absX = absX * absX >> 127;
if (y & 0x2 != 0) {
absResult = absResult * absX >> 127;
}
absX = absX * absX >> 127;
if (y & 0x4 != 0) {
absResult = absResult * absX >> 127;
}
absX = absX * absX >> 127;
if (y & 0x8 != 0) {
absResult = absResult * absX >> 127;
}
absX = absX * absX >> 127;
y >>= 4;
}
absResult >>= 64;
} else {
uint256 absXShift = 63;
if (absX < 0x1000000000000000000000000) { absX <<= 32; absXShift -= 32; }
if (absX < 0x10000000000000000000000000000) { absX <<= 16; absXShift -= 16; }
if (absX < 0x1000000000000000000000000000000) { absX <<= 8; absXShift -= 8; }
if (absX < 0x10000000000000000000000000000000) { absX <<= 4; absXShift -= 4; }
if (absX < 0x40000000000000000000000000000000) { absX <<= 2; absXShift -= 2; }
if (absX < 0x80000000000000000000000000000000) { absX <<= 1; absXShift -= 1; }
uint256 resultShift = 0;
while (y != 0) {
require (absXShift < 64);
if (y & 0x1 != 0) {
absResult = absResult * absX >> 127;
resultShift += absXShift;
if (absResult > 0x100000000000000000000000000000000) {
absResult >>= 1;
resultShift += 1;
}
}
absX = absX * absX >> 127;
absXShift <<= 1;
if (absX >= 0x100000000000000000000000000000000) {
absX >>= 1;
absXShift += 1;
}
y >>= 1;
}
require (resultShift < 64);
absResult >>= 64 - resultShift;
}
int256 result = negative ? -int256 (absResult) : int256 (absResult);
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function sqrt (int128 x) internal pure returns (int128) {
unchecked {
require (x >= 0);
return int128 (sqrtu (uint256 (int256 (x)) << 64));
}
}
function log_2 (int128 x) internal pure returns (int128) {
unchecked {
require (x > 0);
int256 msb = 0;
int256 xc = x;
if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; }
if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
if (xc >= 0x10000) { xc >>= 16; msb += 16; }
if (xc >= 0x100) { xc >>= 8; msb += 8; }
if (xc >= 0x10) { xc >>= 4; msb += 4; }
if (xc >= 0x4) { xc >>= 2; msb += 2; }
if (xc >= 0x2) msb += 1;
int256 result = msb - 64 << 64;
uint256 ux = uint256 (int256 (x)) << uint256 (127 - msb);
for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) {
ux *= ux;
uint256 b = ux >> 255;
ux >>= 127 + b;
result += bit * int256 (b);
}
return int128 (result);
}
}
function ln (int128 x) internal pure returns (int128) {
unchecked {
require (x > 0);
return int128 (int256 (
uint256 (int256 (log_2 (x))) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128));
}
}
function exp_2 (int128 x) internal pure returns (int128) {
unchecked {
require (x < 0x400000000000000000);
if (x < -0x400000000000000000) return 0;
uint256 result = 0x80000000000000000000000000000000;
if (x & 0x8000000000000000 > 0)
result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128;
if (x & 0x4000000000000000 > 0)
result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128;
if (x & 0x2000000000000000 > 0)
result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128;
if (x & 0x1000000000000000 > 0)
result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128;
if (x & 0x800000000000000 > 0)
result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128;
if (x & 0x400000000000000 > 0)
result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128;
if (x & 0x200000000000000 > 0)
result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128;
if (x & 0x100000000000000 > 0)
result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128;
if (x & 0x80000000000000 > 0)
result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128;
if (x & 0x40000000000000 > 0)
result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128;
if (x & 0x20000000000000 > 0)
result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128;
if (x & 0x10000000000000 > 0)
result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128;
if (x & 0x8000000000000 > 0)
result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128;
if (x & 0x4000000000000 > 0)
result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128;
if (x & 0x2000000000000 > 0)
result = result * 0x1000162E525EE054754457D5995292026 >> 128;
if (x & 0x1000000000000 > 0)
result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128;
if (x & 0x800000000000 > 0)
result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128;
if (x & 0x400000000000 > 0)
result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128;
if (x & 0x200000000000 > 0)
result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128;
if (x & 0x100000000000 > 0)
result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128;
if (x & 0x80000000000 > 0)
result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128;
if (x & 0x40000000000 > 0)
result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128;
if (x & 0x20000000000 > 0)
result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128;
if (x & 0x10000000000 > 0)
result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128;
if (x & 0x8000000000 > 0)
result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128;
if (x & 0x4000000000 > 0)
result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128;
if (x & 0x2000000000 > 0)
result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128;
if (x & 0x1000000000 > 0)
result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128;
if (x & 0x800000000 > 0)
result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128;
if (x & 0x400000000 > 0)
result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128;
if (x & 0x200000000 > 0)
result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128;
if (x & 0x100000000 > 0)
result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128;
if (x & 0x80000000 > 0)
result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128;
if (x & 0x40000000 > 0)
result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128;
if (x & 0x20000000 > 0)
result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128;
if (x & 0x10000000 > 0)
result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128;
if (x & 0x8000000 > 0)
result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128;
if (x & 0x4000000 > 0)
result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128;
if (x & 0x2000000 > 0)
result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128;
if (x & 0x1000000 > 0)
result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128;
if (x & 0x800000 > 0)
result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128;
if (x & 0x400000 > 0)
result = result * 0x100000000002C5C85FDF477B662B26945 >> 128;
if (x & 0x200000 > 0)
result = result * 0x10000000000162E42FEFA3AE53369388C >> 128;
if (x & 0x100000 > 0)
result = result * 0x100000000000B17217F7D1D351A389D40 >> 128;
if (x & 0x80000 > 0)
result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128;
if (x & 0x40000 > 0)
result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128;
if (x & 0x20000 > 0)
result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128;
if (x & 0x10000 > 0)
result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128;
if (x & 0x8000 > 0)
result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128;
if (x & 0x4000 > 0)
result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128;
if (x & 0x2000 > 0)
result = result * 0x1000000000000162E42FEFA39F02B772C >> 128;
if (x & 0x1000 > 0)
result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128;
if (x & 0x800 > 0)
result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128;
if (x & 0x400 > 0)
result = result * 0x100000000000002C5C85FDF473DEA871F >> 128;
if (x & 0x200 > 0)
result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128;
if (x & 0x100 > 0)
result = result * 0x100000000000000B17217F7D1CF79E949 >> 128;
if (x & 0x80 > 0)
result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128;
if (x & 0x40 > 0)
result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128;
if (x & 0x20 > 0)
result = result * 0x100000000000000162E42FEFA39EF366F >> 128;
if (x & 0x10 > 0)
result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128;
if (x & 0x8 > 0)
result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128;
if (x & 0x4 > 0)
result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128;
if (x & 0x2 > 0)
result = result * 0x1000000000000000162E42FEFA39EF358 >> 128;
if (x & 0x1 > 0)
result = result * 0x10000000000000000B17217F7D1CF79AB >> 128;
result >>= uint256 (int256 (63 - (x >> 64)));
require (result <= uint256 (int256 (MAX_64x64)));
return int128 (int256 (result));
}
}
function exp (int128 x) internal pure returns (int128) {
unchecked {
require (x < 0x400000000000000000);
if (x < -0x400000000000000000) return 0;
return exp_2 (
int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128));
}
}
function divuu (uint256 x, uint256 y) private pure returns (uint128) {
unchecked {
require (y != 0);
uint256 result;
if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
result = (x << 64) / y;
else {
uint256 msb = 192;
uint256 xc = x >> 192;
if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
if (xc >= 0x10000) { xc >>= 16; msb += 16; }
if (xc >= 0x100) { xc >>= 8; msb += 8; }
if (xc >= 0x10) { xc >>= 4; msb += 4; }
if (xc >= 0x4) { xc >>= 2; msb += 2; }
if (xc >= 0x2) msb += 1;
result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1);
require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
uint256 hi = result * (y >> 128);
uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
uint256 xh = x >> 192;
uint256 xl = x << 64;
if (xl < lo) xh -= 1;
xl -= lo;
lo = hi << 128;
if (xl < lo) xh -= 1;
xl -= lo;
result += xh == hi >> 128 ? xl / y : 1;
}
require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return uint128 (result);
}
}
function sqrtu (uint256 x) private pure returns (uint128) {
unchecked {
if (x == 0) return 0;
else {
uint256 xx = x;
uint256 r = 1;
if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; }
if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; }
if (xx >= 0x100000000) { xx >>= 32; r <<= 16; }
if (xx >= 0x10000) { xx >>= 16; r <<= 8; }
if (xx >= 0x100) { xx >>= 8; r <<= 4; }
if (xx >= 0x10) { xx >>= 4; r <<= 2; }
if (xx >= 0x4) { r <<= 1; }
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
uint256 r1 = x / r;
return uint128 (r < r1 ? r : r1);
}
}
}
}
文件 2 的 13:Cell.sol
pragma solidity ^0.8.25;
uint8 constant CELL_EMPTY = 0;
uint8 constant CELL_NEW = 1;
uint8 constant CELL_WAITING = 2;
uint8 constant CELL_READY = 3;
struct CellData {
address owner;
uint round;
uint8 state;
uint token_price;
address attack_address;
uint attack_end_time;
}
struct CellDataFull {
address owner;
uint round;
uint8 state;
uint token_price;
address attack_address;
uint attack_end_time;
bool need_claim;
}
文件 3 的 13:CellLibrary.sol
pragma solidity ^0.8.25;
import "./Cell.sol";
library CellLibrary {
function is_empty(CellData memory cell) internal pure returns (bool) {
return cell.state == CELL_EMPTY;
}
}
文件 4 的 13:GameEngine.sol
pragma solidity ^0.8.25;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "./IFlags.sol";
import "./IGame.sol";
import "./Startable.sol";
import "./CellLibrary.sol";
import "./noise/Perlin.sol";
string constant ACCOUNT_CAN_NOT_TAKE_CELL = "account can not take this cell";
contract GameEngine is IGame, Startable, ReentrancyGuard {
using CellLibrary for CellData;
IFlags public immutable flags;
uint public constant WORLD_SIZE = 64;
uint public round_timer = 12 hours;
IERC20 public immutable token;
uint _round_number;
uint _round_busy_cells_count;
uint _round_reward_token;
uint _round_reward_eth;
mapping(address owner => AccountData data) _data;
uint _busy_cells_count;
mapping(uint x => mapping(uint y => CellData cell)) _cells;
uint _token_count_for_take_cell = 1e9;
uint public attack_add_percent = 200;
uint public attack_timer_min = 5 minutes;
uint public attack_timer_max = 15 minutes;
uint public total_users_tokens;
uint public fee_percent = 100;
uint public constant calculations_precesion = 1000;
uint public attack_leave_land_percent = 500;
uint public attack_revert_percent = 400;
uint public round_reward_percent_min = 100;
uint public round_reward_percent_max = 300;
constructor(address token_address, address flags_address) {
token = IERC20(token_address);
flags = IFlags(flags_address);
}
modifier valid_coordinates(uint x, uint y) {
require(_is_coordinates_valid(x, y), "invalid coordinates");
_;
}
modifier onlyEoa() {
require(tx.origin == msg.sender, "Not EOA");
_;
}
receive() external payable {}
function flag_size() external view returns (uint x, uint y) {
return flags.flag_size();
}
function set_flag(Rect[] calldata rects) external {
return flags.set_flag(msg.sender, rects);
}
function reset_flag() external {
return flags.reset_flag(msg.sender);
}
function has_custom_flag(address account) external view returns (bool) {
return flags.has_custom_flag(account);
}
function get_flag_svg(
address account
) external view returns (string memory) {
return flags.get_flag_svg(account);
}
function set_attack_timer(uint min, uint max) external onlyOwner {
require(min <= max);
attack_timer_min = min;
attack_timer_max = max;
}
function _is_coordinates_valid(
uint x,
uint y
) internal pure returns (bool) {
return x < WORLD_SIZE && y < WORLD_SIZE;
}
function can_take_cell(
address account,
uint x,
uint y
) public view returns (bool) {
if (!_is_coordinates_valid(x, y)) return false;
AccountData memory account_data = _data[account];
if (
account_data.count == 0 &&
account_data.count_wait == 0 &&
account_data.count_new == 0
) return true;
if (_cell_normalized(_cells[x][y]).owner == account) return false;
if (_cells[x][y].owner == account) return true;
uint i;
uint j;
for (i = x > 0 ? x - 1 : x; i <= x + 1; ++i) {
for (j = y > 0 ? y - 1 : y; j <= y + 1; ++j) {
if (i == x && j == y) continue;
if (!_is_coordinates_valid(i, j)) continue;
if (
_cells[i][j].owner == account ||
_cell_normalized(_cells[i][j]).owner == account
) return true;
}
}
return false;
}
function set_round_reward_percent(uint min, uint max) external onlyOwner {
require(min + max <= calculations_precesion);
round_reward_percent_min = min;
round_reward_percent_max = max;
}
function set_attack_percent(
uint new_attack_leave_land_percent,
uint new_attack_crevert_percent
) external onlyOwner {
require(
new_attack_leave_land_percent + new_attack_crevert_percent <=
calculations_precesion
);
attack_leave_land_percent = new_attack_leave_land_percent;
attack_revert_percent = new_attack_crevert_percent;
}
function set_fee(uint new_fee_percent) external onlyOwner {
require(new_fee_percent < 500);
fee_percent = new_fee_percent;
}
function fee(uint value) public view returns (uint) {
return (value * fee_percent) / calculations_precesion;
}
function rand(uint nonce) internal pure returns (uint) {
return uint(keccak256(abi.encodePacked(nonce, uint(128))));
}
function set_attack_add_percent(
uint new_attack_add_percent
) external onlyOwner {
attack_add_percent = new_attack_add_percent;
}
function total_reward() public view returns (uint token, uint eth) {
token = this.token().balanceOf(address(this)) - total_users_tokens;
eth = address(this).balance;
}
function on_start() internal override {
_update_round();
}
function set_round_timer(uint new_round_timer_minutes) external onlyOwner {
require(new_round_timer_minutes >= 1);
round_timer = new_round_timer_minutes * 1 minutes;
}
function round_number() public view returns (uint) {
if (!is_started()) return 0;
return (block.timestamp - start_time) / round_timer;
}
function next_round_time() public view returns (uint) {
if (!is_started()) return 0;
return start_time + (round_number() + 1) * round_timer;
}
function next_round_lapsed_time() public view returns (uint) {
if (!is_started()) return 0;
if (block.timestamp == start_time) return round_timer;
return (block.timestamp - start_time) % round_timer;
}
function round_is_dirty() public view returns (bool) {
return _round_number != round_number();
}
function try_update_round() external {
require(round_is_dirty(), "round is not dirty");
_update_round();
}
function _try_update_round() private {
if (!round_is_dirty()) return;
_update_round();
}
function _update_round() private {
_round_number = round_number();
_round_busy_cells_count = _busy_cells_count;
(_round_reward_token, _round_reward_eth) = _new_round_reward(
_round_number
);
}
function next_round_reward() public view returns (uint token, uint eth) {
return _new_round_reward(round_number() + 1);
}
function round_reward() public view returns (uint token, uint eth) {
if (round_is_dirty()) return _new_round_reward(round_number());
token = _round_reward_token;
eth = _round_reward_eth;
}
function _new_round_reward(
uint round_number
) internal view returns (uint token, uint eth) {
uint r = round_reward_percent_min +
(rand(round_number) %
(round_reward_percent_max - round_reward_percent_min + 1));
(uint total_token, uint total_eth) = total_reward();
token = (total_token * r) / calculations_precesion;
eth = (total_eth * r) / calculations_precesion;
}
function get_account_data(
address account
) public view returns (AccountData memory) {
return _data_normalized(_data[account]);
}
function _data_normalized(
AccountData memory data
) private view returns (AccountData memory) {
uint round = round_number();
if (round > data.round + 1) {
data.count += data.count_wait + data.count_new;
data.count_wait = 0;
data.count_new = 0;
} else {
if (round > data.round) {
data.count += data.count_wait;
data.count_wait = data.count_new;
data.count_new = 0;
}
}
data.round = round;
return data;
}
function _add_stake(address account, uint count) private {
_data[account] = _add_stake(_data[account], count);
}
function _add_stake(
AccountData memory data,
uint count
) private view returns (AccountData memory) {
data = _data_normalized(data);
data.count_new += count;
return data;
}
function busy_cells_count() external view returns (uint) {
return _busy_cells_count;
}
function get_cell(
uint x,
uint y
) public view valid_coordinates(x, y) returns (CellDataFull memory) {
CellData memory data = _cell_normalized(_cells[x][y]);
CellDataFull memory full;
full.owner = data.owner;
full.round = data.round;
full.state = data.state;
full.token_price = data.token_price;
full.attack_address = data.attack_address;
full.attack_end_time = data.attack_end_time;
full.need_claim = _can_claim_cell(_cells[x][y]);
return full;
}
function get_cells_chunk(
uint x,
uint y,
uint size
) external view returns (CellDataFull[] memory chunk) {
chunk = new CellDataFull[](size * size);
uint i;
uint j;
uint n;
for (j = y; j < y + size; ++j) {
for (i = x; i < x + size; ++i) {
chunk[n++] = get_cell(i, j);
}
}
}
function _cell_normalized(
CellData memory cell
) private view returns (CellData memory) {
if (cell.is_empty()) return cell;
uint round = round_number();
if (cell.state == CELL_NEW && round > cell.round) {
++cell.state;
++cell.round;
}
if (cell.state == CELL_WAITING && round > cell.round) {
++cell.state;
cell.round = round;
}
return _cell_after_attack(cell);
}
function _cell_after_attack(
CellData memory cell
) private view returns (CellData memory) {
if (_can_claim_cell(cell)) {
cell.owner = cell.attack_address;
cell.attack_address = address(0);
cell.token_price = _calc_token_count_for_take_cell(cell);
cell.round = round_number();
}
return cell;
}
function token_count_for_take_cell(
uint x,
uint y
) external view returns (uint) {
return _calc_token_count_for_take_cell(_cell_normalized(_cells[x][y]));
}
function _calc_token_count_for_take_cell(
CellData memory cell
) private view returns (uint) {
if (cell.is_empty()) return _token_count_for_take_cell;
return (cell.token_price * attack_add_percent) / 100;
}
function set_token_count_for_take_cell(
uint new_token_count_for_take_cell
) external onlyOwner {
_token_count_for_take_cell = new_token_count_for_take_cell;
}
function take_cell(
uint x,
uint y
) external valid_coordinates(x, y) on_started nonReentrant onlyEoa {
require(can_take_cell(msg.sender, x, y), ACCOUNT_CAN_NOT_TAKE_CELL);
_take_cell(x, y);
}
function _take_cell(
uint x,
uint y
) private valid_coordinates(x, y) on_started {
_try_update_round();
CellData memory cell = _cell_normalized(_cells[x][y]);
require(cell.is_empty(), "cell is not empty");
cell.owner = msg.sender;
cell.round = round_number();
cell.state = CELL_NEW;
cell.token_price = _token_count_for_take_cell;
token.transferFrom(
msg.sender,
address(this),
_token_count_for_take_cell
);
total_users_tokens += cell.token_price - fee(cell.token_price);
++_busy_cells_count;
_cells[x][y] = cell;
_add_stake(msg.sender, 1);
emit TakeCell(x, y);
}
function attack_cell(
uint x,
uint y
) external valid_coordinates(x, y) on_started nonReentrant onlyEoa {
require(can_take_cell(msg.sender, x, y), ACCOUNT_CAN_NOT_TAKE_CELL);
CellData memory cell = _cells[x][y];
if (_can_claim_cell(cell))
cell = _claim_cell(x, y, cell.attack_address);
require(cell.attack_address == address(0), "already attacked");
require(cell.owner != msg.sender, "can not attack self");
if (cell.is_empty()) {
_take_cell(x, y);
return;
}
uint price = _calc_token_count_for_take_cell(cell);
total_users_tokens += price;
token.transferFrom(msg.sender, address(this), price);
cell.attack_address = msg.sender;
uint attack_timer = attack_timer_min +
(rand(round_number()) % (attack_timer_max - attack_timer_min + 1));
cell.attack_end_time = block.timestamp + attack_timer;
_cells[x][y] = cell;
emit Attack(x, y, msg.sender);
}
function defend_cell(uint x, uint y) public nonReentrant onlyEoa {
_defend_cell(x, y, _cell_normalized(_cells[x][y]));
}
function _defend_cell(
uint x,
uint y,
CellData memory cell
) internal returns (CellData memory) {
require(cell.owner == msg.sender, "only for cell owner");
require(block.timestamp < cell.attack_end_time, "time is up");
uint attack_revert_tokens = _calc_token_count_for_take_cell(cell);
address attack_address = cell.attack_address;
cell.attack_address = address(0);
cell.attack_end_time = 0;
_cells[x][y] = cell;
if (attack_revert_tokens > 0)
token.transfer(attack_address, attack_revert_tokens);
total_users_tokens -= attack_revert_tokens;
emit Defend(x, y);
return cell;
}
function can_claim_cell(uint x, uint y) external view returns (bool) {
return _can_claim_cell(_cells[x][y]);
}
function _can_claim_cell(
CellData memory cell_last
) private view returns (bool) {
return
cell_last.attack_address != address(0) &&
block.timestamp >= cell_last.attack_end_time;
}
function claim_cell(uint x, uint y) external nonReentrant onlyEoa {
_claim_cell(x, y, msg.sender);
}
function _claim_cell(
uint x,
uint y,
address account
) private returns (CellData memory) {
CellData memory cell_last = _cells[x][y];
CellData memory cell_updated = _cell_normalized(_cells[x][y]);
require(
block.timestamp >= cell_last.attack_end_time,
"time has not yet expired"
);
_data[cell_last.owner] = _remove(
get_account_data(cell_last.owner),
cell_updated
);
_data[cell_last.attack_address] = _add(
get_account_data(cell_last.attack_address),
cell_updated
);
total_users_tokens -= cell_last.token_price;
uint leave_tokens = (cell_last.token_price *
attack_leave_land_percent) / calculations_precesion;
uint attack_revert_tokens = (cell_last.token_price *
attack_revert_percent) / calculations_precesion;
if (leave_tokens > 0) token.transfer(cell_last.owner, leave_tokens);
if (attack_revert_tokens > 0)
token.transfer(cell_last.attack_address, attack_revert_tokens);
_cells[x][y] = cell_updated;
emit AttackClaimed(x, y, account);
return cell_updated;
}
function leave_cell(uint x, uint y) external onlyEoa {
_leave_cell(x, y);
}
function _leave_cell(
uint x,
uint y
) private valid_coordinates(x, y) nonReentrant {
_try_update_round();
CellData memory cell = _cell_after_attack(
_cell_normalized(_cells[x][y])
);
AccountData memory data = get_account_data(cell.owner);
if (_has_reward(data)) {
_claim(cell.owner);
cell = _cell_after_attack(_cell_normalized(_cells[x][y]));
}
require(cell.owner == msg.sender, "only for cell owner");
require(cell.attack_address == address(0), "cell is under attack");
_data[cell.owner] = _remove(get_account_data(cell.owner), cell);
--_busy_cells_count;
uint tokens_to_send = cell.token_price - fee(cell.token_price);
total_users_tokens -= tokens_to_send;
token.transfer(cell.owner, tokens_to_send);
delete _cells[x][y];
}
function _remove(
AccountData memory data,
CellData memory cell
) private view returns (AccountData memory) {
data = _data_normalized(data);
if (cell.state == CELL_NEW) {
if (data.count_new > 0) --data.count_new;
} else if (cell.state == CELL_WAITING) {
if (data.count_wait > 0) --data.count_wait;
} else if (cell.state == CELL_READY) {
if (data.count > 0) --data.count;
}
return data;
}
function _add(
AccountData memory data,
CellData memory cell
) private view returns (AccountData memory) {
data = _data_normalized(data);
if (cell.state == CELL_NEW) {
++data.count_new;
} else if (cell.state == CELL_WAITING) {
++data.count_wait;
} else if (cell.state == CELL_READY) {
++data.count;
}
return data;
}
function round_cells_count() public view returns (uint256) {
if (round_is_dirty()) return _busy_cells_count;
return _round_busy_cells_count;
}
function has_reward(address account) public view returns (bool) {
return _has_reward(get_account_data(account));
}
function _has_reward(AccountData memory data) private view returns (bool) {
if (data.claim_round == round_number()) return false;
if (data.count == 0) return false;
return true;
}
function claim() external {
_claim(msg.sender);
}
function _claim(address account) internal {
AccountData memory data = get_account_data(account);
require(_has_reward(data), "has no reward");
data = _claim(data, account);
data.claim_round = round_number();
_data[account] = data;
}
function _claim(
AccountData memory data,
address account
) private onlyEoa returns (AccountData memory) {
_try_update_round();
if (!_has_reward(data)) return data;
(uint token_reward, uint eth_reward) = _round_reward(data);
data.claim_round = round_number();
if (eth_reward > 0) {
(bool sent, ) = payable(account).call{value: eth_reward}("");
require(sent, "eth is not sent");
}
if (token_reward > 0) {
token.transfer(account, token_reward);
}
return data;
}
function round_account_reward(
address account
) external view returns (uint token, uint eth) {
return _round_reward(get_account_data(account));
}
function _round_reward(
AccountData memory data
) private view returns (uint token, uint eth) {
if (!_has_reward(data)) return (0, 0);
if (round_cells_count() == 0) return (0, 0);
(uint round_token, uint round_eth) = round_reward();
token = (round_token * data.count) / round_cells_count();
eth = (round_eth * data.count) / round_cells_count();
}
function get_sector_noise(uint x, uint y) public pure returns (int128) {
return Perlin.noise2d(int(x), int(y), 7, 10);
}
function get_sector(uint x, uint y) public pure returns (uint8) {
int128 noise = Perlin.noise2d(int(x), int(y), 7, 10) +
Perlin.noise2d(int(x), int(y), 14, 9);
int128 precesion = 2 ** 10;
if (noise < (precesion * 70) / 100) return 1;
else {
return 2;
}
}
function get_sector_chunk(
uint x,
uint y,
uint size
) public pure returns (uint8[] memory chunk) {
chunk = new uint8[](size * size);
uint i;
uint j;
uint n;
for (j = y; j < y + size; ++j) {
for (i = x; i < x + size; ++i) {
chunk[n++] = get_sector(i, j);
}
}
}
}
文件 5 的 13:IERC20.sol
pragma solidity ^0.8.20;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
文件 6 的 13:IFlags.sol
pragma solidity ^0.8.25;
import "./Rects.sol";
interface IFlags {
function flag_size() external pure returns (uint x, uint y);
function set_flag(address account, Rect[] calldata rects) external;
function reset_flag(address account) external;
function has_custom_flag(address account) external view returns (bool);
function get_flag_svg(
address account
) external view returns (string memory);
}
文件 7 的 13:IGame.sol
pragma solidity ^0.8.25;
import "./Cell.sol";
import "./Rects.sol";
struct AccountData {
uint count;
uint count_wait;
uint count_new;
uint round;
uint claim_round;
}
interface IGame {
event TakeCell(uint x, uint y);
event Attack(uint x, uint y, address account);
event Defend(uint x, uint y);
event AttackClaimed(uint x, uint y, address account);
function WORLD_SIZE() external pure returns (uint);
function total_users_tokens() external view returns (uint);
function round_timer() external view returns (uint);
function round_number() external view returns (uint);
function next_round_time() external view returns (uint);
function next_round_lapsed_time() external view returns (uint);
function round_is_dirty() external view returns (bool);
function try_update_round() external;
function get_account_data(
address account
) external view returns (AccountData memory);
function busy_cells_count() external view returns (uint);
function get_cell(
uint x,
uint y
) external view returns (CellDataFull memory);
function get_cells_chunk(
uint x,
uint y,
uint size
) external view returns (CellDataFull[] memory chunk);
function token_count_for_take_cell(
uint x,
uint y
) external view returns (uint);
function can_take_cell(
address account,
uint x,
uint y
) external view returns (bool);
function take_cell(uint x, uint y) external;
function leave_cell(uint x, uint y) external;
function round_cells_count() external view returns (uint256);
function total_reward() external view returns (uint token, uint eth);
function round_reward() external view returns (uint token, uint eth);
function next_round_reward() external view returns (uint token, uint eth);
function claim() external;
function has_reward(address account) external view returns (bool);
function round_account_reward(
address account
) external view returns (uint token, uint eth);
function attack_cell(uint x, uint y) external;
function defend_cell(uint x, uint y) external;
function claim_cell(uint x, uint y) external;
function can_claim_cell(uint x, uint y) external view returns (bool);
function get_sector(uint x, uint y) external pure returns (uint8);
function get_sector_chunk(
uint x,
uint y,
uint size
) external pure returns (uint8[] memory chunk);
function flag_size() external view returns (uint x, uint y);
function set_flag(Rect[] calldata rects) external;
function reset_flag() external;
function has_custom_flag(address account) external view returns (bool);
function get_flag_svg(
address account
) external view returns (string memory);
}
文件 8 的 13:Ownable.sol
pragma solidity ^0.8.23;
contract Ownable {
address _owner;
event RenounceOwnership();
constructor() {
_owner = msg.sender;
}
modifier onlyOwner() {
require(_owner == msg.sender, "only owner");
_;
}
function owner() external view virtual returns (address) {
return _owner;
}
function ownerRenounce() public onlyOwner {
_owner = address(0);
emit RenounceOwnership();
}
function transferOwnership(address newOwner) external onlyOwner {
_owner = newOwner;
}
}
文件 9 的 13:Perlin.sol
pragma solidity ^0.8.0;
import {ABDKMath64x64 as Math} from "abdk-libraries-solidity/ABDKMath64x64.sol";
int128 constant _1 = 2**64;
int128 constant _2 = 2 * 2**64;
int128 constant _6 = 6 * 2**64;
int128 constant _10 = 10 * 2**64;
int128 constant _15 = 15 * 2**64;
struct H {
int16 X;
int16 Y;
int16 Z;
int16 A;
int16 AA;
int16 AB;
int16 B;
int16 BA;
int16 BB;
int16 pX;
int16 pA;
int16 pB;
int16 pAA;
int16 pAB;
int16 pBA;
int16 pBB;
int128 x;
int128 y;
int128 z;
int128 u;
int128 v;
int128 w;
int128 r;
}
struct H2 {
int16 X;
int16 Y;
int16 A;
int16 AA;
int16 AB;
int16 B;
int16 BA;
int16 BB;
int16 pX;
int16 pA;
int16 pB;
int128 x;
int128 y;
int128 u;
int128 r;
}
library Perlin {
function noise2d(
int256 _x,
int256 _y,
int256 denom,
uint8 precision
) internal pure returns (int128) {
H2 memory h = H2(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
h.x = Math.divi(_x, denom);
h.y = Math.divi(_y, denom);
h.X = int16(Math.toInt(h.x)) & 0xff;
h.Y = int16(Math.toInt(h.y)) & 0xff;
h.x = Math.sub(h.x, floor(h.x));
h.y = Math.sub(h.y, floor(h.y));
h.u = fade(h.x);
h.pX = p2(h.X);
h.A = i0(h.pX) + h.Y;
h.pA = p2(h.A);
h.AA = i0(h.pA);
h.AB = i1(h.pA);
h.B = i1(h.pX) + h.Y;
h.pB = p2(h.B);
h.BA = i0(h.pB);
h.BB = i1(h.pB);
h.r = lerp(
fade(h.y),
lerp(h.u, grad2d(int16(p(h.AA)), h.x, h.y), grad2d(int16(p(h.BA)), dec(h.x), h.y)),
lerp(h.u, grad2d(int16(p(h.AB)), h.x, dec(h.y)), grad2d(int16(p(h.BB)), dec(h.x), dec(h.y)))
);
return Math.div(Math.add(h.r, _1), _2) >> (64 - precision);
}
function noise(
int256 _x,
int256 _y,
int256 _z,
int256 denom,
uint8 precision
) internal pure returns (int128) {
H memory h = H(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
h.x = Math.divi(_x, denom);
h.y = Math.divi(_y, denom);
h.z = Math.divi(_z, denom);
h.X = int16(Math.toInt(h.x)) & 255;
h.Y = int16(Math.toInt(h.y)) & 255;
h.Z = int16(Math.toInt(h.z)) & 255;
h.x = Math.sub(h.x, floor(h.x));
h.y = Math.sub(h.y, floor(h.y));
h.z = Math.sub(h.z, floor(h.z));
h.u = fade(h.x);
h.v = fade(h.y);
h.w = fade(h.z);
h.pX = p2(h.X);
h.A = i0(h.pX) + h.Y;
h.pA = p2(h.A);
h.AA = i0(h.pA) + h.Z;
h.AB = i1(h.pA) + h.Z;
h.B = i1(h.pX) + h.Y;
h.pB = p2(h.B);
h.BA = i0(h.pB) + h.Z;
h.BB = i1(h.pB) + h.Z;
h.pAA = p2(h.AA);
h.pAB = p2(h.AB);
h.pBA = p2(h.BA);
h.pBB = p2(h.BB);
h.r = lerp(
h.w,
lerp(
h.v,
lerp(h.u, grad(i0(h.pAA), h.x, h.y, h.z), grad(i0(h.pBA), dec(h.x), h.y, h.z)),
lerp(h.u, grad(i0(h.pAB), h.x, dec(h.y), h.z), grad(i0(h.pBB), dec(h.x), dec(h.y), h.z))
),
lerp(
h.v,
lerp(h.u, grad(i1(h.pAA), h.x, h.y, dec(h.z)), grad(i1(h.pBA), dec(h.x), h.y, dec(h.z))),
lerp(h.u, grad(i1(h.pAB), h.x, dec(h.y), dec(h.z)), grad(i1(h.pBB), dec(h.x), dec(h.y), dec(h.z)))
)
);
return Math.div(Math.add(h.r, _1), _2) >> (64 - precision);
}
function dec(int128 x) internal pure returns (int128) {
return Math.sub(x, _1);
}
function floor(int128 x) internal pure returns (int128) {
return Math.fromInt(int256(Math.toInt(x)));
}
function fade(int128 t) internal pure returns (int128) {
return Math.mul(t, Math.mul(t, Math.mul(t, (Math.add(Math.mul(t, (Math.sub(Math.mul(t, _6), _15))), _10)))));
}
function lerp(
int128 t,
int128 a,
int128 b
) internal pure returns (int128) {
return Math.add(a, Math.mul(t, (Math.sub(b, a))));
}
function grad(
int16 _hash,
int128 x,
int128 y,
int128 z
) internal pure returns (int128) {
int16 h = _hash & 0xF;
if (h <= 0x7) {
if (h <= 0x3) {
if (h <= 0x1) {
if (h == 0x0) return Math.add(x, y);
return Math.sub(y, x);
} else {
if (h == 0x2) return Math.sub(x, y);
return Math.sub(Math.neg(x), y);
}
} else {
if (h <= 0x5) {
if (h == 0x4) return Math.add(x, z);
return Math.sub(z, x);
} else {
if (h == 0x6) return Math.sub(x, z);
return Math.sub(Math.neg(x), z);
}
}
} else {
if (h <= 0xB) {
if (h <= 0x9) {
if (h == 0x8) return Math.add(y, z);
return Math.sub(z, y);
} else {
if (h == 0xA) return Math.sub(y, z);
return Math.sub(Math.neg(y), z);
}
} else {
if (h <= 0xD) {
if (h == 0xC) return Math.add(y, x);
return Math.add(Math.neg(y), z);
} else {
if (h == 0xE) return Math.sub(y, x);
return Math.sub(Math.neg(y), z);
}
}
}
}
function grad2d(
int16 _hash,
int128 x,
int128 y
) internal pure returns (int128) {
int16 h = _hash & 0xF;
if (h <= 0x7) {
if (h <= 0x3) {
if (h <= 0x1) {
if (h == 0x0) return Math.add(x, y);
return Math.sub(y, x);
} else {
if (h == 0x2) return Math.sub(x, y);
return Math.sub(Math.neg(x), y);
}
} else {
if (h <= 0x5) {
if (h == 0x4) return x;
return Math.neg(x);
} else {
if (h == 0x6) return x;
return Math.neg(x);
}
}
} else {
if (h <= 0xB) {
if (h <= 0x9) {
if (h == 0x8) return y;
return Math.neg(y);
} else {
if (h == 0xA) return y;
return Math.neg(y);
}
} else {
if (h <= 0xD) {
if (h == 0xC) return Math.add(y, x);
return Math.neg(y);
} else {
if (h == 0xE) return Math.sub(y, x);
return Math.neg(y);
}
}
}
}
function p(int64 i) internal pure returns (int64) {
return int64(ptable(int256(i)) >> 8);
}
function p2(int16 i) internal pure returns (int16) {
return int16(ptable(int256(i)));
}
function i0(int16 tuple) internal pure returns (int16) {
return tuple >> 8;
}
function i1(int16 tuple) internal pure returns (int16) {
return tuple & 0xff;
}
function ptable(int256 i) internal pure returns (int256) {
i &= 0xff;
if (i <= 127) {
if (i <= 63) {
if (i <= 31) {
if (i <= 15) {
if (i <= 7) {
if (i <= 3) {
if (i <= 1) {
if (i == 0) {
return 38816;
} else {
return 41097;
}
} else {
if (i == 2) {
return 35163;
} else {
return 23386;
}
}
} else {
if (i <= 5) {
if (i == 4) {
return 23055;
} else {
return 3971;
}
} else {
if (i == 6) {
return 33549;
} else {
return 3529;
}
}
}
} else {
if (i <= 11) {
if (i <= 9) {
if (i == 8) {
return 51551;
} else {
return 24416;
}
} else {
if (i == 10) {
return 24629;
} else {
return 13762;
}
}
} else {
if (i <= 13) {
if (i == 12) {
return 49897;
} else {
return 59655;
}
} else {
if (i == 14) {
return 2017;
} else {
return 57740;
}
}
}
}
} else {
if (i <= 23) {
if (i <= 19) {
if (i <= 17) {
if (i == 16) {
return 35876;
} else {
return 9319;
}
} else {
if (i == 18) {
return 26398;
} else {
return 7749;
}
}
} else {
if (i <= 21) {
if (i == 20) {
return 17806;
} else {
return 36360;
}
} else {
if (i == 22) {
return 2147;
} else {
return 25381;
}
}
}
} else {
if (i <= 27) {
if (i <= 25) {
if (i == 24) {
return 9712;
} else {
return 61461;
}
} else {
if (i == 26) {
return 5386;
} else {
return 2583;
}
}
} else {
if (i <= 29) {
if (i == 28) {
return 6078;
} else {
return 48646;
}
} else {
if (i == 30) {
return 1684;
} else {
return 38135;
}
}
}
}
}
} else {
if (i <= 47) {
if (i <= 39) {
if (i <= 35) {
if (i <= 33) {
if (i == 32) {
return 63352;
} else {
return 30954;
}
} else {
if (i == 34) {
return 59979;
} else {
return 19200;
}
}
} else {
if (i <= 37) {
if (i == 36) {
return 26;
} else {
return 6853;
}
} else {
if (i == 38) {
return 50494;
} else {
return 15966;
}
}
}
} else {
if (i <= 43) {
if (i <= 41) {
if (i == 40) {
return 24316;
} else {
return 64731;
}
} else {
if (i == 42) {
return 56267;
} else {
return 52085;
}
}
} else {
if (i <= 45) {
if (i == 44) {
return 29987;
} else {
return 8971;
}
} else {
if (i == 46) {
return 2848;
} else {
return 8249;
}
}
}
}
} else {
if (i <= 55) {
if (i <= 51) {
if (i <= 49) {
if (i == 48) {
return 14769;
} else {
return 45345;
}
} else {
if (i == 50) {
return 8536;
} else {
return 22765;
}
}
} else {
if (i <= 53) {
if (i == 52) {
return 60821;
} else {
return 38200;
}
} else {
if (i == 54) {
return 14423;
} else {
return 22446;
}
}
}
} else {
if (i <= 59) {
if (i <= 57) {
if (i == 56) {
return 44564;
} else {
return 5245;
}
} else {
if (i == 58) {
return 32136;
} else {
return 34987;
}
}
} else {
if (i <= 61) {
if (i == 60) {
return 43944;
} else {
return 43076;
}
} else {
if (i == 62) {
return 17583;
} else {
return 44874;
}
}
}
}
}
}
} else {
if (i <= 95) {
if (i <= 79) {
if (i <= 71) {
if (i <= 67) {
if (i <= 65) {
if (i == 64) {
return 19109;
} else {
return 42311;
}
} else {
if (i == 66) {
return 18310;
} else {
return 34443;
}
}
} else {
if (i <= 69) {
if (i == 68) {
return 35632;
} else {
return 12315;
}
} else {
if (i == 70) {
return 7078;
} else {
return 42573;
}
}
}
} else {
if (i <= 75) {
if (i <= 73) {
if (i == 72) {
return 19858;
} else {
return 37534;
}
} else {
if (i == 74) {
return 40679;
} else {
return 59219;
}
}
} else {
if (i <= 77) {
if (i == 76) {
return 21359;
} else {
return 28645;
}
} else {
if (i == 78) {
return 58746;
} else {
return 31292;
}
}
}
}
} else {
if (i <= 87) {
if (i <= 83) {
if (i <= 81) {
if (i == 80) {
return 15571;
} else {
return 54149;
}
} else {
if (i == 82) {
return 34278;
} else {
return 59100;
}
}
} else {
if (i <= 85) {
if (i == 84) {
return 56425;
} else {
return 26972;
}
} else {
if (i == 86) {
return 23593;
} else {
return 10551;
}
}
}
} else {
if (i <= 91) {
if (i <= 89) {
if (i == 88) {
return 14126;
} else {
return 12021;
}
} else {
if (i == 90) {
return 62760;
} else {
return 10484;
}
}
} else {
if (i <= 93) {
if (i == 92) {
return 62566;
} else {
return 26255;
}
} else {
if (i == 94) {
return 36662;
} else {
return 13889;
}
}
}
}
}
} else {
if (i <= 111) {
if (i <= 103) {
if (i <= 99) {
if (i <= 97) {
if (i == 96) {
return 16665;
} else {
return 6463;
}
} else {
if (i == 98) {
return 16289;
} else {
return 41217;
}
}
} else {
if (i <= 101) {
if (i == 100) {
return 472;
} else {
return 55376;
}
} else {
if (i == 102) {
return 20553;
} else {
return 18897;
}
}
}
} else {
if (i <= 107) {
if (i <= 105) {
if (i == 104) {
return 53580;
} else {
return 19588;
}
} else {
if (i == 106) {
return 33979;
} else {
return 48080;
}
}
} else {
if (i <= 109) {
if (i == 108) {
return 53337;
} else {
return 22802;
}
} else {
if (i == 110) {
return 4777;
} else {
return 43464;
}
}
}
}
} else {
if (i <= 119) {
if (i <= 115) {
if (i <= 113) {
if (i == 112) {
return 51396;
} else {
return 50311;
}
} else {
if (i == 114) {
return 34690;
} else {
return 33396;
}
}
} else {
if (i <= 117) {
if (i == 116) {
return 29884;
} else {
return 48287;
}
} else {
if (i == 118) {
return 40790;
} else {
return 22180;
}
}
}
} else {
if (i <= 123) {
if (i <= 121) {
if (i == 120) {
return 42084;
} else {
return 25709;
}
} else {
if (i == 122) {
return 28102;
} else {
return 50861;
}
}
} else {
if (i <= 125) {
if (i == 124) {
return 44474;
} else {
return 47619;
}
} else {
if (i == 126) {
return 832;
} else {
return 16436;
}
}
}
}
}
}
}
} else {
if (i <= 191) {
if (i <= 159) {
if (i <= 143) {
if (i <= 135) {
if (i <= 131) {
if (i <= 129) {
if (i == 128) {
return 13529;
} else {
return 55778;
}
} else {
if (i == 130) {
return 58106;
} else {
return 64124;
}
}
} else {
if (i <= 133) {
if (i == 132) {
return 31867;
} else {
return 31493;
}
} else {
if (i == 134) {
return 1482;
} else {
return 51750;
}
}
}
} else {
if (i <= 139) {
if (i <= 137) {
if (i == 136) {
return 9875;
} else {
return 37750;
}
} else {
if (i == 138) {
return 30334;
} else {
return 32511;
}
}
} else {
if (i <= 141) {
if (i == 140) {
return 65362;
} else {
return 21077;
}
} else {
if (i == 142) {
return 21972;
} else {
return 54479;
}
}
}
}
} else {
if (i <= 151) {
if (i <= 147) {
if (i <= 145) {
if (i == 144) {
return 53198;
} else {
return 52795;
}
} else {
if (i == 146) {
return 15331;
} else {
return 58159;
}
}
} else {
if (i <= 149) {
if (i == 148) {
return 12048;
} else {
return 4154;
}
} else {
if (i == 150) {
return 14865;
} else {
return 4534;
}
}
}
} else {
if (i <= 155) {
if (i <= 153) {
if (i == 152) {
return 46781;
} else {
return 48412;
}
} else {
if (i == 154) {
return 7210;
} else {
return 10975;
}
}
} else {
if (i <= 157) {
if (i == 156) {
return 57271;
} else {
return 47018;
}
} else {
if (i == 158) {
return 43733;
} else {
return 54647;
}
}
}
}
}
} else {
if (i <= 175) {
if (i <= 167) {
if (i <= 163) {
if (i <= 161) {
if (i == 160) {
return 30712;
} else {
return 63640;
}
} else {
if (i == 162) {
return 38914;
} else {
return 556;
}
}
} else {
if (i <= 165) {
if (i == 164) {
return 11418;
} else {
return 39587;
}
} else {
if (i == 166) {
return 41798;
} else {
return 18141;
}
}
}
} else {
if (i <= 171) {
if (i <= 169) {
if (i == 168) {
return 56729;
} else {
return 39269;
}
} else {
if (i == 170) {
return 26011;
} else {
return 39847;
}
}
} else {
if (i <= 173) {
if (i == 172) {
return 42795;
} else {
return 11180;
}
} else {
if (i == 174) {
return 44041;
} else {
return 2433;
}
}
}
}
} else {
if (i <= 183) {
if (i <= 179) {
if (i <= 177) {
if (i == 176) {
return 33046;
} else {
return 5671;
}
} else {
if (i == 178) {
return 10237;
} else {
return 64787;
}
}
} else {
if (i <= 181) {
if (i == 180) {
return 4962;
} else {
return 25196;
}
} else {
if (i == 182) {
return 27758;
} else {
return 28239;
}
}
}
} else {
if (i <= 187) {
if (i <= 185) {
if (i == 184) {
return 20337;
} else {
return 29152;
}
} else {
if (i == 186) {
return 57576;
} else {
return 59570;
}
}
} else {
if (i <= 189) {
if (i == 188) {
return 45753;
} else {
return 47472;
}
} else {
if (i == 190) {
return 28776;
} else {
return 26842;
}
}
}
}
}
}
} else {
if (i <= 223) {
if (i <= 207) {
if (i <= 199) {
if (i <= 195) {
if (i <= 193) {
if (i == 192) {
return 56054;
} else {
return 63073;
}
} else {
if (i == 194) {
return 25060;
} else {
return 58619;
}
}
} else {
if (i <= 197) {
if (i == 196) {
return 64290;
} else {
return 8946;
}
} else {
if (i == 198) {
return 62145;
} else {
return 49646;
}
}
}
} else {
if (i <= 203) {
if (i <= 201) {
if (i == 200) {
return 61138;
} else {
return 53904;
}
} else {
if (i == 202) {
return 36876;
} else {
return 3263;
}
}
} else {
if (i <= 205) {
if (i == 204) {
return 49075;
} else {
return 45986;
}
} else {
if (i == 206) {
return 41713;
} else {
return 61777;
}
}
}
}
} else {
if (i <= 215) {
if (i <= 211) {
if (i <= 209) {
if (i == 208) {
return 20787;
} else {
return 13201;
}
} else {
if (i == 210) {
return 37355;
} else {
return 60409;
}
}
} else {
if (i <= 213) {
if (i == 212) {
return 63758;
} else {
return 3823;
}
} else {
if (i == 214) {
return 61291;
} else {
return 27441;
}
}
}
} else {
if (i <= 219) {
if (i <= 217) {
if (i == 216) {
return 12736;
} else {
return 49366;
}
} else {
if (i == 218) {
return 54815;
} else {
return 8117;
}
}
} else {
if (i <= 221) {
if (i == 220) {
return 46535;
} else {
return 51050;
}
} else {
if (i == 222) {
return 27293;
} else {
return 40376;
}
}
}
}
}
} else {
if (i <= 239) {
if (i <= 231) {
if (i <= 227) {
if (i <= 225) {
if (i == 224) {
return 47188;
} else {
return 21708;
}
} else {
if (i == 226) {
return 52400;
} else {
return 45171;
}
}
} else {
if (i <= 229) {
if (i == 228) {
return 29561;
} else {
return 31026;
}
} else {
if (i == 230) {
return 12845;
} else {
return 11647;
}
}
}
} else {
if (i <= 235) {
if (i <= 233) {
if (i == 232) {
return 32516;
} else {
return 1174;
}
} else {
if (i == 234) {
return 38654;
} else {
return 65162;
}
}
} else {
if (i <= 237) {
if (i == 236) {
return 35564;
} else {
return 60621;
}
} else {
if (i == 238) {
return 52573;
} else {
return 24030;
}
}
}
}
} else {
if (i <= 247) {
if (i <= 243) {
if (i <= 241) {
if (i == 240) {
return 56946;
} else {
return 29251;
}
} else {
if (i == 242) {
return 17181;
} else {
return 7448;
}
}
} else {
if (i <= 245) {
if (i == 244) {
return 6216;
} else {
return 18675;
}
} else {
if (i == 246) {
return 62349;
} else {
return 36224;
}
}
}
} else {
if (i <= 251) {
if (i <= 249) {
if (i == 248) {
return 32963;
} else {
return 49998;
}
} else {
if (i == 250) {
return 20034;
} else {
return 17111;
}
}
} else {
if (i <= 253) {
if (i == 252) {
return 55101;
} else {
return 15772;
}
} else {
if (i == 254) {
return 40116;
} else {
return 46231;
}
}
}
}
}
}
}
}
}
}
文件 10 的 13:Rects.sol
pragma solidity ^0.8.25;
import "./StringConverter.sol";
struct Rect {
string color;
uint x;
uint y;
uint width;
uint height;
}
library RectLibrary {
using RectLibrary for Rect;
using RectLibrary for Rect[];
function to_svg(
Rect memory rect
) internal view returns (string memory svg) {
return
string(
abi.encodePacked(
"<rect fill='#",
rect.color,
"' x='",
StringConverter.to_string(rect.x),
"' y='",
StringConverter.to_string(rect.y),
"' width='",
StringConverter.to_string(rect.width),
"' height='",
StringConverter.to_string(rect.height),
"'/>"
)
);
}
function to_svg(Rect[] memory rects) internal view returns (string memory) {
string memory res;
for (uint i = 0; i < rects.length; ++i) {
res = string(abi.encodePacked(res, rects[i].to_svg()));
}
return res;
}
function to_svg(
Rect[] storage rects
) internal view returns (string memory res) {
for (uint i = 0; i < rects.length; ++i) {
res = string(abi.encodePacked(res, rects[i].to_svg()));
}
return res;
}
}
文件 11 的 13:ReentrancyGuard.sol
pragma solidity ^0.8.20;
abstract contract ReentrancyGuard {
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
_status = ENTERED;
}
function _nonReentrantAfter() private {
_status = NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
文件 12 的 13:Startable.sol
pragma solidity ^0.8.25;
import "../lib/Ownable.sol";
contract Startable is Ownable {
uint public start_time;
modifier on_started() {
require(is_started(), "game is not started");
_;
}
function is_started() public view returns (bool) {
return start_time != 0;
}
function start_game() external onlyOwner {
start_time = block.timestamp;
on_start();
}
function on_start() internal virtual {}
}
文件 13 的 13:StringConverter.sol
pragma solidity ^0.8.25;
library StringConverter {
function to_string(uint value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint temp = value;
uint digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
}
{
"compilationTarget": {
"contracts/game/GameEngine.sol": "GameEngine"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"token_address","type":"address"},{"internalType":"address","name":"flags_address","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"x","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"y","type":"uint256"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Attack","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"x","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"y","type":"uint256"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"AttackClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"x","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"y","type":"uint256"}],"name":"Defend","type":"event"},{"anonymous":false,"inputs":[],"name":"RenounceOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"x","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"y","type":"uint256"}],"name":"TakeCell","type":"event"},{"inputs":[],"name":"WORLD_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"attack_add_percent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"attack_cell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"attack_leave_land_percent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"attack_revert_percent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"attack_timer_max","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"attack_timer_min","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"busy_cells_count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculations_precesion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"can_claim_cell","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"can_take_cell","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"claim_cell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"defend_cell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fee_percent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flag_size","outputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flags","outputs":[{"internalType":"contract IFlags","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"get_account_data","outputs":[{"components":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"count_wait","type":"uint256"},{"internalType":"uint256","name":"count_new","type":"uint256"},{"internalType":"uint256","name":"round","type":"uint256"},{"internalType":"uint256","name":"claim_round","type":"uint256"}],"internalType":"struct AccountData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"get_cell","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"round","type":"uint256"},{"internalType":"uint8","name":"state","type":"uint8"},{"internalType":"uint256","name":"token_price","type":"uint256"},{"internalType":"address","name":"attack_address","type":"address"},{"internalType":"uint256","name":"attack_end_time","type":"uint256"},{"internalType":"bool","name":"need_claim","type":"bool"}],"internalType":"struct CellDataFull","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256","name":"size","type":"uint256"}],"name":"get_cells_chunk","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"round","type":"uint256"},{"internalType":"uint8","name":"state","type":"uint8"},{"internalType":"uint256","name":"token_price","type":"uint256"},{"internalType":"address","name":"attack_address","type":"address"},{"internalType":"uint256","name":"attack_end_time","type":"uint256"},{"internalType":"bool","name":"need_claim","type":"bool"}],"internalType":"struct CellDataFull[]","name":"chunk","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"get_flag_svg","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"get_sector","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256","name":"size","type":"uint256"}],"name":"get_sector_chunk","outputs":[{"internalType":"uint8[]","name":"chunk","type":"uint8[]"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"get_sector_noise","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"has_custom_flag","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"has_reward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"is_started","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"leave_cell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"next_round_lapsed_time","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"next_round_reward","outputs":[{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"eth","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"next_round_time","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerRenounce","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reset_flag","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"round_account_reward","outputs":[{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"eth","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"round_cells_count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"round_is_dirty","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"round_number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"round_reward","outputs":[{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"eth","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"round_reward_percent_max","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"round_reward_percent_min","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"round_timer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"new_attack_add_percent","type":"uint256"}],"name":"set_attack_add_percent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"new_attack_leave_land_percent","type":"uint256"},{"internalType":"uint256","name":"new_attack_crevert_percent","type":"uint256"}],"name":"set_attack_percent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"set_attack_timer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"new_fee_percent","type":"uint256"}],"name":"set_fee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"color","type":"string"},{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256","name":"width","type":"uint256"},{"internalType":"uint256","name":"height","type":"uint256"}],"internalType":"struct Rect[]","name":"rects","type":"tuple[]"}],"name":"set_flag","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"set_round_reward_percent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"new_round_timer_minutes","type":"uint256"}],"name":"set_round_timer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"new_token_count_for_take_cell","type":"uint256"}],"name":"set_token_count_for_take_cell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"start_game","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"start_time","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"take_cell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"token_count_for_take_cell","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"total_reward","outputs":[{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"eth","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"total_users_tokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"try_update_round","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]