BlockChainによる簡単なゲームを実装する
BlockChainは2009年1月にSatoshi Nakamoto氏によってBitcoinの実装の一環として登場して以来、様々な業界にBlockChainを活用してきました。
本記事はRemix上簡単な英単語あてゲームを作ります。ゲームルールは下記の通りです。
英単語のヒントをあげて、単語の1文字を当てたら、当てたアルファベットの位置を表示します。全部当てたら、10ethを上げます。当てなかったら、間違った回数をカウントして、6回以上になったら、「Game Over」になります。
まず、Remixにアクセスします。https://remix.ethereum.org
Environmentsの「Solidity」を押して、下記の画面が表示されます。
左側上から2番目のアイコンを押下して、 browser文字の右側の+を押下して、ファイル名を「game.sol」を入力して、OKボタンを押下します。
右側の編集エリアにソースを入力します。ソースは難しくないですが、見たら大体わかります。時間があったら、ソースの説明を追加します。
pragma solidity ^0.5.0;
contract Game {
string question; // the word to guess
string public message; // message
string public answer; // answer
bytes bytesAnswer; // answer for bytes
uint public wrongNumber; // wrong count
uint maxWrongNumber; // max wrong number
event msgEvent(string message); // message event
event countEvent(uint number); // wrong count event
constructor() public {
wrongNumber = 0; // wrong count
maxWrongNumber = 6; // max wrong number = 6
}
// set the word to guess
function A_SetQuestion(string memory _question) public {
wrongNumber = 0;
question = _question;
bytesAnswer = new bytes(getLength(_question));
answer = "";
}
// fund
function B_SetFund() public payable {
}
// guess
function C_Guess(string memory _input) public {
// get the first alphabet
bytes memory bytesInput = bytes(_input);
byte bInput = bytesInput[0];
// check whether the alphabet exists in the word
bytes memory bytesQuestion = bytes(question);
bool result = false;
for (uint i = 0; i < bytesQuestion.length; i++) {
if (bInput == bytesQuestion[i]) {
bytesAnswer[i] = bInput;
result = true;
}
}
if (result) {
if (checkFinished()) {
message = "You won!";
answer = getInputted();
emit msgEvent(message);
msg.sender.transfer(address(this).balance);
} else {
message = "Good job!";
answer = getInputted();
emit msgEvent(message);
emit msgEvent(answer);
}
} else {
wrongNumber++;
if (wrongNumber > maxWrongNumber) {
message = "You losed!";
emit msgEvent(message);
} else {
message = "Wrong! Please try again";
emit msgEvent(message);
emit countEvent(wrongNumber);
}
}
}
function checkFinished() private view returns(bool) {
for (uint i = 0; i < bytesAnswer.length; i++) {
if (bytesAnswer[i] == 0) {
return false;
}
}
return true;
}
function getInputted() private view returns(string memory) {
bytes memory str = new bytes(bytesAnswer.length);
for (uint i = 0; i < bytesAnswer.length; i++) {
if (bytesAnswer[i] == 0) {
str[i] = '?';
} else {
str[i] = bytesAnswer[i];
}
}
return string(str);
}
function getLength(string memory _str) private pure returns(uint) {
bytes memory bytesStr = bytes(_str);
return bytesStr.length;
}
}
左側上から4番目のボタンを押下して、下記の画面が表示されます。
「Deploy」ボタンを押下して、「Deployed Contracts」エリアに表示されるContractの>矢印を押下したら、下記のような画面が表示されます。
「A_SetQuestion」に「”test”」を入力して、該当ボタンを押下します。これは当て単語です。次はValueの値を「10」etherを入力して、「B_SetFund」を押下して、当てたら10etherを払います。
accountを別のアカウントに変更します。当てる側に相当します。
「C_Guess」の値を「”t”」を入力して、該当ボタンを押下します。次は「answer」ボタンを押下したら、単語は「t??t」を確認できます。「message」ボタンを押下しますと、「Good Job!」のメッセージも表示されます。全部当てますと、「message」が「You won!」になり、「account」を確認して、10etherが付与されることを確認できます。「wrongNumber」ボタン押下後、0になっていることを確認します。イベントも発生させますので、コンソールでも確認できます。
6回以上間違いましたら、messageが「You losed!」になります。動作を確認しながら、ソースを解析したほうがすぐわかると思います。
ご不明点がありましたら、コメントをお願いします。