I wonder if *just solved your homework...*

(define (same-value? vec)
  (define test-val (vector-ref vec 0))
  (if (zero? test-val)
      #f
      (let ((same? (for/and ((v (in-vector vec)))
                     (eqv? test-val v))))
        (and same? test-val))))

(define (winner-by-row row-num)
  (define row (vector-ref board row-num))
  (same-value? row))

(define (winner-by-col col-num)
  (define col (for/vector ((row (in-vector board)))
                (vector-ref row col-num)))
  (same-value? col))

(define (winner-by-diag direction)
  (define diag (for/vector (((row index) (in-indexed board)))
                 (define idx (if (eqv? direction 1)
                                 index
                                 (- (vector-length row) (add1 index))))
                 (vector-ref row idx)))
  (same-value? diag))

(define winner (lambda ()
                 ; return winner (1 or 2) or 0 if no winner

                 (or
                  (for/or ((row (in-range 3)))
                    (winner-by-row row))
                  (for/or ((col (in-range 3)))
                    (winner-by-col col))
                  (winner-by-diag 1)
                  (winner-by-diag -1)
                 
                 0)))

Alex.

On Friday, May 4, 2018 at 2:12:17 AM UTC+8, ademko...@gmail.com wrote:
>
> hey guys, struggling with a project, have an incomplete template of a 
> noughts and crosses game but need to change the state and display the 
> winner once they have 3 in a row.
>
> #lang racket/gui
>
> ; o and x game
> ; with a GUI. Attempts to use an MVC-like approach.
>
> ;---------------------------------------------------------------------
> ; Model: State of the game
> ; use vectors as they are mutable - we can change the state
> (define board (vector
>                (vector 0 0 0)
>                (vector 0 0 0)
>                (vector 0 0 0) ))
>
> ; Size of game:
> (define rows 3)
> (define cols 3)
>
> ; current go: either 1 or 2
> (define currentPlayer 1)
>
> ;---------------------------------------------------------------------
> ; functions to modify state
>
> (define updateState (lambda (rowNum colNum val)
>                       ; update the state 
>                       (vector-set! (vector-ref board rowNum) colNum val)
>                       ))
>
> (define switchPlayer (lambda () (set! currentPlayer (- 3 currentPlayer))))
>
> (define winner (lambda ()
>                  ; return winner (1 or 2) or 0 if no winner
>                  
>                  ; row
>                  ; col
>                  ; diagonal
>                  
>                  0))
>
> ;---------------------------------------------------------------------
> ; View: create button matrix; 
>
> ; adds a button to container - callback does the actionFunc and calls 
> update to refresh display
> ; updateFunc added to the updator set
> (define addButton (lambda (container actionFunc updateFunc rowNum colNum)
>                     (let ((newBut
>                            (new button% [label ""] [parent container] 
> [callback
>                                                                        
> (lambda (button event)
>                                                                          
> (actionFunc)
>                                                                          
> (update)
>                                                                          
> )])
>                            ))
>                       (addUpdator (lambda () (updateFunc newBut)))
>                       )
>                     ))
>
>
> (define createButRow (lambda (rowContainer rowNum numberOfButtons)
>                        ; create a row of buttons
>                        (cond
>                          ((equal? numberOfButtons 0))
>                          (else  (let ((buttonIndex (+ (* cols (- rowNum 
> 1)) numberOfButtons)))
>                                   
>                                   (addButton
>                                    rowContainer
>                                    (lambda () ; actionFunc: set data item 
> buttonIndex to currentPlayer; change currentPlayer
>                                      (updateState (- rowNum 1) (- 
> numberOfButtons 1) currentPlayer)
>                                      (switchPlayer)
>                                      )
>                                    (lambda (button) (updateButton button 
> (- rowNum 1) (- numberOfButtons 1) )) ; updateFunc
>                                    rowNum numberOfButtons)
>                                   
>                                   )
>                                 (createButRow rowContainer rowNum (- 
> numberOfButtons 1)))
>                          )))
>
>
> (define createButtonRows (lambda (vContainer rowCount colCount)
>                            ; create a rowCount rows of buttons
>                            (cond
>                              ((equal? rowCount 0) )
>                              (else  
>                               (createButRow 
>                                (new horizontal-panel% [parent vContainer]
>                                     [alignment '(center center)])  
> rowCount colCount)
>                               (createButtonRows vContainer (- rowCount 1) 
> colCount) 
>                               )
>                              )
>                            )
>   )
> (define createBoard (lambda (container rowCount colCount) 
>                       (createButtonRows 
>                        (new vertical-panel% [parent container]
>                             [alignment '(center center)])
>                        rowCount colCount)
>                       )
>   )
>
> ; add a message box at the bottom: this will be updated by do show whose 
> turn it is
> (define addMessageArea (lambda (container)
>                          (let  ((messageBox (new message% [label ""] 
> [parent container] [ auto-resize #t])))
>                            (addUpdator (lambda ()
>                                          (let ((w (winner)))
>                                            (cond
>                                              ((equal? w 0) (send 
> messageBox set-label (format "Player ~a to play" currentPlayer)))
>                                              (#t (send messageBox 
> set-label (format "Winner is ~a" w)))
>                                              )
>                                            ))
>                                        ))))
>
>
> ;---------------------------------------------------------------------
> ; update a button - change label and disable
>
> (define updateButton (lambda (but rowNum colNum)
>                        (let* ((val (vector-ref (vector-ref board  rowNum) 
> colNum))
>                               (str (cond
>                                      ((= val 1) "X")
>                                      ((= val 2) "O")
>                                      (#t "")
>                                      )))
>                          (send but set-label str)
>                          (cond ((> val 0) (send but enable #f))) ; disable 
> if already played in that cell
>                          )
>                        )
>   )
>
> ; list of functions to update display
> (define updators (list))
> ; run all update functions
> (define update (lambda ()
>                  (for-each (lambda (func) (func))  updators)
>                  ))
> (define addUpdator (lambda (fun)
>                      (set! updators (cons fun updators))))
> ;---------------------------------------------------------------------
> ; initialisation - create the view
> (define myFrame (new frame%
>                      [label "O and X game"]
>                      [width 200] [height 200]))
> (createBoard myFrame rows cols)
> (addMessageArea myFrame)
> (send myFrame show #t)
> (update)
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to