@@ -8,18 +8,18 @@ import { RotateCcw } from "lucide-react";
88type Player = { id : number ; name : string ; score : number ; doubledIn : boolean } ;
99
1010type ThrowRecord = {
11- playerId : number ;
12- prevScore : number ;
13- prevDoubledIn : boolean ;
14- prevActiveId : number | null ;
15- prevThrowsThisTurn : number ;
16- prevGameOver : { winnerId : number } | null ;
17- points : number ;
18- isDouble : boolean ;
11+ playerId : number ;
12+ prevScore : number ;
13+ prevDoubledIn : boolean ;
14+ prevActiveId : number | null ;
15+ prevThrowsThisTurn : number ;
16+ prevGameOver : { winnerId : number } | null ;
17+ points : number ;
18+ isDouble : boolean ;
1919} ;
2020
2121export default function X01 ( ) {
22- const [ history , setHistory ] = useState < ThrowRecord [ ] > ( [ ] ) ;
22+ const [ , setHistory ] = useState < ThrowRecord [ ] > ( [ ] ) ;
2323 const [ startScore , setStartScore ] = useState < number > ( 301 ) ;
2424 const [ players , setPlayers ] = useState < Player [ ] > ( [ ] ) ;
2525 const [ removeMode , setRemoveMode ] = useState ( false ) ;
@@ -59,95 +59,63 @@ export default function X01() {
5959 } ) ;
6060 } ;
6161
62- const advanceToNextPlayer = ( ) => {
62+ const endTurn = ( ) => {
6363 if ( ! players . length || activeId === null ) return ;
6464 const idx = players . findIndex ( p => p . id === activeId ) ;
6565 const nextIdx = ( idx + 1 ) % players . length ;
6666 setActiveId ( players [ nextIdx ] . id ) ;
6767 setThrowsThisTurn ( 0 ) ;
6868 } ;
6969
70- const applyScore = ( points : number , detail : { isDouble : boolean } ) => {
70+ const registerThrow = ( points : number , { isDouble } : { isDouble : boolean } ) => {
7171 if ( gameOver || activeId === null || ! players . length ) return ;
7272
7373 const curr = players . find ( p => p . id === activeId ) ! ;
74- let valid = false ;
74+ const prevScore = curr . score ;
75+ const prevDoubledIn = curr . doubledIn ;
76+
7577 let winnerId : number | null = null ;
7678
7779 setPlayers ( prev => prev . map ( p => {
7880 if ( p . id !== activeId ) return p ;
7981
82+ // Not doubled-in yet
8083 if ( ! p . doubledIn ) {
81- if ( ! detail . isDouble ) return p ; // must double-in
82- const nextScore = p . score - points ;
83- if ( nextScore < 0 ) return p ; // bust
84- valid = true ;
85- const doubledIn = true ;
86- if ( nextScore === 0 ) winnerId = p . id ;
87- return { ...p , score : nextScore , doubledIn } ;
84+ if ( ! isDouble ) {
85+ return p ;
86+ }
87+ const ns = p . score - points ;
88+ return { ...p , score : ns , doubledIn : true } ;
8889 }
8990
90- const nextScore = p . score - points ;
91- if ( nextScore < 0 ) return p ;
92- if ( nextScore === 0 && ! detail . isDouble ) return p ; // must double-out
93- valid = true ;
94- if ( nextScore === 0 ) winnerId = p . id ;
95- return { ...p , score : nextScore } ;
91+ // Already doubled-in
92+ const ns = p . score - points ;
93+ if ( ns === 0 ) winnerId = p . id ;
94+ return { ...p , score : ns } ;
9695 } ) ) ;
9796
98- if ( valid ) {
99- const rec : ThrowRecord = {
100- playerId : activeId ,
101- prevScore : curr . score ,
102- prevDoubledIn : curr . doubledIn ,
103- prevActiveId : activeId ,
104- prevThrowsThisTurn : throwsThisTurn ,
105- prevGameOver : gameOver ,
106- points,
107- isDouble : detail . isDouble ,
108- } ;
109- setHistory ( h => [ ...h , rec ] ) ;
110- }
111-
112- if ( winnerId ) {
113- setGameOver ( { winnerId } ) ;
114- return ;
115- }
116-
117- if ( valid ) {
118- setThrowsThisTurn ( t => {
119- const nt = t + 1 ;
120- if ( nt >= 3 ) {
121- advanceToNextPlayer ( ) ;
122- return 0 ;
123- }
124- return nt ;
125- } ) ;
126- }
127- } ;
128-
129- // Miss or don't score points
130- const registerMiss = ( ) => {
131- if ( gameOver || activeId === null || ! players . length ) return ;
132- const curr = players . find ( p => p . id === activeId ) ! ;
133-
97+ //History
13498 const rec : ThrowRecord = {
13599 playerId : activeId ,
136- prevScore : curr . score ,
137- prevDoubledIn : curr . doubledIn ,
100+ prevScore,
101+ prevDoubledIn,
138102 prevActiveId : activeId ,
139103 prevThrowsThisTurn : throwsThisTurn ,
140104 prevGameOver : gameOver ,
141- points : 0 ,
142- isDouble : false ,
105+ points,
106+ isDouble,
143107 } ;
144108 setHistory ( h => [ ...h , rec ] ) ;
145109
146- setThrowsThisTurn ( t => {
147- const nt = t + 1 ;
148- if ( nt >= 3 ) { advanceToNextPlayer ( ) ; return 0 ; }
149- return nt ;
150- } ) ;
110+ if ( winnerId ) { setGameOver ( { winnerId } ) ; return ; }
111+
112+ // Use the dart
113+ const nextThrow = throwsThisTurn + 1 ;
114+ if ( nextThrow >= 3 ) {
115+ endTurn ( ) ;
116+ } else {
117+ setThrowsThisTurn ( nextThrow ) ;
118+ }
151119 } ;
152120
153121 // Undo last throw or miss
@@ -157,11 +125,11 @@ export default function X01() {
157125 const last = h [ h . length - 1 ] ;
158126
159127 setPlayers ( prev =>
160- prev . map ( p =>
161- p . id === last . playerId
162- ? { ...p , score : last . prevScore , doubledIn : last . prevDoubledIn }
163- : p
164- )
128+ prev . map ( p =>
129+ p . id === last . playerId
130+ ? { ...p , score : last . prevScore , doubledIn : last . prevDoubledIn }
131+ : p
132+ )
165133 ) ;
166134
167135 setActiveId ( last . prevActiveId ) ;
@@ -273,8 +241,8 @@ export default function X01() {
273241 { /* Score keeper */ }
274242 < div className = "mt-6" >
275243 < X01ScoreKeeper
276- onScore = { ( points , detail ) => applyScore ( points , { isDouble : detail . isDouble } ) }
277- onMiss = { registerMiss }
244+ onScore = { ( points , detail ) => registerThrow ( points , { isDouble : detail . isDouble } ) }
245+ onMiss = { ( ) => registerThrow ( 0 , { isDouble : false } ) }
278246 onUndo = { undoLast }
279247 disabled = { removeMode || ! players . length || activeId === null || ! ! gameOver }
280248 currentScore = { activePlayer ? activePlayer . score : 0 }
0 commit comments