I am a bit frustrated and in need of some help. I am writing a turn based matching card flip game (Memory) with a multiplayer component and I am having a hard time knowing where to start for the server. The player code is as follows: (require 2htdp/image) (require 2htdp/universe)
;; Constants (define ESCN-LEN 600) (define ESCN-HEIGHT 400) (define ESCN-COLOR 'darkgreen) (define CARD-LEN 20) (define CARD-HEIGHT 40) (define CARD-COLOR 'black) (define TEXT-SIZE 36) (define TEXT-COLOR 'white) (define NON-TURN 'non-turn) (define PLAYER 1)
(define ESCN-BCKGRND (rectangle ESCN-LEN ESCN-HEIGHT 'solid ESCN-COLOR)) (define FLIP-INSTR (text "Press a corresponding number key to flip a card (i.e. 0 to flip the first card)." 16 'white)) (define TURN-INSTR (text "Press space to advance the turn to the next player." 16 'white)) (define ESCN2 (place-image FLIP-INSTR (/ ESCN-LEN 2) (* 0.8 ESCN-HEIGHT) ESCN-BCKGRND)) (define ESCN1 (place-image TURN-INSTR (/ ESCN-LEN 2) (* 0.86 ESCN-HEIGHT) ESCN2))
;; A card is a strucutre: ;; (make-card flipped? matched? color num) (define-struct card (flipped? matched? color num))
;; Sample cards (define CARD0 (make-card #f #f 'green 0)) (define CARD1 (make-card #f #f 'blue 0))
;; loc is a list of cards ;; Sample instances of list of cards (define INIT-LOC (list (make-card #f #f 'red 0) (make-card #f #f 'yellow 1) (make-card #f #f 'blue 2) (make-card #f #f 'yellow 3) (make-card #f #f 'pink 4) (make-card #f #f 'green 5) (make-card #f #f 'pink 6) (make-card #f #f 'red 7) (make-card #f #f 'blue 8) (make-card #f #f 'green 9))) (define INIT-LOC1 (list (make-card #t #t 'green 0) (make-card #t #t 'green 1) (make-card #f #t 'red 2) (make-card #f #t 'red 3) (make-card #f #t 'blue 4) (make-card #f #t 'blue 5) (make-card #f #t 'yellow 6) (make-card #f #t 'yellow 7) (make-card #f #t 'pink 8) (make-card #f #t 'pink 9)))
#| Template for functions on a card ;; card ... -> ... ;; Purpose: (define f-on-card a-card ...) ...)
;; Sample expressions for f-on-card
;; Tests using sample computations for f-on-card
;; Tests using sample values for f-on-card |#
;; A world is a structure, (make-world loc p-turn) ;; where loc is a list of cards, and p-turn is the current player turn (define-struct world (cards p-turn))
;; Sample worlds (define INIT-WORLD (make-world INIT-LOC 1)) ; p-turn starts at 1 so that player 1 can start the game (define INIT-WORLD1 (make-world INIT-LOC1 1))
;; world -> scene ;; to draw the given world in the empty-scene. (define (draw-world a-world) (local [;; card -> img ;; Purpose: to take a given card and draw it on the screen, face up if its flipped, and face down if not. (define (mk-card-img a-card) (if (not (card-flipped? a-card)) (overlay (text (number->string (card-num a-card)) TEXT-SIZE TEXT-COLOR) (rectangle CARD-LEN CARD-HEIGHT 'solid CARD-COLOR)) (rectangle CARD-LEN CARD-HEIGHT 'solid (card-color a-card))))
;; Sample expressions for mk-card-img
(define CARD-IMG-0 (mk-card-img (list-ref (world-cards a-world) 0)))
(define CARD-IMG-1 (mk-card-img (list-ref (world-cards a-world) 1)))
(define CARD-IMG-2 (mk-card-img (list-ref (world-cards a-world) 2)))
(define CARD-IMG-3 (mk-card-img (list-ref (world-cards a-world) 3)))
(define CARD-IMG-4 (mk-card-img (list-ref (world-cards a-world) 4)))
(define CARD-IMG-5 (mk-card-img (list-ref (world-cards a-world) 5)))
(define CARD-IMG-6 (mk-card-img (list-ref (world-cards a-world) 6)))
(define CARD-IMG-7 (mk-card-img (list-ref (world-cards a-world) 7)))
(define CARD-IMG-8 (mk-card-img (list-ref (world-cards a-world) 8)))
(define CARD-IMG-9 (mk-card-img (list-ref (world-cards a-world) 9)))
(define ESCN (overlay
(above (beside CARD-IMG-0 CARD-IMG-1 CARD-IMG-2 CARD-IMG-3 CARD-IMG-4)
(beside CARD-IMG-5 CARD-IMG-6 CARD-IMG-7 CARD-IMG-8 CARD-IMG-9)) ESCN1))
(define P-TURN-TEXT (text (string-append "current turn: player " (number->string (world-p-turn a-world))) 24 'white))
;; a-world -> scene
;; Purpose: to draw the given world in the empty scene.
(define (draw-world a-world)
(place-image P-TURN-TEXT
(/ ESCN-LEN 2)
(* 0.3 ESCN-HEIGHT)
ESCN))]
(draw-world a-world)))
; computer player, randomly pick 0 through 9. ; implement tests.
;; Key processing functions
;; world a-key -> world ;; Purpose: process a key event to return next world (define (process-key a-world a-key) (local [;; a-loc -> num ;; Purpose: to count the number of flipped cards in a-loc, excluding matched cards. (define (numof-cards-flipped a-loc) (if (empty? a-loc) 0 (if (and (card-flipped? (first a-loc)) (not (card-matched? (first a-loc)))) (+ 1 (numof-cards-flipped (rest a-loc))) (numof-cards-flipped (rest a-loc)))))
;; a-loc -> boolean
;; Purpose: to check if two cards are flipped in a-loc.
(define (two-cards-flipped? a-loc)
(= (numof-cards-flipped a-loc) 2))
;; a-card a-loc -> boolean
;; Purpose: to determine whether two cards are matched or not.
(define (has-match? a-card a-loc)
(ormap (λ (a-card1)
(and (not (= (card-num a-card) (card-num a-card1)))
(card-flipped? a-card)
(card-flipped? a-card1)
(equal? (card-color a-card)
(card-color a-card1))))
a-loc))
;; a-card a-loc key-num down? -> a-card
;; Purpose: to update the flipped? and matched? values of a-card in a-loc, depending on whether we are flipping down or up.
(define (update-flipped-card a-card a-loc key-num down?)
(cond [down? ; flipping cards down
(if (has-match? a-card a-loc)
(make-card #t #t (card-color a-card) (card-num a-card))
(make-card #f #f (card-color a-card) (card-num a-card)))]
[else ; flipping a card up
(if (= (card-num a-card) key-num)
(make-card #t #f (card-color a-card) (card-num a-card))
a-card)]))
;; a-loc key-num -> a-loc
;; Purpose: to flip a specific card in a-loc up.
(define (flip-card-up a-loc key-num)
(map (lambda (a-card) (update-flipped-card a-card a-loc key-num #f)) a-loc))
;; a-loc key-num -> a-loc
;; Purpose: to determine whether or not a card can be flipped, and flip it if so.
(define (flip-card a-loc key-num)
(if (two-cards-flipped? a-loc)
a-loc
(if (card-flipped? (list-ref a-loc key-num))
a-loc
(if (empty? a-loc)
'()
(flip-card-up a-loc key-num)))))
;; a-world -> boolean
;; Purpose: to determine whether it is the players turn or not.
(define (is-player-turn? a-world)
(= (world-p-turn a-world) PLAYER))
;; p-turn (num) -> p-turn (num)
;; Purpose: to cycle through the p-turns, 0 through 2.
(define (increment-p-turn p-turn) ; ONLY INCREMENT IF THE TWO CARDS THE THE PLAYER FLIPPED ARE NOT MATCHED. ----------
(if (= p-turn 2)
0
(add1 p-turn)))
;; a-loc -> a-loc
;; Purpose: to flip a-loc down.
(define (flip-cards-down a-loc)
(map (lambda (a-card) (update-flipped-card a-card a-loc 0 #t)) a-loc))
;; a-world -> a-world
;; Purpose: to advance the turn of one player to the next, flipping down the necessary cards, and incrementing the player turn.
(define (advance-turn a-world)
(make-world (flip-cards-down (world-cards a-world)) (increment-p-turn (world-p-turn a-world))))
;; world key -> world
;; Purpose: to process a key event to return a world
(define (process-key a-world a-key)
(cond [(key=? a-key "0")
(make-world (flip-card (world-cards a-world) 0) (world-p-turn a-world))]
[(key=? a-key "1")
(make-world (flip-card (world-cards a-world) 1) (world-p-turn a-world))]
[(key=? a-key "2")
(make-world (flip-card (world-cards a-world) 2) (world-p-turn a-world))]
[(key=? a-key "3")
(make-world (flip-card (world-cards a-world) 3) (world-p-turn a-world))]
[(key=? a-key "4")
(make-world (flip-card (world-cards a-world) 4) (world-p-turn a-world))]
[(key=? a-key "5")
(make-world (flip-card (world-cards a-world) 5) (world-p-turn a-world))]
[(key=? a-key "6")
(make-world (flip-card (world-cards a-world) 6) (world-p-turn a-world))]
[(key=? a-key "7")
(make-world (flip-card (world-cards a-world) 7) (world-p-turn a-world))]
[(key=? a-key "8")
(make-world (flip-card (world-cards a-world) 8) (world-p-turn a-world))]
[(key=? a-key "9")
(make-world (flip-card (world-cards a-world) 9) (world-p-turn a-world))]
[(key=? a-key " ")
(advance-turn a-world)]
[else a-world]))]
(if (is-player-turn? a-world)
(process-key a-world a-key)
a-world)))
;; world -> boolean ;; Purpose: to determine if the game is over or not. (define (game-over? a-world) (andmap (lambda (a-card) (card-flipped? a-card)) (world-cards a-world)))
(define (draw-final-world a-world) (place-image (text "Game Over D:" 80 'black) (/ ESCN-LEN 2) (/ ESCN-HEIGHT 2) (draw-world a-world)))
;; name -> world (define (run a-name) (big-bang INIT-WORLD (on-draw draw-world) (on-key process-key) (stop-when game-over? draw-final-world) ;(on-receive process-message) ;(register LOCALHOST) (name a-name)))
And the server code is: ;; Any -> universe ;; Purpose: Run the universe server (define (run-server a-z) (universe INIT-UNIV (on-new add-new-iworld) (on-msg process-message) (on-disconnect rm-iworld)))
Please let me know what I could/should do to get this working, I am not very good at the language. Anything helps.
I tried using Chatgpt to outline what I need for the server, but it went on and on with meaningless extra information which is not available in the Racket handbook nor our textboo. I could just really use some help.