about summary refs log tree commit diff stats
path: root/game.scm
diff options
context:
space:
mode:
Diffstat (limited to 'game.scm')
-rwxr-xr-xgame.scm177
1 files changed, 177 insertions, 0 deletions
diff --git a/game.scm b/game.scm new file mode 100755 index 0000000..a799ba7 --- /dev/null +++ b/game.scm
@@ -0,0 +1,177 @@
1#!/bin/sh
2#| -*- scheme -*-
3exec csi -R r7rs -ss "$0" "$@"
4|#
5#+chicken (import r7rs)
6
7(import (scheme base)
8 (scheme write)
9 (chicken io)
10 (chicken port)
11 (srfi 133)
12 (yolk common)
13 (yolk xterm)
14 (yolk erase)
15 (yolk cursor)
16 (matchable)
17 (stty))
18
19(define (draw . instructions)
20 (for-each (lambda (i)
21 (cond
22 ((string? i)
23 (display i))
24 ((list? i)
25 (apply draw i))))
26 instructions))
27
28(define me
29 (string-append "@" (cursor-left 1)))
30
31(define rock
32 (string-append "o" (cursor-left 1)))
33
34(define blank
35 (string-append " " (cursor-left 1)))
36
37(define WIDTH
38 (make-parameter 80))
39
40(define HEIGHT
41 (make-parameter 24))
42
43(define WORLD
44 (make-vector (* (WIDTH) (HEIGHT)) 0))
45
46(define (get-position x y)
47 (if (or (> x (WIDTH))
48 (< x 0)
49 (> y (HEIGHT))
50 (< y 0))
51 #f
52 (vector-ref WORLD (+ y (* (WIDTH) x)))))
53
54(define (set-position! x y thing)
55 (if (or (> x (WIDTH))
56 (< x 0)
57 (> y (HEIGHT))
58 (< y 0))
59 (error "Out of bounds" (list (WIDTH) (HEIGHT)) (list x y))
60 (vector-set! WORLD (+ y (* (WIDTH) x)) thing)))
61
62(define X
63 (make-parameter (/ (WIDTH) 2)))
64
65(define Y
66 (make-parameter (/ (HEIGHT) 2)))
67
68(define (move-up)
69 (unless (<= (Y) 2)
70 (draw blank (cursor-up 1) me)
71 (Y (- (Y) 1))))
72
73(define (move-left)
74 (unless (<= (X) 2)
75 (draw blank (cursor-left 1) me)
76 (X (- (X) 1))))
77
78(define (move-right)
79 (unless (>= (X) (- (WIDTH) 1))
80 (draw blank (cursor-right 1) me)
81 (X (+ (X) 1))))
82
83(define (move-down)
84 (unless (>= (Y) (- (HEIGHT) 1))
85 (draw blank (cursor-down 1) me)
86 (Y (+ (Y) 1))))
87
88(define (game-setup)
89 (stty '(raw (not echo)))
90 (set-buffering-mode! (current-input-port) #:none 1)
91 (set-buffering-mode! (current-output-port) #:none 1)
92 ;; Set up screen
93 (draw alt-buffer-enable
94 erase-screen
95 (cursor-save)
96 invisible-cursor)
97
98 ;; Draw borders
99 (draw cursor-home
100 "/"
101 (list->string
102 (let loop ((c 1)
103 (acc '()))
104 (if (>= c (- (WIDTH) 1))
105 acc
106 (loop (+ 1 c)
107 (cons #\- acc)))))
108 "\\"
109 (let loop ((r 2)
110 (acc '()))
111 (if (>= r (HEIGHT))
112 acc
113 (loop (+ 1 r)
114 (append `(,(cursor-move 0 r)
115 "|"
116 ,(cursor-move (WIDTH) r)
117 "|")
118 acc))))
119 (cursor-move 1 (HEIGHT))
120 "\\"
121 (list->string
122 (let loop ((c 1)
123 (acc '()))
124 (if (>= c (- (WIDTH) 1))
125 acc
126 (loop (+ 1 c)
127 (cons #\- acc)))))
128 "/")
129
130 ;; Draw character
131 (draw (cursor-move (X) (Y))
132 me))
133
134(define (game-cleanup)
135 (stty '(cooked echo))
136 (draw cursor-home
137 (cursor-restore)
138 alt-buffer-disable
139 visible-cursor))
140
141(define (readch)
142 (integer->char (read-byte)))
143
144(define (car* x)
145 (and (pair? x)
146 (car x)))
147
148(define (game-loop)
149 (let loop ((c (readch)))
150 (if (eq? c 'done)
151 #t
152 (let ((done? #f))
153 (match c
154 ((or #\q #\) (set! done? #t))
155 (#\h (move-left))
156 (#\j (move-down))
157 (#\k (move-up))
158 (#\l (move-right))
159 ;; Escape characters
160 (#\escape
161 (match (readch)
162 (#\[ (match (readch)
163 (#\A (move-up))
164 (#\B (move-down))
165 (#\C (move-right))
166 (#\D (move-left))
167 (else)))
168 (else)))
169 (else))
170 (loop (if done? 'done (readch)))))))
171
172(define (main args)
173 (dynamic-wind
174 game-setup
175 game-loop
176 game-cleanup)
177 #t)