generated from phel-lang/phel-scaffolding
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgame.phel
79 lines (65 loc) · 2.64 KB
/
game.phel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#########################################################################################
# This is a full version of the snake-cli-game, with the following elements:
# - A board
# - A snake with constant speed inside the board
# - The game ends when the snake touches the board
#########################################################################################
# Try it out: vendor/bin/phel run src/simple-version/game.phel
#########################################################################################
(ns phel-snake\simple-version\game
(:require phel-cli-gui\terminal-gui :as gui))
(gui/add-output-formatter {:style-name "snake-head"
:foreground "black" :background "red" :options ["bold"]})
(gui/add-output-formatter {:style-name "snake-tail"
:foreground "black" :background "green" :options ["bold"]})
(defstruct board-struct [width height])
(defstruct snake-struct [direction speed head tail])
(def board (board-struct 40 20))
# Hexadecimal keys
(def directions
{"1b5b44" :left
"1b5b42" :down
"1b5b43" :right
"1b5b41" :up})
(defn move-snake [s next-direction]
(if (nil? next-direction)
(recur s (s :direction))
(let [s2 (case next-direction
:left (update-in s [:head :x] dec)
:right (update-in s [:head :x] inc)
:up (update-in s [:head :y] dec)
:down (update-in s [:head :y] inc))
new-tail (push (drop 1 (s2 :tail)) (s :head))
s3 (put s2 :tail new-tail)]
(put s3 :direction next-direction))))
(defn collision-with-board? [snake]
(or
(>= 1 (get-in snake [:head :x]))
(>= 0 (get-in snake [:head :y]))
(= (board :width) (get-in snake [:head :x]))
(= (dec (board :height)) (get-in snake [:head :y]))))
(defn render-snake [snake]
(for [t :in (snake :tail)]
(gui/render (t :x) (t :y) " " "snake-tail"))
(let [h (snake :head)]
(gui/render (h :x) (h :y) " " "snake-head")))
(defn game-over [snake]
(render-snake snake)
(println "GAME OVER")
(php/exit))
(defn render-board []
(gui/clear-screen)
(gui/render-board board {:horizontal "-" :vertical "|" :corner "+"}))
(def initial-snake (snake-struct :right 1 {:x 5 :y 5} [{:x 4 :y 5} {:x 3 :y 5}]))
(defn simple-game []
(loop [snake initial-snake]
(render-board)
(println "Move your snake with the arrow-keys [UP, DOWN, LEFT, RIGHT]")
(if (collision-with-board? snake)
(game-over snake))
(let [{:hex in} (gui/read-input 3)
next-direction (directions in)
new-snake (move-snake snake next-direction)]
(render-snake new-snake)
(php/usleep 50000)
(recur new-snake))))