@@ -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 " );
0 commit comments