Skip to content

Commit

Permalink
finished
Browse files Browse the repository at this point in the history
  • Loading branch information
arjanjohan committed Apr 29, 2024
1 parent b1f9bfc commit 9793d07
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 23 deletions.
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,44 @@

## Partner Bounties

### Ankr

This project uses Ankr RPC to deploy the game smart contracts. See the hardhat config file [here](https://github.com/arjanjohan/scroll-fighter/blob/1784b9fefb680b3d1a046fe318004f25a14a7aad/packages/hardhat/hardhat.config.ts#L106).

### Aztec

A contract written in Noir is used to verify the validity of the challenger's committed strategy. By providing a proof generated by Noir, the game smart contract can use the on-chain verifier to ensure the strategy is valid. The Noir verifier checks if the fighter exists and if the moves are valid.

- [Noir circuit](https://github.com/arjanjohan/scroll-fighter/blob/33e5e043bd6b3beb35e60fb84cbf66c5dde24264/packages/noir/circuits/src/main.nr)
- [UltraVerifier on Scroll Sepolia](https://sepolia.scrollscan.com/address/0x06cA44b817F9172e1BaB3a8e8a36020AeC6D7e8d#code)

### Sindri

Scroll Fighter uses Sindri to generate proofs using their API.

- [Sindri configuration](https://github.com/arjanjohan/scroll-fighter/tree/33e5e043bd6b3beb35e60fb84cbf66c5dde24264/packages/noir)
- [Sindri frontend intregation](https://github.com/arjanjohan/scroll-fighter/blob/2f9f2b9487f9a2df05dee49a2c94bd32b3fa2c13/packages/nextjs/components/GameForm.tsx#L154)

### The Graph

A subgraph is created to query created games on the ScrollFighterV2 contract.
A subgraph is created to query created games on the ScrollFighter contract.

- [Subgraph code](https://github.com/arjanjohan/scroll-fighter/tree/main/packages/graph).
- [Subgraph endpoint](https://api.studio.thegraph.com/query/72991/scrollfighter/version/latest)

### Sindri

Scroll Fighter uses Sindri to generate proofs using their API.
### Ankr

- [Sindri configuration](https://github.com/arjanjohan/scroll-fighter/tree/33e5e043bd6b3beb35e60fb84cbf66c5dde24264/packages/noir)
- [Sindri frontend intregation](https://github.com/arjanjohan/scroll-fighter/blob/2f9f2b9487f9a2df05dee49a2c94bd32b3fa2c13/packages/nextjs/components/GameForm.tsx#L154)
This project uses Ankr RPC to deploy the game smart contracts. See the hardhat config file [here](https://github.com/arjanjohan/scroll-fighter/blob/1784b9fefb680b3d1a046fe318004f25a14a7aad/packages/hardhat/hardhat.config.ts#L106).

## Next steps

Due to the limited time, I could not complete everything I set out to do. Additional features that I plan to add are:

- Overview of current games, using The Graph to query existing games.
- Create open games (anyone can join/accept)
- Create a new page with overview of all games, using The Graph to query existing games.
- Allow challengers to start open games (anyone can join/accept)
- Complete and polish up game display animations

## Links

- [Vercel deployment](https://scrollfighter.vercel.app/)
- [Presentation slides](https://docs.google.com/presentation/d/1IYbLM9cwdpbuSvShZCdJoJ4JEDa683sMTGp3Bh6K79o/edit?usp=sharing)
- [Presentation video]()
- [Presentation video](https://www.loom.com/share/bf35511f16b140e98bf324ac79085769?sid=247ee967-9e0c-4594-88cf-a2f3587ee6b9)
- [Dorahacks BUILD](https://dorahacks.io/buidl/11485)
- [GitHub](https://github.com/arjanjohan/scroll-fighter)

Expand Down
34 changes: 24 additions & 10 deletions packages/nextjs/components/FightDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export const FightDisplay: React.FC = () => {
const [showRoundAnnouncement, setShowRoundAnnouncement] = useState<boolean>(false);
const [gameLoaded, setGameLoaded] = useState<boolean>(false);
const [gameId, setGameId] = useState<string>("");
const [playerOneHealth, setPlayerOneHealth] = useState<number>(0);
const [playerTwoHealth, setPlayerTwoHealth] = useState<number>(0);
const contractName = "ScrollFighter";

const { data: deployedContractData } = useDeployedContractInfo(contractName);
Expand Down Expand Up @@ -69,15 +71,18 @@ export const FightDisplay: React.FC = () => {
setShowRoundAnnouncement(false);
setTimeout(() => {
playRound(round + 1);
}, 3000); // Duration of action before next round starts
}, 2000); // Duration to show round announcement
}, 2000); // Duration of action before next round starts
}, 1000); // Duration to show round announcement
} else {
setPlayFight(false); // End the fight
}
};

useEffect(() => {
if (playFight) {
setPlayerOneHealth(Number(fighters.find(f => f.id === Number(gameData?.fighterIds[0]))!.health));
setPlayerTwoHealth(Number(fighters.find(f => f.id === Number(gameData?.fighterIds[1]))!.health));

playRound(0);
}
}, [playFight]);
Expand All @@ -92,6 +97,10 @@ export const FightDisplay: React.FC = () => {
setGameLoaded(true);
}
console.log("Game data", gameData);
if (gameData) {
// setPlayerOneHealth(Number(fighters.find(f => f.id === Number(gameData?.fighterIds[0]))!.health));
// setPlayerTwoHealth(Number(fighters.find(f => f.id === Number(gameData?.fighterIds[1]))!.health));
}
}, [gameId, gameData, isGameLoading]);

return (
Expand Down Expand Up @@ -154,8 +163,8 @@ export const FightDisplay: React.FC = () => {
backgroundColor: "red",
height: "10px",
width: `${
// (100 * Number(gameData.currentHealth[0])) /
fighters.find(f => f.id === Number(gameData.fighterIds[0]))!.health * 5
(40 * Number(playerOneHealth)) /
fighters.find(f => f.id === Number(gameData.fighterIds[0]))!.health
}%`,
margin: "0 10px",
}}
Expand All @@ -165,8 +174,8 @@ export const FightDisplay: React.FC = () => {
backgroundColor: "red",
height: "10px",
width: `${
// (100 * Number(gameData.currentHealth[1])) /
fighters.find(f => f.id === Number(gameData.fighterIds[1]))!.health * 5
(40 * Number(playerTwoHealth)) /
fighters.find(f => f.id === Number(gameData.fighterIds[1]))!.health
}%`,
margin: "0 10px",
}}
Expand Down Expand Up @@ -206,13 +215,18 @@ export const FightDisplay: React.FC = () => {
</>
)}
</div>
{gameData && (
{gameLoaded && gameData && Number(gameData.fighterIds[0]) != 0 && Number(gameData.fighterIds[1]) != 0 && (
<div style={{ marginTop: "20px", fontSize: "16px" }}>
<p>Results: {gameData?.winner}</p>
<strong>Wagered Amount:</strong> {gameData.wageredAmount.toString()} ETH
<p>
<strong>Winner:</strong> {gameData?.winner == gameData?.players[0] && "PLAYER ONE"}
{gameData?.winner == gameData?.players[1] && "PLAYER TWO"}
{gameData?.winner == "0x0000000000000000000000000000000000000000" && "DRAW"}
</p>
<p>
<strong>Wagered Amount:</strong> {(gameData.wageredAmount / BigInt(10n ** 18n)).toString()}
</p>
</div>
)}{" "}
{/* other parts of the component */}{" "}
</div>
</div>
);
Expand Down

0 comments on commit 9793d07

Please sign in to comment.