Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fde9d86
WIP: React UI for the BSG sample app and contract update to provide h…
pbienek Jul 11, 2024
a7a8801
WIP: Fixes some missing depenencies
pbienek Jul 12, 2024
c74abad
Introduce proper linting and package order etc
pbienek Jul 12, 2024
406564e
WIP: Updates contract to emit game state when the user makes a guess.…
pbienek Jul 12, 2024
3e81662
WIP: Add some extra polish around guess states adding cursor effects …
pbienek Jul 13, 2024
2409efd
WIP: Add Unknown game state to components. Fix layout bug in the HUD …
pbienek Jul 13, 2024
de93b11
WIP: Persist data between page reloads by saving state to local storage.
pbienek Jul 13, 2024
00880d0
WIP: Added unknown state. Added battle store types. Added additional …
pbienek Jul 14, 2024
b361c59
WIP: Vastly improve performance by significantly reducing the number …
pbienek Jul 15, 2024
25cea55
WIP: Fix missing question marks due to last commit.
pbienek Jul 15, 2024
0e79849
WIP: Adds how to play page.
pbienek Jul 15, 2024
f426109
WIP: Add charts to fleet strength and cells remaining components.
pbienek Jul 15, 2024
138d6fa
WIP: move new BSG codebase from work from wip folder to the existing one
pbienek Jul 15, 2024
b29beff
WIP: Fix type errors
pbienek Jul 15, 2024
174b1d8
WIP: Adds hardhat step to build process
pbienek Jul 15, 2024
cbe288f
WIP: prevent page from shifting down when notification window opens
pbienek Jul 16, 2024
ffcbc90
Fix bug where Connect to metamask button doesnt work
pbienek Jul 16, 2024
4933f19
reposition guess notification window
pbienek Jul 16, 2024
7d6dbb9
ensure UI doesnt hang with a blank while waiting for initial wallet c…
pbienek Jul 16, 2024
27d0725
Removes styles applied in light mode.
pbienek Jul 16, 2024
419c13a
some refactoring
pbienek Jul 18, 2024
cdc6792
Adds responsiveness and a number of bug fixes.
Jul 22, 2024
b94cf59
Merge branch 'main' into pete/3591-BSG-react-port
Jul 23, 2024
3335f87
Merge branch 'main' into pete/3591-BSG-react-port
Aug 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions battleship-game/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,15 @@ pnpm-debug.log*
lerna-debug.log*

node_modules
.DS_Store
dist
dist-ssr
coverage
*.local

/cypress/videos/
/cypress/screenshots/

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
Expand Down
1 change: 1 addition & 0 deletions battleship-game/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v20.15.1
19 changes: 19 additions & 0 deletions battleship-game/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"plugins": ["@trivago/prettier-plugin-sort-imports"],
"importOrder": [
"^react$",
"<THIRD_PARTY_MODULES>",
"^@/(.*)$",
"^[./]"
],
"importOrderSeparation": true,
"importOrderSortSpecifiers": true,
"printWidth": 100,
"tabWidth": 4,
"singleQuote": true,
"trailingComma": "es5",
"semi": true,
"newline-before-return": true,
"no-duplicate-variable": [true, "check-parameters"],
"no-var-keyword": true
}
8 changes: 0 additions & 8 deletions battleship-game/.prettierrc.json

This file was deleted.

3 changes: 0 additions & 3 deletions battleship-game/.vscode/extensions.json

This file was deleted.

52 changes: 21 additions & 31 deletions battleship-game/README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,30 @@
# vue-tutorial
# React + TypeScript + Vite

This template should help get you started developing with Vue 3 in Vite.
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

## Recommended IDE Setup
Currently, two official plugins are available:

