diff --git a/biome.lisp b/biome.lisp index 648452e..6be8217 100644 --- a/biome.lisp +++ b/biome.lisp @@ -59,3 +59,14 @@ :name "stream" :char #\~ :init-items NIL ;TODO :update-fn #'update-stream) + +;; Hill biome + +(defun update-hill (patch-pos) + ;;TODO + ) + +(new-biome 'hill + :name "hill" :char #\m + :init-items NIL ;TODO + :update-fn #'update-hill) diff --git a/biome.lisp b/biome.lisp index 648452e..6be8217 100644 --- a/biome.lisp +++ b/biome.lisp @@ -59,3 +59,14 @@ :name "stream" :char #\~ :init-items NIL ;TODO :update-fn #'update-stream) + +;; Hill biome + +(defun update-hill (patch-pos) + ;;TODO + ) + +(new-biome 'hill + :name "hill" :char #\m + :init-items NIL ;TODO + :update-fn #'update-hill) diff --git a/terranostra.lisp b/terranostra.lisp index 1377574..7771626 100644 --- a/terranostra.lisp +++ b/terranostra.lisp @@ -1,19 +1,25 @@ ;#!/usr/bin/clisp ;;;; ;;;; Terra Nostra is a Minecraft-like survival game for the commandline. -;;;; +;;;; +;;;; This file defines patches and administrates the world object. +;;;; ;;;; (c) 2018 Daniel Vedder, MIT license ;;;; -(load "util.lisp") ;; I want to avoid using this if possible +(load "util.lisp") +(load "items.lisp") (load "biome.lisp") +(load "animals.lisp") (defvar *world* NIL) (defconstant *directions* '(N NE E SE S SW W NW)) (defstruct patch (pos '(0 0)) ;position - (biome (make-biome))) + (biome (get-biome 'grassland)) + (items '()) + (animals '())) (defun init-matrix (size) @@ -35,6 +41,12 @@ (let ((pos (position dir *directions*))) (when pos (nth (rem (+ 4 pos) 8) *directions*)))) +(defun next-dir (dir &optional (cw T)) + "Get the neighbouring direction (clockwise or anticlockwise)" + (let ((pos (position dir *directions*)) + (diff (if cw 1 -1))) + (when pos (nth (rem (+ diff pos 8) 8) *directions*)))) + (defun dir2patch (herex herey therex therey) "Calculate the direction to a patch" (cond ((> herex therex) @@ -76,19 +88,38 @@ "Save the world topography as a csv file" (with-open-file (tf file-name :direction :output) (dolist (row world) - ;; XXX This would be quicker with (string-from-list), but I - ;; don't want to use util.lisp just yet + ;; TODO This would be quicker with (string-from-list) (do ((x 0 (1+ x)) (xstr "")) ((= x (length world)) (format tf "~&~A~%" xstr)) - ;;TODO (setf xstr (concatenate 'string xstr (unless (= x 0) ",") (format NIL "~S" (biome-char (patch-biome (nth x row)))))))))) -(defun create-world (size name &optional (world *world*)) +(defun generate-biome-patch (biome-type x y width &optional (world *world*)) + ;;TODO + ) + +(defun generate-stream (x0 y0 &optional (world *world*)) + (do* ((dir (random-elt *directions*) + (if (chancep 60) dir (next-dir dir (random-elt '(T NIL))))) + (patch (coord x0 y0) (neighbour patch dir))) + ((or (null patch) (eq (patch-biome patch) (get-biome 'stream)))) + (setf (patch-biome patch) (get-biome 'stream)))) + +(defun create-world (size name &optional (world *world*) + (biomes '(forest hill)) (size-factor 30)) (setf world NIL) (setf world (init-matrix size)) + ;;XXX magic numbers + (dotimes (s (round (/ (expt size 2) (* size-factor 10)))) + (generate-stream (random size) (random size) world)) + (dotimes (f (round (/ (expt size 2) (expt size-factor 2)))) + (generate-biome-patch 'forest (random size) (random size) + (random size-factor) world)) + (dotimes (h (round (/ (expt size 2) (* 1.5 (expt size-factor 2))))) + (generate-biome-patch 'hill (random size) (random size) + (random (round (/ 2 size-factor))) world)) ;;TODO (save-topography name world)) diff --git a/biome.lisp b/biome.lisp index 648452e..6be8217 100644 --- a/biome.lisp +++ b/biome.lisp @@ -59,3 +59,14 @@ :name "stream" :char #\~ :init-items NIL ;TODO :update-fn #'update-stream) + +;; Hill biome + +(defun update-hill (patch-pos) + ;;TODO + ) + +(new-biome 'hill + :name "hill" :char #\m + :init-items NIL ;TODO + :update-fn #'update-hill) diff --git a/terranostra.lisp b/terranostra.lisp index 1377574..7771626 100644 --- a/terranostra.lisp +++ b/terranostra.lisp @@ -1,19 +1,25 @@ ;#!/usr/bin/clisp ;;;; ;;;; Terra Nostra is a Minecraft-like survival game for the commandline. -;;;; +;;;; +;;;; This file defines patches and administrates the world object. +;;;; ;;;; (c) 2018 Daniel Vedder, MIT license ;;;; -(load "util.lisp") ;; I want to avoid using this if possible +(load "util.lisp") +(load "items.lisp") (load "biome.lisp") +(load "animals.lisp") (defvar *world* NIL) (defconstant *directions* '(N NE E SE S SW W NW)) (defstruct patch (pos '(0 0)) ;position - (biome (make-biome))) + (biome (get-biome 'grassland)) + (items '()) + (animals '())) (defun init-matrix (size) @@ -35,6 +41,12 @@ (let ((pos (position dir *directions*))) (when pos (nth (rem (+ 4 pos) 8) *directions*)))) +(defun next-dir (dir &optional (cw T)) + "Get the neighbouring direction (clockwise or anticlockwise)" + (let ((pos (position dir *directions*)) + (diff (if cw 1 -1))) + (when pos (nth (rem (+ diff pos 8) 8) *directions*)))) + (defun dir2patch (herex herey therex therey) "Calculate the direction to a patch" (cond ((> herex therex) @@ -76,19 +88,38 @@ "Save the world topography as a csv file" (with-open-file (tf file-name :direction :output) (dolist (row world) - ;; XXX This would be quicker with (string-from-list), but I - ;; don't want to use util.lisp just yet + ;; TODO This would be quicker with (string-from-list) (do ((x 0 (1+ x)) (xstr "")) ((= x (length world)) (format tf "~&~A~%" xstr)) - ;;TODO (setf xstr (concatenate 'string xstr (unless (= x 0) ",") (format NIL "~S" (biome-char (patch-biome (nth x row)))))))))) -(defun create-world (size name &optional (world *world*)) +(defun generate-biome-patch (biome-type x y width &optional (world *world*)) + ;;TODO + ) + +(defun generate-stream (x0 y0 &optional (world *world*)) + (do* ((dir (random-elt *directions*) + (if (chancep 60) dir (next-dir dir (random-elt '(T NIL))))) + (patch (coord x0 y0) (neighbour patch dir))) + ((or (null patch) (eq (patch-biome patch) (get-biome 'stream)))) + (setf (patch-biome patch) (get-biome 'stream)))) + +(defun create-world (size name &optional (world *world*) + (biomes '(forest hill)) (size-factor 30)) (setf world NIL) (setf world (init-matrix size)) + ;;XXX magic numbers + (dotimes (s (round (/ (expt size 2) (* size-factor 10)))) + (generate-stream (random size) (random size) world)) + (dotimes (f (round (/ (expt size 2) (expt size-factor 2)))) + (generate-biome-patch 'forest (random size) (random size) + (random size-factor) world)) + (dotimes (h (round (/ (expt size 2) (* 1.5 (expt size-factor 2))))) + (generate-biome-patch 'hill (random size) (random size) + (random (round (/ 2 size-factor))) world)) ;;TODO (save-topography name world)) diff --git a/util.lisp b/util.lisp index f3e68a4..baa2885 100644 --- a/util.lisp +++ b/util.lisp @@ -198,6 +198,10 @@ "Return a random element of this sequence" (elt seq (random (length seq)))) +(defun chancep (percent) + "Do a random test, with the percentage giving the success probability" + (> percent (random 100))) + (defun load-text-file (file-name) "Load a text file into a list of strings (representing the lines)" (with-open-file (f file-name)