From 905f440b604fc64db31537252e06b911c03ccbfa Mon Sep 17 00:00:00 2001 From: yusuf idi maina <120538505+yusufidimaina9989@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:35:27 +0100 Subject: [PATCH 1/8] Create index.html.ts --- src/pages/Tic-tac-toe 5x5/index.html.ts | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/pages/Tic-tac-toe 5x5/index.html.ts diff --git a/src/pages/Tic-tac-toe 5x5/index.html.ts b/src/pages/Tic-tac-toe 5x5/index.html.ts new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/pages/Tic-tac-toe 5x5/index.html.ts @@ -0,0 +1 @@ + From 497e9d0182552f0a32fda30cfdb871e6e97451a3 Mon Sep 17 00:00:00 2001 From: yusuf idi maina <120538505+yusufidimaina9989@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:40:24 +0100 Subject: [PATCH 2/8] Create index.md --- src/pages/Tic-tac-toe 5x5/index.md | 297 +++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 src/pages/Tic-tac-toe 5x5/index.md diff --git a/src/pages/Tic-tac-toe 5x5/index.md b/src/pages/Tic-tac-toe 5x5/index.md new file mode 100644 index 0000000..f4e7b5d --- /dev/null +++ b/src/pages/Tic-tac-toe 5x5/index.md @@ -0,0 +1,297 @@ +--- +title: Tic-Tac-Toe 5x5 +version: 0.1.0 +description: Tic-Tac-Toe 5x5 in sCrypt +--- +To initiate a game, Alice and Bob each lock up X amount of bitcoins into a contract UTXO. They take turns to play the game by sending signed transactions interacting with the [stateful contract](https://scrypt.io/scrypt-ts/tutorials/stateful-contract). If one of them wins, the winner claims the 2X bitcoins. If there is a draw, they take back their bitcoins. +```ts +import { + prop, method, SmartContract, PubKey, FixedArray, assert, Sig, Utils, toByteString, hash160, + hash256, + fill, + ContractTransaction, + MethodCallOptions, + bsv +} from "scrypt-ts"; + +export class TicTacToe extends SmartContract { + @prop() + alice: PubKey; + @prop() + bob: PubKey; + + @prop(true) + isAliceTurn: boolean; + + @prop(true) + board: FixedArray; + + static readonly EMPTY: bigint = 0n; + static readonly ALICE: bigint = 1n; + static readonly BOB: bigint = 2n; + + constructor(alice: PubKey, bob: PubKey) { + super(...arguments) + this.alice = alice; + this.bob = bob; + this.isAliceTurn = true; + this.board = fill(TicTacToe.EMPTY, 25); + } + + @method() + public move(n: bigint, sig: Sig) { + // check position `n` + assert(n >= 0n && n < 25n); + // check signature `sig` + let player: PubKey = this.isAliceTurn ? this.alice : this.bob; + assert(this.checkSig(sig, player), `checkSig failed, pubkey: ${player}`); + // update stateful properties to make the move + assert(this.board[Number(n)] === TicTacToe.EMPTY, `board at position ${n} is not empty: ${this.board[Number(n)]}`); + let play = this.isAliceTurn ? TicTacToe.ALICE : TicTacToe.BOB; + this.board[Number(n)] = play; + this.isAliceTurn = !this.isAliceTurn; + + // build the transation outputs + let outputs = toByteString(''); + if (this.won(play)) { + outputs = Utils.buildPublicKeyHashOutput(hash160(player), this.ctx.utxo.value); + } + else if (this.full()) { + const halfAmount = this.ctx.utxo.value / 2n; + const aliceOutput = Utils.buildPublicKeyHashOutput(hash160(this.alice), halfAmount); + const bobOutput = Utils.buildPublicKeyHashOutput(hash160(this.bob), halfAmount); + outputs = aliceOutput + bobOutput; + } + else { + // build a output that contains latest contract state. + outputs = this.buildStateOutput(this.ctx.utxo.value); + } + + if (this.changeAmount > 0n) { + outputs += this.buildChangeOutput(); + } + // make sure the transaction contains the expected outputs built above + assert(this.ctx.hashOutputs === hash256(outputs), "check hashOutputs failed"); + } + + @method() + won(play: bigint): boolean { + let lines: FixedArray, 87> = [ + // Rows + [0n, 1n, 2n, 3n, 4n], + [1n, 2n, 3n, 4n, 5n], + [2n, 3n, 4n, 5n, 6n], + [5n, 6n, 7n, 8n, 9n], + [6n, 7n, 8n, 9n, 10n], + [7n, 8n, 9n, 10n, 11n], + [10n, 11n, 12n, 13n, 14n], + [11n, 12n, 13n, 14n, 15n], + [12n, 13n, 14n, 15n, 16n], + [15n, 16n, 17n, 18n, 19n], + [16n, 17n, 18n, 19n, 20n], + [17n, 18n, 19n, 20n, 21n], + [20n, 21n, 22n, 23n, 24n], + [21n, 22n, 23n, 24n, 25n], + [22n, 23n, 24n, 25n, 26n], + [25n, 26n, 27n, 28n, 29n], + [26n, 27n, 28n, 29n, 30n], + [27n, 28n, 29n, 30n, 31n], + [30n, 31n, 32n, 33n, 34n], + [31n, 32n, 33n, 34n, 35n], + [32n, 33n, 34n, 35n, 36n], + [35n, 36n, 37n, 38n, 39n], + [36n, 37n, 38n, 39n, 40n], + [37n, 38n, 39n, 40n, 41n], + [40n, 41n, 42n, 43n, 44n], + [41n, 42n, 43n, 44n, 45n], + [42n, 43n, 44n, 45n, 46n], + [45n, 46n, 47n, 48n, 49n], + [46n, 47n, 48n, 49n, 50n], + [47n, 48n, 49n, 50n, 51n], + [50n, 51n, 52n, 53n, 54n], + [51n, 52n, 53n, 54n, 55n], + [52n, 53n, 54n, 55n, 56n], + + // Columns + [0n, 5n, 10n, 15n, 20n], + [5n, 10n, 15n, 20n, 25n], + [10n, 15n, 20n, 25n, 30n], + [15n, 20n, 25n, 30n, 35n], + [20n, 25n, 30n, 35n, 40n], + [25n, 30n, 35n, 40n, 45n], + [30n, 35n, 40n, 45n, 50n], + [35n, 40n, 45n, 50n, 55n], + [40n, 45n, 50n, 55n, 60n], + [1n, 6n, 11n, 16n, 21n], + [6n, 11n, 16n, 21n, 26n], + [11n, 16n, 21n, 26n, 31n], + [16n, 21n, 26n, 31n, 36n], + [21n, 26n, 31n, 36n, 41n], + [26n, 31n, 36n, 41n, 46n], + [31n, 36n, 41n, 46n, 51n], + [36n, 41n, 46n, 51n, 56n], + [41n, 46n, 51n, 56n, 61n], + [2n, 7n, 12n, 17n, 22n], + [7n, 12n, 17n, 22n, 27n], + [12n, 17n, 22n, 27n, 32n], + [17n, 22n, 27n, 32n, 37n], + [22n, 27n, 32n, 37n, 42n], + [27n, 32n, 37n, 42n, 47n], + [32n, 37n, 42n, 47n, 52n], + [37n, 42n, 47n, 52n, 57n], + [42n, 47n, 52n, 57n, 62n], + [3n, 8n, 13n, 18n, 23n], + [8n, 13n, 18n, 23n, 28n], + [13n, 18n, 23n, 28n, 33n], + [18n, 23n, 28n, 33n, 38n], + [23n, 28n, 33n, 38n, 43n], + [28n, 33n, 38n, 43n, 48n], + [33n, 38n, 43n, 48n, 53n], + [38n, 43n, 48n, 53n, 58n], + [43n, 48n, 53n, 58n, 63n], + [4n, 9n, 14n, 19n, 24n], + [9n, 14n, 19n, 24n, 29n], + [14n, 19n, 24n, 29n, 34n], + [19n, 24n, 29n, 34n, 39n], + [24n, 29n, 34n, 39n, 44n], + [29n, 34n, 39n, 44n, 49n], + [34n, 39n, 44n, 49n, 54n], + [39n, 44n, 49n, 54n, 59n], + [44n, 49n, 54n, 59n, 64n], + [5n, 10n, 15n, 20n, 25n], + [10n, 15n, 20n, 25n, 30n], + [15n, 20n, 25n, 30n, 35n], + [20n, 25n, 30n, 35n, 40n], + [25n, 30n, 35n, 40n, 45n], + [30n, 35n, 40n, 45n, 50n], + [35n, 40n, 45n, 50n, 55n], + [40n, 45n, 50n, 55n, 60n], + [45n, 50n, 55n, 60n, 65n], + ]; + + let anyLine = false; + + for (let i = 0; i < 87; i++) { + let line = true; + for (let j = 0; j < 5; j++) { + line = line && this.board[Number(lines[i][j])] === play; + } + + anyLine = anyLine || line; + } + + return anyLine; + } + + @method() + full(): boolean { + let full = true; + for (let i = 0; i < 25; i++) { + full = full && this.board[i] !== TicTacToe.EMPTY; + } + return full; + } + + static buildTxForMove( + current: TicTacToe, + options: MethodCallOptions, + n: bigint + ): Promise { + const play = current.isAliceTurn ? TicTacToe.ALICE : TicTacToe.BOB + const nextInstance = current.next() + nextInstance.board[Number(n)] = play + nextInstance.isAliceTurn = !current.isAliceTurn + + const unsignedTx: bsv.Transaction = new bsv.Transaction().addInput( + current.buildContractInput(options.fromUTXO) + ) + + if (nextInstance.won(play)) { + const script = Utils.buildPublicKeyHashScript( + hash160(current.isAliceTurn ? current.alice : current.bob) + ) + unsignedTx + .addOutput( + new bsv.Transaction.Output({ + script: bsv.Script.fromHex(script), + satoshis: current.balance, + }) + ) + + if (options.changeAddress) { + unsignedTx.change(options.changeAddress) + } + + return Promise.resolve({ + tx: unsignedTx, + atInputIndex: 0, + nexts: [], + }) + } + + if (nextInstance.full()) { + const halfAmount = current.balance / 2 + + unsignedTx + .addOutput( + new bsv.Transaction.Output({ + script: bsv.Script.fromHex( + Utils.buildPublicKeyHashScript( + hash160(current.alice) + ) + ), + satoshis: halfAmount, + }) + ) + .addOutput( + new bsv.Transaction.Output({ + script: bsv.Script.fromHex( + Utils.buildPublicKeyHashScript(hash160(current.bob)) + ), + satoshis: halfAmount, + }) + ) + + if (options.changeAddress) { + unsignedTx.change(options.changeAddress) + } + + return Promise.resolve({ + tx: unsignedTx, + atInputIndex: 0, + nexts: [], + }) + } + + unsignedTx + .setOutput(0, () => { + return new bsv.Transaction.Output({ + script: nextInstance.lockingScript, + satoshis: current.balance, + }) + }) + + + if (options.changeAddress) { + unsignedTx.change(options.changeAddress) + } + + + const nexts = [ + { + instance: nextInstance, + atOutputIndex: 0, + balance: current.balance, + }, + ] + + return Promise.resolve({ + tx: unsignedTx, + atInputIndex: 0, + nexts, + next: nexts[0], + }) + + } +} +``` From b41a851f5747b955124a42ac6f69026be743c75b Mon Sep 17 00:00:00 2001 From: yusuf idi maina <120538505+yusufidimaina9989@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:42:13 +0100 Subject: [PATCH 3/8] Create index.tsx --- src/pages/Tic-tac-toe 5x5/index.tsx | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/pages/Tic-tac-toe 5x5/index.tsx diff --git a/src/pages/Tic-tac-toe 5x5/index.tsx b/src/pages/Tic-tac-toe 5x5/index.tsx new file mode 100644 index 0000000..65e6167 --- /dev/null +++ b/src/pages/Tic-tac-toe 5x5/index.tsx @@ -0,0 +1,29 @@ +import React from "react" +import Example from "../../components/Example" +import html, { version, title, description, replitLink } from "./index.html" + +interface Path { + path: string + title: string +} + +interface Props { + prev: Path | null + next: Path | null +} + +const ExamplePage: React.FC = ({ prev, next }) => { + return ( + + ) +} + +export default ExamplePage From da22aeb53d8495b8c0f0d0c44037665433148090 Mon Sep 17 00:00:00 2001 From: yusuf idi maina <120538505+yusufidimaina9989@users.noreply.github.com> Date: Wed, 17 Jan 2024 19:03:42 +0100 Subject: [PATCH 4/8] Update index.html.ts --- src/pages/Tic-tac-toe 5x5/index.html.ts | 196 ++++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/src/pages/Tic-tac-toe 5x5/index.html.ts b/src/pages/Tic-tac-toe 5x5/index.html.ts index 8b13789..2849311 100644 --- a/src/pages/Tic-tac-toe 5x5/index.html.ts +++ b/src/pages/Tic-tac-toe 5x5/index.html.ts @@ -1 +1,197 @@ +// metadata +export const version = "0.1.0" +export const title = "Tic-Tac-Toe 5x5" +export const description = "Tic-Tac-Toe 5x5 in sCrypt" +export const replitLink = "https://replit.com/@yusufedresmaina/tictactoe5x5?embed=true" +const html = `

To initiate a game, Alice and Bob each lock up X amount of bitcoins into a contract UTXO. They take turns to play the game by sending signed transactions interacting with the stateful contract. If one of them wins, the winner claims the 2X bitcoins. If there is a draw, they take back their bitcoins.

+
class TicTacToe extends SmartContract {
+  @prop()
+  alice: PubKey
+  @prop()
+  bob: PubKey
+
+  @prop(true)
+  is_alice_turn: boolean
+
+  @prop(true)
+  board: FixedArray<bigint, 25>
+
+  @prop()
+  static readonly TURNLEN: bigint = 1n
+  @prop()
+  static readonly BOARDLEN: bigint = 25n
+  @prop()
+  static readonly EMPTY: bigint = 0n
+  @prop()
+  static readonly ALICE: bigint = 1n
+  @prop()
+  static readonly BOB: bigint = 2n
+
+  constructor(
+    alice: PubKey,
+    bob: PubKey,
+    is_alice_turn: boolean,
+    board: FixedArray<bigint, 25>
+  ) {
+    super(alice, bob, is_alice_turn, board)
+    this.alice = alice
+    this.bob = bob
+    this.is_alice_turn = is_alice_turn
+    this.board = board
+  }
+
+  @method()
+  public move(n: bigint, sig: Sig, amount: bigint) {
+    assert(n >= 0n && n < TicTacToe.BOARDLEN, "Field out of bounds")
+    assert(this.board[Number(n)] == TicTacToe.EMPTY, "Field not empty")
+
+    let play = this.is_alice_turn ? TicTacToe.ALICE : TicTacToe.BOB
+    let player: PubKey = this.is_alice_turn ? this.alice : this.bob
+
+    assert(this.checkSig(sig, player), "Bad sig")
+    // make the move
+    this.board[Number(n)] = play
+    this.is_alice_turn = !this.is_alice_turn
+
+    let outputs = toByteString("")
+    if (this.won(play)) {
+      let outputScript = Utils.buildPublicKeyHashScript(hash160(player))
+      let output = Utils.buildOutput(outputScript, amount)
+      outputs = output
+    } else if (this.full()) {
+      let aliceScript = Utils.buildPublicKeyHashScript(hash160(this.alice))
+      let aliceOutput = Utils.buildOutput(aliceScript, amount)
+
+      let bobScript = Utils.buildPublicKeyHashScript(hash160(this.bob))
+      let bobOutput = Utils.buildOutput(bobScript, amount)
+
+      outputs = aliceOutput + bobOutput
+    } else {
+      outputs = this.buildStateOutput(amount)
+    }
+
+    assert(this.ctx.hashOutputs == hash256(outputs), "Output hashes don't match")
+  }
+
+  @method()
+  won(play: bigint): boolean {
+    let lines: FixedArray<FixedArray<BigInt, 5>, 87> = [
+           [0n, 1n, 2n, 3n, 4n],
+            [1n, 2n, 3n, 4n, 5n],
+            [2n, 3n, 4n, 5n, 6n],
+            [5n, 6n, 7n, 8n, 9n],
+            [6n, 7n, 8n, 9n, 10n],
+            [7n, 8n, 9n, 10n, 11n],
+            [10n, 11n, 12n, 13n, 14n],
+            [11n, 12n, 13n, 14n, 15n],
+            [12n, 13n, 14n, 15n, 16n],
+            [15n, 16n, 17n, 18n, 19n],
+            [16n, 17n, 18n, 19n, 20n],
+            [17n, 18n, 19n, 20n, 21n],
+            [20n, 21n, 22n, 23n, 24n],
+            [21n, 22n, 23n, 24n, 25n],
+            [22n, 23n, 24n, 25n, 26n],
+            [25n, 26n, 27n, 28n, 29n],
+            [26n, 27n, 28n, 29n, 30n],
+            [27n, 28n, 29n, 30n, 31n],
+            [30n, 31n, 32n, 33n, 34n],
+            [31n, 32n, 33n, 34n, 35n],
+            [32n, 33n, 34n, 35n, 36n],
+            [35n, 36n, 37n, 38n, 39n],
+            [36n, 37n, 38n, 39n, 40n],
+            [37n, 38n, 39n, 40n, 41n],
+            [40n, 41n, 42n, 43n, 44n],
+            [41n, 42n, 43n, 44n, 45n],
+            [42n, 43n, 44n, 45n, 46n],
+            [45n, 46n, 47n, 48n, 49n],
+            [46n, 47n, 48n, 49n, 50n],
+            [47n, 48n, 49n, 50n, 51n],
+            [50n, 51n, 52n, 53n, 54n],
+            [51n, 52n, 53n, 54n, 55n],
+            [52n, 53n, 54n, 55n, 56n],
+        
+            // Columns
+            [0n, 5n, 10n, 15n, 20n],
+            [5n, 10n, 15n, 20n, 25n],
+            [10n, 15n, 20n, 25n, 30n],
+            [15n, 20n, 25n, 30n, 35n],
+            [20n, 25n, 30n, 35n, 40n],
+            [25n, 30n, 35n, 40n, 45n],
+            [30n, 35n, 40n, 45n, 50n],
+            [35n, 40n, 45n, 50n, 55n],
+            [40n, 45n, 50n, 55n, 60n],
+            [1n, 6n, 11n, 16n, 21n],
+            [6n, 11n, 16n, 21n, 26n],
+            [11n, 16n, 21n, 26n, 31n],
+            [16n, 21n, 26n, 31n, 36n],
+            [21n, 26n, 31n, 36n, 41n],
+            [26n, 31n, 36n, 41n, 46n],
+            [31n, 36n, 41n, 46n, 51n],
+            [36n, 41n, 46n, 51n, 56n],
+            [41n, 46n, 51n, 56n, 61n],
+            [2n, 7n, 12n, 17n, 22n],
+            [7n, 12n, 17n, 22n, 27n],
+            [12n, 17n, 22n, 27n, 32n],
+            [17n, 22n, 27n, 32n, 37n],
+            [22n, 27n, 32n, 37n, 42n],
+            [27n, 32n, 37n, 42n, 47n],
+            [32n, 37n, 42n, 47n, 52n],
+            [37n, 42n, 47n, 52n, 57n],
+            [42n, 47n, 52n, 57n, 62n],
+            [3n, 8n, 13n, 18n, 23n],
+            [8n, 13n, 18n, 23n, 28n],
+            [13n, 18n, 23n, 28n, 33n],
+            [18n, 23n, 28n, 33n, 38n],
+            [23n, 28n, 33n, 38n, 43n],
+            [28n, 33n, 38n, 43n, 48n],
+            [33n, 38n, 43n, 48n, 53n],
+            [38n, 43n, 48n, 53n, 58n],
+            [43n, 48n, 53n, 58n, 63n],
+            [4n, 9n, 14n, 19n, 24n],
+            [9n, 14n, 19n, 24n, 29n],
+            [14n, 19n, 24n, 29n, 34n],
+            [19n, 24n, 29n, 34n, 39n],
+            [24n, 29n, 34n, 39n, 44n],
+            [29n, 34n, 39n, 44n, 49n],
+            [34n, 39n, 44n, 49n, 54n],
+            [39n, 44n, 49n, 54n, 59n],
+            [44n, 49n, 54n, 59n, 64n],
+            [5n, 10n, 15n, 20n, 25n],
+            [10n, 15n, 20n, 25n, 30n],
+            [15n, 20n, 25n, 30n, 35n],
+            [20n, 25n, 30n, 35n, 40n],
+            [25n, 30n, 35n, 40n, 45n],
+            [30n, 35n, 40n, 45n, 50n],
+            [35n, 40n, 45n, 50n, 55n],
+            [40n, 45n, 50n, 55n, 60n],
+            [45n, 50n, 55n, 60n, 65n],
+        ];
+
+    let anyLine = false
+
+    for (let i = 0; i < 87; i++) {
+      let line = true
+      for (let j = 0; j < 5; j++) {
+        line = line && this.board[Number(lines[i][j])] == play
+      }
+
+      anyLine = anyLine || line
+    }
+
+    return anyLine
+  }
+
+  @method()
+  full(): boolean {
+    let full = true
+    for (let i = 0; i < TicTacToe.BOARDLEN; i++) {
+      full = full && this.board[i] != TicTacToe.EMPTY
+    }
+    return full
+  }
+}
+
+` + +export default html From c9bcc4f025a937466adb84a325d1edafc9c58739 Mon Sep 17 00:00:00 2001 From: yusuf idi maina <120538505+yusufidimaina9989@users.noreply.github.com> Date: Tue, 23 Jan 2024 12:42:51 +0100 Subject: [PATCH 5/8] Update routes.tsx --- src/routes.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes.tsx b/src/routes.tsx index 1d4e9c4..3061c9c 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -29,6 +29,7 @@ import component_return from "./pages/return" import component_script_context from "./pages/script-context" import component_state from "./pages/state" import component_tic_tac_toe from "./pages/tic-tac-toe" +import component_Tic_tac_toe_5x5 from "./pages/Tic-tac-toe 5x5" import component_time_lock from "./pages/time-lock" import component_user_defined_types from "./pages/user-defined-types" import component_variable_declarations from "./pages/variable-declarations" From ff584105ad06b950afda730d915505b294035c48 Mon Sep 17 00:00:00 2001 From: yusuf idi maina <120538505+yusufidimaina9989@users.noreply.github.com> Date: Tue, 23 Jan 2024 16:04:41 +0100 Subject: [PATCH 6/8] Update and rename index.md to index.md --- src/pages/{Tic-tac-toe 5x5 => tic-tac-toe-5x5}/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/pages/{Tic-tac-toe 5x5 => tic-tac-toe-5x5}/index.md (99%) diff --git a/src/pages/Tic-tac-toe 5x5/index.md b/src/pages/tic-tac-toe-5x5/index.md similarity index 99% rename from src/pages/Tic-tac-toe 5x5/index.md rename to src/pages/tic-tac-toe-5x5/index.md index f4e7b5d..2760724 100644 --- a/src/pages/Tic-tac-toe 5x5/index.md +++ b/src/pages/tic-tac-toe-5x5/index.md @@ -1,5 +1,5 @@ --- -title: Tic-Tac-Toe 5x5 +title: Tic-Tac-Toe5x5 version: 0.1.0 description: Tic-Tac-Toe 5x5 in sCrypt --- From 00624e97ae5d178ff433cce3dc7167e74a9e7ef3 Mon Sep 17 00:00:00 2001 From: yusuf idi maina <120538505+yusufidimaina9989@users.noreply.github.com> Date: Tue, 23 Jan 2024 16:05:19 +0100 Subject: [PATCH 7/8] Update index.md --- src/pages/tic-tac-toe-5x5/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/tic-tac-toe-5x5/index.md b/src/pages/tic-tac-toe-5x5/index.md index 2760724..1ceec57 100644 --- a/src/pages/tic-tac-toe-5x5/index.md +++ b/src/pages/tic-tac-toe-5x5/index.md @@ -1,7 +1,7 @@ --- -title: Tic-Tac-Toe5x5 +title: Tic-Tac-Toe-5x5 version: 0.1.0 -description: Tic-Tac-Toe 5x5 in sCrypt +description: Tic-Tac-Toe-5x5 in sCrypt --- To initiate a game, Alice and Bob each lock up X amount of bitcoins into a contract UTXO. They take turns to play the game by sending signed transactions interacting with the [stateful contract](https://scrypt.io/scrypt-ts/tutorials/stateful-contract). If one of them wins, the winner claims the 2X bitcoins. If there is a draw, they take back their bitcoins. ```ts From d68d45ee5923a94ed8a46f3960556506f365878c Mon Sep 17 00:00:00 2001 From: yusuf idi maina <120538505+yusufidimaina9989@users.noreply.github.com> Date: Tue, 23 Jan 2024 16:06:23 +0100 Subject: [PATCH 8/8] Update routes.tsx --- src/routes.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.tsx b/src/routes.tsx index 3061c9c..532b8e2 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -29,7 +29,7 @@ import component_return from "./pages/return" import component_script_context from "./pages/script-context" import component_state from "./pages/state" import component_tic_tac_toe from "./pages/tic-tac-toe" -import component_Tic_tac_toe_5x5 from "./pages/Tic-tac-toe 5x5" +import component_tic_tac_toe_5x5 from "./pages/tic-tac-toe-5x5" import component_time_lock from "./pages/time-lock" import component_user_defined_types from "./pages/user-defined-types" import component_variable_declarations from "./pages/variable-declarations"