@@ -7,183 +7,140 @@ import { Timer } from "../components/Timer";
77import { getRandomInt , unMemberFilter } from "../utils" ;
88import { useGameDataset } from "../hooks/useGameDataset" ;
99
10+ const sortByName = ( a , b ) => a . name . common . localeCompare ( b . name . common ) ;
11+
1012export default function Game ( ) {
1113 const dataset = useGameDataset ( ) ;
12- const data = unMemberFilter ( useContext ( DataContext ) )
13- const [ score , setScore ] = useState ( [ 0 , 0 ] ) ;
14- const [ results , setResults ] = useState ( [ ] )
15- const [ time , setTime ] = useState ( 10 ) ;
16- const [ randomFlag , setRandomFlag ] = useState (
17- dataset [ Math . floor ( Math . random ( ) * dataset ?. length ) ]
18- ) ;
19- const [ countries , setCountries ] = useState ( dataset ) ;
20- const getOptions = ( ) => {
21- let tempOptions = [ ] ;
22- while ( tempOptions . length < 4 ) {
23- let temp = data [ getRandomInt ( data . length ) ] ;
24- if ( tempOptions . indexOf ( temp ) === - 1 ) {
25- tempOptions . push ( temp ) ;
26- }
14+ const data = unMemberFilter ( useContext ( DataContext ) ) ;
15+
16+ const generateOptions = ( correct , pool ) => {
17+ const others = pool . filter ( ( c ) => c . ccn3 !== correct . ccn3 ) ;
18+ const picked = [ ] ;
19+ while ( picked . length < 4 ) {
20+ const rand = others [ getRandomInt ( others . length ) ] ;
21+ if ( ! picked . includes ( rand ) ) picked . push ( rand ) ;
2722 }
28- return tempOptions ;
29- }
30- const [ options , setOptions ] = useState ( [ ] ) ;
31-
32-
33-
23+ return [ ...picked , correct ] . sort ( sortByName ) ;
24+ } ;
3425
26+ const [ countries , setCountries ] = useState ( dataset ) ;
27+ const [ randomFlag , setRandomFlag ] = useState (
28+ dataset [ getRandomInt ( dataset . length ) ]
29+ ) ;
30+ const [ options , setOptions ] = useState ( ( ) =>
31+ generateOptions ( randomFlag , data )
32+ ) ;
33+ const [ score , setScore ] = useState ( [ 0 , 0 ] ) ;
34+ const [ results , setResults ] = useState ( [ ] ) ;
35+ const [ time , setTime ] = useState ( 10 ) ;
3536 const [ rmClick , setRmClick ] = useState ( false ) ;
36- const handleClick = ( event ) => {
37- setRmClick ( true )
37+ const [ skipFlag , setSkipFlag ] = useState ( false ) ;
3838
39+ useEffect ( ( ) => {
40+ document . title = "Where in the world? - Guess the flag" ;
41+ } , [ ] ) ;
3942
40- let target = event . target . innerHTML ;
41-
42- let selected = data . find ( value => value . name . common === target ) ;
43- let tempResult = { options, selected : selected , correct : randomFlag } ;
44- let temps = [ ...results , tempResult ] ;
45-
46- setResults ( temps )
47-
43+ const handleClick = ( event ) => {
44+ setRmClick ( true ) ;
45+ const target = event . target . innerHTML ;
46+ const selected = data . find ( ( v ) => v . name . common === target ) ;
4847
48+ setResults ( ( prev ) => [ ...prev , { options, selected, correct : randomFlag } ] ) ;
4949
5050 if ( target === randomFlag . name . common ) {
51- win ( true ) ;
51+ win ( ) ;
5252 } else {
53- loss ( true ) ;
53+ loss ( ) ;
5454 }
5555
56- setTimeout ( ( ) => {
57- setRmClick ( false ) ;
58- } , 120 ) ;
56+ setTimeout ( ( ) => setRmClick ( false ) , 120 ) ;
5957 } ;
6058
61- const win = ( flag ) => {
62- let scoreTemp = score ;
63- scoreTemp [ 0 ] = score [ 0 ] + 1 ;
64- setScore ( scoreTemp ) ;
65- setSkipFlag ( flag ) ;
66- reset ( ) ;
67- // setTime(false);
68- }
69-
70- const loss = ( flag ) => {
71- let scoreTemp = score ;
72- scoreTemp [ 1 ] = score [ 1 ] + 1 ;
73- setScore ( scoreTemp ) ;
74- setSkipFlag ( flag ) ;
75- reset ( ) ;
76- }
59+ const win = ( ) => {
60+ setScore ( ( prev ) => [ prev [ 0 ] + 1 , prev [ 1 ] ] ) ;
61+ setSkipFlag ( true ) ;
62+ advance ( ) ;
63+ } ;
7764
65+ const loss = ( ) => {
66+ setScore ( ( prev ) => [ prev [ 0 ] , prev [ 1 ] + 1 ] ) ;
67+ setSkipFlag ( true ) ;
68+ advance ( ) ;
69+ } ;
7870
79- const [ skipFlag , setSkipFlag ] = useState ( ) ;
80-
81- const reset = ( ) => {
82- let countriesTemp = countries . filter ( ( element ) => {
83- return element . ccn3 !== randomFlag . ccn3 ;
84- } ) ;
85- setCountries ( countriesTemp ) ;
86- let random = countriesTemp [ Math . floor ( Math . random ( ) * countriesTemp . length ) ] ;
87- setRandomFlag ( random ) ;
88- let temOptions = data . filter ( ( element ) => {
89- return element . ccn3 !== random . ccn3 ;
90- } ) ;
91- let optionsTemp = [ ] ;
92-
93- while ( optionsTemp . length <= 3 ) {
94- let temp = temOptions [ getRandomInt ( temOptions . length ) ] ;
95- if ( optionsTemp . indexOf ( temp ) === - 1 ) {
96- optionsTemp . push ( temp ) ;
97- }
98- }
99- optionsTemp . push ( random ) ;
100-
101- optionsTemp . sort ( ( a , b ) => {
102- let x = a . name . common . toLowerCase ( ) ;
103- let y = b . name . common . toLowerCase ( ) ;
104- if ( x < y ) {
105- return - 1 ;
106- }
107- if ( x > y ) {
108- return 1 ;
109- }
110- return 0 ;
111- } ) ;
112-
113-
114- setOptions ( optionsTemp ) ;
71+ const advance = ( ) => {
72+ const remaining = countries . filter ( ( c ) => c . ccn3 !== randomFlag . ccn3 ) ;
73+ setCountries ( remaining ) ;
74+ if ( remaining . length === 0 ) return ;
75+ const next = remaining [ getRandomInt ( remaining . length ) ] ;
76+ setRandomFlag ( next ) ;
77+ setOptions ( generateOptions ( next , data ) ) ;
11578 setTime ( 10 ) ;
11679 } ;
80+
11781 const startAgain = ( ) => {
118- setRandomFlag ( dataset [ getRandomInt ( dataset . length ) ] )
82+ const first = dataset [ getRandomInt ( dataset . length ) ] ;
11983 setCountries ( dataset ) ;
84+ setRandomFlag ( first ) ;
85+ setOptions ( generateOptions ( first , data ) ) ;
12086 setTime ( 10 ) ;
12187 setRmClick ( false ) ;
122- setScore ( [ 0 , 0 ] )
123- setResults ( [ ] )
124- setSkipFlag ( false )
125- }
126-
127- useEffect ( ( ) => {
128- document . title = `Where in the world? - Guess the flag` ;
129- setOptions ( [ ...getOptions ( ) , randomFlag ] )
130- options . sort ( ( a , b ) => {
131- let x = a . name . common . toLowerCase ( ) ;
132- let y = b . name . common . toLowerCase ( ) ;
133- if ( x < y ) {
134- return - 1 ;
135- }
136- if ( x > y ) {
137- return 1 ;
138- }
139- return 0 ;
140- } ) ;
141- } , [ ] ) ;
88+ setScore ( [ 0 , 0 ] ) ;
89+ setResults ( [ ] ) ;
90+ setSkipFlag ( false ) ;
91+ } ;
14292
14393 if ( dataset . length <= 0 ) {
144- return < Navigate replace to = { ' /games' } />
94+ return < Navigate replace to = " /games" /> ;
14595 }
14696
147- if ( countries . length !== 0 ) {
148- // if (false) {
149- return (
150- < div className = "dark:text-white flex flex-col h-full w-11/12 justify-center items-center mx-auto relative " >
151- < div className = "flex flex-col bg-white/10 backdrop-blur-sm p-10 rounded gap-5 px-5 w-full sm:w-[500px]" >
152- { countries . length >= dataset . length && < h1 className = "font-semibold text-2xl" >
153- Choose the name of the country based on the flag
154- </ h1 > }
155- < div className = "w-full h-[250px] flex-auto" >
156- < FlagTransition flag = { randomFlag } />
157- </ div >
158- < div className = { `flex flex-col gap-x-2 justify-center flex-wrap w-full gap-2 ${ rmClick ? 'pointer-events-none' : '' } ` } >
159- { options . map ( ( element , index ) => {
160- return (
161- < button
162- key = { index }
163- onClick = { handleClick }
164- className = "shadow disabled:bg-invalid rounded p-2 bg-white dark:bg-dark-fe border hover:bg-dark-mode-ligth/10 transition-colors dark:hover:bg-dark-mode-ligth/10 hover:cursor-pointer select-none"
165- >
166- { element . name . common }
167- </ button >
168- ) ;
169- } ) }
170- </ div >
171- < div className = "flex flex-row justify-between items-center" >
172- < div className = "font-bold" > { countries . length } </ div >
173- < Timer reducer = { 1 } time = { time } skip = { skipFlag } skipf = { setSkipFlag } loss = { loss } setTime = { setTime } className = { "self-end" } />
174- </ div >
175- </ div >
176- </ div >
177- ) ;
178- } else {
97+ if ( countries . length === 0 ) {
17998 return (
18099 < Modal
181100 title = "You finished the game 😁👍🏻"
182- desc = "Congrats! see you score, also you can play again or go back to play more puzzles"
101+ desc = "Congrats! See your score, play again or go back to play more puzzles"
183102 again = { startAgain }
184103 score = { score }
185104 results = { results }
186105 />
187106 ) ;
188107 }
108+
109+ return (
110+ < div className = "dark:text-white flex flex-col h-full w-11/12 justify-center items-center mx-auto relative" >
111+ < div className = "flex flex-col bg-white/10 backdrop-blur-sm p-10 rounded gap-5 px-5 w-full sm:w-[500px]" >
112+ { countries . length >= dataset . length && (
113+ < h1 className = "font-semibold text-2xl" >
114+ Choose the name of the country based on the flag
115+ </ h1 >
116+ ) }
117+ < div className = "w-full h-[250px] flex-auto" >
118+ < FlagTransition flag = { randomFlag } />
119+ </ div >
120+ < div className = { `flex flex-col justify-center w-full gap-2 ${ rmClick ? "pointer-events-none" : "" } ` } >
121+ { options . map ( ( element , index ) => (
122+ < button
123+ key = { index }
124+ onClick = { handleClick }
125+ className = "shadow rounded p-2 bg-white dark:bg-dark-fe border hover:bg-dark-mode-ligth/10 transition-colors dark:hover:bg-dark-mode-ligth/10 hover:cursor-pointer select-none"
126+ >
127+ { element . name . common }
128+ </ button >
129+ ) ) }
130+ </ div >
131+ < div className = "flex flex-row justify-between items-center" >
132+ < div className = "font-bold" > { countries . length } </ div >
133+ < Timer
134+ reducer = { 1 }
135+ time = { time }
136+ skip = { skipFlag }
137+ skipf = { setSkipFlag }
138+ loss = { loss }
139+ setTime = { setTime }
140+ className = "self-end"
141+ />
142+ </ div >
143+ </ div >
144+ </ div >
145+ ) ;
189146}
0 commit comments