One of Clojure’s greatest strengths is the fact that it sits on the JVM. This puts all of those jars that people have worked tirelessly over the years to produce right at your fingertips ready for use in your Clojure code. Today’s post will just be a short tutorial on some of the most basic routines to use Java classes in your Clojure code. All of the examples that I’ll produce are all based on the Java_interop page on the Clojure site.
Importing classes
First things first. You’ll need to import the classes that you want to use. You don’t have to, it just makes your code a little less verbose later on.
(import'java.net.URL)
We’re now able to use the URL class in our code. If you’re importing classes into your programs that aren’t local and need to be downloaded as a dependency, I suggest you use Leiningen to do all the heavy lifting for you there. You’d just need to list your external package in the dependencies list in your project file and away you go.
Using the classes
We need to construct some objects so that we’ll be able to call methods on them, so following on from the example, we construct instances of the classes that we import like so.
(defgoogle(newURL"http://www.google.com"))
This is really getting the Java mojo mixed in with Clojure now. So “google” is our constructed object, we can start to call methods on this variable like so.
We were able to find out the protocol of the URL using getProtocol and we were able to compare “google” and “yahoo” using sameFile.
doto
The last thing I want to talk about is doto. doto evaluates its first parameter than allows you to chain a series of calls (just as you would in Java using the . operator) together. Here’s a an example using a HashMap class and chaining a few put’s together. This statement will return the built HashMap.
Still trying to flex my skills in the Haskell arena and am still chasing a real project to do. Until I find said project, silly little games it is. A little while ago I watched the Haskell Live videos and in these videos a good start is made on a chess framework. Very interesting stuff to see how something like this is put together and if you haven’t seen them, I suggest you go and check out episode 1 and episode 2. Anyway, the videos don’t yet take you through to a completed implementation and while I’d love to say that I possess the skills to take the chess game through, I’d be punching above my weight. In compromise, I’ve been able to use some of the concepts that Rein has demonstrated in his videos - in my own implementation of Tic Tac Toe. Today’s post will take you through my implementation.
Functional Specification
Well, if you’re really wanting the functional in’s-and-out’s of the game Tic-tac-toe, I suggest you step our of your bubble and read this. This implementation will involve two rather random computer players battling it out, so no user interactivity (yet). Well, thanks to a cheeky link to a wikipedia article, that’s the smallest functional specification I’ve ever seen. On to the code.
Pieces
First up, we’ll deal with pieces. To this program, a piece can be a Naught or a Cross. When the piece is a Naught, we want to represent it with a ‘o’, when the piece is a Cross, we want to represent it with an ‘x’. Here’s the type declaration and functions we’ll use to work with pieces.
-- | A piece is what a player places in a celldataPiece=Naught|Crossderiving(Eq,Show,Read)-- | Converts a piece into the board representation showPiece::Piece->CharshowPieceNaught='o'showPieceCross='x'-- | Converts the board representation back into a piecereadPiece::Char->PiecereadPiece'o'=NaughtreadPiece'x'=Cross
A piece can only be either a Naught or a Cross, nothing else. The functions are all very straight forward and meeting the requirements of our specification. Naughts will look like “o’s” and Crosses will look like “x’s”. Just to be sure, we can setup a couple of QuickCheck tests to assure us that it’s ok.
A cell is a representation of one of the nine squares that you find on a tic-tac-toe board. A cell differs from a piece as a cell can have a piece value or it can be empty. In our implementation, empty cells will be represented by a period .. Let’s take a look at the types and the functions we’ll use to interact with cells.
-- | A cell is empty or it contains a piecetypeCell=MaybePiece-- | Shows the value of a cell showCell::Cell->CharshowCellNothing='.'showCell(Justp)=showPiecep-- | Reads a board cell and transformsreadCell::Char->CellreadCell'.'=NothingreadCellp=Just$readPiecep
We use Maybe to allow either a Nothing or a Piece value for a cell. With the help of those functions we’ve already written for pieces, you can see that these cell functions are very simple. We’ve only had to cater for one extra case, the case of when there’s no value in a cell. We’ll setup a few more QuickCheck tests just to make sure that our Cell code is working ok.
Great. With this code written we’re ready to wrap up a List of these cells into a field that we will play on.
The Field
A 3x3 grid is normally what’s drawn prior to playing a game of tic-tac-toe. We will define the field as an array of an array of cells. Here’s the type and supporting functions for a field.
-- | A field is a 3x3 array of cellstypeField=[[Cell]]-- | Shows a field of cells showField::Field->[String]showField=mapshowCellRowwhereshowCellRow=mapshowCell-- | Reads a field readField::[String]->FieldreadField=mapreadCellRowwherereadCellRow=mapreadCell
Much as before, you can see that we’re leaning on our already-built set of functions to implement all of our field-based functions. At this point, we can define the starting field that all of our games will originate with.
initialField=["...","...","..."]
You can see that the field is in string format. It’s a little more human to read and it’s all ready for our readField function to use as is demonstrated by the following QuickCheck test.
It’s at this point where any similarities between the Haskell Live videos and my implementation end. It’s probably natural that this is the point as we’re going to start dealing with some game logic.
Winners and Losers
There are a few tests that we have to be constantly running in order to simulate a real-life game of tic-tac-toe. One of which is “do we have a winner yet? Testing if a winner has been established is testing if the same symbol appears on a horizontal, vertical or diagonal line. In each of these configurations, there are only going to be three cells to test, so I made a general purpose array tester. I’ve use pattern matching in this function to be as clear as possible. It’s not as DRY as it could be, but we can improve it later - let’s just get it working. Here’s the function to test three list elements to see if there’s a winner.
-- | Tests a prepared row for a winner testRow::[Cell]->MaybePiecetestRow[JustNaught,JustNaught,JustNaught]=JustNaughttestRow[JustCross,JustCross,JustCross]=JustCrosstestRow_=Nothing
Easy. This function looks like it will be very effective in testing winners on the horizontal lines. But what about the vertical lines that occur in different arrays? and the diagonal lines that exist in different arrays and in different indexes across the horizontal axis? My answer here is to create a function that make all of these testable vectors into horizontal rows so that we can use the above function on all of the different win configurations. Here’s the code to build an array of these 3 element arrays.
-- | Flattens the winnable view of a field into testable rows makeRows::Field->[[Cell]]makeRowsf=horiz++vert++diagwherehoriz=[r|r<-f]col1=[r|r<-headf]col2=[r|r<-head$drop1f]col3=[r|r<-head$drop2f]vert=[col1,col2,col3]diag=[[headcol1,head$drop1col2,head$drop2col3],[head$drop2col1,head$drop1col2,headcol3]]
Walking through this one piece-by-piece, we can see a number of items in the where clause. Sure, these could be consolidated into a big-fat-one-liner, but I wanted to make clear exactly what was being concatenated. So, horiz is a list comprehension giving you each horizontal line, col1, col2 and col3 are the vertical columns. diag is a little less clearer through its use of head and drop, but it does form the diagonals into testable rows.
Playing the game
Weather you’re a computer or human player, you’ll need to know where are the valid spots to move. It’ll be intuitive enough from the user interface presented for a human to realise where their next move will be, but our computer player counterparts will need to be told explicitly where they can move. This next function just finds all of the available cells that you can move into.
-- | Gathers all of the positions that are free getOptions::Field->[Int]getOptionsf=[sndx|x<-zip(concatf)[0..],fstx==Nothing]
We assign an index (from 0 to 8) to each cell and only return the indexes that are paired with a Nothing value. This function will help us later when we go to build a user interface for this application. We’ll be able to prompt the user intuitively.
Flattening the array gives us the [0..8] range, which over the 3x3 grid (which is really our tic-tac-toe representation), the range looks like this.
0 1 2
3 4 5
6 7 8
This is timely information as we’re just about to present the function that will place a piece on the field for us. Placing a piece will require us to provide the current game field, the piece we want to apply and the index that we want to apply it at. This function cuts the list on the index that we want to apply and then re-concatenates the broken list around the new piece (obviously dropping the cell that we’re putting a piece into). Here’s the code.
-- | Places a piece on the board placePiece::Field->Piece->Int->FieldplacePiecefpn=chunksOf3$prior++[cell]++afterwhereflat=concatfprior=taken$flatafter=drop(n+1)$flatcell=(Justp)::Cell
Trying to be as clear as possible with my names here. prior being the list before the break, after is what comes after. Now it’s time to introduce our “artificial intelligence” which really - there isn’t any intelligence here. It’s based purely off of a random number generator. Here’s how our computer players will play a round of tic-tac-toe.
-- | Takes a random turn on a field takeRandomTurn::StdGen->Piece->Field->(StdGen,Field)takeRandomTurngenpf=(seed,placePiecefp(opts!!idx))whereopts=getOptionsf(idx,seed)=randomR(0,(lengthopts)-1)gen::(Int,StdGen)
We’re taking in a random number generator, the piece type that the computer will place and the field that it will be placed in. The output to which will be a new random number generator and the changed field. This way, we can repeatedly call this function and not worry about losing our sense of entropy (or field state!). Finally we have the function that will play our game until we have a result (win naught, win cross or tie). I needed to implement a “not” function for my piece type. This is just so I can offer each “player” a go interchangeably. Here’s the code.
-- | Acts like a boolean "not" for tic-tac-toe pieces otherPiece::Piece->PieceotherPieceCross=NaughtotherPieceNaught=Cross-- | Plays a game between two random cpu players playGame::StdGen->Piece->Field->IO()playGamegenpf=ifspaces==0thenputStrLn"Game was a tie!"elseifwinner/=NothingthendoputStrLn$(unlinesfstr)putStrLn$(showwinner)++" won the game!"elsedoputStrLn$(unlinesfstr)playGameng(otherPiecep)nfwherewinner=hasWinnerfspaces=length$getOptionsf(ng,nf)=takeRandomTurngenpffstr=showFieldf
This reads fairly humanly. We assume that if execution breaks into this function, a result wasn’t established on the execution prior, so we’re comfortable in the first check that if there are no spaces left to put pieces, we must declare the game as a tie. The next test is if the previous call to this function caused the other player to win the game. In the event that this check is confirmed, a message is written out and we do not continue any further. If there still isn’t a winner, we get this player to place a piece into a cell and then recurse on this function as the other player. Here is how a game runs when using 1 into mkStdGen.
*TicTacToe> let f = readField initialField
*TicTacToe> playGame (mkStdGen 1) Cross f
...
...
...
..x
...
...
o.x
...
...
o.x
...
..x
o.x
...
.ox
oxx
...
.ox
oxx
.o.
.ox
oxx
.o.
xox
oxx
.oo
xox
Game was a tie!
That’s tic-tac-toe.
Next time I’ll add some user interactivity so that the computer doesn’t have all the fun!
I needed to distribute one of my ruby programs to be setup as a job, so I needed to add a shebang to the top of the file. I run my development environment using RVM so I had no idea how to address ruby in the shebang. Then it hit me ..
#!/usr/bin/env ruby
Interestingly, things are a little different when trying to execute a ruby with one of your RVM installed rubies from a cron job. The rvm website has a whole section regarding the topic of cron integration. The command that I passed to successfully execute these jobs needed to be addressed absolutely:
Cleaner, clearer code is better. It’s easier to debug, it’s easier to read, it’s just plain - better. Assembly code isn’t known for its ability to allow the developer to make their intentions clear in its source code, but we can get closer with some carefully craft macros. Macros are symbols that you can use in your code to represent a block of code. Macros are allowed to take parameters which makes them an extremely flexible and valuable tool in your arsenal. These symbols that you use in your code are swapped out by nasm at the time of assembly for the blocks of code that they represent. If you want to go further in depth to the nasm pre-processor and macros, check it out in the manual here.
Today’s post will be focused on cleaning up the code that we’d written in this previous article to look a little more human.
Revisiting write and strlen
In the previous article “strlen() implementation in NASM”, we’d put together a couple of ways to take the length of a string. This article will assume that we’re already using this code. With this in mind, we can put together a general purpose print function that will display a zero terminated string with the following.
; _print;; input; rdi points to the zero terminated string that ; we're printing;; output; none_print:pushrcx; start off by preserving the registerspushrdx; that we know that we'll trash in thispushrax; procpushrbxmovrcx,rdi; rcx = string memory locationcall_strlen; calculate the string's lengthmovrdx,rax; rdx = string lengthmovrax,4; write() is syscall 4movrbx,1; we're writing to stdoutint0x80; execute the callpoprbx; restore all of the registerspopraxpoprdxpoprcxret; get out
Ok, that’s a nice and neat little bundle. Now, everytime that we want to call this function, we need to write code that looks like the following.
movrdi,message; load our string into rdicall_print; write the message
Which, isn’t too bad I guess. We can make it look better though. Consider the following code that wraps this code into a macro.
; print - prints a null terminated string%macro print 1
pushrdi; save off rdimovrdi,%1; load the address of the stringcall_print; print the stringpoprdi; restore rdi%endmacro
The syntax here may look a little alien to begin with, but it’ll all make sense in a minute. So, we start the macro block off with a %macro directive. What follows is the name of the macro, in this case print and after that is the number of parameters that this macro will expect (we want one parameter, being the string to print). We have the print code between the directives. You’ll see that rdi gets loaded with %1 which just means “replace %1 with the first thing passed to this macro”. To finish up your macro, you have %endmacro. With that macro defined, you can now print a message to screen by doing this.
printmessage
This is starting to look a little higher-level now. A bit more “human” on the eyes. Another nifty trick that I’d picked up a while ago was a macro for defining strings. In all of the examples we’ve seen so far, you’d declare strings in the data segment with the following syntax.
section.datamessagedb"Hello, world",0
This is perfectly fine, however we can wrap this string declaration up into a macro of its own as well allowing us to define strings where ever we are. We need to be careful though. Defining a string in the code segment without the appropriate jumps is dangerous as we run the risk of executing the string data. The following macro does this safely.
; sz - defines a zero terminated string%macro sz 2
jmp%1_after_def; jump over the string that we define %1 db %2, 0 ; declare the string
%1_after_def: ; continue on
%endmacro
You can see that we’ve declared a macro that expects two parameters. The first parameter is the name of the variable that we declare. This name is also used to formulate the labels that we jump to so that they are unique between string definitions. The second parameter is the actual string data itself. Now that we have both of these macros defined, the following code is perfectly legal and works a treat.
Well, this is only the start of what you can accomplish with macros. An exercise to the reader would be to implement your own version of print that prints a new line after it prints the string - you never know, you might even want to call it “println”!