Skip to content

Commit 92a8587

Browse files
committed
Добавлена обработка ESC для отмены выделения ячейки; реализована логика определения первого хода через стартовые кости
1 parent 6e6686b commit 92a8587

File tree

4 files changed

+528
-49
lines changed

4 files changed

+528
-49
lines changed

packages/foundry/contracts/Backgammon.sol

Lines changed: 157 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,16 @@ contract Backgammon {
2929
address public whitePlayer; // First player (white)
3030
address public blackPlayer; // Second player (black)
3131
uint256 public stakeAmount; // Amount each player must stake
32-
bool public gameStarted; // True when both players have staked
32+
bool public gameStarted; // True when both players have staked (but game not active yet)
33+
bool public gameActive; // True when first turn is determined and game can begin
3334
bool public fundsWithdrawn; // True when winner has withdrawn funds
3435

36+
// Start dice rolls to determine first turn
37+
uint256 public whiteStartDice; // White player's start dice roll (1-6)
38+
uint256 public blackStartDice; // Black player's start dice roll (1-6)
39+
bool public whiteStartDiceRolled; // True when white player rolled start dice
40+
bool public blackStartDiceRolled; // True when black player rolled start dice
41+
3542
event WhiteTurn(uint256 _from, uint256 _to);
3643
event BlackTurn(uint256 _from, uint256 _to);
3744
event DiceRolled(bool isBlack, uint256 dice1, uint256 dice2);
@@ -44,6 +51,8 @@ contract Backgammon {
4451
uint256 stakeAmount
4552
);
4653
event FundsWithdrawn(address winner, uint256 amount);
54+
event StartDiceRolled(address player, uint256 dice);
55+
event FirstTurnDetermined(bool isBlackTurn, uint256 dice1, uint256 dice2);
4756

4857
constructor() payable {
4958
// black: [0,0,0,0,0,5,0,3,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,2]
@@ -71,9 +80,18 @@ contract Backgammon {
7180
_;
7281
}
7382

74-
// Modifier to check if game has started (both players staked)
75-
modifier gameHasStarted() {
76-
require(gameStarted, "Game has not started yet");
83+
// Modifier to check if game is active (first turn determined)
84+
modifier gameIsActive() {
85+
require(
86+
gameActive,
87+
"Game is not active yet. Determine first turn first."
88+
);
89+
_;
90+
}
91+
92+
// Modifier to check if both players have staked
93+
modifier bothPlayersStaked() {
94+
require(gameStarted, "Both players must stake first");
7795
_;
7896
}
7997

@@ -104,7 +122,12 @@ contract Backgammon {
104122
);
105123
require(msg.sender != whitePlayer, "Cannot play against yourself");
106124
blackPlayer = msg.sender;
107-
gameStarted = true;
125+
gameStarted = true; // Both players staked, but game not active yet
126+
// Reset start dice flags
127+
whiteStartDiceRolled = false;
128+
blackStartDiceRolled = false;
129+
whiteStartDice = 0;
130+
blackStartDice = 0;
108131
emit StakeDeposited(msg.sender, msg.value);
109132
emit GameStarted(whitePlayer, blackPlayer, stakeAmount);
110133
}
@@ -167,20 +190,143 @@ contract Backgammon {
167190
address _blackPlayer,
168191
uint256 _stakeAmount,
169192
bool _gameStarted,
193+
bool _gameActive,
170194
uint8 _winner,
171195
bool _fundsWithdrawn,
172-
uint256 _balance
196+
uint256 _balance,
197+
uint256 _whiteStartDice,
198+
uint256 _blackStartDice,
199+
bool _whiteStartDiceRolled,
200+
bool _blackStartDiceRolled
173201
)
174202
{
175203
return (
176204
whitePlayer,
177205
blackPlayer,
178206
stakeAmount,
179207
gameStarted,
208+
gameActive,
180209
winner,
181210
fundsWithdrawn,
182-
address(this).balance
211+
address(this).balance,
212+
whiteStartDice,
213+
blackStartDice,
214+
whiteStartDiceRolled,
215+
blackStartDiceRolled
216+
);
217+
}
218+
219+
// Roll start dice for black player (second player rolls first)
220+
function rollStartDiceBlack() public bothPlayersStaked returns (uint256) {
221+
require(!gameActive, "Game already active");
222+
require(
223+
msg.sender == blackPlayer,
224+
"Only black player can roll start dice"
225+
);
226+
require(
227+
!blackStartDiceRolled,
228+
"Black player already rolled start dice"
229+
);
230+
231+
// Generate random dice value (1-6)
232+
uint256 seed = uint256(
233+
keccak256(
234+
abi.encodePacked(
235+
block.timestamp,
236+
block.prevrandao,
237+
blockhash(block.number - 1),
238+
msg.sender
239+
)
240+
)
241+
);
242+
uint256 dice = (seed % 6) + 1;
243+
244+
blackStartDice = dice;
245+
blackStartDiceRolled = true;
246+
emit StartDiceRolled(msg.sender, dice);
247+
248+
// If white already rolled, determine first turn
249+
if (whiteStartDiceRolled) {
250+
_determineFirstTurn();
251+
}
252+
253+
return dice;
254+
}
255+
256+
// Roll start dice for white player (first player rolls second)
257+
function rollStartDiceWhite() public bothPlayersStaked returns (uint256) {
258+
require(!gameActive, "Game already active");
259+
require(
260+
msg.sender == whitePlayer,
261+
"Only white player can roll start dice"
183262
);
263+
require(
264+
!whiteStartDiceRolled,
265+
"White player already rolled start dice"
266+
);
267+
require(blackStartDiceRolled, "Black player must roll first");
268+
269+
// Generate random dice value (1-6)
270+
uint256 seed = uint256(
271+
keccak256(
272+
abi.encodePacked(
273+
block.timestamp,
274+
block.prevrandao,
275+
blockhash(block.number - 1),
276+
msg.sender
277+
)
278+
)
279+
);
280+
uint256 dice = (seed % 6) + 1;
281+
282+
whiteStartDice = dice;
283+
whiteStartDiceRolled = true;
284+
emit StartDiceRolled(msg.sender, dice);
285+
286+
// Determine first turn
287+
_determineFirstTurn();
288+
289+
return dice;
290+
}
291+
292+
// Internal function to determine first turn based on start dice rolls
293+
function _determineFirstTurn() internal {
294+
require(
295+
whiteStartDiceRolled && blackStartDiceRolled,
296+
"Both players must roll start dice"
297+
);
298+
299+
// If dice are equal, reset and require re-roll
300+
if (whiteStartDice == blackStartDice) {
301+
whiteStartDiceRolled = false;
302+
blackStartDiceRolled = false;
303+
whiteStartDice = 0;
304+
blackStartDice = 0;
305+
return; // Players need to roll again
306+
}
307+
308+
// Determine who goes first (higher dice wins)
309+
if (blackStartDice > whiteStartDice) {
310+
// Black goes first
311+
isItBlackTurn = true;
312+
// Set initial dice combination for first turn (use the two dice values)
313+
blackMovesCount = 2;
314+
blackAvailableMoves[0] = blackStartDice;
315+
blackAvailableMoves[1] = whiteStartDice;
316+
blackDiceRolled = true;
317+
} else {
318+
// White goes first
319+
isItBlackTurn = false;
320+
// Set initial dice combination for first turn (use the two dice values)
321+
whiteMovesCount = 2;
322+
whiteAvailableMoves[0] = whiteStartDice;
323+
whiteAvailableMoves[1] = blackStartDice;
324+
whiteDiceRolled = true;
325+
}
326+
327+
// Activate the game
328+
gameActive = true;
329+
emit FirstTurnDetermined(isItBlackTurn, whiteStartDice, blackStartDice);
184330
}
185331

186332
// Check for win condition and set winner if game is won
@@ -229,7 +375,7 @@ contract Backgammon {
229375
function rollDiceWhite()
230376
public
231377
gameNotFinished
232-
gameHasStarted
378+
gameIsActive
233379
returns (uint256 dice1, uint256 dice2)
234380
{
235381
require(!isItBlackTurn, "Is Black Turn");
@@ -279,7 +425,7 @@ contract Backgammon {
279425
function moveWhite(
280426
uint256 _from,
281427
uint256 _to
282-
) public gameNotFinished gameHasStarted {
428+
) public gameNotFinished gameIsActive {
283429
require(!isItBlackTurn, "Is Black Turn");
284430
require(msg.sender == whitePlayer, "Only white player can move");
285431
require(whiteDiceRolled, "Must roll dice before making a move");
@@ -541,7 +687,7 @@ contract Backgammon {
541687
function rollDiceBlack()
542688
public
543689
gameNotFinished
544-
gameHasStarted
690+
gameIsActive
545691
returns (uint256 dice1, uint256 dice2)
546692
{
547693
require(isItBlackTurn, "Is White Turn");
@@ -591,7 +737,7 @@ contract Backgammon {
591737
function moveBlack(
592738
uint256 _from,
593739
uint256 _to
594-
) public gameNotFinished gameHasStarted {
740+
) public gameNotFinished gameIsActive {
595741
require(isItBlackTurn, "Is White Turn");
596742
require(msg.sender == blackPlayer, "Only black player can move");
597743
require(blackDiceRolled, "Must roll dice before making a move");

packages/foundry/scripts-js/sendStake.js

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,44 +6,44 @@ import { foundry } from "viem/chains";
66
const PRIVATE_KEY = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
77

88
async function main() {
9-
const account = privateKeyToAccount(PRIVATE_KEY);
10-
11-
const client = createWalletClient({
12-
account,
13-
chain: foundry,
14-
transport: http("http://localhost:8545"),
15-
});
16-
17-
const contractAddress = "0x19A1c09fE3399C4Daaa2C98b936a8E460fC5Eaa4";
18-
const amount = parseEther("0.00000000000001");
19-
20-
console.log(`Sending ${amount.toString()} wei to contract ${contractAddress}...`);
21-
console.log(`From account: ${account.address}`);
22-
23-
try {
24-
const hash = await client.sendTransaction({
25-
to: contractAddress,
26-
value: amount,
9+
const account = privateKeyToAccount(PRIVATE_KEY);
10+
11+
const client = createWalletClient({
12+
account,
13+
chain: foundry,
14+
transport: http("http://localhost:8545"),
2715
});
2816

29-
console.log(`Transaction hash: ${hash}`);
30-
console.log(`Waiting for confirmation...`);
31-
32-
// Wait a bit for the transaction to be mined
33-
await new Promise(resolve => setTimeout(resolve, 2000));
34-
35-
console.log("Transaction sent successfully!");
36-
console.log(`Check the contract at: ${contractAddress}`);
37-
} catch (error) {
38-
console.error("Error sending transaction:", error);
39-
process.exit(1);
40-
}
17+
const contractAddress = "0x19A1c09fE3399C4Daaa2C98b936a8E460fC5Eaa4";
18+
const amount = parseEther("0.00000000000001");
19+
20+
console.log(`Sending ${amount.toString()} wei to contract ${contractAddress}...`);
21+
console.log(`From account: ${account.address}`);
22+
23+
try {
24+
const hash = await client.sendTransaction({
25+
to: contractAddress,
26+
value: amount,
27+
});
28+
29+
console.log(`Transaction hash: ${hash}`);
30+
console.log(`Waiting for confirmation...`);
31+
32+
// Wait a bit for the transaction to be mined
33+
await new Promise(resolve => setTimeout(resolve, 2000));
34+
35+
console.log("Transaction sent successfully!");
36+
console.log(`Check the contract at: ${contractAddress}`);
37+
} catch (error) {
38+
console.error("Error sending transaction:", error);
39+
process.exit(1);
40+
}
4141
}
4242

4343
main()
44-
.then(() => process.exit(0))
45-
.catch((error) => {
46-
console.error(error);
47-
process.exit(1);
48-
});
44+
.then(() => process.exit(0))
45+
.catch((error) => {
46+
console.error(error);
47+
process.exit(1);
48+
});
4949

0 commit comments

Comments
 (0)