Skip to content

Commit

Permalink
Minor notation & indentation fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Shigoto-dev19 committed Feb 29, 2024
1 parent 9a33ba3 commit ef29b7b
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 30 deletions.
7 changes: 6 additions & 1 deletion game-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,9 @@ whether a game is joinable or not.
- Better check with `proofsEnable=true` when running zkapp on a local blockchain.
- Depending on the size of the variable, the developer can bundle a set of small-size state and store it as a single field on-chain.
- This technique evidently saves storage on-chain with the tradeoff of adding computation(deserialization) when generating the proof.
- This can be helpful especially when developing a game due to the need of multiple state variables.
- This can be helpful especially when developing a game due to the need of multiple state variables.
- I think it would be good to add a variable in o1js that fetches state from the zkapp --> This would help reduce variable calls to fetch on-chain data.
````typescript
let state-on-chain = zkapp.state.get();
let { state1, stat2, state3 } = state-on-chain;
````
3 changes: 2 additions & 1 deletion src/Battleships.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,4 +266,5 @@ class Battleships extends SmartContract {
//TODO --> add one after serialized to distinguish value from initial value
//TODO have a last check on zkapp error handling & messages

//players from hitting the same target multiple times
//players from hitting the same target multiple times
//TODO Add salt for player ID generation
11 changes: 6 additions & 5 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,13 @@ class BattleShipsClient {
const PURPLE = '\x1b[35m%s\x1b[0m';
const BLUE = '\x1b[36m%s\x1b[0m';
const inBoldGreen = (msg: string) => `\x1b[1m\x1b[32m${msg}\x1b[0m`;

const isHost = this.playerId.toBigInt() === hostId;
const LINE = '-'.repeat(107);

console.log('----------------------------------------------------------------------------------');
const isHost = this.playerId.toBigInt() === hostId;

console.log(LINE);
console.log(PURPLE, `${isHost ? 'Host' : 'Joiner'} - Player${isHost ? '1' : '2'} Game Stats`);
console.log('----------------------------------------------------------------------------------');
console.log(LINE);
console.log(BLUE, 'Turn Count: ', turnCount);
console.log(BLUE, 'MINA Address: ', this.playerAddress.toBase58());
console.log(BLUE, 'Player HEX ID: ', this.playerId.toBigInt().toString(16));
Expand All @@ -248,7 +249,7 @@ class BattleShipsClient {
console.log(BLUE, 'Winner: ', ` ${inBoldGreen('Joiner - Player2')}`);
else
console.log(BLUE, 'No Winner yet!');
console.log('----------------------------------------------------------------------------------\n');
console.log(LINE, '\n');
}

displayGameSummary() {
Expand Down
6 changes: 3 additions & 3 deletions src/displayUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ function parseCoordinates(target: number[]) {
*/
function printLog(msg: string) {
if (process.stdout.isTTY) {
process.stdout.clearLine(-1);
process.stdout.cursorTo(0);
process.stdout.write(msg);
process.stdout.clearLine(-1);
process.stdout.cursorTo(0);
process.stdout.write(msg);
}
}
46 changes: 30 additions & 16 deletions src/provableUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,19 @@ class AttackUtils {
return [targetX, targetY];
}

static decodeHitTarget(serializedTarget: Field) {
const deserializedTarget = Provable.witness(Provable.Array(Field, 2), () => {
let serialized = serializedTarget.toBigInt() - 1n;
const x = serialized % 10n;
const y = serialized / 10n;

return [x, y].map(Field);
});
serializedTarget.assertEquals(AttackUtils.encodeHitTarget(deserializedTarget));

return deserializedTarget
}

static validateTarget(serializedTarget: Field) {
// validate that the target is in the game map range
const target = AttackUtils.deserializeTarget(serializedTarget);
Expand Down Expand Up @@ -208,26 +221,25 @@ class AttackUtils {
}

/**
* We serialize data differently than serializeTarget to showcase an alternative approach and to conserve storage space.
* We encode data differently than serializeTarget to showcase an alternative approach and to conserve storage space.
*
* When bitifying two numbers from 0 to 9 together, it typically requires 8 bits in total. However, by employing a technique
* like bitifying 9 + 9*10 + 1, we reduce the storage requirement to 7 bits. This results in a total saving of 32 bits
* because we store a maximum of 32 targets that land a successful hit.
* like bitifying 9 + 9*10 + 1, we reduce the storage requirement to 7 bits. This results in a total saving of 34 bits
* because we store a maximum of 34 targets that land a successful hit.
*
* @note Before serializing and storing a target, ensure it successfully hits its intended destination.
*/
static serializeHitTarget(hitTarget: Field[]) {
static encodeHitTarget(hitTarget: Field[]) {
/**
* Serialization is achieved by mapping a target [x, y] to a single field element: x + 10 * y.
* Serialization is achieved by mapping a target [x, y] to a single field element: x + 10 * y + 1.
*
* To distinguish serialized hit targets from initial values, we add one to the result.
* To distinguish encoded hit targets from initial values, we add one to the result.
* For example, if [0, 0] represents a target that successfully hits the adversary,
* serializing it would result in 0, which is indistinguishable from the initial value and prone to errors.
*
* Therefore, we add one to the serialized value to avoid confusion and ensure proper differentiation.
* Therefore, we add one to the encoded value to avoid confusion and ensure proper differentiation.
*/
const serializedHitTarget = hitTarget[0].add(hitTarget[1].mul(10)).add(1);
return serializedHitTarget;
const encodeHitTarget = hitTarget[0].add(hitTarget[1].mul(10)).add(1);
return encodeHitTarget;
}

// returns an array of serialized hitTargets
Expand All @@ -248,11 +260,13 @@ class AttackUtils {
//TODO validate before update
//TODO should return field
static updateHitTargetHistory(target: Field[], isHit: Bool, playerHitTargets: Field[], index: Field) {
const serializedTarget = AttackUtils.serializeHitTarget(target);

let serializedHitTarget = Provable.if(
const encodedTarget = AttackUtils.encodeHitTarget(target);

// Before encoding and storing a target, ensure it successfully hits its intended destination.
// Otherwise take the encoded targetas init value = 0
let encodedHitTarget = Provable.if(
isHit,
serializedTarget,
encodedTarget,
Field(0),
);

Expand All @@ -263,7 +277,7 @@ class AttackUtils {
// To prevent this, we create a copy of the input array instead of directly modifying it.
// This ensures that the attack method operates on a separate copy, preserving the integrity of the original input.
let updated = [...playerHitTargets]
updated[hitTargetIndex] = serializedHitTarget;
updated[hitTargetIndex] = encodedHitTarget;

return updated;
});
Expand All @@ -282,7 +296,7 @@ class AttackUtils {
// We opt not to deserialize the hitTargetHistory to save computational resources.
// Instead we serialize the target and then directly scan occurrences through an array of serialized targets.
// This approach conserves computational resources and enhances efficiency.
let serializedTarget = AttackUtils.serializeHitTarget(target);
let serializedTarget = AttackUtils.encodeHitTarget(target);
let check = Provable.witness(Bool, () => {
let isNullified = hitTargetHistory.some(item => item.equals(serializedTarget).toBoolean());
return Bool(isNullified)
Expand Down
7 changes: 3 additions & 4 deletions src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,14 @@ const game1Shots = {
[1, 1], [2, 1], [3, 1], [4, 1],
[1, 2], [2, 2], [3, 2],
[1, 3], [2, 3], [3, 3],
[1, 4], [2, 4]
[1, 4], [2, 4],
],
joiner: [
[9, 9], [9, 8], [9, 7], [9, 6], [9, 5],
[9, 4], [9, 3], [9, 2], [9, 1],
[9, 0], [8, 9], [0, 8],
[8, 7], [8, 6], [8, 8],
[8, 4], [8, 5]
[8, 4], [8, 5],
],
}

Expand All @@ -166,7 +166,7 @@ const game1Shots = {
*/
await runGame(game1Boards, game1Shots);

/*

const game2Boards = {
host: [
[4, 2, 1],
Expand Down Expand Up @@ -202,4 +202,3 @@ const game2Shots = {
}

await runGame(game2Boards, game2Shots);
*/

0 comments on commit ef29b7b

Please sign in to comment.