import ĠPlayer . O Ċ import ĠPlayer . X Ċ Ċ class ĠViewModel Ġ: ĠView Listener Ġ{ ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġview State : ĠView State ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġview : ĠView ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġmodel : ĠModel ĊĊĠĠĠ Ġoverride Ġfun Ġon User Input ( input : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! model . has User Entered Row ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . user Row Entry Ġ= Ġcheck User Input ( input ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Row Column Within Board ( model . user Row Entry )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . has User Entered Row Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . has User Entered Column Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Row Or Column () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdont Display Out Put But Ask ForUser Input () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . has User Entered Row Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . has User Entered Column Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Row Or Column () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdont Display Out Put But Ask ForUser Input () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! model . has User Entered Column ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . user Column Entry Ġ= Ġcheck User Input ( input ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Row Column Within Board ( model . user Column Entry )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is User Coordinate Valid ( Pair ( model . user Row Entry , Ġmodel . user Column Entry ))) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmark Current Player Move On Board ( Pair ( model . user Row Entry , Ġmodel . user Column Entry )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Turn Processing () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . has User Entered Row Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . has User Entered Column Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Row Or Column () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdont Display Out Put But Ask ForUser Input () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . has User Entered Row Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . has User Entered Column Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Row Or Column () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdont Display Out Put But Ask ForUser Input () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstart Game () Ġ{ ĊĠĠĠĠĠĠĠ Ġview State Ġ= ĠView State () ĊĠĠĠĠĠĠĠ Ġview Ġ= ĠView ( this ) ĊĠĠĠĠĠĠĠ Ġmodel Ġ= ĠModel () ĊĠĠĠĠĠĠĠ Ġwith ( model ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġai Player Pick Ġ= Ġif Ġ(( 0 .. 1 ). random () Ġ== Ġ 0 ) ĠX Ġelse ĠO ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhuman Player Pick Ġ= Ġget Other Player ( ai Player Pick ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhas User Entered Row Ġ= Ġai Player Pick Ġ== ĠX ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Welcome Message () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Board () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Player Ġ== Ġai Player Pick ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplay Computer Turn () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Turn Processing () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhas User Entered Row Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhas User Entered Column Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Row Or Column () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdont Display Out Put But Ask ForUser Input () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġpost Turn Processing () Ġ{ ĊĠĠĠĠĠĠĠ Ġview State . text To Output Ġ= Ġ"" ĊĠĠĠĠĠĠĠ Ġwith ( model ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Board () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( has Player W on ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Game Over () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Board Full ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Draw Game () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Human Turn ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Player Ġ= Ġget Other Player ( current Player ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplay Computer Turn () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Turn Processing () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Player Ġ= Ġget Other Player ( current Player ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhas User Entered Row Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhas User Entered Column Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Human Turn Message () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Row Or Column () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdont Display Out Put But Ask ForUser Input () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshow Board () Ġ{ ĊĠĠĠĠĠĠĠ Ġdisplay Out Put But Dont Ask ForUser Input () ĊĠĠĠĠĠĠĠ Ġview State . text To Output Ġ= Ġmodel . board ToString () ĊĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġplay Computer Turn () Ġ{ ĊĠĠĠĠĠĠĠ Ġshow A IT urn Message () ĊĠĠĠĠĠĠĠ Ġvar Ġcoordinate Candidate : ĠPair < Int , ĠInt > ĊĠĠĠĠĠĠĠ Ġdo Ġcoordinate Candidate Ġ= ĠPair (( 0 .. 2 ). random (), Ġ( 0 .. 2 ). random ()) ĊĠĠĠĠĠĠĠ Ġwhile Ġ(! is User Coordinate Valid ( coordinate Candidate )) ĊĠĠĠĠĠĠĠ Ġmark Current Player Move On Board ( coordinate Candidate ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmark Current Player Move On Board ( coordinate : ĠPair < Int , ĠInt >) Ġ{ ĊĠĠĠĠĠĠĠ Ġmodel . game Board [ coordinate . first ][ coordinate . second ] Ġ= Ġmodel . current Player ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis User Coordinate Valid ( coordinate : ĠPair < Int , ĠInt >): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠ Ġmodel . game Board [ coordinate . first ][ coordinate . second ] Ġ== ĠPlayer . NA ĊĊĊĠĠĠ Ġprivate Ġfun Ġshow A IT urn Message () Ġ{ ĊĠĠĠĠĠĠĠ Ġview State . text To Output Ġ= ĠModel . AI _ T URN Ġ+ Ġ"\ n " ĊĠĠĠĠĠĠĠ Ġdisplay Out Put But Dont Ask ForUser Input () ĊĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshow Human Turn Message () Ġ{ ĊĠĠĠĠĠĠĠ Ġview State . text To Output Ġ= ĠModel . HUM AN _ T URN Ġ+ Ġ"\ n " ĊĠĠĠĠĠĠĠ Ġdisplay Out Put But Dont Ask ForUser Input () ĊĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdisplay Out Put But Dont Ask ForUser Input () Ġ{ ĊĠĠĠĠĠĠĠ Ġview State . does Require User Input Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġview State . is Display ing Output Ġ= Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdont Display Out Put But Ask ForUser Input () Ġ{ ĊĠĠĠĠĠĠĠ Ġview State . does Require User Input Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġview State . is Display ing Output Ġ= Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdont Display And Dont Ask ForUser Input () Ġ{ ĊĠĠĠĠĠĠĠ Ġview State . does Require User Input Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġview State . is Display ing Output Ġ= Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Other Player ( player : ĠPlayer ): ĠPlayer Ġ= Ġif Ġ( player Ġ== ĠX ) ĠO Ġelse ĠX ĊĊĠĠĠ Ġprivate Ġfun Ġis Row Column Within Board ( input : ĠInt ) Ġ= Ġinput Ġ> Ġ- 1 Ġ&& Ġinput Ġ< Ġ 3 ĊĊĠĠĠ Ġprivate Ġfun Ġcheck User Input ( input : ĠString ?): ĠInt Ġ= ĊĠĠĠĠĠĠĠ Ġif Ġ( input Ġ== Ġnull ) Ġ- 1 ĊĠĠĠĠĠĠĠ Ġelse Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput . toInt () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠNumber FormatException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ- 1 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshow Draw Game () Ġ{ ĊĠĠĠĠĠĠĠ Ġview State . text To Output Ġ= ĠModel . ITS _ A _ DRAW ĊĠĠĠĠĠĠĠ Ġdisplay Out Put But Dont Ask ForUser Input () ĊĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshow Welcome Message () Ġ{ ĊĠĠĠĠĠĠĠ Ġview State . text To Output Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠModel . W EL CO ME _ TO _ TICK Ġ+ Ġ"\ n " Ġ+ ĠModel . YO U _ ARE _ PLAYER Ġ+ Ġ"${ model . human Player Pick } Ġ\ n " ĊĠĠĠĠĠĠĠ Ġdisplay Out Put But Dont Ask ForUser Input () ĊĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshow Game Over () Ġ{ ĊĠĠĠĠĠĠĠ Ġdisplay Out Put But Dont Ask ForUser Input () ĊĠĠĠĠĠĠĠ Ġview State . text To Output Ġ= Ġ"${ Model . YO U _ WIN } Ġ${ Model . PLAYER } Ġ${ model . current Player } Ġ" ĊĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠĠĠĠĠ Ġdont Display And Dont Ask ForUser Input () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshow Row Or Column () Ġ{ ĊĠĠĠĠĠĠĠ Ġdisplay Out Put But Dont Ask ForUser Input () ĊĠĠĠĠĠĠĠ Ġif Ġ(! model . has User Entered Row ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġview State . text To Output Ġ= ĠModel . ENTER _ ROW Ġ+ Ġ"\ n " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġview State . text To Output Ġ= ĠModel . ENTER _ COLUMN Ġ+ Ġ"\ n " ĊĠĠĠĠĠĠĠ Ġinvalidate View () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinvalidate View () Ġ{ ĊĠĠĠĠĠĠĠ Ġview . set New ViewState ( view State ) ĊĠĠĠ Ġ} Ċ }