[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## Type Support for `.vue` Imports in TS
## Expanding the ESLint configuration

TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:

If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
- Configure the top-level `parserOptions` property like this:

1. Disable the built-in TypeScript Extension
1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.

## Customize configuration

See [Vite Configuration Reference](https://vitejs.dev/config/).

## Project Setup

```sh
npm install
```js
export default {
// other rules...
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: ['./tsconfig.json', './tsconfig.node.json'],
tsconfigRootDir: __dirname,
},
}
```

### Compile and Hot-Reload for Development

```sh
npm run dev
```

### Type-Check, Compile and Minify for Production

```sh
npm run build
```
- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list
70 changes: 64 additions & 6 deletions battleship-game/contracts/BattleshipGame.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ contract BattleshipGame {
Ship[totalShips] public ships;
mapping(uint16 => uint8) private positionToShipIndex;
mapping(uint16 => bool) public hits;
mapping(uint16 => bool) private misses;
uint256 private seed;
uint256 private nonce = 0;
uint256 public prizePool;
bool[totalShips] public graveyard;
uint8 public sunkShipsCount;
bool public gameOver;

Position[] public hitPositions;
Position[] private allHits;
Position[] private allMisses;

mapping(address => uint16) private playerHits;
mapping(address => uint16) private playerSinks;
Expand All @@ -41,6 +42,15 @@ contract BattleshipGame {
generatePositions();
}

/// @notice Emitted when a guess is made.
/// @param user The address of the user making the guess.
/// @param guessedCoords The coordinates submitted by the user.
/// @param success True if the guess hit a ship, false otherwise.
//TODO: Add comments
event HitFeedback(address indexed user, uint8[2] guessedCoords, bool success, Position[] allHits, Position[] allMisses, bool[totalShips] graveyard, uint256 prizePool);


/// @notice Generates unique positions for ships on the grid.
function generatePositions() private {
uint8 index = 0;
while (index < totalShips) {
Expand All @@ -63,6 +73,10 @@ contract BattleshipGame {
}
}

/// @notice Checks if the ship position is unique and fits within the grid.
/// @param x The x-coordinate of the ship's start position.
/// @param y The y-coordinate of the ship's start position.
/// @return bool indicating whether the position is unique and fits within the grid.
function isPositionUniqueAndFits(uint8 x, uint8 y) private view returns (bool) {
if (x + shipLength > gridSize) return false;
for (uint8 j = 0; j < shipLength; j++) {
Expand All @@ -74,43 +88,62 @@ contract BattleshipGame {
return true;
}

/// @notice Packs x and y coordinates into a single uint16 value.
/// @param x The x-coordinate.
/// @param y The y-coordinate.
/// @return uint16 representing the packed coordinates.
function packCoordinates(uint8 x, uint8 y) private pure returns (uint16) {
return (uint16(x) << 8) | uint16(y);
}

/// @notice Gets the position of a specific ship by its index.
/// @param shipIndex The index of the ship.
/// @return Position of the ship.
function getShipPosition(uint8 shipIndex) public view returns (Position memory) {
require(shipIndex < totalShips, 'Ship index out of bounds');
return ships[shipIndex].start;
}

/// @notice Gets positions of all ships.
/// @return Array of all ships.
function getAllShipPositions() public view returns (Ship[totalShips] memory) {
return ships;
}

/// @notice Gets the index of the ship at a specific grid position.
/// @param x The x-coordinate of the position.
/// @param y The y-coordinate of the position.
/// @return The index of the ship at the specified position.
function getShipAtPosition(uint8 x, uint8 y) public view returns (uint8) {
uint16 positionKey = packCoordinates(x, y);
uint8 shipIndex = positionToShipIndex[positionKey];
require(shipIndex != 0, 'No ship at given position');
return shipIndex;
}

/// @notice Hits a position on the grid and checks if a ship is hit.
/// @param x The x-coordinate of the position to hit.
/// @param y The y-coordinate of the position to hit.
function hit(uint8 x, uint8 y) public payable {
require(!gameOver, 'Game is over, no more hits accepted');
require(msg.value == 0.0443 ether, 'Incorrect fee amount');
uint16 positionKey = packCoordinates(x, y);
require(!hits[positionKey], 'Cell already hit');

bool success;

prizePool += msg.value;
hits[positionKey] = true;
hitPositions.push(Position(x, y));
totalHits++;
playerHits[msg.sender]++;

uint8 shipIndex = positionToShipIndex[positionKey];
if (shipIndex != 0) {
success = true;
Ship storage ship = ships[shipIndex];
uint8 hitIndex = x - ship.start.x;
ship.hits[hitIndex] = true;
allHits.push(Position(x, y));

bool allHit = true;
for (uint8 i = 0; i < shipLength; i++) {
Expand All @@ -131,31 +164,56 @@ contract BattleshipGame {
}
}
}
else {
success = false;
misses[positionKey] = true;
allMisses.push(Position(x, y));
}

emit HitFeedback(msg.sender, [x, y], success, allHits, allMisses, graveyard, prizePool);
}

/// @notice Checks if a specific position on the grid is hit.
/// @param x The x-coordinate of the position.
/// @param y The y-coordinate of the position.
/// @return bool indicating whether the position is hit.
function isHit(uint8 x, uint8 y) public view returns (bool) {
uint16 positionKey = packCoordinates(x, y);
return hits[positionKey];
}

/// @notice Checks if a specific ship is sunk.
/// @param shipIndex The index of the ship.
/// @return bool indicating whether the ship is sunk.
function isSunk(uint8 shipIndex) public view returns (bool) {
require(shipIndex < totalShips, 'Ship index out of bounds');
return graveyard[shipIndex];
}

/// @notice Gets the hit status of each part of a specific ship.
/// @param shipIndex The index of the ship.
/// @return Array indicating which parts of the ship are hit.
function getHitsOnShip(uint8 shipIndex) public view returns (bool[shipLength] memory) {
require(shipIndex < totalShips, 'Ship index out of bounds');
return ships[shipIndex].hits;
}

/// @notice Gets the status of all ships in the graveyard.
/// @return Array indicating which ships are sunk.
function getGraveyard() public view returns (bool[totalShips] memory) {
return graveyard;
}

/// @notice Gets all hit positions on the grid.
/// @return An array of Position structs representing the hit positions.
/// @notice Gets all hit positions on the grid.
/// @return An array of Position structs representing the hit positions.
function getAllHits() public view returns (Position[] memory) {
return hitPositions;
return allHits;
}

/// @notice Gets all miss positions so far.
/// @return Array of positions that have been missed.
function getAllMisses() public view returns (Position[] memory) {
return allMisses;
}

function getPersonalStats() public view returns (uint16 personalHits, uint16 personalSinks) {
Expand Down
9 changes: 0 additions & 9 deletions battleship-game/env.d.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

require('dotenv').config()
require('@nomicfoundation/hardhat-toolbox')
require('@nomiclabs/hardhat-ethers')

const { PRIVATE_KEY, USER_KEY } = process.env

Expand Down
28 changes: 13 additions & 15 deletions battleship-game/index.html
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<title>Ten's Battleship Game</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TEN | Battleships Game</title>
<meta
name="description"
content="Ten's Battleship Game is a blockchain-based game that allows users to guess the positions of randomly placed ships and try to sink them. The game is built on the Ten network."
name="description"
content="Ten's Battleship Game is a blockchain-based game that allows users to guess the positions of randomly placed ships and try to sink them. The game is built on the Ten network."
/>
<meta
name="keywords"
content="Ethereum, Hardhat, ethers.js, Solidity, privacy, blockchain privacy, encryption on ethereum, ethereum encyption, Arbitrum, TEN, battleship, battleship game, Ten's battleship game, Ten's Guessing Game, Ten's battleship game, Ten's battleship game game, Ten's battleship game competition, Ten's battleship game blockchain game, Ten's battleship game blockchain competition, Ten's battleship game blockchain guessing game, Ten's battleship game blockchain competition game"
name="keywords"
content="Ethereum, Hardhat, ethers.js, Solidity, privacy, blockchain privacy, encryption on ethereum, ethereum encyption, Arbitrum, TEN, battleship, battleship game, Ten's battleship game, Ten's Guessing Game, Ten's battleship game, Ten's battleship game game, Ten's battleship game competition, Ten's battleship game blockchain game, Ten's battleship game blockchain competition, Ten's battleship game blockchain guessing game, Ten's battleship game blockchain competition game"
/>
<meta charset="UTF-8" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap"
rel="stylesheet"
/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&display=swap" rel="stylesheet">
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading