Update api

This commit is contained in:
Loic Guegan 2019-05-09 18:38:31 +02:00
parent f0ccb136eb
commit d261883d41
6 changed files with 91 additions and 11 deletions

View file

@ -22,8 +22,8 @@
"syn": 1,
"game-id": 1,
"game-over": false,
"snake": [(1,2),(1,3)],
"food": [(6,7)]
"snake": [[1,2],[1,3]],
"food": [[6,7]]
}
#+END_SRC
Note that, syn entry is used to keep packet ordering consistent and detecting packet inversion on the network. Thus,
@ -46,8 +46,8 @@
"syn": 2,
"game-id": 1,
"game-over": false,
"snake": [(0,2),(1,2)],
"food": [(6,7)]
"snake": [[0,2],[1,2]],
"food": [[6,7]]
}
#+END_SRC
*** Refresh Screen
@ -67,8 +67,8 @@
"syn": 3,
"game-id": 1,
"game-over": false,
"snake": [(1,2),(0,2)],
"food": [(6,7)]
"snake": [[1,2],[0,2]],
"food": [[6,7]]
}
#+END_SRC
*** End Game
@ -79,8 +79,8 @@
"syn": null,
"game-id": 1,
"game-over": true,
"snake": [(0,2),(1,2)],
"food": [(6,7)]
"snake": [[0,2],[1,2]],
"food": [[6,7]]
}
#+END_SRC
- No reply is expected from the client and server will be in charge to free local memory. Note that syn=null.

Binary file not shown.

View file

@ -4,6 +4,68 @@
(defclass api ()
((gm
:initform (make-instance 'game-manager))))
:initform (make-instance 'game-manager))
(games-syn
:initform '())))
(defmethod create-syn ((api api) game-id &optional (initial-value 0))
(unless (eq nil (get-syn api game-id)) (error "This game ~a already have a syn !" game-id))
(with-slots (games-syn) api
(push (list :game-id game-id :syn initial-value) games-syn)
initial-value))
(defmethod refresh-syn ((api api) game-id)
(with-slots (games-syn) api
(incf (getf (first (remove-if-not #'(lambda (entry) (eql game-id (getf entry :game-id))) games-syn)) :syn))))
(defmethod get-syn ((api api) game-id)
(with-slots (games-syn) api
(getf (first (remove-if-not #'(lambda (entry) (eql game-id (getf entry :game-id))) games-syn)) :syn)))
;;; TODO: Handle errors (valid json etc..)
(defun parse-request (request)
(flet ((normalizer (key)
(string-upcase key)))
(let ((p-request (parse request :normalize-all t :keyword-normalizer #'normalizer )))
p-request)))
(defmethod handle-new-game ((api api) data)
(with-slots (gm) api
(let* ((game-id (create-game gm))
(game-syn (create-syn api game-id 1))) ; Create syn with 1 (since first packet already receive)
(let ((game-dump (dump gm game-id)))
(setf (getf game-dump :game-over) :null) ; Define nil as null (for json)
(to-json
(append (list :type "state" :syn game-syn) game-dump))))))
;;; TODO: RETURN JSON !!!!
(defmethod handle-update ((api api) data)
(with-slots (gm) api
(let* ((dir (getf data :direction))
(game-id (getf data :game-id))
(game (get-game gm game-id)))
(cond
((equal dir "up") (setf dir :up))
((equal dir "down") (setf dir :down))
((equal dir "left") (setf dir :left))
((equal dir "right") (setf dir :right))
(t (setf dir nil)))
(if dir
(refresh game :dir dir)
(refresh game)))))
(defmethod handle-request ((api api) request)
(let* ((data (parse-request request))
(type (getf data :type)))
(cond
((equal type "new-game") (handle-new-game api data))
((equal type "update") (handle-update api data))
(t (format t "Unknow type")))))

View file

@ -24,6 +24,14 @@
(with-slots (games) gm
(setf games (remove-if #'(lambda (entry) (eql game-id (getf entry :id))) games))))
(defgeneric dump (g game-id)
(:documentation "Dump a game in the Game manager. Return a plist."))
(defmethod dump ((g game-manager) game-id)
(with-slots (games) g
(append (list :id game-id) (remote-snake-server-game:dump (get-game g game-id)))))
(defmethod get-game ((gm game-manager) game-id)
(with-slots (games) gm
(let ((game (remove-if-not #'(lambda (entry) (eql game-id (getf entry :id))) games)))

View file

@ -39,6 +39,13 @@
(format t "~%Direction: ~a" dir)
(format t "~%Food: ~a" food)))
(defgeneric dump (g)
(:documentation "Dump a game. Return a plist."))
(defmethod dump ((g game))
(with-slots (snake food game-over) g
(list :snake snake :food food :game-over game-over)))
;;; Note that there is no waranty that nb food are added (ex: if food position collide with snake position)
(defgeneric add-food (g nb)
(:documentation "Add food on the game grid."))

View file

@ -2,10 +2,13 @@
(:nicknames :rsg)
(:use :common-lisp)
(:export
#:game))
#:game
#:dump
#:refresh))
(defpackage :remote-snake-server-api
(:nicknames :rsapi)
(:use :common-lisp :jonathan)
(:use :common-lisp :jonathan :remote-snake-server-game)
(:shadow #:dump) ; Because game-manager also has a dump method
(:export
#:api))