Created
October 17, 2022 04:42
-
-
Save RossPfeiffer/8fa970745d4cd9f4a0fda568b87862c4 to your computer and use it in GitHub Desktop.
Not done
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.17; | |
contract fomoChess{ | |
address x0 = address(0); | |
address THIS = address(this); | |
ERC20 x$h33p = ERC20(0x2f712f2c2e4EEE913D15CAa8E4709400D61BFBAc); | |
address public key; | |
uint public boards=1; | |
mapping(uint=>Board) board_by_ID; | |
mapping(int=>mapping(int=>uint)) public MAP; | |
mapping(uint=>mapping(int=>uint)) BOARD;//board->index->pieceID | |
//mapping(int=>mapping(int=>bool)) BOARD;//for starting a board only | |
struct Board{ | |
uint pieces; | |
uint jackpot; | |
uint parent; | |
} | |
uint public pieces; | |
mapping(uint=>Piece) piece_by_ID; | |
struct Piece{ | |
address owner; | |
uint kind;//0empty 1pawn 2knight 3bishop 4rooke 5queen 6king . . . 8 gems | |
uint[] hand; | |
uint damage; | |
uint life; | |
uint lastMove; | |
uint lastAttack; | |
uint lastDraw; | |
mapping(uint/*ID of mechanic*/=>uint/*value applied for mechanic*/) effect; | |
mapping(uint=>mapping(uint=>uint)) replacedCardsOfDeck; | |
uint deck; | |
uint cardsDrawn; | |
} | |
mapping(address=>uint) public $$$; | |
mapping(uint=>uint) public N; | |
uint genesis; | |
constructor(){ | |
key = msg.sender; | |
genesis = block.timestamp; | |
Board storage board = board_by_ID[1]; | |
board.parent=1; | |
board_by_ID[1] = board; | |
MAP[0][0] = 1; | |
} | |
event Withdraw( address indexed user, uint amount ); | |
function withdraw() external{ | |
address sender = msg.sender; | |
uint $_$ = $$$[sender]; | |
$$$[sender] = 0; | |
x$h33p.transfer(sender,$_$); | |
emit Withdraw(sender,$_$); | |
} | |
bool numbersLocked; | |
function lockNumbers() external { | |
require(msg.sender == key); | |
numbersLocked = true; | |
} | |
function rule(uint[] memory indexes, uint[] memory values) external { | |
require(msg.sender == key && !numbersLocked); | |
uint L = indexes.length; | |
for(uint i = 0; i<L; i+=1){ | |
N[indexes[i]] = values[i]; | |
} | |
} | |
/* | |
ace of spades | |
hearts | |
diamonds | |
clubs | |
*/ | |
mapping(uint=>uint) public boosterPrice; | |
function boosterPriceUP(uint x) public pure returns(uint){ | |
return x+x/4; | |
} | |
event NewBoard(uint boardID, uint parentID, int x, int y); | |
function spawn(bool developingBoard0_freshBoard1, int boardX, int boardY, uint direction , int x, int y, int x2, int y2, uint[] memory boosterPack) external{ | |
address sender=msg.sender; | |
uint boosterCosts; | |
uint L = boosterPack.length; | |
uint cardcode; | |
for(uint i;i<L && i<5;i++){ | |
cardcode = boosterPack[i]; | |
require(cardcode<=52); | |
if(cardcode!=0){ | |
if(boosterPrice[cardcode]==0){ | |
boosterCosts += 1e16; | |
boosterPrice[cardcode] = boosterPriceUP(1e16); | |
}else{ | |
boosterCosts +=boosterPrice[cardcode]; | |
boosterPrice[cardcode] = boosterPriceUP(boosterPrice[cardcode]); | |
} | |
} | |
} | |
require(x$h33p.transferFrom(sender,THIS,boosterCosts+1e17/*cost of pawn*/) && !(x2==x&&y2==y) && L<=5 && x<8 && y<8 && x2<8 && y2<8); | |
$$$[key] += boosterCosts; | |
uint board = MAP[boardX][boardY]; | |
if(developingBoard0_freshBoard1){ | |
(int xx,int yy) = cardinal(boardX,boardY,direction); | |
//boards have to be filled before they can have neighbors | |
require(board_by_ID[board].pieces == 64); | |
require(MAP[xx][yy]==0) | |
boards += 1; | |
Board storage adjBoard = board_by_ID[boards]; | |
adjBoard.parent = board; | |
MAP[xx][yy] = boards; | |
spawnPiece(sender,boards,x,y,x2,y2,boosterPack); | |
emit NewBoard(boards,board,xx,yy); | |
}else{ | |
require(board<=boards && board>0 && 0==BOARD[board][y*8+x] && 0==BOARD[board][y*8+x]); | |
spawnPiece(sender,board,x,y,x2,y2,boosterPack); | |
} | |
} | |
function cardinal(int x,int y, uint direction) internal pure returns(int xx,int yy){ | |
if(direction==0){ | |
xx=x + 1; | |
}else if(direction==1){ | |
yy=y + 1; | |
}else if(direction==2){ | |
xx=x - 1; | |
}else{ | |
yy=y - 1; | |
} | |
} | |
event SpawnPiece(uint board, uint piece, int x, int y, int x2, int y2, uint[] boosterPack); | |
function spawnPiece(address owner,uint board,int x, int y,int x2, int y2, uint[] memory boosterPack) internal{ | |
pieces+=1; | |
Piece storage piece = piece_by_ID[pieces]; | |
piece.owner=owner; | |
piece.lastDraw=rolls; | |
piece.kind=1; | |
Board storage _board = board_by_ID[board]; | |
BOARD[board][y*8+x]=pieces; | |
uint L = boosterPack.length; | |
for(uint i;i<L;i++){ | |
piece.hand[i] = boosterPack[i]; | |
} | |
pieces+=1; | |
piece = piece_by_ID[pieces]; | |
BOARD[board][y2*8+x2]=pieces; | |
_board.pieces += 2; | |
emit SpawnPiece(board,pieces,x,y,x2,y2,boosterPack); | |
} | |
function proximity(int x1, int x2,int y1, int y2, bool ring)internal pure returns(bool near,int dx,int dy){ | |
int dX = (x1<x2?(x2-x1):(x1-x2)); | |
int dY = (y1<y2?(y2-y1):(y1-y2)); | |
int distX = int(dX); | |
int distY = int(dY); | |
if(ring){ | |
return ( (distX+distY == 2 && x1 != x2 && y1 != y2) || (distX+distY == 1), distX, distY); | |
}else{//if Adjacent | |
return (distX+distY == 1, distX, distY); | |
} | |
} | |
event Move(uint indexed piece, uint indexed board, int x, int y); | |
function move(uint board, int piece_loc, int dx, int dy, int[] memory knightPath) external{ | |
address sender = msg.sender; | |
uint pid = BOARD[board][piece_loc]; | |
Piece storage piece = piece_by_ID[ pid ]; | |
//uint kind = piece.kind; | |
int[] memory INTS = new int[](5); | |
INTS[0]=piece_loc%8; | |
INTS[1]=piece_loc/8; | |
//i | |
bool near; | |
(near, INTS[3], INTS[4]) = proximity(INTS[0],INTS[1],dx,dy,true); | |
//destination checks | |
require( | |
board_by_ID[board].pieces==64 && | |
dx<8 && | |
dy<8 && | |
!(INTS[0]==dx && INTS[1]==dy) && | |
piece.damage<piece.life && | |
piece.owner == sender && | |
block.timestamp-piece.lastMove > 0 &&/*###*/ | |
0<INTS[3]+INTS[4] && | |
( | |
( piece.kind==1 && INTS[3]+INTS[4]==1 )|| | |
( piece.kind==2 && ( (INTS[3]==2 && INTS[4]==1) || (INTS[3]==1 && INTS[4]==2) ) )|| | |
( piece.kind==3 && INTS[3]==INTS[4] )|| | |
( piece.kind==4 && ( INTS[0]==dx || INTS[1]==dy ) )|| | |
( piece.kind==5 && ( INTS[0]==dx || INTS[1]==dy || INTS[3]==INTS[4] ) )|| | |
( piece.kind==6 && near ) | |
) | |
); | |
piece_loc = dy*8+dx; | |
piece.lastMove = block.timestamp; | |
if(piece.kind == 1 || piece.kind == 3 || piece.kind == 4 || piece.kind == 5 || piece.kind == 6){ | |
if(INTS[3]>0){dx = (dx-INTS[0])/INTS[3];}else{dx=0;} | |
if(INTS[4]>0){dy = (dy-INTS[1])/INTS[4];}else{dy=0;} | |
INTS[3] = INTS[3]>INTS[4]?INTS[3]:INTS[4]; | |
} | |
uint P; | |
if(piece.kind == 1 || piece.kind == 3 || piece.kind == 4 || piece.kind == 5){ | |
for(INTS[2]=1;INTS[2]<=INTS[3];INTS[2]+=1){ | |
P = BOARD[board][(INTS[1]+dy*INTS[2])*8+(INTS[0]+dx*INTS[2])]; | |
BOARD[board][(INTS[1]+dy*(INTS[2]-1))*8+(INTS[0]+dx*(INTS[2]-1))] = P; | |
} | |
}else if(piece.kind == 2){ | |
INTS[3] = knightPath[0]/8; | |
INTS[4] = knightPath[0]%8; | |
for(INTS[2]=0;INTS[2]<3;INTS[2]++){ | |
(near,,) = proximity(INTS[0],INTS[1],INTS[3],INTS[4],false); | |
require(near); | |
P = BOARD[board][INTS[4]*8+INTS[3]]; | |
BOARD[board][INTS[1]*8+INTS[0]] = P; | |
INTS[1] = INTS[3]; | |
INTS[0] = INTS[4]; | |
if(INTS[2]!=2){ | |
INTS[3] = knightPath[uint(INTS[2]+1)]/8; | |
INTS[4] = knightPath[uint(INTS[2]+1)]%8; | |
} | |
} | |
require(INTS[0] == dx && INTS[1] == dy); | |
}else if(piece.kind == 6){ | |
for(INTS[2]=8;INTS[2]>=1;INTS[2]-=1){ | |
P = BOARD[board][( (INTS[1]+dy*INTS[2])%8 )*8+( (INTS[0]+dx*INTS[2])%8 )]; | |
BOARD[board][( (INTS[1]+dy*(INTS[2]+1))%8 )*8+( (INTS[0]+dx*(INTS[2]+1))%8 )] = P; | |
} | |
} | |
BOARD[board][piece_loc] = pid; | |
emit Move(pid, board, dx, dy); | |
} | |
function isAlive(Piece storage defender)internal view returns(bool){ | |
return defender.damage<defender.life; | |
} | |
function claimNaturalResources(uint board) external{ | |
address sender = msg.sender; | |
Piece storage piece; | |
bool others; | |
for(int i;i<64;i++){ | |
piece = piece_by_ID[ BOARD[board][i] ]; | |
if( piece.owner != sender && piece.owner!=x0 && isAlive(piece) ){ | |
others = true; | |
break; | |
} | |
} | |
if(!others){ | |
Board storage _board = board_by_ID[board]; | |
Board storage parent = board_by_ID[_board.parent]; | |
uint jp = _board.jackpot; | |
$$$[sender] += jp-jp/10; | |
parent.jackpot += jp/10; | |
_board.jackpot = 0; | |
} | |
} | |
event Attack(uint board, int attacker_loc, int defender_loc); | |
function attack(uint board, int attacker_loc, int defender_loc) external{ | |
address sender = msg.sender; | |
Piece storage attacker = piece_by_ID[BOARD[board][attacker_loc]]; | |
Piece storage defender = piece_by_ID[BOARD[board][defender_loc]]; | |
(bool adj, int dx, int dy) = proximity(attacker_loc%8,attacker_loc/8,defender_loc%8,defender_loc/8,false); | |
require( | |
board_by_ID[board].pieces==64 && | |
attacker.owner == sender && | |
isAlive(defender) && | |
block.timestamp-attacker.lastAttack > 0/*###*/ && | |
( adj || (attacker.effect[77/*long reach*/]==1 && dx+dy==2) ) | |
); | |
attacker.lastAttack = block.timestamp; | |
damage(defender, 5/*###*/, sender, board); | |
emit Attack(board,attacker_loc,defender_loc); | |
} | |
function damage(Piece storage defender, uint _damage, address accountable, uint board)internal returns(bool kill){ | |
require( isAlive(defender) ); | |
defender.damage+=_damage; | |
if( !isAlive(defender) ){ | |
board_by_ID[board].jackpot += 1e17/2; | |
$$$[accountable] += 1e17/2; | |
return true; | |
} | |
return false; | |
} | |
uint rolls; | |
mapping(uint=>uint) seeds; | |
uint lastRoll; | |
function secretRandomness(uint seed)external{ | |
require(msg.sender==key); | |
if( block.timestamp-lastRoll>N[0] ){ | |
seeds[rolls] = seed; | |
rolls+=1; | |
lastRoll = block.timestamp; | |
}else{ | |
revert(); | |
} | |
} | |
function draw(uint pieceID)external{ | |
Piece storage piece = piece_by_ID[pieceID]; | |
require(msg.sender == piece.owner); | |
uint ld = piece.lastDraw; | |
if(rolls>ld){ | |
uint emptySpots; | |
uint draws; | |
uint[] memory handSlots = new uint[](3); | |
uint i; | |
for(i;i<5;i++){ | |
if(piece.hand[i]==0){ | |
handSlots[emptySpots] = i; | |
emptySpots+=1; | |
} | |
} | |
uint pickedCardSlot; | |
uint card; | |
uint rpcod; | |
for(i=0; i<emptySpots && piece.cardsDrawn+i<52; i++){ | |
draws+=1; | |
pickedCardSlot = uint( keccak256(abi.encodePacked(seeds[ld+1],i,pieceID)) ) % (52-(piece.cardsDrawn+i) ); | |
rpcod = piece.replacedCardsOfDeck[piece.deck][pickedCardSlot]; | |
if(rpcod==0){ | |
card = pickedCardSlot; | |
}else{ | |
card = rpcod; | |
} | |
rpcod = piece.replacedCardsOfDeck[piece.deck][52-piece.cardsDrawn+i]; | |
if(rpcod==0){ | |
piece.replacedCardsOfDeck[piece.deck][pickedCardSlot] = 52-piece.cardsDrawn+i; | |
}else{ | |
piece.replacedCardsOfDeck[piece.deck][pickedCardSlot] = piece.replacedCardsOfDeck[piece.deck][pickedCardSlot]; | |
} | |
piece.hand[handSlots[i]] = card; | |
} | |
piece.lastDraw = rolls; | |
piece.cardsDrawn += draws; | |
} | |
} | |
function viewMap(int x, int y, int width, int height) external view returns( uint[] memory IDs, uint[] memory $,uint[] memory pieceCounts, uint[] memory parents ){ | |
IDs = new uint[](uint(width*height)); | |
$ = new uint[](uint(width*height)); | |
pieceCounts = new uint[](uint(width*height)); | |
parents = new uint[](uint(width*height)); | |
int i; | |
int j; | |
uint r; | |
for(i=y;i<height;i++){ | |
for(j=x;j<width;j++){ | |
IDs[r] = MAP[j][i]; | |
$[r] = board_by_ID[ MAP[j][i] ].jackpot; | |
pieceCounts[r] = board_by_ID[ MAP[j][i] ].pieces; | |
parents[r] = board_by_ID[ MAP[j][i] ].parent; | |
r+=1; | |
} | |
} | |
} | |
function viewBoard(uint board) external view returns( uint[] memory UINTs, address[] memory owners ){ | |
UINTs = new uint[](64*(7+5+10)); | |
owners = new address[](64); | |
uint i; | |
uint j; | |
uint ID; | |
Piece storage piece; | |
for(i=0;i<64;i++){ | |
ID = BOARD[board][int(i)]; | |
piece = piece_by_ID[ ID ]; | |
UINTs[i] = ID; | |
UINTs[i+1] = piece.kind; | |
UINTs[i+2] = piece.life; | |
UINTs[i+3] = piece.damage; | |
UINTs[i+4] = piece.lastMove; | |
UINTs[i+5] = piece.lastAttack; | |
UINTs[i+6] = piece.lastDraw; | |
UINTs[i+7] = piece.cardsDrawn; | |
UINTs[i+8] = piece.hand[0]; | |
UINTs[i+9] = piece.hand[1]; | |
UINTs[i+10] = piece.hand[2]; | |
UINTs[i+11] = piece.hand[3]; | |
UINTs[i+12] = piece.hand[4]; | |
for(j=0;j<10;j++){ | |
UINTs[i+12+j] = piece.effect[j]; | |
} | |
} | |
} | |
function viewPiece(uint piece) external view | |
returns( | |
uint kind, | |
uint life, | |
uint _damage, | |
uint lastMove, | |
uint lastAttack, | |
uint lastDraw, | |
uint cardsDrawn, | |
uint[] memory hand, | |
uint[] memory effect | |
){ | |
uint j; | |
Piece storage p = piece_by_ID[piece]; | |
kind = p.kind; | |
life = p.life; | |
_damage = p.damage; | |
lastMove = p.lastMove; | |
lastAttack = p.lastAttack; | |
lastDraw = p.lastDraw; | |
cardsDrawn = p.cardsDrawn; | |
for(j=0;j<5;j++){ | |
hand[j] = p.hand[j]; | |
} | |
for(j=0;j<10;j++){ | |
effect[j] = p.effect[j]; | |
} | |
} | |
} | |
/* | |
0 Drawing cards cooldown timer | |
*/ | |
// ui | |
// then finally 52 ablities | |
//whenever a piece dies or moves off board | |
//if(conquered[boardID][x0]+conquered[boardID][ ... ]==64) | |
//the cards you hold give you your stats ... attack and speed are the only stats. AJQK for speed, 2-10 for attack | |
abstract contract ERC20{ | |
function transfer(address _to, uint _value) public virtual returns (bool); | |
function transferFrom(address src, address dst, uint amount) public virtual returns (bool); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment