; Take the stick!
;
; by Alexander Griesser <tuxx@aon.at>
; Christoph Pittracher <pitt@gmx.at>
; Manfred Steinkellner <manfred.steinkellner@gmx.net>
;
; <http://www.tuxx-home.at/lisp/>
; Read a number from stdin and check, if it is in a valid
; range (1 2 3), (1 2) or even just (1) (depends on n_sticks)
(defun input(n_sticks)
; Determine the number of items for the valid_input list
(setq n_vi (if (>= (- 3 n_sticks) 0) (- 3 n_sticks) 0))
; If necessary, remove some possibilities from this list
(setq valid_input (nthcdr n_vi '(3 2 1)))
; Prompt the user for an input, as long as he enters
; invalid values
(format t "You take? ~A " valid_input)
(do ((inp (read) (read)))
; check if the user-input is a member of our valid-input list
((member inp valid_input) (return inp))
(format t "invalid input, you take? ~A " valid_input)
)
)
(defun splash_screen()
(format t " _______~
~% / take /~
~%/ stick/~%")
)
(defun getRandom(range)
(return-from getRandom (+ (mod (- (random (get-universal-time)) (+ (random (round (/ (get-universal-time) (get-internal-run-time)))) (random (get-internal-real-time)))) (+ (random range) 1)) 1))
)
; The CPU's brain ;)
; (this function returns the remaining no. of sticks)
(defun cpu_take_sticks(n_sticks)
; Determine the number of items for the valid_input list
(setq n_vi (if (>= (- 3 n_sticks) 0) (- 3 n_sticks) 0))
; If necessary, remove some possibilities from this list
(setq valid_input (nthcdr n_vi '(3 2 1)))
; replace random movement through state of the art intelligence :)
; random movement
; (setq tmp (+ (mod (random 10000) (+ (random (list-length valid_input)) 1)) 1))
(setq keyValues '(1 5 9 13 17 21))
; if the current number of elements left is one of the key values the computer
; should take only one element, thus the chance is highest to get on one of
; the key elements in the next move
(setq tmp 0)
(if (member n_sticks keyValues) (setq tmp (getRandom (list-length valid_input))))
; check the cases between one and three sticks distance from a
(if (equal tmp 0)
(setq tmp (loop as i from 1 to 3
do (if (member (- n_sticks i) keyValues) (return i)))
))
(loop as i from 1 to 10
do (format t ".")
(sleep 0.1))
; formatted output text
(format t "CPU takes ~D stick~:P~%" tmp)
(return-from cpu_take_sticks (- n_sticks tmp))
)
; The player's interface
; (this function returns the remaining no. of sticks)
(defun p1_take_sticks(n_sticks)
(setq tmp (input n_sticks))
(format t "Player takes ~R stick~:P~%" tmp)
(return-from p1_take_sticks (- n_sticks tmp))
)
; Display some information about this programm
(splash_screen)
; determine the winner
(setq winner (do ((n_sticks 23) (run 1 (+ run 1)))
((<= n_sticks 0) (return (mod run 2)))
(setq n_sticks (if (eql (mod run 2) 0) (cpu_take_sticks n_sticks) (p1_take_sticks n_sticks)))
(format t "~R stick~:P left~%~%" n_sticks)
))
; print the name of the winner (computer/player) dep. on "winner"
(format t "~[Computer~;Player~] has won!~%" winner)
syntax highlighted by Code2HTML, v. 0.9