EOS三连棋游戏

本文由【区块链研习社】优质内容计划支持,更多关于区块链的深度好文,请点击《区块链研习社》

前言

好吧,我承认本文有点“标题党”,本文其实是相通过玩三连棋,学习EOS的智能合约。

一、准备

参考上一篇文章《EOS智能合约部署》,这里我创建了一个tic.tac.toe账户。

二、部署

1、编译智能合约代码

由于编译EOS代码的时候没有编译tic_tac_toe,需要手动编译。

小tips:EOS自带智能合约源代码在~/eos/contracts目录下面,编译EOS代码时候生成的文件在~/eos/build/contracts目录下面。

$ eosc -o tic_tac_toe.wast tic_tac_toe.cpp

2、部署智能合约

$ eosc set contract tic.tac.toe tic_tac_toe.wast tic_tac_toe.abi

三、开始游戏

从abi文件可以看到,这个智能合约支持四种action(操作),分别是create、move、restart和close。

"actions": [{
      "action_name": "**create**",
      "type": "create"
    },{
      "action_name": "**restart**",
      "type": "restart"
    },{
      "action_name": "**close**",
      "type": "close"
    },{
      "action_name": "**move**",
      "type": "move"
    }
  ]

游戏开始,GO!

首先,我们先来创建棋局,tic.tac.toe是东道主,currency是挑战者(currency账户由上一篇文章《EOS智能合约部署》创建),创建棋局需要东道主的授权(–permission tic.tac.toe@active)

$ eosc push message tic.tac.toe create '{"challenger":"currency", "host":"tic.tac.toe"}' --scope currency,tic.tac.toe --permission tic.tac.toe@active

从abi文件可以看出,create操作所需要的数据,即challenger和host。

{
      "name": "create",
      "base": "",
      "fields": {
        "challenger": "account_name",
        "host": "account_name"
      }
}

现在开始下棋,东道主先下(比如东道主先在1行0列落子)。

$  eosc push message tic.tac.toe move '{"challenger":"currency", "host":"tic.tac.toe", "by":"tic.tac.toe", "movement":{"row":1,"column":0}}' --scope currency,tic.tac.toe --permission tic.tac.toe@active

从abi文件可以看出,move操作所需要的数据,即challenger、host、by和movement。

其中,by表示当前下棋人,movement表示落子的位置。

{
      "name": "move",
      "base": "",
      "fields": {
        "challenger": "account_name",
        "host": "account_name",
        "by": "account_name",
        "movement": "movement"
      }
  }

movement的结构中有row和column两个成员。

{
      "name": "movement",
      "base": "",
      "fields": {
        "row": "uint32",
        "column": "uint32"
      }
}

我们如何知道落子已经成功了呢?简单,查看一下棋局即可:

$ eosc get table tic.tac.toe tic.tac.toe games
{
  "rows": [{
      "challenger": "currency",
      "host": "tic.tac.toe",
      "turn": "currency",
      "winner": "none",
      "board": [
        0,
        0,
        0,
        1,
        0,
        0,
        0,
        0,
        0
      ]
    }
  ],
  "more": true
}

从上面可以看到,在1行0列已经有子了。

tips:从ABI文件可以看到,table_name是games,所以get table的最后一个参数是games

"tables": {
"table_name": "**games**",
        "type": "game",
        "index_type": "i64",
        "key_names" : ["challenger"],
        "key_types" : ["account_name"]
 }

而game的类型如下,这与get table出来的数据结构一致

{
      "name": "game",
      "base": "",
      "fields": {
        "challenger": "account_name",
        "host": "account_name",
        "turn": "account_name",
        "winner": "account_name",
        "board": "uint8[]"
      }
}

好了,现在轮到挑战者落子了,原理和上面一样,这里就不多说了。

$ eosc push message tic.tac.toe move '{"challenger":"currency", "host":"tic.tac.toe", "by":"currency", "movement":{"row":0,"column":1}}' --scope currency,tic.tac.toe --permission currency@active

从下面可以看到,在0行1列已经有子了。

$ eosc get table tic.tac.toe tic.tac.toe games
{
  "rows": [{
      "challenger": "currency",
      "host": "tic.tac.toe",
      "turn": "tic.tac.toe",
      "winner": "none",
      "board": [
        0,
        2,
        0,
        1,
        0,
        0,
        0,
        0,
        0
      ]
    }
  ],
  "more": true
}

为了演示的简单,我们设定东道主从上往下下,挑战者从左往右下,那最终结果就是东道主胜利。

当东道主下第3子后,我们查看一下当前的棋局,发现胜负已定,winner是tic.tac.toe。

$ eosc get table tic.tac.toe tic.tac.toe games
{
  "rows": [{
      "challenger": "currency",
      "host": "tic.tac.toe",
      "turn": "currency",
      "**winner**": "tic.tac.toe",
      "board": [
        0,
        2,
        2,
        1,
        1,
        1,
        0,
        0,
        0
      ]
    }
  ],
  "more": true
}

到这里,game over了,如果还想再来一盘,任何一方都已发起,再来一盘可以使用restart操作。

注意:如果使用restart操作,并不能改变挑战者和东道主的角色。

$ eosc push message tic.tac.toe restart '{"challenger":"currency", "host":"tic.tac.toe", "by":"currency"}' --scope currency,tic.tac.toe --permission currency@active

从abi文件可以看出,restart操作所需要的数据,即challenger、host和by。

{
      "name": "restart",
      "base": "",
      "fields": {
        "challenger": "account_name",
        "host": "account_name",
        "by": "account_name"
      }
}

如果玩完了,那就关掉棋局。

