Duke
4 months ago
9 changed files with 24 additions and 2674 deletions
@ -1,292 +0,0 @@ |
|||
// Copyright (c) 2016-2023 The Hush developers
|
|||
// Distributed under the GPLv3 software license, see the accompanying
|
|||
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
|||
|
|||
#include "prices.h" |
|||
#include <time.h> |
|||
#include <unistd.h> |
|||
#ifdef BUILD_GAMESCC |
|||
#include "../rogue/cursesd.h" |
|||
#else |
|||
#include <curses.h> |
|||
#endif |
|||
|
|||
#define SATOSHIDEN ((uint64_t)100000000L) |
|||
#define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"prices",cmdstr,0,0,0) |
|||
extern int64_t Net_change,Betsize; |
|||
|
|||
int random_tetromino(struct games_state *rs) |
|||
{ |
|||
rs->seed = _games_rngnext(rs->seed); |
|||
return(rs->seed % NUM_TETROMINOS); |
|||
} |
|||
|
|||
int32_t pricesdata(struct games_player *P,void *ptr) |
|||
{ |
|||
tetris_game *tg = (tetris_game *)ptr; |
|||
P->gold = tg->points; |
|||
P->dungeonlevel = tg->level; |
|||
//fprintf(stderr,"score.%d level.%d\n",tg->points,tg->level);
|
|||
return(0); |
|||
} |
|||
|
|||
void sleep_milli(int milliseconds) |
|||
{ |
|||
struct timespec ts; |
|||
ts.tv_sec = 0; |
|||
ts.tv_nsec = milliseconds * 1000 * 1000; |
|||
nanosleep(&ts, NULL); |
|||
} |
|||
|
|||
struct games_state globalR; |
|||
extern char Gametxidstr[]; |
|||
int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eventid,gamesevent c); |
|||
uint64_t get_btcusd(); |
|||
int32_t issue_bet(struct games_state *rs,int64_t x,int64_t betsize); |
|||
|
|||
void *gamesiterate(struct games_state *rs) |
|||
{ |
|||
bool running = true; uint32_t eventid = 0; int64_t price; |
|||
if ( rs->guiflag != 0 || rs->sleeptime != 0 ) |
|||
{ |
|||
initscr(); // initialize curses
|
|||
cbreak(); // pass key presses to program, but not signals
|
|||
noecho(); // don't echo key presses to screen
|
|||
timeout(0); |
|||
} |
|||
while ( running != 0 ) |
|||
{ |
|||
//running = tg_tick(rs,tg,move);
|
|||
if ( rs->guiflag != 0 || rs->sleeptime != 0 ) |
|||
{ |
|||
} |
|||
if ( rs->guiflag != 0 ) |
|||
{ |
|||
#ifdef STANDALONE |
|||
price = get_btcusd(); |
|||
//fprintf(stderr,"%llu -> t%u %.4f\n",(long long)price,(uint32_t)(price >> 32),(double)(price & 0xffffffff)/10000);
|
|||
//issue_games_events(rs,Gametxidstr,eventid,price);
|
|||
issue_bet(rs,price,Betsize); |
|||
eventid++; |
|||
doupdate(); |
|||
sleep(10); |
|||
switch ( getch() ) |
|||
{ |
|||
case '+': Net_change++; break; |
|||
case '-': Net_change--; break; |
|||
case '0': Net_change = 0; break; |
|||
case '$': Betsize = SATOSHIDEN; break; |
|||
case '^': Betsize += (Betsize >> 3); break; |
|||
case '/': Betsize -= (Betsize >> 3); break; |
|||
} |
|||
/*if ( (counter++ % 10) == 0 )
|
|||
doupdate(); |
|||
c = games_readevent(rs); |
|||
if ( c <= 0x7f || skipcount == 0x3fff ) |
|||
{ |
|||
if ( skipcount > 0 ) |
|||
issue_games_events(rs,Gametxidstr,eventid-skipcount,skipcount | 0x4000); |
|||
if ( c <= 0x7f ) |
|||
issue_games_events(rs,Gametxidstr,eventid,c); |
|||
if ( tg->level != prevlevel ) |
|||
{ |
|||
flushkeystrokes(rs,0); |
|||
prevlevel = tg->level; |
|||
} |
|||
skipcount = 0; |
|||
} else skipcount++;*/ |
|||
#endif |
|||
} |
|||
else |
|||
{ |
|||
if ( rs->replaydone != 0 ) |
|||
break; |
|||
if ( rs->sleeptime != 0 ) |
|||
{ |
|||
sleep_milli(1); |
|||
} |
|||
/*if ( skipcount == 0 )
|
|||
{ |
|||
c = games_readevent(rs); |
|||
//fprintf(stderr,"%04x score.%d level.%d\n",c,tg->points,tg->level);
|
|||
if ( (c & 0x4000) == 0x4000 ) |
|||
{ |
|||
skipcount = (c & 0x3fff); |
|||
c = 'S'; |
|||
} |
|||
} |
|||
if ( skipcount > 0 ) |
|||
skipcount--;*/ |
|||
} |
|||
eventid++; |
|||
} |
|||
return(0); |
|||
} |
|||
|
|||
#ifdef STANDALONE |
|||
#include <ncurses.h> |
|||
#include "dapps/dappstd.c" |
|||
int64_t Net_change,Betsize = SATOSHIDEN; |
|||
|
|||
char *send_curl(char *url,char *fname) |
|||
{ |
|||
char *retstr; |
|||
retstr = issue_curl(url); |
|||
return(retstr); |
|||
} |
|||
|
|||
cJSON *get_urljson(char *url,char *fname) |
|||
{ |
|||
char *jsonstr; cJSON *json = 0; |
|||
if ( (jsonstr= send_curl(url,fname)) != 0 ) |
|||
{ |
|||
//printf("(%s) -> (%s)\n",url,jsonstr);
|
|||
json = cJSON_Parse(jsonstr); |
|||
free(jsonstr); |
|||
} |
|||
return(json); |
|||
} |
|||
|
|||
//////////////////////////////////////////////
|
|||
// start of dapp
|
|||
//////////////////////////////////////////////
|
|||
|
|||
uint64_t get_btcusd() |
|||
{ |
|||
cJSON *pjson,*bpi,*usd; char str[512]; uint64_t x,newprice,mult,btcusd = 0; |
|||
if ( (pjson= get_urljson((char *)"http://api.coindesk.com/v1/bpi/currentprice.json",(char *)"/tmp/oraclefeed.json")) != 0 ) |
|||
{ |
|||
if ( (bpi= jobj(pjson,(char *)"bpi")) != 0 && (usd= jobj(bpi,(char *)"USD")) != 0 ) |
|||
{ |
|||
btcusd = jdouble(usd,(char *)"rate_float") * SATOSHIDEN; |
|||
mult = 10000 + Net_change*10; |
|||
newprice = (btcusd * mult) / 10000; |
|||
x = ((uint64_t)time(NULL) << 32) | ((newprice / 10000) & 0xffffffff); |
|||
sprintf(str,"BTC/USD %.4f -> Betsize %.8f (^ / to change) && %.4f Net %.1f%% [+ - to change]\n",dstr(btcusd),dstr(Betsize),dstr(newprice),(double)100*(mult-10000)/10000); |
|||
mvaddstr(0, 0, str); |
|||
clrtoeol(); |
|||
doupdate(); |
|||
} |
|||
free_json(pjson); |
|||
} |
|||
return(x); |
|||
} |
|||
|
|||
char *clonestr(char *str) |
|||
{ |
|||
char *clone; int32_t len; |
|||
if ( str == 0 || str[0] == 0 ) |
|||
{ |
|||
printf("warning cloning nullstr.%p\n",str); |
|||
#ifdef __APPLE__ |
|||
while ( 1 ) sleep(1); |
|||
#endif |
|||
str = (char *)"<nullstr>"; |
|||
} |
|||
len = strlen(str); |
|||
clone = (char *)calloc(1,len+16); |
|||
strcpy(clone,str); |
|||
return(clone); |
|||
} |
|||
|
|||
int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eventid,gamesevent c) |
|||
{ |
|||
static FILE *fp; |
|||
char params[512],*retstr; cJSON *retjson,*resobj; int32_t retval = -1; |
|||
if ( fp == 0 ) |
|||
fp = fopen("events.log","wb"); |
|||
rs->buffered[rs->num++] = c; |
|||
if ( 1 ) |
|||
{ |
|||
if ( sizeof(c) == 1 ) |
|||
sprintf(params,"[\"events\",\"17\",\"[%%22%02x%%22,%%22%s%%22,%u]\"]",(uint8_t)c&0xff,gametxidstr,eventid); |
|||
else if ( sizeof(c) == 2 ) |
|||
sprintf(params,"[\"events\",\"17\",\"[%%22%04x%%22,%%22%s%%22,%u]\"]",(uint16_t)c&0xffff,gametxidstr,eventid); |
|||
else if ( sizeof(c) == 4 ) |
|||
sprintf(params,"[\"events\",\"17\",\"[%%22%08x%%22,%%22%s%%22,%u]\"]",(uint32_t)c&0xffffffff,gametxidstr,eventid); |
|||
else if ( sizeof(c) == 8 ) |
|||
sprintf(params,"[\"events\",\"17\",\"[%%22%016llx%%22,%%22%s%%22,%u]\"]",(long long)c,gametxidstr,eventid); |
|||
if ( (retstr= hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) |
|||
{ |
|||
if ( (retjson= cJSON_Parse(retstr)) != 0 ) |
|||
{ |
|||
if ( (resobj= jobj(retjson,(char *)"result")) != 0 ) |
|||
{ |
|||
retval = 0; |
|||
if ( fp != 0 ) |
|||
{ |
|||
fprintf(fp,"%s\n",jprint(resobj,0)); |
|||
fflush(fp); |
|||
} |
|||
} |
|||
free_json(retjson); |
|||
} else fprintf(fp,"error parsing %s\n",retstr); |
|||
free(retstr); |
|||
} else fprintf(fp,"error issuing method %s\n",params); |
|||
return(retval); |
|||
} else return(0); |
|||
} |
|||
|
|||
int32_t issue_bet(struct games_state *rs,int64_t x,int64_t betsize) |
|||
{ |
|||
char params[512],hexstr[64],*retstr; cJSON *retjson,*resobj; int32_t i,retval = -1; |
|||
memset(hexstr,0,sizeof(hexstr)); |
|||
for (i=0; i<8; i++) |
|||
{ |
|||
sprintf(&hexstr[i<<1],"%02x",(uint8_t)(x & 0xff)); |
|||
x >>= 8; |
|||
} |
|||
sprintf(params,"[\"bet\",\"17\",\"[%.8f,%%22%s%%22]\"]",dstr(betsize),hexstr); |
|||
if ( (retstr= hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) |
|||
{ |
|||
if ( (retjson= cJSON_Parse(retstr)) != 0 ) |
|||
{ |
|||
if ( (resobj= jobj(retjson,(char *)"result")) != 0 ) |
|||
{ |
|||
retval = 0; |
|||
//fprintf(stderr,"%s\n",jprint(resobj,0));
|
|||
} |
|||
free_json(retjson); |
|||
} |
|||
free(retstr); |
|||
} |
|||
return(retval); |
|||
} |
|||
|
|||
int prices(int argc, char **argv) |
|||
{ |
|||
struct games_state *rs = &globalR; |
|||
int32_t c,skipcount=0; uint32_t eventid = 0; |
|||
memset(rs,0,sizeof(*rs)); |
|||
rs->guiflag = 1; |
|||
rs->sleeptime = 1; // non-zero to allow refresh()
|
|||
if ( argc >= 2 && strlen(argv[2]) == 64 ) |
|||
{ |
|||
#ifdef _WIN32 |
|||
#ifdef _MSC_VER |
|||
rs->origseed = _strtoui64(argv[1], NULL, 10); |
|||
#else |
|||
rs->origseed = atol(argv[1]); // windows, but not MSVC
|
|||
#endif // _MSC_VER
|
|||
#else |
|||
rs->origseed = atol(argv[1]); // non-windows
|
|||
#endif // _WIN32
|
|||
rs->seed = rs->origseed; |
|||
if ( argc >= 3 ) |
|||
{ |
|||
strcpy(Gametxidstr,argv[2]); |
|||
fprintf(stderr,"setplayerdata %s\n",Gametxidstr); |
|||
if ( games_setplayerdata(rs,Gametxidstr) < 0 ) |
|||
{ |
|||
fprintf(stderr,"invalid gametxid, or already started\n"); |
|||
return(-1); |
|||
} |
|||
} |
|||
} else rs->seed = 777; |
|||
gamesiterate(rs); |
|||
//gamesbailout(rs);
|
|||
return 0; |
|||
} |
|||
|
|||
#endif |
|||
|
@ -1,283 +0,0 @@ |
|||
// Copyright (c) 2016-2023 The Hush developers
|
|||
// Distributed under the GPLv3 software license, see the accompanying
|
|||
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
|||
/******************************************************************************
|
|||
* Copyright © 2014-2019 The SuperNET Developers. * |
|||
* * |
|||
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * |
|||
* the top-level directory of this distribution for the individual copyright * |
|||
* holder information and the developer policies on copyright and licensing. * |
|||
* * |
|||
* Unless otherwise agreed in a custom licensing agreement, no part of the * |
|||
* SuperNET software, including this file may be copied, modified, propagated * |
|||
* or distributed except according to the terms contained in the LICENSE file * |
|||
* * |
|||
* Removal or modification of this copyright notice is prohibited. * |
|||
* * |
|||
******************************************************************************/ |
|||
|
|||
std::string MYCCLIBNAME = (char *)"prices"; |
|||
|
|||
#define PRICES_BETPERIOD 3 |
|||
UniValue games_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag); |
|||
extern uint8_t ASSETCHAINS_OVERRIDE_PUBKEY33[33]; |
|||
|
|||
#define bstr(x) ((double)((uint32_t)x) / 10000.) |
|||
|
|||
struct prices_bar |
|||
{ |
|||
uint64_t open,high,low,close,sum; |
|||
int32_t num; |
|||
}; |
|||
|
|||
int32_t prices_barupdate(struct prices_bar *bar,uint64_t pricebits) |
|||
{ |
|||
uint32_t uprice,timestamp; |
|||
timestamp = (uint32_t)(pricebits >> 32); |
|||
uprice = (uint32_t)pricebits; |
|||
bar->sum += uprice, bar->num++; |
|||
if ( bar->open == 0 ) |
|||
bar->open = bar->high = bar->low = pricebits; |
|||
if ( uprice > (uint32_t)bar->high ) |
|||
bar->high = pricebits; |
|||
else if ( uprice < (uint32_t)bar->low ) |
|||
bar->low = pricebits; |
|||
bar->close = pricebits; |
|||
return(0); |
|||
} |
|||
|
|||
int64_t prices_bardist(struct prices_bar *bar,uint32_t aveprice,uint64_t pricebits) |
|||
{ |
|||
int64_t a,dist = 0; |
|||
if ( aveprice != 0 ) |
|||
{ |
|||
a = (pricebits & 0xffffffff); |
|||
dist = (a - aveprice); |
|||
dist *= dist; |
|||
//fprintf(stderr,"dist.%lld (u %u - ave %u) %d\n",(long long)dist,uprice,aveprice,uprice-aveprice);
|
|||
} |
|||
return(dist); |
|||
} |
|||
|
|||
void prices_bardisp(struct prices_bar *bar) |
|||
{ |
|||
if ( bar->num == 0 ) |
|||
fprintf(stderr,"BAR null\n"); |
|||
else fprintf(stderr,"BAR ave %.4f (O %.4f, H %.4f, L %.4f, C %.4f)\n",bstr(bar->sum/bar->num),bstr(bar->open),bstr(bar->high),bstr(bar->low),bstr(bar->close)); |
|||
} |
|||
|
|||
int64_t prices_blockinfo(int32_t height,char *acaddr) |
|||
{ |
|||
std::vector<uint8_t> vopret; CBlockIndex *pindex; CBlock block; CTransaction tx,vintx; uint64_t pricebits; char destaddr[64]; uint32_t aveprice=0,timestamp,uprice; uint256 hashBlock; int64_t dist,mindist=(1LL<<60),prizefund = 0; int32_t mini=-1,i,n,vini,numvouts,iter; struct prices_bar refbar; |
|||
if ( (pindex= hush_chainactive(height)) != 0 ) |
|||
{ |
|||
if ( hush_blockload(block,pindex) == 0 ) |
|||
{ |
|||
n = block.vtx.size(); |
|||
vini = 0; |
|||
memset(&refbar,0,sizeof(refbar)); |
|||
for (iter=0; iter<2; iter++) |
|||
{ |
|||
for (i=0; i<n; i++) |
|||
{ |
|||
tx = block.vtx[i]; |
|||
if ( myGetTransaction(tx.vin[vini].prevout.hash,vintx,hashBlock) == 0 ) |
|||
continue; |
|||
else if ( tx.vin[vini].prevout.n >= vintx.vout.size() || Getscriptaddress(destaddr,vintx.vout[tx.vin[vini].prevout.n].scriptPubKey) == 0 ) |
|||
continue; |
|||
else if ( (numvouts= tx.vout.size()) > 1 && tx.vout[numvouts-1].scriptPubKey[0] == 0x6a ) |
|||
{ |
|||
GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret); |
|||
if ( vopret.size() == 8 ) |
|||
{ |
|||
E_UNMARSHAL(vopret,ss >> pricebits); |
|||
timestamp = (uint32_t)(pricebits >> 32); |
|||
uprice = (uint32_t)pricebits; |
|||
if ( iter == 0 ) |
|||
{ |
|||
prizefund += tx.vout[0].nValue; |
|||
if ( strcmp(acaddr,destaddr) == 0 ) |
|||
{ |
|||
//fprintf(stderr,"REF ");
|
|||
prices_barupdate(&refbar,pricebits); |
|||
} |
|||
} |
|||
else if ( strcmp(acaddr,destaddr) != 0 ) |
|||
{ |
|||
dist = prices_bardist(&refbar,aveprice,pricebits); |
|||
if ( dist < mindist ) |
|||
{ |
|||
mindist = dist; |
|||
mini = i; |
|||
} |
|||
fprintf(stderr,"mini.%d i.%d %.8f t%u %.4f v.%d %s lag.%d i.%d dist.%lld\n",mini,i,(double)tx.vout[0].nValue/COIN,timestamp,(double)uprice/10000,numvouts,destaddr,(int32_t)(pindex->nTime-timestamp),iter,(long long)dist); |
|||
} |
|||
} else return(-3); |
|||
} |
|||
} |
|||
if ( iter == 0 ) |
|||
{ |
|||
prices_bardisp(&refbar); |
|||
if ( refbar.num != 0 ) |
|||
aveprice = (uint32_t)refbar.sum / refbar.num; |
|||
} |
|||
} |
|||
return(prizefund); |
|||
} else return(-2); |
|||
} else return(-1); |
|||
} |
|||
|
|||
UniValue games_settle(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) |
|||
{ |
|||
UniValue result(UniValue::VOBJ); char acaddr[64]; CPubKey acpk,mypk,gamespk; int64_t prizefund = 0; int32_t height,nextheight = hush_nextheight(); |
|||
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] == 0 ) |
|||
{ |
|||
result.push_back(Pair("result","error")); |
|||
result.push_back(Pair("error"," no -ac_pubkey for price reference")); |
|||
return(result); |
|||
} |
|||
mypk = pubkey2pk(Mypubkey()); |
|||
gamespk = GetUnspendable(cp,0); |
|||
acpk = buf2pk(ASSETCHAINS_OVERRIDE_PUBKEY33); |
|||
Getscriptaddress(acaddr,CScript() << ParseHex(HexStr(acpk)) << OP_CHECKSIG); |
|||
if ( params != 0 && cJSON_GetArraySize(params) == 1 ) |
|||
{ |
|||
height = juint(jitem(params,0),0); |
|||
result.push_back(Pair("height",(int64_t)height)); |
|||
if ( (prizefund= prices_blockinfo(height,acaddr)) < 0 ) |
|||
{ |
|||
result.push_back(Pair("result","error")); |
|||
result.push_back(Pair("errorcode",prizefund)); |
|||
result.push_back(Pair("error","blockinfo error")); |
|||
} |
|||
else |
|||
{ |
|||
// display bets
|
|||
if ( height <= nextheight-PRICES_BETPERIOD ) |
|||
{ |
|||
// settle bets by first nonzero reference bar
|
|||
} |
|||
result.push_back(Pair("prizefund",ValueFromAmount(prizefund))); |
|||
result.push_back(Pair("result","success")); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
result.push_back(Pair("result","error")); |
|||
result.push_back(Pair("error","couldnt parse")); |
|||
} |
|||
return(result); |
|||
} |
|||
|
|||
UniValue games_bet(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) |
|||
{ |
|||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); |
|||
UniValue result(UniValue::VOBJ); std::string rawtx; int64_t amount,inputsum; uint64_t price; CPubKey gamespk,mypk,acpk; |
|||
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] == 0 ) |
|||
{ |
|||
result.push_back(Pair("result","error")); |
|||
result.push_back(Pair("error"," no -ac_pubkey for price reference")); |
|||
return(result); |
|||
} |
|||
mypk = pubkey2pk(Mypubkey()); |
|||
gamespk = GetUnspendable(cp,0); |
|||
acpk = buf2pk(ASSETCHAINS_OVERRIDE_PUBKEY33); |
|||
if ( params != 0 && cJSON_GetArraySize(params) == 2 ) |
|||
{ |
|||
amount = jdouble(jitem(params,0),0) * COIN + 0.0000000049; |
|||
if ( cclib_parsehash((uint8_t *)&price,jitem(params,1),8) < 0 ) |
|||
{ |
|||
result.push_back(Pair("result","error")); |
|||
result.push_back(Pair("error","couldnt parsehash")); |
|||
return(result); |
|||
} |
|||
if ( mypk == acpk ) |
|||
{ |
|||
amount = 0; // i am the reference price feed
|
|||
//fprintf(stderr,"i am the reference\n");
|
|||
} |
|||
//fprintf(stderr,"amount %llu price %llx\n",(long long)amount,(long long)price);
|
|||
if ( (inputsum= AddNormalinputs(mtx,mypk,amount+GAMES_TXFEE,64)) >= amount+GAMES_TXFEE ) |
|||
{ |
|||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,gamespk)); |
|||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,GAMES_TXFEE,CScript() << OP_RETURN << price); |
|||
return(games_rawtxresult(result,rawtx,1)); |
|||
} |
|||
else |
|||
{ |
|||
result.push_back(Pair("result","error")); |
|||
result.push_back(Pair("error","not enough funds")); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
result.push_back(Pair("result","error")); |
|||
result.push_back(Pair("error","couldnt parse")); |
|||
} |
|||
return(result); |
|||
} |
|||
|
|||
void prices_update(uint32_t timestamp,uint32_t uprice,int32_t ismine) |
|||
{ |
|||
//fprintf(stderr,"%s t%u %.4f %16llx\n",ismine!=0?"mine":"ext ",timestamp,(double)uprice/10000,(long long)((uint64_t)timestamp<<32) | uprice);
|
|||
} |
|||
|
|||
// game specific code for daemon
|
|||
void games_packitemstr(char *packitemstr,struct games_packitem *item) |
|||
{ |
|||
strcpy(packitemstr,""); |
|||
} |
|||
|
|||
int64_t games_cashout(struct games_player *P) |
|||
{ |
|||
int32_t dungeonlevel = P->dungeonlevel; int64_t mult=1000,cashout = 0; |
|||
cashout = (uint64_t)P->gold * mult * dungeonlevel * dungeonlevel; |
|||
return(cashout); |
|||
} |
|||
|
|||
void pricesplayerjson(UniValue &obj,struct games_player *P) |
|||
{ |
|||
obj.push_back(Pair("packsize",(int64_t)P->packsize)); |
|||
obj.push_back(Pair("hitpoints",(int64_t)P->hitpoints)); |
|||
obj.push_back(Pair("strength",(int64_t)(P->strength&0xffff))); |
|||
obj.push_back(Pair("maxstrength",(int64_t)(P->strength>>16))); |
|||
obj.push_back(Pair("level",(int64_t)P->level)); |
|||
obj.push_back(Pair("experience",(int64_t)P->experience)); |
|||
obj.push_back(Pair("dungeonlevel",(int64_t)P->dungeonlevel)); |
|||
} |
|||
|
|||
int32_t disp_gamesplayer(char *str,struct games_player *P) |
|||
{ |
|||
str[0] = 0; |
|||
//if ( P->gold <= 0 )//|| P->hitpoints <= 0 || (P->strength&0xffff) <= 0 || P->level <= 0 || P->experience <= 0 || P->dungeonlevel <= 0 )
|
|||
// return(-1);
|
|||
sprintf(str," <- playerdata: gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d",P->gold,P->hitpoints,P->strength&0xffff,P->strength>>16,P->level,P->experience,P->dungeonlevel); |
|||
return(0); |
|||
} |
|||
|
|||
int32_t games_payloadrecv(CPubKey pk,uint32_t timestamp,std::vector<uint8_t> payload) |
|||
{ |
|||
uint256 gametxid; int32_t i,len; char str[67]; int64_t price; uint32_t eventid = 0; |
|||
if ( (len= payload.size()) > 36 ) |
|||
{ |
|||
len -= 36; |
|||
for (i=0; i<32; i++) |
|||
((uint8_t *)&gametxid)[i] = payload[len+i]; |
|||
eventid = (uint32_t)payload[len+32]; |
|||
eventid |= (uint32_t)payload[len+33] << 8; |
|||
eventid |= (uint32_t)payload[len+34] << 16; |
|||
eventid |= (uint32_t)payload[len+35] << 24; |
|||
for (i=0; i<len&&i<sizeof(price); i++) |
|||
((uint8_t *)&price)[7-i] = payload[i]; |
|||
prices_update((uint32_t)(price >> 32),(uint32_t)(price & 0xffffffff),pk == pubkey2pk(Mypubkey())); |
|||
//fprintf(stderr,"%llu -> t%u %.4f ",(long long)price,(uint32_t)(price >> 32),(double)(price & 0xffffffff)/10000);
|
|||
//fprintf(stderr," got payload, from %s %s/e%d\n",pubkey33_str(str,(uint8_t *)&pk),gametxid.GetHex().c_str(),eventid);
|
|||
return(0); |
|||
} else return(-1); |
|||
} |
|||
|
|||
bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) |
|||
{ |
|||
return(true); |
|||
} |
|||
|
@ -1,211 +0,0 @@ |
|||
// Copyright (c) 2016-2023 The Hush developers
|
|||
// Distributed under the GPLv3 software license, see the accompanying
|
|||
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
|||
|
|||
#ifndef H_PRICES_H |
|||
#define H_PRICES_H |
|||
|
|||
/***************************************************************************/ |
|||
/** https://github.com/brenns10/tetris
|
|||
@file main.c |
|||
@author Stephen Brennan |
|||
@date Created Wednesday, 10 June 2015 |
|||
@brief Main program for tetris. |
|||
@copyright Copyright (c) 2015, Stephen Brennan. Released under the Revised |
|||
BSD License. See LICENSE.txt for details. |
|||
*******************************************************************************/ |
|||
|
|||
/*
|
|||
Convert a tetromino type to its corresponding cell. |
|||
*/ |
|||
#define TYPE_TO_CELL(x) ((x)+1) |
|||
|
|||
/*
|
|||
Strings for how you would print a tetris board. |
|||
*/ |
|||
#define TC_EMPTY_STR " " |
|||
#define TC_BLOCK_STR "\u2588" |
|||
|
|||
/*
|
|||
Questions about a tetris cell. |
|||
*/ |
|||
#define TC_IS_EMPTY(x) ((x) == TC_EMPTY) |
|||
#define TC_IS_FILLED(x) (!TC_IS_EMPTY(x)) |
|||
|
|||
/*
|
|||
How many cells in a tetromino? |
|||
*/ |
|||
#define TETRIS 4 |
|||
/*
|
|||
How many tetrominos? |
|||
*/ |
|||
#define NUM_TETROMINOS 7 |
|||
/*
|
|||
How many orientations of a tetromino? |
|||
*/ |
|||
#define NUM_ORIENTATIONS 4 |
|||
|
|||
/*
|
|||
Level constants. |
|||
*/ |
|||
#define MAX_LEVEL 19 |
|||
#define LINES_PER_LEVEL 10 |
|||
|
|||
/*
|
|||
A "cell" is a 1x1 block within a tetris board. |
|||
*/ |
|||
typedef enum { |
|||
TC_EMPTY, TC_CELLI, TC_CELLJ, TC_CELLL, TC_CELLO, TC_CELLS, TC_CELLT, TC_CELLZ |
|||
} tetris_cell; |
|||
|
|||
/*
|
|||
A "type" is a type/shape of a tetromino. Not including orientation. |
|||
*/ |
|||
typedef enum { |
|||
TET_I, TET_J, TET_L, TET_O, TET_S, TET_T, TET_Z |
|||
} tetris_type; |
|||
|
|||
/*
|
|||
A row,column pair. Negative numbers allowed, because we need them for |
|||
offsets. |
|||
*/ |
|||
typedef struct { |
|||
int row; |
|||
int col; |
|||
} tetris_location; |
|||
|
|||
/*
|
|||
A "block" is a struct that contains information about a tetromino. |
|||
Specifically, what type it is, what orientation it has, and where it is. |
|||
*/ |
|||
typedef struct { |
|||
int typ; |
|||
int ori; |
|||
tetris_location loc; |
|||
} tetris_block; |
|||
|
|||
/*
|
|||
All possible moves to give as input to the game. |
|||
*/ |
|||
typedef enum { |
|||
TM_LEFT, TM_RIGHT, TM_CLOCK, TM_COUNTER, TM_DROP, TM_HOLD, TM_NONE |
|||
} tetris_move; |
|||
|
|||
/*
|
|||
A game object! |
|||
*/ |
|||
typedef struct { |
|||
/*
|
|||
Game board stuff: |
|||
*/ |
|||
int rows; |
|||
int cols; |
|||
/*
|
|||
Scoring information: |
|||
*/ |
|||
int points; |
|||
int level; |
|||
/*
|
|||
Falling block is the one currently going down. Next block is the one that |
|||
will be falling after this one. Stored is the block that you can swap out. |
|||
*/ |
|||
tetris_block falling; |
|||
tetris_block next; |
|||
tetris_block stored; |
|||
/*
|
|||
Number of game ticks until the block will move down. |
|||
*/ |
|||
int ticks_till_gravity; |
|||
/*
|
|||
Number of lines until you advance to the next level. |
|||
*/ |
|||
int lines_remaining; |
|||
char board[]; |
|||
} tetris_game; |
|||
|
|||
/*
|
|||
This array stores all necessary information about the cells that are filled by |
|||
each tetromino. The first index is the type of the tetromino (i.e. shape, |
|||
e.g. I, J, Z, etc.). The next index is the orientation (0-3). The final |
|||
array contains 4 tetris_location objects, each mapping to an offset from a |
|||
point on the upper left that is the tetromino "origin". |
|||
*/ |
|||
extern const tetris_location TETROMINOS[NUM_TETROMINOS][NUM_ORIENTATIONS][TETRIS]; |
|||
|
|||
/*
|
|||
This array tells you how many ticks per gravity by level. Decreases as level |
|||
increases, to add difficulty. |
|||
*/ |
|||
extern const int GRAVITY_LEVEL[MAX_LEVEL+1]; |
|||
|
|||
// Data structure manipulation.
|
|||
void tg_init(tetris_game *obj, int rows, int cols); |
|||
tetris_game *tg_create(struct games_state *rs,int rows, int cols); |
|||
void tg_destroy(tetris_game *obj); |
|||
void tg_delete(tetris_game *obj); |
|||
tetris_game *tg_load(FILE *f); |
|||
void tg_save(tetris_game *obj, FILE *f); |
|||
|
|||
// Public methods not related to memory:
|
|||
char tg_get(tetris_game *obj, int row, int col); |
|||
bool tg_check(tetris_game *obj, int row, int col); |
|||
bool tg_tick(struct games_state *rs,tetris_game *obj, tetris_move move); |
|||
void tg_print(tetris_game *obj, FILE *f); |
|||
|
|||
/******************************************************************************
|
|||
* Copyright © 2014-2019 The SuperNET Developers. * |
|||
* * |
|||
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * |
|||
* the top-level directory of this distribution for the individual copyright * |
|||
* holder information and the developer policies on copyright and licensing. * |
|||
* * |
|||
* Unless otherwise agreed in a custom licensing agreement, no part of the * |
|||
* SuperNET software, including this file may be copied, modified, propagated * |
|||
* or distributed except according to the terms contained in the LICENSE file * |
|||
* * |
|||
* Removal or modification of this copyright notice is prohibited. * |
|||
* * |
|||
******************************************************************************/ |
|||
#define GAMENAME "prices" // name of executable
|
|||
#define GAMEMAIN prices // main program of game
|
|||
#define GAMEPLAYERJSON pricesplayerjson // displays game specific json
|
|||
#define GAMEDATA pricesdata // extracts data from game specific variables into games_state
|
|||
#define CHAINNAME "PRICES" // -ac_name=
|
|||
typedef uint64_t gamesevent; // can be 8, 16, 32, or 64 bits
|
|||
|
|||
#define MAXPACK 23 |
|||
struct games_packitem |
|||
{ |
|||
int32_t type,launch,count,which,hplus,dplus,arm,flags,group; |
|||
char damage[8],hurldmg[8]; |
|||
}; |
|||
|
|||
struct games_player |
|||
{ |
|||
int32_t gold,hitpoints,strength,level,experience,packsize,dungeonlevel,amulet; |
|||
struct games_packitem gamespack[MAXPACK]; |
|||
}; |
|||
|
|||
struct games_state |
|||
{ |
|||
uint64_t seed,origseed; |
|||
char *keystrokeshex; |
|||
uint32_t needflush,replaydone; |
|||
int32_t numkeys,ind,num,guiflag,counter,sleeptime,playersize,restoring,lastnum; |
|||
FILE *logfp; |
|||
struct games_player P; |
|||
gamesevent buffered[5000],*keystrokes; |
|||
uint8_t playerdata[8192]; |
|||
}; |
|||
extern struct games_state globalR; |
|||
void *gamesiterate(struct games_state *rs); |
|||
int32_t flushkeystrokes(struct games_state *rs,int32_t waitflag); |
|||
|
|||
void games_packitemstr(char *packitemstr,struct games_packitem *item); |
|||
uint64_t _games_rngnext(uint64_t initseed); |
|||
int32_t games_replay2(uint8_t *newdata,uint64_t seed,gamesevent *keystrokes,int32_t num,struct games_player *player,int32_t sleepmillis); |
|||
gamesevent games_revendian(gamesevent revx); |
|||
int32_t disp_gamesplayer(char *str,struct games_player *P); |
|||
|
|||
#endif |
|||
|
@ -1,907 +0,0 @@ |
|||
// Copyright (c) 2016-2023 The Hush developers
|
|||
// Distributed under the GPLv3 software license, see the accompanying
|
|||
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
|||
|
|||
#include "tetris.h" |
|||
|
|||
/*
|
|||
In order to port a game into gamesCC, the RNG needs to be seeded with the gametxid seed, also events needs to be broadcast using issue_games_events. Also the game engine needs to be daemonized, preferably by putting all globals into a single data structure. |
|||
|
|||
also, the standalone game needs to support argv of seed gametxid, along with replay args |
|||
*/ |
|||
|
|||
int random_tetromino(struct games_state *rs) |
|||
{ |
|||
rs->seed = _games_rngnext(rs->seed); |
|||
return(rs->seed % NUM_TETROMINOS); |
|||
} |
|||
|
|||
int32_t tetrisdata(struct games_player *P,void *ptr) |
|||
{ |
|||
tetris_game *tg = (tetris_game *)ptr; |
|||
P->gold = tg->points; |
|||
P->dungeonlevel = tg->level; |
|||
//fprintf(stderr,"score.%d level.%d\n",tg->points,tg->level);
|
|||
return(0); |
|||
} |
|||
|
|||
/***************************************************************************/ |
|||
/** https://github.com/brenns10/tetris
|
|||
@file main.c |
|||
@author Stephen Brennan |
|||
@date Created Wednesday, 10 June 2015 |
|||
@brief Main program for tetris. |
|||
@copyright Copyright (c) 2015, Stephen Brennan. Released under the Revised |
|||
BSD License. See LICENSE.txt for details. |
|||
*******************************************************************************/ |
|||
|
|||
|
|||
#include <stdio.h> // for FILE |
|||
#include <stdbool.h> // for bool |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <stdbool.h> |
|||
#include <string.h> |
|||
#include <time.h> |
|||
#include <string.h> |
|||
|
|||
#ifdef BUILD_GAMESCC |
|||
#include "../rogue/cursesd.h" |
|||
#else |
|||
#include <curses.h> |
|||
#endif |
|||
|
|||
|
|||
#define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) |
|||
#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) |
|||
|
|||
/*******************************************************************************
|
|||
Array Definitions |
|||
*******************************************************************************/ |
|||
|
|||
const tetris_location TETROMINOS[NUM_TETROMINOS][NUM_ORIENTATIONS][TETRIS] = |
|||
{ |
|||
// I
|
|||
{{{1, 0}, {1, 1}, {1, 2}, {1, 3}}, |
|||
{{0, 2}, {1, 2}, {2, 2}, {3, 2}}, |
|||
{{3, 0}, {3, 1}, {3, 2}, {3, 3}}, |
|||
{{0, 1}, {1, 1}, {2, 1}, {3, 1}}}, |
|||
// J
|
|||
{{{0, 0}, {1, 0}, {1, 1}, {1, 2}}, |
|||
{{0, 1}, {0, 2}, {1, 1}, {2, 1}}, |
|||
{{1, 0}, {1, 1}, {1, 2}, {2, 2}}, |
|||
{{0, 1}, {1, 1}, {2, 0}, {2, 1}}}, |
|||
// L
|
|||
{{{0, 2}, {1, 0}, {1, 1}, {1, 2}}, |
|||
{{0, 1}, {1, 1}, {2, 1}, {2, 2}}, |
|||
{{1, 0}, {1, 1}, {1, 2}, {2, 0}}, |
|||
{{0, 0}, {0, 1}, {1, 1}, {2, 1}}}, |
|||
// O
|
|||
{{{0, 1}, {0, 2}, {1, 1}, {1, 2}}, |
|||
{{0, 1}, {0, 2}, {1, 1}, {1, 2}}, |
|||
{{0, 1}, {0, 2}, {1, 1}, {1, 2}}, |
|||
{{0, 1}, {0, 2}, {1, 1}, {1, 2}}}, |
|||
// S
|
|||
{{{0, 1}, {0, 2}, {1, 0}, {1, 1}}, |
|||
{{0, 1}, {1, 1}, {1, 2}, {2, 2}}, |
|||
{{1, 1}, {1, 2}, {2, 0}, {2, 1}}, |
|||
{{0, 0}, {1, 0}, {1, 1}, {2, 1}}}, |
|||
// T
|
|||
{{{0, 1}, {1, 0}, {1, 1}, {1, 2}}, |
|||
{{0, 1}, {1, 1}, {1, 2}, {2, 1}}, |
|||
{{1, 0}, {1, 1}, {1, 2}, {2, 1}}, |
|||
{{0, 1}, {1, 0}, {1, 1}, {2, 1}}}, |
|||
// Z
|
|||
{{{0, 0}, {0, 1}, {1, 1}, {1, 2}}, |
|||
{{0, 2}, {1, 1}, {1, 2}, {2, 1}}, |
|||
{{1, 0}, {1, 1}, {2, 1}, {2, 2}}, |
|||
{{0, 1}, {1, 0}, {1, 1}, {2, 0}}}, |
|||
}; |
|||
|
|||
const int GRAVITY_LEVEL[MAX_LEVEL+1] = { |
|||
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
|||
50, 48, 46, 44, 42, 40, 38, 36, 34, 32, |
|||
//10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
|||
30, 28, 26, 24, 22, 20, 16, 12, 8, 4 |
|||
}; |
|||
|
|||
/*******************************************************************************
|
|||
Helper Functions for Blocks |
|||
*******************************************************************************/ |
|||
|
|||
void sleep_milli(int milliseconds) |
|||
{ |
|||
struct timespec ts; |
|||
ts.tv_sec = 0; |
|||
ts.tv_nsec = milliseconds * 1000 * 1000; |
|||
nanosleep(&ts, NULL); |
|||
} |
|||
|
|||
/*
|
|||
Return the block at the given row and column. |
|||
*/ |
|||
char tg_get(tetris_game *obj, int row, int column) |
|||
{ |
|||
return obj->board[obj->cols * row + column]; |
|||
} |
|||
|
|||
/*
|
|||
Set the block at the given row and column. |
|||
*/ |
|||
static void tg_set(tetris_game *obj, int row, int column, char value) |
|||
{ |
|||
obj->board[obj->cols * row + column] = value; |
|||
} |
|||
|
|||
/*
|
|||
Check whether a row and column are in bounds. |
|||
*/ |
|||
bool tg_check(tetris_game *obj, int row, int col) |
|||
{ |
|||
return 0 <= row && row < obj->rows && 0 <= col && col < obj->cols; |
|||
} |
|||
|
|||
/*
|
|||
Place a block onto the board. |
|||
*/ |
|||
static void tg_put(tetris_game *obj, tetris_block block) |
|||
{ |
|||
int i; |
|||
for (i = 0; i < TETRIS; i++) { |
|||
tetris_location cell = TETROMINOS[block.typ][block.ori][i]; |
|||
tg_set(obj, block.loc.row + cell.row, block.loc.col + cell.col, |
|||
TYPE_TO_CELL(block.typ)); |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
Clear a block out of the board. |
|||
*/ |
|||
static void tg_remove(tetris_game *obj, tetris_block block) |
|||
{ |
|||
int i; |
|||
for (i = 0; i < TETRIS; i++) { |
|||
tetris_location cell = TETROMINOS[block.typ][block.ori][i]; |
|||
tg_set(obj, block.loc.row + cell.row, block.loc.col + cell.col, TC_EMPTY); |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
Check if a block can be placed on the board. |
|||
*/ |
|||
static bool tg_fits(tetris_game *obj, tetris_block block) |
|||
{ |
|||
int i, r, c; |
|||
for (i = 0; i < TETRIS; i++) { |
|||
tetris_location cell = TETROMINOS[block.typ][block.ori][i]; |
|||
r = block.loc.row + cell.row; |
|||
c = block.loc.col + cell.col; |
|||
if (!tg_check(obj, r, c) || TC_IS_FILLED(tg_get(obj, r, c))) { |
|||
return false; |
|||
} |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
/*
|
|||
Create a new falling block and populate the next falling block with a random |
|||
one. |
|||
*/ |
|||
static void tg_new_falling(struct games_state *rs,tetris_game *obj) |
|||
{ |
|||
// Put in a new falling tetromino.
|
|||
obj->falling = obj->next; |
|||
obj->next.typ = random_tetromino(rs); |
|||
obj->next.ori = 0; |
|||
obj->next.loc.row = 0; |
|||
obj->next.loc.col = obj->cols/2 - 2; |
|||
} |
|||
|
|||
/*******************************************************************************
|
|||
Game Turn Helpers |
|||
*******************************************************************************/ |
|||
|
|||
/*
|
|||
Tick gravity, and move the block down if gravity should act. |
|||
*/ |
|||
static void tg_do_gravity_tick(struct games_state *rs,tetris_game *obj) |
|||
{ |
|||
obj->ticks_till_gravity--; |
|||
if (obj->ticks_till_gravity <= 0) { |
|||
tg_remove(obj, obj->falling); |
|||
obj->falling.loc.row++; |
|||
if (tg_fits(obj, obj->falling)) { |
|||
obj->ticks_till_gravity = GRAVITY_LEVEL[obj->level]; |
|||
} else { |
|||
obj->falling.loc.row--; |
|||
tg_put(obj, obj->falling); |
|||
|
|||
tg_new_falling(rs,obj); |
|||
} |
|||
tg_put(obj, obj->falling); |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
Move the falling tetris block left (-1) or right (+1). |
|||
*/ |
|||
static void tg_move(tetris_game *obj, int direction) |
|||
{ |
|||
tg_remove(obj, obj->falling); |
|||
obj->falling.loc.col += direction; |
|||
if (!tg_fits(obj, obj->falling)) { |
|||
obj->falling.loc.col -= direction; |
|||
} |
|||
tg_put(obj, obj->falling); |
|||
} |
|||
|
|||
/*
|
|||
Send the falling tetris block to the bottom. |
|||
*/ |
|||
static void tg_down(struct games_state *rs,tetris_game *obj) |
|||
{ |
|||
tg_remove(obj, obj->falling); |
|||
while (tg_fits(obj, obj->falling)) { |
|||
obj->falling.loc.row++; |
|||
} |
|||
obj->falling.loc.row--; |
|||
tg_put(obj, obj->falling); |
|||
tg_new_falling(rs,obj); |
|||
} |
|||
|
|||
/*
|
|||
Rotate the falling block in either direction (+/-1). |
|||
*/ |
|||
static void tg_rotate(tetris_game *obj, int direction) |
|||
{ |
|||
tg_remove(obj, obj->falling); |
|||
|
|||
while (true) { |
|||
obj->falling.ori = (obj->falling.ori + direction) % NUM_ORIENTATIONS; |
|||
|
|||
// If the new orientation fits, we're done.
|
|||
if (tg_fits(obj, obj->falling)) |
|||
break; |
|||
|
|||
// Otherwise, try moving left to make it fit.
|
|||
obj->falling.loc.col--; |
|||
if (tg_fits(obj, obj->falling)) |
|||
break; |
|||
|
|||
// Finally, try moving right to make it fit.
|
|||
obj->falling.loc.col += 2; |
|||
if (tg_fits(obj, obj->falling)) |
|||
break; |
|||
|
|||
// Put it back in its original location and try the next orientation.
|
|||
obj->falling.loc.col--; |
|||
// Worst case, we come back to the original orientation and it fits, so this
|
|||
// loop will terminate.
|
|||
} |
|||
|
|||
tg_put(obj, obj->falling); |
|||
} |
|||
|
|||
/*
|
|||
Swap the falling block with the block in the hold buffer. |
|||
*/ |
|||
static void tg_hold(struct games_state *rs,tetris_game *obj) |
|||
{ |
|||
tg_remove(obj, obj->falling); |
|||
if (obj->stored.typ == -1) { |
|||
obj->stored = obj->falling; |
|||
tg_new_falling(rs,obj); |
|||
} else { |
|||
int typ = obj->falling.typ, ori = obj->falling.ori; |
|||
obj->falling.typ = obj->stored.typ; |
|||
obj->falling.ori = obj->stored.ori; |
|||
obj->stored.typ = typ; |
|||
obj->stored.ori = ori; |
|||
while (!tg_fits(obj, obj->falling)) { |
|||
obj->falling.loc.row--; |
|||
if (tg_fits(obj, obj->falling)) { |
|||
break; |
|||
} |
|||
obj->falling.loc.col--; |
|||
if (tg_fits(obj, obj->falling)) { |
|||
break; |
|||
} |
|||
obj->falling.loc.col += 2; |
|||
} |
|||
} |
|||
tg_put(obj, obj->falling); |
|||
} |
|||
|
|||
/*
|
|||
Perform the action specified by the move. |
|||
*/ |
|||
static void tg_handle_move(struct games_state *rs,tetris_game *obj, tetris_move move) |
|||
{ |
|||
switch (move) { |
|||
case TM_LEFT: |
|||
//fprintf(stderr,"LEFT ");
|
|||
tg_move(obj, -1); |
|||
break; |
|||
case TM_RIGHT: |
|||
//fprintf(stderr,"RIGHT ");
|
|||
tg_move(obj, 1); |
|||
break; |
|||
case TM_DROP: |
|||
tg_down(rs,obj); |
|||
break; |
|||
case TM_CLOCK: |
|||
tg_rotate(obj, 1); |
|||
break; |
|||
case TM_COUNTER: |
|||
tg_rotate(obj, -1); |
|||
break; |
|||
case TM_HOLD: |
|||
tg_hold(rs,obj); |
|||
break; |
|||
default: |
|||
// pass
|
|||
break; |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
Return true if line i is full. |
|||
*/ |
|||
static bool tg_line_full(tetris_game *obj, int i) |
|||
{ |
|||
int j; |
|||
for (j = 0; j < obj->cols; j++) { |
|||
if (TC_IS_EMPTY(tg_get(obj, i, j))) |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
/*
|
|||
Shift every row above r down one. |
|||
*/ |
|||
static void tg_shift_lines(tetris_game *obj, int r) |
|||
{ |
|||
int i, j; |
|||
for (i = r-1; i >= 0; i--) { |
|||
for (j = 0; j < obj->cols; j++) { |
|||
tg_set(obj, i+1, j, tg_get(obj, i, j)); |
|||
tg_set(obj, i, j, TC_EMPTY); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
Find rows that are filled, remove them, shift, and return the number of |
|||
cleared rows. |
|||
*/ |
|||
static int tg_check_lines(tetris_game *obj) |
|||
{ |
|||
int i, nlines = 0; |
|||
tg_remove(obj, obj->falling); // don't want to mess up falling block
|
|||
|
|||
for (i = obj->rows-1; i >= 0; i--) { |
|||
if (tg_line_full(obj, i)) { |
|||
tg_shift_lines(obj, i); |
|||
i++; // do this line over again since they're shifted
|
|||
nlines++; |
|||
} |
|||
} |
|||
|
|||
tg_put(obj, obj->falling); // replace
|
|||
return nlines; |
|||
} |
|||
|
|||
/*
|
|||
Adjust the score for the game, given how many lines were just cleared. |
|||
*/ |
|||
static void tg_adjust_score(tetris_game *obj, int lines_cleared) |
|||
{ |
|||
static int line_multiplier[] = {0, 40, 100, 300, 1200}; |
|||
obj->points += line_multiplier[lines_cleared] * (obj->level + 1); |
|||
if (lines_cleared >= obj->lines_remaining) { |
|||
obj->level = MIN(MAX_LEVEL, obj->level + 1); |
|||
lines_cleared -= obj->lines_remaining; |
|||
obj->lines_remaining = LINES_PER_LEVEL - lines_cleared; |
|||
} else { |
|||
obj->lines_remaining -= lines_cleared; |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
Return true if the game is over. |
|||
*/ |
|||
static bool tg_game_over(tetris_game *obj) |
|||
{ |
|||
int i, j; |
|||
bool over = false; |
|||
tg_remove(obj, obj->falling); |
|||
for (i = 0; i < 2; i++) { |
|||
for (j = 0; j < obj->cols; j++) { |
|||
if (TC_IS_FILLED(tg_get(obj, i, j))) { |
|||
over = true; |
|||
} |
|||
} |
|||
} |
|||
tg_put(obj, obj->falling); |
|||
return over; |
|||
} |
|||
|
|||
/*******************************************************************************
|
|||
Main Public Functions |
|||
*******************************************************************************/ |
|||
|
|||
/*
|
|||
Do a single game tick: process gravity, user input, and score. Return true if |
|||
the game is still running, false if it is over. |
|||
*/ |
|||
bool tg_tick(struct games_state *rs,tetris_game *obj, tetris_move move) |
|||
{ |
|||
int lines_cleared; |
|||
// Handle gravity.
|
|||
tg_do_gravity_tick(rs,obj); |
|||
|
|||
// Handle input.
|
|||
tg_handle_move(rs,obj, move); |
|||
|
|||
// Check for cleared lines
|
|||
lines_cleared = tg_check_lines(obj); |
|||
|
|||
tg_adjust_score(obj, lines_cleared); |
|||
|
|||
// Return whether the game will continue (NOT whether it's over)
|
|||
return !tg_game_over(obj); |
|||
} |
|||
|
|||
void tg_init(struct games_state *rs,tetris_game *obj, int rows, int cols) |
|||
{ |
|||
// Initialization logic
|
|||
obj->rows = rows; |
|||
obj->cols = cols; |
|||
//obj->board = (char *)malloc(rows * cols);
|
|||
memset(obj->board, TC_EMPTY, rows * cols); |
|||
obj->points = 0; |
|||
obj->level = 0; |
|||
obj->ticks_till_gravity = GRAVITY_LEVEL[obj->level]; |
|||
obj->lines_remaining = LINES_PER_LEVEL; |
|||
//srand(time(NULL));
|
|||
tg_new_falling(rs,obj); |
|||
tg_new_falling(rs,obj); |
|||
obj->stored.typ = -1; |
|||
obj->stored.ori = 0; |
|||
obj->stored.loc.row = 0; |
|||
obj->next.loc.col = obj->cols/2 - 2; |
|||
//printf("%d", obj->falling.loc.col);
|
|||
} |
|||
|
|||
tetris_game *tg_create(struct games_state *rs,int rows, int cols) |
|||
{ |
|||
tetris_game *obj = (tetris_game *)malloc(sizeof(tetris_game) + rows*cols); |
|||
tg_init(rs,obj, rows, cols); |
|||
return obj; |
|||
} |
|||
|
|||
/*void tg_destroy(tetris_game *obj)
|
|||
{ |
|||
// Cleanup logic
|
|||
free(obj->board); |
|||
}*/ |
|||
|
|||
void tg_delete(tetris_game *obj) { |
|||
//tg_destroy(obj);
|
|||
free(obj); |
|||
} |
|||
|
|||
/*
|
|||
Load a game from a file. |
|||
|
|||
tetris_game *tg_load(FILE *f) |
|||
{ |
|||
tetris_game *obj = (tetris_game *)malloc(sizeof(tetris_game)); |
|||
if (fread(obj, sizeof(tetris_game), 1, f) != 1 ) |
|||
{ |
|||
fprintf(stderr,"read game error\n"); |
|||
free(obj); |
|||
obj = 0; |
|||
} |
|||
else |
|||
{ |
|||
obj->board = (char *)malloc(obj->rows * obj->cols); |
|||
if (fread(obj->board, sizeof(char), obj->rows * obj->cols, f) != obj->rows * obj->cols ) |
|||
{ |
|||
fprintf(stderr,"fread error\n"); |
|||
free(obj->board); |
|||
free(obj); |
|||
obj = 0; |
|||
} |
|||
} |
|||
return obj; |
|||
}*/ |
|||
|
|||
/*
|
|||
Save a game to a file. |
|||
|
|||
void tg_save(tetris_game *obj, FILE *f) |
|||
{ |
|||
if (fwrite(obj, sizeof(tetris_game), 1, f) != 1 ) |
|||
fprintf(stderr,"error writing tetrisgame\n"); |
|||
else if (fwrite(obj->board, sizeof(char), obj->rows * obj->cols, f) != obj->rows * obj->cols ) |
|||
fprintf(stderr,"error writing board\n"); |
|||
}*/ |
|||
|
|||
/*
|
|||
Print a game board to a file. Really just for early debugging. |
|||
*/ |
|||
void tg_print(tetris_game *obj, FILE *f) { |
|||
int i, j; |
|||
for (i = 0; i < obj->rows; i++) { |
|||
for (j = 0; j < obj->cols; j++) { |
|||
if (TC_IS_EMPTY(tg_get(obj, i, j))) { |
|||
fputs(TC_EMPTY_STR, f); |
|||
} else { |
|||
fputs(TC_BLOCK_STR, f); |
|||
} |
|||
} |
|||
fputc('\n', f); |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
2 columns per cell makes the game much nicer. |
|||
*/ |
|||
#define COLS_PER_CELL 2 |
|||
/*
|
|||
Macro to print a cell of a specific type to a window. |
|||
*/ |
|||
#define ADD_BLOCK(w,x) waddch((w),' '|A_REVERSE|COLOR_PAIR(x)); \ |
|||
waddch((w),' '|A_REVERSE|COLOR_PAIR(x)) |
|||
#define ADD_EMPTY(w) waddch((w), ' '); waddch((w), ' ') |
|||
|
|||
/*
|
|||
Print the tetris board onto the ncurses window. |
|||
*/ |
|||
void display_board(WINDOW *w, tetris_game *obj) |
|||
{ |
|||
int i, j; |
|||
box(w, 0, 0); |
|||
for (i = 0; i < obj->rows; i++) { |
|||
wmove(w, 1 + i, 1); |
|||
for (j = 0; j < obj->cols; j++) { |
|||
if (TC_IS_FILLED(tg_get(obj, i, j))) { |
|||
ADD_BLOCK(w,tg_get(obj, i, j)); |
|||
} else { |
|||
ADD_EMPTY(w); |
|||
} |
|||
} |
|||
} |
|||
wnoutrefresh(w); |
|||
} |
|||
|
|||
/*
|
|||
Display a tetris piece in a dedicated window. |
|||
*/ |
|||
void display_piece(WINDOW *w, tetris_block block) |
|||
{ |
|||
int b; |
|||
tetris_location c; |
|||
wclear(w); |
|||
box(w, 0, 0); |
|||
if (block.typ == -1) { |
|||
wnoutrefresh(w); |
|||
return; |
|||
} |
|||
for (b = 0; b < TETRIS; b++) { |
|||
c = TETROMINOS[block.typ][block.ori][b]; |
|||
wmove(w, c.row + 1, c.col * COLS_PER_CELL + 1); |
|||
ADD_BLOCK(w, TYPE_TO_CELL(block.typ)); |
|||
} |
|||
wnoutrefresh(w); |
|||
} |
|||
|
|||
/*
|
|||
Display score information in a dedicated window. |
|||
*/ |
|||
void display_score(WINDOW *w, tetris_game *tg) |
|||
{ |
|||
wclear(w); |
|||
box(w, 0, 0); |
|||
wprintw(w, (char *)"Score\n%d\n", tg->points); |
|||
wprintw(w, (char *)"Level\n%d\n", tg->level); |
|||
wprintw(w, (char *)"Lines\n%d\n", tg->lines_remaining); |
|||
wnoutrefresh(w); |
|||
} |
|||
|
|||
/*
|
|||
Save and exit the game. |
|||
|
|||
void save(tetris_game *game, WINDOW *w) |
|||
{ |
|||
FILE *f; |
|||
|
|||
wclear(w); |
|||
box(w, 0, 0); // return the border
|
|||
wmove(w, 1, 1); |
|||
wprintw(w, (char *)"Save and exit? [Y/n] "); |
|||
wrefresh(w); |
|||
timeout(-1); |
|||
if (getch() == 'n') { |
|||
timeout(0); |
|||
return; |
|||
} |
|||
f = fopen("tetris.save", "w"); |
|||
tg_save(game, f); |
|||
fclose(f); |
|||
tg_delete(game); |
|||
endwin(); |
|||
fprintf(stderr,"Game saved to \"tetris.save\".\n"); |
|||
fprintf(stderr,"Resume by passing the filename as an argument to this program.\n"); |
|||
exit(EXIT_SUCCESS); |
|||
}*/ |
|||
|
|||
/*
|
|||
Do the NCURSES initialization steps for color blocks. |
|||
*/ |
|||
void init_colors(void) |
|||
{ |
|||
start_color(); |
|||
//init_color(COLOR_ORANGE, 1000, 647, 0);
|
|||
init_pair(TC_CELLI, COLOR_CYAN, COLOR_BLACK); |
|||
init_pair(TC_CELLJ, COLOR_BLUE, COLOR_BLACK); |
|||
init_pair(TC_CELLL, COLOR_WHITE, COLOR_BLACK); |
|||
init_pair(TC_CELLO, COLOR_YELLOW, COLOR_BLACK); |
|||
init_pair(TC_CELLS, COLOR_GREEN, COLOR_BLACK); |
|||
init_pair(TC_CELLT, COLOR_MAGENTA, COLOR_BLACK); |
|||
init_pair(TC_CELLZ, COLOR_RED, COLOR_BLACK); |
|||
} |
|||
|
|||
struct games_state globalR; |
|||
extern char Gametxidstr[]; |
|||
int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eventid,gamesevent c); |
|||
gamesevent games_readevent(struct games_state *rs); |
|||
|
|||
void *gamesiterate(struct games_state *rs) |
|||
{ |
|||
uint32_t counter = 0; bool running = true; tetris_move move = TM_NONE; |
|||
gamesevent c; uint16_t skipcount=0; int32_t prevlevel; uint32_t eventid = 0; tetris_game *tg; |
|||
WINDOW *board, *next, *hold, *score; |
|||
if ( rs->guiflag != 0 || rs->sleeptime != 0 ) |
|||
{ |
|||
// NCURSES initialization:
|
|||
initscr(); // initialize curses
|
|||
cbreak(); // pass key presses to program, but not signals
|
|||
noecho(); // don't echo key presses to screen
|
|||
keypad(stdscr, TRUE); // allow arrow keys
|
|||
timeout(0); // no blocking on getch()
|
|||
curs_set(0); // set the cursor to invisible
|
|||
init_colors(); // setup tetris colors
|
|||
} |
|||
tg = tg_create(rs,22, 10); |
|||
prevlevel = tg->level; |
|||
// Create windows for each section of the interface.
|
|||
board = newwin(tg->rows + 2, 2 * tg->cols + 2, 0, 0); |
|||
next = newwin(6, 10, 0, 2 * (tg->cols + 1) + 1); |
|||
hold = newwin(6, 10, 7, 2 * (tg->cols + 1) + 1); |
|||
score = newwin(6, 10, 14, 2 * (tg->cols + 1 ) + 1); |
|||
while ( running != 0 ) |
|||
{ |
|||
running = tg_tick(rs,tg,move); |
|||
if ( 1 && (rs->guiflag != 0 || rs->sleeptime != 0) ) |
|||
{ |
|||
display_board(board,tg); |
|||
display_piece(next,tg->next); |
|||
display_piece(hold,tg->stored); |
|||
display_score(score,tg); |
|||
} |
|||
if ( rs->guiflag != 0 ) |
|||
{ |
|||
#ifdef STANDALONE |
|||
sleep_milli(15); |
|||
if ( (counter++ % 10) == 0 ) |
|||
doupdate(); |
|||
c = games_readevent(rs); |
|||
if ( c <= 0x7f || skipcount == 0x3fff ) |
|||
{ |
|||
if ( skipcount > 0 ) |
|||
issue_games_events(rs,Gametxidstr,eventid-skipcount,skipcount | 0x4000); |
|||
if ( c <= 0x7f ) |
|||
issue_games_events(rs,Gametxidstr,eventid,c); |
|||
if ( tg->level != prevlevel ) |
|||
{ |
|||
flushkeystrokes(rs,0); |
|||
prevlevel = tg->level; |
|||
} |
|||
skipcount = 0; |
|||
} else skipcount++; |
|||
#endif |
|||
} |
|||
else |
|||
{ |
|||
if ( rs->replaydone != 0 ) |
|||
break; |
|||
if ( rs->sleeptime != 0 ) |
|||
{ |
|||
sleep_milli(1); |
|||
if ( (counter++ % 20) == 0 ) |
|||
doupdate(); |
|||
} |
|||
if ( skipcount == 0 ) |
|||
{ |
|||
c = games_readevent(rs); |
|||
//fprintf(stderr,"%04x score.%d level.%d\n",c,tg->points,tg->level);
|
|||
if ( (c & 0x4000) == 0x4000 ) |
|||
{ |
|||
skipcount = (c & 0x3fff); |
|||
c = 'S'; |
|||
} |
|||
} |
|||
if ( skipcount > 0 ) |
|||
skipcount--; |
|||
} |
|||
eventid++; |
|||
switch ( c ) |
|||
{ |
|||
case 'h': |
|||
move = TM_LEFT; |
|||
break; |
|||
case 'l': |
|||
move = TM_RIGHT; |
|||
break; |
|||
case 'k': |
|||
move = TM_CLOCK; |
|||
break; |
|||
case 'j': |
|||
move = TM_DROP; |
|||
break; |
|||
case 'q': |
|||
running = false; |
|||
move = TM_NONE; |
|||
break; |
|||
/*case 'p':
|
|||
wclear(board); |
|||
box(board, 0, 0); |
|||
wmove(board, tg->rows/2, (tg->cols*COLS_PER_CELL-6)/2); |
|||
wprintw(board, "PAUSED"); |
|||
wrefresh(board); |
|||
timeout(-1); |
|||
getch(); |
|||
timeout(0); |
|||
move = TM_NONE; |
|||
break; |
|||
case 's': |
|||
save(tg, board); |
|||
move = TM_NONE; |
|||
break;*/ |
|||
case ' ': |
|||
move = TM_HOLD; |
|||
break; |
|||
default: |
|||
move = TM_NONE; |
|||
} |
|||
} |
|||
return(tg); |
|||
} |
|||
|
|||
#ifdef STANDALONE |
|||
/*
|
|||
Main tetris game! |
|||
*/ |
|||
#include "dapps/dappstd.c" |
|||
|
|||
|
|||
char *clonestr(char *str) |
|||
{ |
|||
char *clone; int32_t len; |
|||
if ( str == 0 || str[0] == 0 ) |
|||
{ |
|||
printf("warning cloning nullstr.%p\n",str); |
|||
#ifdef __APPLE__ |
|||
while ( 1 ) sleep(1); |
|||
#endif |
|||
str = (char *)"<nullstr>"; |
|||
} |
|||
len = strlen(str); |
|||
clone = (char *)calloc(1,len+16); |
|||
strcpy(clone,str); |
|||
return(clone); |
|||
} |
|||
|
|||
int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eventid,gamesevent c) |
|||
{ |
|||
static FILE *fp; |
|||
char params[512],*retstr; cJSON *retjson,*resobj; int32_t retval = -1; |
|||
if ( fp == 0 ) |
|||
fp = fopen("events.log","wb"); |
|||
rs->buffered[rs->num++] = c; |
|||
if ( 0 ) |
|||
{ |
|||
if ( sizeof(c) == 1 ) |
|||
sprintf(params,"[\"events\",\"17\",\"[%%22%02x%%22,%%22%s%%22,%u]\"]",(uint8_t)c&0xff,gametxidstr,eventid); |
|||
else if ( sizeof(c) == 2 ) |
|||
sprintf(params,"[\"events\",\"17\",\"[%%22%04x%%22,%%22%s%%22,%u]\"]",(uint16_t)c&0xffff,gametxidstr,eventid); |
|||
else if ( sizeof(c) == 4 ) |
|||
sprintf(params,"[\"events\",\"17\",\"[%%22%08x%%22,%%22%s%%22,%u]\"]",(uint32_t)c&0xffffffff,gametxidstr,eventid); |
|||
else if ( sizeof(c) == 8 ) |
|||
sprintf(params,"[\"events\",\"17\",\"[%%22%016llx%%22,%%22%s%%22,%u]\"]",(long long)c,gametxidstr,eventid); |
|||
if ( (retstr= hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) |
|||
{ |
|||
if ( (retjson= cJSON_Parse(retstr)) != 0 ) |
|||
{ |
|||
if ( (resobj= jobj(retjson,(char *)"result")) != 0 ) |
|||
{ |
|||
retval = 0; |
|||
if ( fp != 0 ) |
|||
{ |
|||
fprintf(fp,"%s\n",jprint(resobj,0)); |
|||
fflush(fp); |
|||
} |
|||
} |
|||
free_json(retjson); |
|||
} else fprintf(fp,"error parsing %s\n",retstr); |
|||
free(retstr); |
|||
} else fprintf(fp,"error issuing method %s\n",params); |
|||
return(retval); |
|||
} else return(0); |
|||
} |
|||
|
|||
int tetris(int argc, char **argv) |
|||
{ |
|||
struct games_state *rs = &globalR; |
|||
int32_t c,skipcount=0; uint32_t eventid = 0; tetris_game *tg = 0; |
|||
memset(rs,0,sizeof(*rs)); |
|||
rs->guiflag = 1; |
|||
rs->sleeptime = 1; // non-zero to allow refresh()
|
|||
if ( argc >= 2 && strlen(argv[2]) == 64 ) |
|||
{ |
|||
#ifdef _WIN32 |
|||
#ifdef _MSC_VER |
|||
rs->origseed = _strtoui64(argv[1], NULL, 10); |
|||
#else |
|||
rs->origseed = atol(argv[1]); // windows, but not MSVC
|
|||
#endif // _MSC_VER
|
|||
#else |
|||
rs->origseed = atol(argv[1]); // non-windows
|
|||
#endif // _WIN32
|
|||
rs->seed = rs->origseed; |
|||
if ( argc >= 3 ) |
|||
{ |
|||
strcpy(Gametxidstr,argv[2]); |
|||
fprintf(stderr,"setplayerdata %s\n",Gametxidstr); |
|||
if ( games_setplayerdata(rs,Gametxidstr) < 0 ) |
|||
{ |
|||
fprintf(stderr,"invalid gametxid, or already started\n"); |
|||
return(-1); |
|||
} |
|||
} |
|||
} else rs->seed = 777; |
|||
|
|||
/* Load file if given a filename.
|
|||
if (argc >= 2) { |
|||
FILE *f = fopen(argv[1], "r"); |
|||
if (f == NULL) { |
|||
perror("tetris"); |
|||
exit(EXIT_FAILURE); |
|||
} |
|||
tg = tg_load(f); |
|||
fclose(f); |
|||
} else { |
|||
// Otherwise create new game.
|
|||
tg = tg_create(rs,22, 10); |
|||
}*/ |
|||
|
|||
// Game loop
|
|||
tg = (tetris_game *)gamesiterate(rs); |
|||
gamesbailout(rs); |
|||
// Deinitialize NCurses
|
|||
wclear(stdscr); |
|||
endwin(); |
|||
// Output ending message.
|
|||
printf("Game over!\n"); |
|||
printf("You finished with %d points on level %d.\n", tg->points, tg->level); |
|||
|
|||
// Deinitialize Tetris
|
|||
tg_delete(tg); |
|||
return 0; |
|||
} |
|||
|
|||
#endif |
|||
|
@ -1,88 +0,0 @@ |
|||
// Copyright (c) 2016-2023 The Hush developers
|
|||
|
|||
/******************************************************************************
|
|||
* Copyright © 2014-2019 The SuperNET Developers. * |
|||
* * |
|||
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * |
|||
* the top-level directory of this distribution for the individual copyright * |
|||
* holder information and the developer policies on copyright and licensing. * |
|||
* * |
|||
* Unless otherwise agreed in a custom licensing agreement, no part of the * |
|||
* SuperNET software, including this file may be copied, modified, propagated * |
|||
* or distributed except according to the terms contained in the LICENSE file * |
|||
* * |
|||
* Removal or modification of this copyright notice is prohibited. * |
|||
* * |
|||
******************************************************************************/ |
|||
|
|||
std::string MYCCLIBNAME = (char *)"gamescc"; |
|||
|
|||
// game specific code for daemon
|
|||
void games_packitemstr(char *packitemstr,struct games_packitem *item) |
|||
{ |
|||
strcpy(packitemstr,""); |
|||
} |
|||
|
|||
int64_t games_cashout(struct games_player *P) |
|||
{ |
|||
int32_t dungeonlevel = P->dungeonlevel; int64_t mult=10000,cashout = 0; |
|||
cashout = (uint64_t)P->gold * mult; |
|||
return(cashout); |
|||
} |
|||
|
|||
void tetrisplayerjson(UniValue &obj,struct games_player *P) |
|||
{ |
|||
obj.push_back(Pair("packsize",(int64_t)P->packsize)); |
|||
obj.push_back(Pair("hitpoints",(int64_t)P->hitpoints)); |
|||
obj.push_back(Pair("strength",(int64_t)(P->strength&0xffff))); |
|||
obj.push_back(Pair("maxstrength",(int64_t)(P->strength>>16))); |
|||
obj.push_back(Pair("level",(int64_t)P->level)); |
|||
obj.push_back(Pair("experience",(int64_t)P->experience)); |
|||
obj.push_back(Pair("dungeonlevel",(int64_t)P->dungeonlevel)); |
|||
} |
|||
|
|||
int32_t disp_gamesplayer(char *str,struct games_player *P) |
|||
{ |
|||
str[0] = 0; |
|||
//if ( P->gold <= 0 )//|| P->hitpoints <= 0 || (P->strength&0xffff) <= 0 || P->level <= 0 || P->experience <= 0 || P->dungeonlevel <= 0 )
|
|||
// return(-1);
|
|||
sprintf(str," <- playerdata: gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d",P->gold,P->hitpoints,P->strength&0xffff,P->strength>>16,P->level,P->experience,P->dungeonlevel); |
|||
return(0); |
|||
} |
|||
|
|||
int32_t games_payloadrecv(CPubKey pk,uint32_t timestamp,std::vector<uint8_t> payload) |
|||
{ |
|||
uint256 gametxid; int32_t i,len; char str[67]; uint32_t eventid = 0; |
|||
if ( (len= payload.size()) > 36 ) |
|||
{ |
|||
len -= 36; |
|||
for (i=0; i<32; i++) |
|||
((uint8_t *)&gametxid)[i] = payload[len+i]; |
|||
eventid = (uint32_t)payload[len+32]; |
|||
eventid |= (uint32_t)payload[len+33] << 8; |
|||
eventid |= (uint32_t)payload[len+34] << 16; |
|||
eventid |= (uint32_t)payload[len+35] << 24; |
|||
//for (i=0; i<len; i++)
|
|||
// fprintf(stderr,"%02x",payload[i]);
|
|||
//fprintf(stderr," got payload, from %s %s/e%d\n",pubkey33_str(str,(uint8_t *)&pk),gametxid.GetHex().c_str(),eventid);
|
|||
return(0); |
|||
} else return(-1); |
|||
} |
|||
|
|||
UniValue games_bet(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) |
|||
{ |
|||
UniValue result; |
|||
return(result); |
|||
} |
|||
|
|||
UniValue games_settle(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) |
|||
{ |
|||
UniValue result; |
|||
return(result); |
|||
} |
|||
|
|||
bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) |
|||
{ |
|||
return(true); |
|||
} |
|||
|
@ -1,211 +0,0 @@ |
|||
// Copyright (c) 2016-2023 The Hush developers
|
|||
// Distributed under the GPLv3 software license, see the accompanying
|
|||
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
|||
|
|||
#ifndef H_TETRIS_H |
|||
#define H_TETRIS_H |
|||
|
|||
/***************************************************************************/ |
|||
/** https://github.com/brenns10/tetris
|
|||
@file main.c |
|||
@author Stephen Brennan |
|||
@date Created Wednesday, 10 June 2015 |
|||
@brief Main program for tetris. |
|||
@copyright Copyright (c) 2015, Stephen Brennan. Released under the Revised |
|||
BSD License. See LICENSE.txt for details. |
|||
*******************************************************************************/ |
|||
|
|||
/*
|
|||
Convert a tetromino type to its corresponding cell. |
|||
*/ |
|||
#define TYPE_TO_CELL(x) ((x)+1) |
|||
|
|||
/*
|
|||
Strings for how you would print a tetris board. |
|||
*/ |
|||
#define TC_EMPTY_STR " " |
|||
#define TC_BLOCK_STR "\u2588" |
|||
|
|||
/*
|
|||
Questions about a tetris cell. |
|||
*/ |
|||
#define TC_IS_EMPTY(x) ((x) == TC_EMPTY) |
|||
#define TC_IS_FILLED(x) (!TC_IS_EMPTY(x)) |
|||
|
|||
/*
|
|||
How many cells in a tetromino? |
|||
*/ |
|||
#define TETRIS 4 |
|||
/*
|
|||
How many tetrominos? |
|||
*/ |
|||
#define NUM_TETROMINOS 7 |
|||
/*
|
|||
How many orientations of a tetromino? |
|||
*/ |
|||
#define NUM_ORIENTATIONS 4 |
|||
|
|||
/*
|
|||
Level constants. |
|||
*/ |
|||
#define MAX_LEVEL 19 |
|||
#define LINES_PER_LEVEL 10 |
|||
|
|||
/*
|
|||
A "cell" is a 1x1 block within a tetris board. |
|||
*/ |
|||
typedef enum { |
|||
TC_EMPTY, TC_CELLI, TC_CELLJ, TC_CELLL, TC_CELLO, TC_CELLS, TC_CELLT, TC_CELLZ |
|||
} tetris_cell; |
|||
|
|||
/*
|
|||
A "type" is a type/shape of a tetromino. Not including orientation. |
|||
*/ |
|||
typedef enum { |
|||
TET_I, TET_J, TET_L, TET_O, TET_S, TET_T, TET_Z |
|||
} tetris_type; |
|||
|
|||
/*
|
|||
A row,column pair. Negative numbers allowed, because we need them for |
|||
offsets. |
|||
*/ |
|||
typedef struct { |
|||
int row; |
|||
int col; |
|||
} tetris_location; |
|||
|
|||
/*
|
|||
A "block" is a struct that contains information about a tetromino. |
|||
Specifically, what type it is, what orientation it has, and where it is. |
|||
*/ |
|||
typedef struct { |
|||
int typ; |
|||
int ori; |
|||
tetris_location loc; |
|||
} tetris_block; |
|||
|
|||
/*
|
|||
All possible moves to give as input to the game. |
|||
*/ |
|||
typedef enum { |
|||
TM_LEFT, TM_RIGHT, TM_CLOCK, TM_COUNTER, TM_DROP, TM_HOLD, TM_NONE |
|||
} tetris_move; |
|||
|
|||
/*
|
|||
A game object! |
|||
*/ |
|||
typedef struct { |
|||
/*
|
|||
Game board stuff: |
|||
*/ |
|||
int rows; |
|||
int cols; |
|||
/*
|
|||
Scoring information: |
|||
*/ |
|||
int points; |
|||
int level; |
|||
/*
|
|||
Falling block is the one currently going down. Next block is the one that |
|||
will be falling after this one. Stored is the block that you can swap out. |
|||
*/ |
|||
tetris_block falling; |
|||
tetris_block next; |
|||
tetris_block stored; |
|||
/*
|
|||
Number of game ticks until the block will move down. |
|||
*/ |
|||
int ticks_till_gravity; |
|||
/*
|
|||
Number of lines until you advance to the next level. |
|||
*/ |
|||
int lines_remaining; |
|||
char board[]; |
|||
} tetris_game; |
|||
|
|||
/*
|
|||
This array stores all necessary information about the cells that are filled by |
|||
each tetromino. The first index is the type of the tetromino (i.e. shape, |
|||
e.g. I, J, Z, etc.). The next index is the orientation (0-3). The final |
|||
array contains 4 tetris_location objects, each mapping to an offset from a |
|||
point on the upper left that is the tetromino "origin". |
|||
*/ |
|||
extern const tetris_location TETROMINOS[NUM_TETROMINOS][NUM_ORIENTATIONS][TETRIS]; |
|||
|
|||
/*
|
|||
This array tells you how many ticks per gravity by level. Decreases as level |
|||
increases, to add difficulty. |
|||
*/ |
|||
extern const int GRAVITY_LEVEL[MAX_LEVEL+1]; |
|||
|
|||
// Data structure manipulation.
|
|||
void tg_init(tetris_game *obj, int rows, int cols); |
|||
tetris_game *tg_create(struct games_state *rs,int rows, int cols); |
|||
void tg_destroy(tetris_game *obj); |
|||
void tg_delete(tetris_game *obj); |
|||
tetris_game *tg_load(FILE *f); |
|||
void tg_save(tetris_game *obj, FILE *f); |
|||
|
|||
// Public methods not related to memory:
|
|||
char tg_get(tetris_game *obj, int row, int col); |
|||
bool tg_check(tetris_game *obj, int row, int col); |
|||
bool tg_tick(struct games_state *rs,tetris_game *obj, tetris_move move); |
|||
void tg_print(tetris_game *obj, FILE *f); |
|||
|
|||
/******************************************************************************
|
|||
* Copyright © 2014-2019 The SuperNET Developers. * |
|||
* * |
|||
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * |
|||
* the top-level directory of this distribution for the individual copyright * |
|||
* holder information and the developer policies on copyright and licensing. * |
|||
* * |
|||
* Unless otherwise agreed in a custom licensing agreement, no part of the * |
|||
* SuperNET software, including this file may be copied, modified, propagated * |
|||
* or distributed except according to the terms contained in the LICENSE file * |
|||
* * |
|||
* Removal or modification of this copyright notice is prohibited. * |
|||
* * |
|||
******************************************************************************/ |
|||
#define GAMENAME "tetris" // name of executable
|
|||
#define GAMEMAIN tetris // main program of game
|
|||
#define GAMEPLAYERJSON tetrisplayerjson // displays game specific json
|
|||
#define GAMEDATA tetrisdata // extracts data from game specific variables into games_state
|
|||
#define CHAINNAME "GTEST" // -ac_name=
|
|||
typedef uint16_t gamesevent; // can be 8, 16, 32, or 64 bits
|
|||
|
|||
#define MAXPACK 23 |
|||
struct games_packitem |
|||
{ |
|||
int32_t type,launch,count,which,hplus,dplus,arm,flags,group; |
|||
char damage[8],hurldmg[8]; |
|||
}; |
|||
|
|||
struct games_player |
|||
{ |
|||
int32_t gold,hitpoints,strength,level,experience,packsize,dungeonlevel,amulet; |
|||
struct games_packitem gamespack[MAXPACK]; |
|||
}; |
|||
|
|||
struct games_state |
|||
{ |
|||
uint64_t seed,origseed; |
|||
char *keystrokeshex; |
|||
uint32_t needflush,replaydone; |
|||
int32_t numkeys,ind,num,guiflag,counter,sleeptime,playersize,restoring,lastnum; |
|||
FILE *logfp; |
|||
struct games_player P; |
|||
gamesevent buffered[5000],*keystrokes; |
|||
uint8_t playerdata[8192]; |
|||
}; |
|||
extern struct games_state globalR; |
|||
void *gamesiterate(struct games_state *rs); |
|||
int32_t flushkeystrokes(struct games_state *rs,int32_t waitflag); |
|||
|
|||
void games_packitemstr(char *packitemstr,struct games_packitem *item); |
|||
uint64_t _games_rngnext(uint64_t initseed); |
|||
int32_t games_replay2(uint8_t *newdata,uint64_t seed,gamesevent *keystrokes,int32_t num,struct games_player *player,int32_t sleepmillis); |
|||
gamesevent games_revendian(gamesevent revx); |
|||
int32_t disp_gamesplayer(char *str,struct games_player *P); |
|||
|
|||
#endif |
|||
|
@ -1,123 +0,0 @@ |
|||
// Copyright (c) 2016-2023 The Hush developers
|
|||
// Distributed under the GPLv3 software license, see the accompanying
|
|||
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
|||
#ifndef H_GAMESCC_H |
|||
#define H_GAMESCC_H |
|||
|
|||
#include <stdint.h> |
|||
#include <stdio.h> |
|||
#define GAMES_RNGMULT 11109 |
|||
#define GAMES_RNGOFFSET 13849 |
|||
#define GAMES_MAXRNGS 10000 |
|||
|
|||
#ifndef STANDALONE |
|||
|
|||
#define ENABLE_WALLET |
|||
extern CWallet* pwalletMain; |
|||
|
|||
#include "CCinclude.h" |
|||
#include "secp256k1.h" |
|||
|
|||
|
|||
#define EVAL_GAMES (EVAL_FAUCET2+1) |
|||
#define GAMES_TXFEE 10000 |
|||
#define GAMES_MAXITERATIONS 777 |
|||
#define GAMES_MAXKEYSTROKESGAP 60 |
|||
#define GAMES_MAXPLAYERS 64 |
|||
#define GAMES_REGISTRATIONSIZE (100 * 10000) |
|||
#define GAMES_REGISTRATION 1 |
|||
|
|||
|
|||
#define MYCCNAME "games" |
|||
|
|||
std::string Games_pname; |
|||
|
|||
#define RPC_FUNCS \ |
|||
{ (char *)MYCCNAME, (char *)"rng", (char *)"hash,playerid", 1, 2, ' ', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"rngnext", (char *)"seed", 1, 1, ' ', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"fund", (char *)"amount", 1, 1, ' ', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"players", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"games", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"pending", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"setname", (char *)"pname", 1, 1, ' ', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"newgame", (char *)"maxplayers,buyin", 2, 2, 'C', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"playerinfo", (char *)"playertxid", 1, 1, ' ', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"gameinfo", (char *)"gametxid", 1, 1, ' ', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"keystrokes", (char *)"txid,hexstr", 2, 2, 'K', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"bailout", (char *)"gametxid", 1, 1, 'Q', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"highlander", (char *)"gametxid", 1, 1, 'H', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"events", (char *)"eventshex [gametxid [eventid]]", 1, 3, ' ', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"extract", (char *)"gametxid [pubkey]", 1, 2, ' ', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"bet", (char *)"amount hexstr", 2, 2, ' ', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"settle", (char *)"height", 1, 1, ' ', EVAL_GAMES }, \ |
|||
{ (char *)MYCCNAME, (char *)"register", (char *)"gametxid [playertxid]", 1, 2, 'R', EVAL_GAMES }, |
|||
|
|||
bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx); |
|||
UniValue games_rng(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_rngnext(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_fund(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_players(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_games(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_setname(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_newgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_playerinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_bailout(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_highlander(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_bet(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
UniValue games_settle(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); |
|||
|
|||
#define CUSTOM_DISPATCH \ |
|||
if ( cp->evalcode == EVAL_GAMES ) \ |
|||
{ \ |
|||
if ( strcmp(method,"rng") == 0 ) \ |
|||
return(games_rng(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"rngnext") == 0 ) \ |
|||
return(games_rngnext(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"newgame") == 0 ) \ |
|||
return(games_newgame(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"gameinfo") == 0 ) \ |
|||
return(games_gameinfo(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"register") == 0 ) \ |
|||
return(games_register(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"events") == 0 ) \ |
|||
return(games_events(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"players") == 0 ) \ |
|||
return(games_players(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"games") == 0 ) \ |
|||
return(games_games(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"pending") == 0 ) \ |
|||
return(games_pending(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"setname") == 0 ) \ |
|||
return(games_setname(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"playerinfo") == 0 ) \ |
|||
return(games_playerinfo(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"keystrokes") == 0 ) \ |
|||
return(games_keystrokes(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"extract") == 0 ) \ |
|||
return(games_extract(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"bailout") == 0 ) \ |
|||
return(games_bailout(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"highlander") == 0 ) \ |
|||
return(games_highlander(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"fund") == 0 ) \ |
|||
return(games_fund(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"bet") == 0 ) \ |
|||
return(games_bet(txfee,cp,params)); \ |
|||
else if ( strcmp(method,"settle") == 0 ) \ |
|||
return(games_settle(txfee,cp,params)); \ |
|||
else \ |
|||
{ \ |
|||
result.push_back(Pair("result","error")); \ |
|||
result.push_back(Pair("error","invalid gamescc method")); \ |
|||
return(result); \ |
|||
} \ |
|||
} |
|||
#endif |
|||
|
|||
#endif |
Loading…
Reference in new issue