First post of the year... Somehow I was too busy for the whole of January to post anything. Anyway, moving on...
I've been yearning to use cl-opengl and Vecto for SOMETHING but can never seem to come up with any ideas. The only useful thing I have used cl-opengl for is a cellular automata simulator, but it's all very basic and minimal. So instead of trying to come up with a new idea, I'm going to re-use an old idea and extend cl-mines; my small, currently CLI-based, Minesweeper game.
I intend to use Vecto to generate each of the images for the mines and uncovered tiles. Not the most intense usage for Vecto, but it's better than nothing for now.
And I, obviously, intend to use cl-opengl for displaying and running the whole game.
Another, secondary, goal is to use more macros, if appropriate. Macros are a feature of Common Lisp I am yet to use in a complex way and is a skill I think I'm missing out on with Lisp.
So that's what I am going to be slowly working on in my spare time between everything else! That should keep me busy for a little while, I hope.
Showing posts with label lisp. Show all posts
Showing posts with label lisp. Show all posts
Tuesday, February 2, 2010
Tuesday, December 8, 2009
Profiling Common Lisp Code
I just finished reading (and applying to my own projects) an article on profiling and optimising Common Lisp code using SBCL's profiler. The article is here. The whole series that the article belongs to is good reading for any novice-to-intermediate Lisp programmer actually, but this one stands out more for me.
Thursday, November 19, 2009
Manually installing ASDF packages for SBCL
When I started getting back into Lisp earlier this year, after a bit of reading I quickly found out that ASDF was the more popular method for installing third-party packages. I also quickly found a problem though: simply typing (asdf-install:install 'package-name) doesn't always work, because some packages, while they have ASDF system files written, are not uploaded to - or are not up to date on - the remote site (cliki.net) and thus fail when you try to install it. So when you're out of options and decide to download or checkout the source for the package, how the hell do you install it?
In your home directory you should have a .sbcl directory. Inside this directory you should have two more directories: site and systems. To manually install a package:
Note: If your SBCL doesn't look in systems for packages, you can check the asdf:*central-registry* variable for the correct directory.
Another note: If you prefer to install packages for the entire system rather than just your specific user, ASDF system symlinks live in /usr/local/lib/sbcl/site-systems (assuming you installed SBCL in /usr/local).
Last note, I promise: The obvious shortcoming of manually installing libraries is it won't automatically retrieve dependencies for you :(
In your home directory you should have a .sbcl directory. Inside this directory you should have two more directories: site and systems. To manually install a package:
- Unzip/untar/checkout the source code into its own directory inside the site directory. For example, on my machine cl-ppcre is unpackaged into .sbcl/site/cl-ppcre-2.0.1/
- Create a symlink from the ASDF system file to the systems directory. For example, .sbcl/site/cl-ppcre-2.0.1/cl-ppcre.asd is symlinked to .sbcl/systems/cl-ppcre.asd
Note: If your SBCL doesn't look in systems for packages, you can check the asdf:*central-registry* variable for the correct directory.
Another note: If you prefer to install packages for the entire system rather than just your specific user, ASDF system symlinks live in /usr/local/lib/sbcl/site-systems (assuming you installed SBCL in /usr/local).
Last note, I promise: The obvious shortcoming of manually installing libraries is it won't automatically retrieve dependencies for you :(
Thursday, September 3, 2009
SBCL and Command-line Common Lisp Apps
Ok, first things first: read Xach's steps to creating small Common Lisp projects. Without it, I was unable to find anything as straight-forward as that to explain a process for creating Lisp projects. There is a lot of very useful stuff in there.
Second thing: I am not a Lisp expert so this may not be The One True Way to do things.
Finished reading? Good. Ok. Xach's article is not aimed at creating utilities to be run from the command line, but in full Lisp environments, like SLIME. Xach's guide gives you all the information you need as far as laying out your Lisp code and setting up ASDF system files are concerned. The last bits and pieces you need are concerned with the shell environment. So, you will need:
The contents of the Makefile for a project named "my-project":
This will compile all of the packages you defined in your ASDF system file into .fasl bytecode files and then save a .core file. Now all you need is a shell script to run the .core:
And that'll do it! This assumes that your code has an exported defun, 'main', as the entry point for your program. Now run the shell script and your application will run.
Edit: Xach mentioned in the comments that you can use the :executable argument to save-lisp-and-die to create an executable, thus removing the need for the wrapper script above.
This is the build process I use for my little cl-mines game, so you can check out the setup there if there is anything that was unclear.
Second thing: I am not a Lisp expert so this may not be The One True Way to do things.
Finished reading? Good. Ok. Xach's article is not aimed at creating utilities to be run from the command line, but in full Lisp environments, like SLIME. Xach's guide gives you all the information you need as far as laying out your Lisp code and setting up ASDF system files are concerned. The last bits and pieces you need are concerned with the shell environment. So, you will need:
- Your code (obviously)
- An ASDF system file (from Xach's article)
- A Makefile to compile your code to .fasl and a .core (for SBCL)
- A shell script to run your .core file
The contents of the Makefile for a project named "my-project":
SBCL = /usr/local/bin/sbcl
all:
$(SBCL) --eval "(require 'asdf)" --eval " \
(progn \
(asdf:oos 'asdf:load-op 'my-project) \
(save-lisp-and-die \"my-project.core\"))"
clean:
rm -rf *.fasl
rm -rf *.core
This will compile all of the packages you defined in your ASDF system file into .fasl bytecode files and then save a .core file. Now all you need is a shell script to run the .core:
#!/bin/sh
SBCL=/usr/local/bin/sbcl
$SBCL --core my-project.core --noinform \
--eval "(progn (my-project:main) (quit))"
And that'll do it! This assumes that your code has an exported defun, 'main', as the entry point for your program. Now run the shell script and your application will run.
Edit: Xach mentioned in the comments that you can use the :executable argument to save-lisp-and-die to create an executable, thus removing the need for the wrapper script above.
This is the build process I use for my little cl-mines game, so you can check out the setup there if there is anything that was unclear.
Wednesday, August 26, 2009
cl-mines - A Minesweeper Clone
I uploaded my Minesweeper clone, cl-mines to GitHub a few days ago. It's just a simple, command-line Minesweeper game. It doesn't really have a proper build process yet.
I've only tested it on SBCL, but there isn't any SBCL-specific code that I'm aware of and it is, by far, not the most complicated piece of Lisp code out there, so it should work with other Common Lisp implementations.
I've only tested it on SBCL, but there isn't any SBCL-specific code that I'm aware of and it is, by far, not the most complicated piece of Lisp code out there, so it should work with other Common Lisp implementations.
Wednesday, July 1, 2009
Project Euler problem 28
DISCLAIMER: This post contains a solution to Project Euler problem 28. Go away if you don't want to know. DISCLAIMER 2: I am not the most mathematically minded person, so this may/will seem slow for pro mathematicians.
See here for the problem description.
So I got around to solving problem 28 last night (14 more until I get to level 2!) and, like most problems, I quickly found out the reason why this problem is on Project Euler: there's a subtle and beautiful pattern hidden in the middle of what seems like a random math problem.
The first pattern is that as the pyramid builds, the top right corners are always perfect squares of 1, 3, 5, 7 etc...
The other subtle pattern is that the gap between the corners also increments by 1, 3, 5, 7 etc... with each new layer of the pyramid. Therefor if we are at the top right corner which is n2, the top left corner is n2 - n + 1, the bottom left corner is n2 - 2n + 2, and the bottom right corner is n2 - 3n + 3, which follows an easy summation pattern which we can represent with a simple Lisp function:
And a simple loop, described earlier, to tie everything together:
See here for the problem description.
So I got around to solving problem 28 last night (14 more until I get to level 2!) and, like most problems, I quickly found out the reason why this problem is on Project Euler: there's a subtle and beautiful pattern hidden in the middle of what seems like a random math problem.
The first pattern is that as the pyramid builds, the top right corners are always perfect squares of 1, 3, 5, 7 etc...
43 44 45 46 47 48 49 42 21 22 23 24 25 26 41 20 7 8 9 10 27 40 19 6 1 2 11 28 39 18 5 4 3 12 29 38 17 16 15 14 13 30 37 36 35 34 33 32 31So we start looping from 1 to 1001 by 2s.
The other subtle pattern is that the gap between the corners also increments by 1, 3, 5, 7 etc... with each new layer of the pyramid. Therefor if we are at the top right corner which is n2, the top left corner is n2 - n + 1, the bottom left corner is n2 - 2n + 2, and the bottom right corner is n2 - 3n + 3, which follows an easy summation pattern which we can represent with a simple Lisp function:
(defun sum-corners (n)
(loop for x from 0 to 3
sum (+ (- (* n n)
(* x n))
x)))
Note: That can be simplified further into one equation, rather than a loop, if you like.And a simple loop, described earlier, to tie everything together:
(defun euler-28 ()
(1+ (loop for n from 3 to 1001 by 2
sum (sum-corners n))))
Done. A simple problem disguised as something a little more difficult than it really is and has a couple of simple but cool patterns.
Thursday, June 11, 2009
When to use defparameter and defvar
Because I always forget:
< gigamonkey> Say you were running a genetic algorithm and you
said (defparameter *populations* nil)
< gigamonkey> Then you run it for a few days and *populations*
is full of thousands of populations you've
generated. Then you change some code in the file
and reload it. Ooops. You've just wiped out your
*populations*.
< gigamonkey> (defvar *populations* nil) saves you from that.
< gigamonkey> Conversely if you have
(defvar *mutation-rate* .01) and then you decide
to tweak things and change the .01 to .001 and
reload the file, you'll be confused when nothing
changes.
< gigamonkey> In that case you should have used defparamater.
< gigamonkey> spelled right, of course.
Subscribe to:
Posts (Atom)