(defstruct starship
  name
  energy
  torpedoes)

(defstruct klingon-ship
  name
  energy)

(defun initialize-starship (starship)
  (setf (starship-energy starship) 100000
        (starship-torpedoes starship) 100))

(defun initialize-klingon-ships (klingon-ships)
  (loop for i from 0 below (length klingon-ships)
        do (setf (klingon-ship-name (aref klingon-ships i)) (format nil "Klingon Ship ~D" (+ i 1))
                 (klingon-ship-energy (aref klingon-ships i)) (+ (random 201) 800))))

(defun print-ship-status (starship)
  (format t "*********************~%")
  (format t "~A status:~%" (starship-name starship))
  (format t "Energy: ~D~%" (starship-energy starship))
  (format t "Torpedoes: ~D~%" (starship-torpedoes starship))
  (format t "---------------------~%"))

(defun main ()
  (let ((player (make-starship :name "" :energy 0 :torpedoes 0))
        (klingon-ships (make-array 3 :element-type 'klingon-ship)))
    (initialize-starship player)
    (initialize-klingon-ships klingon-ships)
    (format t "Welcome to the Star Trek game!~%")
    (format t "You are the captain of the USS Enterprise.~%")
    (format t "Your mission is to destroy all Klingon ships.~%")

    (loop while (> (length klingon-ships) 0)
          do (progn
               (print-ship-status player)
               (format t "Enter your choice (1. Fire phasers, 2. Fire photon torpedoes): ")
               (let ((choice (parse-integer (read-line))))
                 (cond
                   ((= choice 1)
                    (let* ((energy-loss (+ (random 201) 100))
                           (hit-chance (/ (random) (float (random-most-positive-fixnum)))))
                      (if (< hit-chance 0.8)
                          (progn
                            (format t "Phasers fired successfully!~%")
                            (format t "~A lost ~D energy.~%" (starship-name player) energy-loss)
                            (decf (starship-energy player) energy-loss))
                          (format t "Phasers missed!~%"))))
                   ((= choice 2)
                    (if (> (starship-torpedoes player) 0)
                        (progn
                          (let* ((torpedo-damage (+ (random 301) 200))
                                 (target-index (random (length klingon-ships)))
                                 (target-ship (aref klingon-ships target-index)))
                            (format t "Photon torpedo fired at ~A!~%" (klingon-ship-name target-ship))
                            (format t "~A lost ~D energy.~%" (klingon-ship-name target-ship) torpedo-damage)
                            (decf (klingon-ship-energy target-ship) torpedo-damage)
                            (decf (starship-torpedoes player)))
                          (format t "No photon torpedoes remaining!~%")))
                   (t (format t "Invalid choice. Please try again.~%"))))

               (setf klingon-ships (remove-if (lambda (klingon-ship) (<= (klingon-ship-energy klingon-ship) 0))
                                              klingon-ships))

               (loop for klingon-ship in klingon-ships
                     do (let ((player-damage (+ (random 301) 100)))
                          (format t "~A attacks ~A!~%" (klingon-ship-name klingon-ship) (starship-name player))
                          (format t "~A lost ~D energy.~%" (starship-name player) player-damage)
                          (decf (starship-energy player) player-damage))))

          (when (<= (starship-energy player) 0)
            (format t "Your starship has been destroyed. Game over!~%")
            (return-from main)))
    (format t "Congratulations! You have destroyed all Klingon ships. You win!~%")))

(main)
 

Common Lisp online compiler

Write, Run & Share Common Lisp code online using OneCompiler's Common Lisp online compiler for free. It's one of the robust, feature-rich online compilers for Common Lisp language, running the latest Common Lisp version 5.3. Getting started with the OneCompiler's Common Lisp editor is easy and fast. The editor shows sample boilerplate code when you choose language as Common Lisp and start coding.

Read inputs from stdin

OneCompiler's Common Lisp online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Common Lisp program which takes name as input and prints hello message with your name.

(setq name (read))
(princ "Hello ")
(write name)

About Common Lisp

Common Lisp is a generic language suitable for a wide range of industry applications. It is often referred as Programmable programming language because of it's high extensibility, machine independence, extensive control structures, dynamic updation of programs etc.

Common LISP was invented by John McCarthy in 1958 and was first implemenyted by Steve Russell on an IBM 704 computer.

Syntax help

Variables

  • Global variables are declared using defvar keyword and these variables will be in effect until a new value is assigned.
  • Type declaration is not required in LISP

Example

(defvar x 10)
(write x)
  • Local variables are declared with in a function or a procedure. The scope of local variables will be only in that function.
  • let and progare used to declare local variables.

Syntax

(let ((var1  value1) (var2  value2).. (varn  valuen))<expressions>)
  • You can also create global and local variables using setq

Example

(setq a 10)

Loops

1. Loop:

This is the simplest looping mechanism in LISP. This allows the execute the set of statements repeatedly until a return statement is encountered.

Syntax

(loop (s-expressions))

2. For:

For loop is used to iterate a set of statements based on a condition.

(loop for loop-variable in <a list>
   do (action)
)

3. Do:

Do is also used to iterate a set of statements and then check the condition

(do ((var1    val1   updated-val1)
      (var2   val2   updated-val2)
      (var3   val3   updated-val3)
   ...)
   (test return-value)
   (s-expressions)
)

4. Dotimes:

Dotimes is used to iterate for fixed number of iterations.

Syntax:

(dotimes (n val)
  statements