Vivien Chow
Thu Tran
December 7, 2014


Our project is a re-creation of our favorite childhood games" Tic-Tac-Toe and a math game call Operations. To play Tic-Tac-Toe, players switch turns choosing a position from 0 to 8 on the game board to place either the letter x or o, this process repeats until a player wins or both players tie. Operations is a math game where the player choose the appropriate math operation for the math equation.


(You may attach a PNG, GIF, or JPG file. Please note theAttach: Attach: syntax for doing this. After you save the wiki page, you will see the Attach: link with a blue triangle. Click on the link, and then you will be brought to a page where you can upload the attachment. After you upload the attachment, the link goes away and you see the image instead.)

Concepts Demonstrated

  • Data abstraction is used represent the grid lines of the tic-tac-toe game board. The concept is pair abstraction using constructors make-point and make-segment, with accessor like get-x and get-y. Another is the possible winning paths is represented as a tree structure. Data abstraction is used in order to record the current question number, the question set and the answer to each question in “Operations”. All of these are defined at the beginning of the game, and was accessed in different functions. For example, ret-quest is a function that returns the question by matching the current question number (which is a global variable) to the set of questions, so that it will return associated question when the current question number was being incremented.
  • Higher order procedure is used for printing appropriate messages if the user got the correct or incorrect answer and to display questions.
  • Global variables such as a list representing the tic-tac-toe game board and a list of the winning path are used and will be accessed, examined, and modified by procedure in the program. Global variables is in Operations used as quest_num, which is the current question number that the user’s at; the pre-set questions and the answers to each question.
  • Recursion is used to populate the tic-tac-toe game-board after each move, and to evaluate of if the move is a legal move on the game board(for example, prevent selecting the same position or to prevent entries other than number keys 0 to 8).
  • Lambdas were used to construct procedures such as a procedure to evaluate if there is a winning path on the current game board.
  • Conditional Expressions and predicates were used often in our project. Predicates to see if it is a new-game?, or evaluate if a key-press is a legal-move? and many more. Conditionals are used in Operations to return the question as a string, which also serves as the get function, and for checking a correct or incorrect answer. Also, it is used to handle different click events on the buttons.

External Technology and Libraries

We've used two external libraries, which is the GUI library (racket/gui) and the draw (racket/draw) library. The GUI library was used for implementing windows (frames), buttons, canvas and messages for both games. And the draw library was used for drawing the game board in tic-tac-toe.

Favorite Lines of Code

  • Thu:
       (for-each (lambda (win-path)
            (let ((n0 (first win-path))
                  (n1 (second win-path))
                  (n2 (third win-path))
                  (sum (+ (char->integer (list-ref game-board (first win-path))) 
                          (char->integer (list-ref game-board (second win-path)))
                          (char->integer (list-ref game-board (third win-path))))))
                (display count-vect-spaces)
                (vector-set! list-sum count-vect-spaces sum )
                (when (or (= sum 333) (= sum 360)) 
                  (set! win-path-to-draw (cons n0 (cons n1 (cons n2 '())))) 
                  (set! winning-pos count-vect-spaces)
                  (if (= sum 333)
                      (set! winner "o")
                      (set! winner "x")))
                (set! count-vect-spaces (+ count-vect-spaces 1)))                           

This code reads in a list of three integers at a time from a list of all possible winning paths, then use those three integers as an index to reference the elements of the current game board and sets the winning path and winner if there is one.

  • Vivien:
     (define (button-check c e)
        (send frame-operations show #f)
        (cond ((eq? c add-button) (begin (if (zero? (check-ans quest_num 1))
              ((eq? c sub-button) (begin (if (zero? (check-ans quest_num 2)) 
              ((eq? c mul-button) (begin (if (zero? (check-ans quest_num 3)) 
              ((eq? c div-button) (begin (if (zero? (check-ans quest_num 4)) 
    ;functions for sending frames
    (define (ans-correct)
      (send frame-ops-correct center 'both) 
      (send frame-ops-correct show #t))
    (define (ans-wrong)
      (send frame-ops-wrong center 'both) 
      (send frame-ops-wrong show #t))

This block of code is used for the click event for the addition button in "Operations" specifically. If the addition button was clicked, it checks whether the answer is correct or not by calling check-ans, which is a function that compares the input with the set of answer. Then, it will view another frame to show whether user got the correct/incorrect answer.

Technology Used Block Diagram