1
+ import React , { useState , useEffect } from 'react' ;
2
+ import ReactDOM from 'react-dom' ;
3
+
4
+ const rowStyle = {
5
+ display : 'flex'
6
+ }
7
+
8
+ const squareStyle = {
9
+ 'width' :'60px' ,
10
+ 'height' :'60px' ,
11
+ 'backgroundColor' : '#ddd' ,
12
+ 'margin' : '4px' ,
13
+ 'display' : 'flex' ,
14
+ 'justifyContent' : 'center' ,
15
+ 'alignItems' : 'center' ,
16
+ 'fontSize' : '20px' ,
17
+ 'color' : 'white' ,
18
+ 'cursor' : 'pointer' ,
19
+ }
20
+
21
+ const boardStyle = {
22
+ 'backgroundColor' : '#eee' ,
23
+ 'width' : '208px' ,
24
+ 'alignItems' : 'center' ,
25
+ 'justifyContent' : 'center' ,
26
+ 'display' : 'flex' ,
27
+ 'flexDirection' : 'column' ,
28
+ 'border' : '3px #eee solid'
29
+ }
30
+
31
+ const containerStyle = {
32
+ 'display' : 'flex' ,
33
+ 'alignItems' : 'center' ,
34
+ 'flexDirection' : 'column'
35
+ }
36
+
37
+ const instructionsStyle = {
38
+ 'marginTop' : '5px' ,
39
+ 'marginBottom' : '5px' ,
40
+ 'fontWeight' : 'bold' ,
41
+ 'fontSize' : '16px' ,
42
+ }
43
+
44
+ const buttonStyle = {
45
+ 'marginTop' : '15px' ,
46
+ 'marginBottom' : '16px' ,
47
+ 'width' : '80px' ,
48
+ 'height' : '40px' ,
49
+ 'backgroundColor' : '#8acaca' ,
50
+ 'color' : 'white' ,
51
+ 'fontSize' : '16px' ,
52
+ 'cursor' : 'pointer' ,
53
+ }
54
+
55
+ const Square = ( { playerXSquares, playerOSquares, handleClick, value, disabled } ) => {
56
+ return (
57
+ < div
58
+ className = "square"
59
+ style = { squareStyle }
60
+ disabled = { disabled }
61
+ value = { value }
62
+ onClick = { ( ) => {
63
+ if ( ! disabled ) {
64
+ handleClick ( value )
65
+ }
66
+ } }
67
+ >
68
+ < span className = "square-text" >
69
+ { playerXSquares . indexOf ( value ) > - 1 ? 'X' : playerOSquares . indexOf ( value ) > - 1 ? 'O' : '' }
70
+ </ span >
71
+ </ div >
72
+ ) ;
73
+ } ;
74
+
75
+ const Board = ( ) => {
76
+ const [ currentPlayer , setCurrentPlayer ] = useState ( 'player X' ) ;
77
+ const [ winner , setWinner ] = useState ( 'None' )
78
+ const [ playerXSquares , setPlayerXSquares ] = useState ( [ ] ) ;
79
+ const [ playerOSquares , setPlayerOSquares ] = useState ( [ ] ) ;
80
+
81
+ const handleClick = value => {
82
+ if ( currentPlayer === 'player X' ) {
83
+ setPlayerXSquares ( [ ...playerXSquares , value ] ) ;
84
+ setCurrentPlayer ( 'player O' ) ;
85
+ } else {
86
+ setPlayerOSquares ( [ ...playerOSquares , value ] ) ;
87
+ setCurrentPlayer ( 'player X' ) ;
88
+ }
89
+ }
90
+
91
+ const determineWinner = ( playerXSquares , playerOSquares ) => {
92
+
93
+ function checkRows ( ) {
94
+ if (
95
+ ( playerXSquares . includes ( 0 ) && playerXSquares . includes ( 1 ) && playerXSquares . includes ( 2 ) ) ||
96
+ ( playerXSquares . includes ( 3 ) && playerXSquares . includes ( 4 ) && playerXSquares . includes ( 5 ) ) ||
97
+ ( playerXSquares . includes ( 6 ) && playerXSquares . includes ( 7 ) && playerXSquares . includes ( 8 ) )
98
+ ) {
99
+ return setWinner ( 'Player X' ) ;
100
+ }
101
+
102
+ if (
103
+ ( playerOSquares . includes ( 0 ) && playerOSquares . includes ( 1 ) && playerOSquares . includes ( 2 ) ) ||
104
+ ( playerOSquares . includes ( 3 ) && playerOSquares . includes ( 4 ) && playerOSquares . includes ( 5 ) ) ||
105
+ ( playerOSquares . includes ( 6 ) && playerOSquares . includes ( 7 ) && playerOSquares . includes ( 8 ) )
106
+ ) {
107
+ return setWinner ( 'Player O' ) ;
108
+ }
109
+
110
+ }
111
+
112
+ function checkColumns ( ) {
113
+ if (
114
+ ( playerXSquares . includes ( 0 ) && playerXSquares . includes ( 3 ) && playerXSquares . includes ( 6 ) ) ||
115
+ ( playerXSquares . includes ( 1 ) && playerXSquares . includes ( 4 ) && playerXSquares . includes ( 7 ) ) ||
116
+ ( playerXSquares . includes ( 2 ) && playerXSquares . includes ( 5 ) && playerXSquares . includes ( 8 ) )
117
+ ) {
118
+ return setWinner ( 'Player X' ) ;
119
+ }
120
+
121
+ if (
122
+ ( playerOSquares . includes ( 0 ) && playerOSquares . includes ( 3 ) && playerOSquares . includes ( 6 ) ) ||
123
+ ( playerOSquares . includes ( 1 ) && playerOSquares . includes ( 4 ) && playerOSquares . includes ( 7 ) ) ||
124
+ ( playerOSquares . includes ( 2 ) && playerOSquares . includes ( 5 ) && playerOSquares . includes ( 8 ) )
125
+ ) {
126
+ return setWinner ( 'Player O' ) ;
127
+ }
128
+ }
129
+
130
+ function checkDiagnols ( ) {
131
+ if ( playerXSquares . includes ( 4 ) ) {
132
+ if ( ( playerXSquares . includes ( 0 ) && playerXSquares . includes ( 8 ) ) || ( playerXSquares . includes ( 2 ) && playerXSquares . includes ( 6 ) ) ) {
133
+ return setWinner ( 'Player X' ) ;
134
+ }
135
+ }
136
+ if ( playerOSquares . includes ( 4 ) ) {
137
+ if ( ( playerOSquares . includes ( 0 ) && playerOSquares . includes ( 8 ) ) || ( playerOSquares . includes ( 2 ) && playerOSquares . includes ( 6 ) ) ) {
138
+ return setWinner ( 'Player O' ) ;
139
+ }
140
+ }
141
+ }
142
+
143
+ if ( winner === 'None' ) {
144
+ checkRows ( ) ;
145
+ checkColumns ( ) ;
146
+ checkDiagnols ( ) ;
147
+ }
148
+ }
149
+
150
+
151
+ const reset = ( ) => {
152
+ setCurrentPlayer ( 'Player X' ) ;
153
+ setPlayerXSquares ( [ ] ) ;
154
+ setPlayerOSquares ( [ ] ) ;
155
+ setWinner ( 'None' ) ;
156
+ }
157
+
158
+ useEffect ( ( ) => {
159
+ determineWinner ( playerXSquares , playerOSquares ) ;
160
+ } , [ playerXSquares , playerOSquares ] ) ;
161
+
162
+ return (
163
+ < div style = { containerStyle } className = "gameBoard" >
164
+ < div id = "statusArea" className = "status" style = { instructionsStyle } > Next player: < span > { currentPlayer === 'Player X' ? 'Player O' : 'Player X' } </ span > </ div >
165
+ < div id = "winnerArea" className = "winner" style = { instructionsStyle } > Winner: < span > { winner } </ span > </ div >
166
+ < button onClick = { reset } style = { buttonStyle } > Reset</ button >
167
+ < div style = { boardStyle } >
168
+ < div className = "board-row" style = { rowStyle } >
169
+ < Square disabled = { playerXSquares . includes ( 0 ) || playerOSquares . includes ( 0 ) || winner !== 'None' } playerXSquares = { playerXSquares } playerOSquares = { playerOSquares } handleClick = { handleClick } value = { 0 } />
170
+ < Square disabled = { playerXSquares . includes ( 1 ) || playerOSquares . includes ( 1 ) || winner !== 'None' } playerXSquares = { playerXSquares } playerOSquares = { playerOSquares } handleClick = { handleClick } value = { 1 } />
171
+ < Square disabled = { playerXSquares . includes ( 2 ) || playerOSquares . includes ( 2 ) || winner !== 'None' } playerXSquares = { playerXSquares } playerOSquares = { playerOSquares } handleClick = { handleClick } value = { 2 } />
172
+ </ div >
173
+ < div className = "board-row" style = { rowStyle } >
174
+ < Square disabled = { playerXSquares . includes ( 2 ) || playerOSquares . includes ( 3 ) || winner !== 'None' } playerXSquares = { playerXSquares } playerOSquares = { playerOSquares } handleClick = { handleClick } value = { 3 } />
175
+ < Square disabled = { playerXSquares . includes ( 2 ) || playerOSquares . includes ( 4 ) || winner !== 'None' } playerXSquares = { playerXSquares } playerOSquares = { playerOSquares } handleClick = { handleClick } value = { 4 } />
176
+ < Square disabled = { playerXSquares . includes ( 2 ) || playerOSquares . includes ( 5 ) || winner !== 'None' } playerXSquares = { playerXSquares } playerOSquares = { playerOSquares } handleClick = { handleClick } value = { 5 } />
177
+ </ div >
178
+ < div className = "board-row" style = { rowStyle } >
179
+ < Square disabled = { playerXSquares . includes ( 2 ) || playerOSquares . includes ( 6 ) || winner !== 'None' } playerXSquares = { playerXSquares } playerOSquares = { playerOSquares } handleClick = { handleClick } value = { 6 } />
180
+ < Square disabled = { playerXSquares . includes ( 2 ) || playerOSquares . includes ( 7 ) || winner !== 'None' } playerXSquares = { playerXSquares } playerOSquares = { playerOSquares } handleClick = { handleClick } value = { 7 } />
181
+ < Square disabled = { playerXSquares . includes ( 2 ) || playerOSquares . includes ( 8 ) || winner !== 'None' } playerXSquares = { playerXSquares } playerOSquares = { playerOSquares } handleClick = { handleClick } value = { 8 } />
182
+ </ div >
183
+ </ div >
184
+ </ div >
185
+ ) ;
186
+ } ;
187
+
188
+ const Game = ( ) => {
189
+ return (
190
+ < div className = "game" >
191
+ < div className = "game-board" >
192
+ < Board />
193
+ </ div >
194
+ </ div >
195
+ ) ;
196
+ } ;
197
+
198
+ ReactDOM . render (
199
+ < Game /> ,
200
+ document . getElementById ( 'root' )
201
+ ) ;
0 commit comments