关掉棋局可以使用close操作。

$ eosc push message tic.tac.toe close '{"challenger":"currency", "host":"tic.tac.toe"}' --scope currency,tic.tac.toe --permission tic.tac.toe@active

从abi文件可以看出,close操作所需要的数据和create一样,即challenger和host。

{
      "name": "close",
      "base": "",
      "fields": {
        "challenger": "account_name",
        "host": "account_name"
      }
}

好了,游戏到此结束,想要知道上面规则还要阅读源代码,本人更多从ABI文件出发,和智能合约互动。

求教!!! 关于三连游戏编程问题

10-19

以下是我的code, 我的intermove 不能正确工作,求大神指教, 在intermove function中, 我的for loop 中的gamecheck 不能正确的测试我board1和board2, 但是当我加入printboard(board1or2)时他会打印出我想要的board。 求帮助!万分感谢!rnrnrnrnrnrnrnrnrnrnrnrnrnrnrnrnrnrnrnrnrnvoid playGame(int first,int xlevel,int olevel)rnint board[9];rnint i;rnfor (i=0;i<9;i++) board[i]=-1; /*initialize the tic table */rnprintBoard(board);rnwhile (gameCheck(board)==-1)rnif (first==1)printf("X's turn\n");rn if (xlevel==0)noviceMove(board,1);rn else if (xlevel==1)interMove(board,1);rn else if (xlevel==2)advMove(board,1);rn else if (xlevel==3)humanMove(board,1);rnfirst=0;rnrnelse printf("O's turn\n");rn if (olevel==0)noviceMove(board,0);rn else if (olevel==1)interMove(board,0);rn else if (olevel==2)advMove(board,0);rn else if (olevel==3)humanMove(board,0);rnfirst=1;rnrnprintBoard(board);rnrnif (gameCheck(board)==1)printf("X win!");rnelse if (gameCheck(board)==0)printf("O win!");rnelse printf("TIE!");rnrnint gameCheck(const int board[])rn int R=2;/*assume this game do not have any winer if R will not change*/rn int i;rn if ((board[0]==board[4]&&board[4]==board[8])||(board[2]==board[4]&&board[4]==board[6])||(board[1]==board[4]&&board[4]==board[7])||(board[3]==board[4]&&board[4]==board[5])) R=board[4];rn/*check all lines have no.4*/rn else if ((board[0]==board[1]&&board[1]==board[2])||(board[0]==board[3]&&board[3]==board[6]))R=board[0];rn/*check all lines have no.0*/rn else if ((board[8]==board[5]&&board[5]==board[2])||(board[8]==board[7]&&board[7]==board[6])) R=board[8];rn/*check all lines have no.8*/rnif (R==2)for(i=0;i<9;i++)if (board[i]==-1)R=-1;break; /*if the board have any -1, and there is no winer,the game is not over set returen value to -1*/rnrnreturn R;rnrnvoid noviceMove(int board[],int player)rnint i;rni=ranf_next(9);/* get a random number*/rnwhile (board[i]!=-1)rni=ranf_next(9);rnboard[i]=player;/*check if this position empty*/rnrnvoid interMove(int board[],int player)rnint i,k=0,g=0;rnint board1[9];rnint board2[9];rnfor (k=0;k<9;k++)for (i=0;i<9;i++)board1[i]=board[i]; /* reset test1 in every loop*/rnboard1[k]=player;rn if (gameCheck(board1)==player)rn break;rn rn/* try to find a position that can win this game*/rnfor (g=0;g<9;g++)for (i=0;i<9;i++)board2[i]=board[i]; /* reset test1 in every loop*/rnboard2[g]=1-player;rnif (gameCheck(board2)==(1-player))rn break;rnrnrn/*try to find a position that can block others*/rnif (gameCheck(board1)==player) board[k]=player;/*check if this move can win the game, do it*/rnelse if (gameCheck(board2)==(1-player)) board[g]=player;/*check if this move can block*/rnelse noviceMove(board,player);rnrnvoid advMove(int board[],int player)rnint i;rnint k=1;rnfor (i=0;i<9;i++)if(board[i]==player)k=0;/*check if player is fist move*/rnrnif (k)if(board[4]==-1)board[4]=player;rn else board[2]=player;rnrnelse interMove(board,player);rnrnrnvoid humanMove(int board[],int player)rnint i;rnprintf("Your move?");rnscanf("%d",&i);rnwhile (board[i]!=-1)rnprintf("Your move?");rnscanf("%d",&i);rnrnboard[i]=player;rnrnvoid printBoard(const int board[])rnint i;rnfor (i=0;i<2;i++)rn if (board[i]==-1)printf("-|");rn else if (board[i]==0)printf("O|");rn else if (board[i]==1)printf("X|");rn rn if (board[2]==-1)printf("-\n----------\n");rn else if (board[2]==0)printf("O\n----------\n");rn else if (board[2]==1)printf("X\n----------\n");rnrnfor (i=3;i<5;i++)rn if (board[i]==-1)printf("-|");rn else if (board[i]==0)printf("O|");rn else if (board[i]==1)printf("X|");rn rn if (board[5]==-1)printf("-\n----------\n");rn else if (board[5]==0)printf("O\n----------\n");rn else if (board[5]==1)printf("X\n----------\n");rnfor (i=6;i<8;i++)rn if (board[i]==-1)printf("-|");rn else if (board[i]==0)printf("O|");rn else if (board[i]==1)printf("X|");rn rn if (board[8]==-1)printf("-\n");rn else if (board[8]==0)printf("O\n");rn else if (board[8]==1)printf("X\n");

没有更多推荐了,返回首页