Author Archives: joe

About joe

.NET developer and board game geek located in the greater Atlanta region.

Flex Game of Life Pt 2

I made a few user interface updates to my crappy Flex version of Conway’s Game of Life.

The board now wraps, and I added a Timer with an adjustable delay via the lovely HSlider control. I wanted to replace the cells with Sprites but it’s giving me grief and I want to play The Sims.

I’m still making my mind up about Flex, but I have to admit that aside from the Sprite issue I’ve been pleasantly surprised at how easy everything’s been coming together.

You can view source on the application, or you can download the zip.

How to issue a simple HTTPRequest in Java

I needed a way to issue an HTTPRequest in Java, and I don’t care about the return value. I wasn’t able to find a simple example so I thought I’d post my that part of my solution. I don’t know that it’s the best way, but it works.

import java.net.URL;

public class Request {
  public static void main(String[] args) throws Exception {
      if(args.length == 0) {
          System.out.println("URL required.");
          return;
      }
      URL url = new URL(args[0]);
      url.openStream().close();
  }
}

And to use it you just pass in the url via the command line

java Request http://joezack.com

Flex Game of Life

Continuing down the Flex Path, I built another really crappy version of Conway’s Game of Life. Version 2 forthcoming.

I’m still figuring out this whole Flex thing, so please, any help would be much appreciated!

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx         = "http://www.adobe.com/2006/mxml"
	layout           = "vertical"
	creationComplete = "init(gameArea);"
	width            = "425"
	height           = "425"
>
	<mx:Script><![CDATA[
		import model.*;
		private var board:Board;

		private function init(application:DisplayObjectContainer):void {
			board = new Board(application, 10, 0, 0, 30, 30, 5);
		}
	]]></mx:Script>

	<mx:Canvas id="gameArea"></mx:Canvas>
	<mx:HBox>
		<mx:Button label="Reset"  click="board.reset();" />
		<mx:Button label="Update" click="board.update();" />		
	</mx:HBox>
</mx:Application>
package model {

	import flash.display.DisplayObjectContainer;

	public class Board {

		private var size:int;
		private var startX:int;
		private var startY:int;
		private var tileWidth:int;
		private var tileHeight:int;
		private var tileBuffer:int;	
		private var board:Array;
		private var container:DisplayObjectContainer;

		public function Board(
			container:DisplayObjectContainer,
			size:int,
			startX:int,
			startY:int,
			tileWidth:int,
			tileHeight:int,
			tileBuffer:int
		) {
			this.container  = container;
			this.size       = size;
			this.startX     = startX;
			this.startY     = startY;
			this.tileWidth  = tileWidth;
			this.tileHeight = tileHeight;
			this.tileBuffer = tileBuffer;
			reset();
		}

		public function reset():void {
			this.board = new Array(this.size);
			var x:int = startX;
			var y:int = startY;

			clear();

			for(var i:int = 0; i < this.size; i++) {
				this.board[i] = new Array(this.size);
				x = startX;
				for(var j:int = 0; j < this.size; j++) {
					board[i][j] = new Cell(x, y, tileWidth, tileHeight);
					x += this.tileWidth + this.tileBuffer;
					this.container.addChild(board[i][j]);
				}
				y += this.tileHeight + this.tileBuffer;
			}
		}

		public function update():void {
			var next:Array = next();
			for(var i:int = 0; i < this.size; i++) {
				for(var j:int = 0; j < this.size; j++) {
					board[i][j].update(next[i][j]);
				}
			}
		}

		public function clear():void {
			while(this.container.numChildren) {
				this.container.removeChildAt(0);
			}
		}

		public function next():Array {
			var total:int     = 0;
			var next:Array = new Array(this.size);
			for(var i:int = 0; i < this.size; i++) {
				next[i] = new Array(this.size);
				for(var j:int = 0; j < this.size; j++) {
					next[i][j] = board[i][j].next(countNeighbors(i,j));
				}
			}
			return next;
		}

		public function isValid(position:int):Boolean {
			return(position >= 0 && position < this.size);
		}

		public function stateAt(i:int, j:int):Boolean {
			if(isValid(i) && isValid(j)) {
				return board[i][j].state;
			}
			return false;
		}

		public function countNeighbors(x:int, y:int):int {
			var count:int = 0;
			
			for(var i:int = x - 1; i <= x + 1; i++) {
				for(var j:int = y - 1; j <= y + 1; j++) {
					if(!(i == x && j == y) && stateAt(i,j)) {
						count += 1;
					}
				}
			}
			return count;
		}

	}
}
package model {
	import flash.events.MouseEvent;
	
	import mx.controls.Button;

	public class Cell extends Button {

		public var state:Boolean;

		public function Cell(x:int, y:int, width:int, height:int) {
			this.x     = x;
			this.y     = y;
			this.width = width;
			this.height = height;
			this.addEventListener(MouseEvent.CLICK,swap);
			this.reset();
		}

		public function reset():void {
			this.state = false;
		}

		public function next(neighborCount:int):Boolean {
			return((this.state && neighborCount == 2) || neighborCount == 3);
		}

		public function update(state:Boolean):void {
			this.state = state;
			if(this.state) {
				this.label = "0";
			} else {
				this.label = "";
			}
		}

		public function swap(e:MouseEvent):void {
			update(!this.state);
		}

	}
}

My First Flex App: Tic-Tac-Toe

So, at the insistence of my co-worker Mario I’ve been reading up a bit on Flex. I can’t say it’s been love at first site, but I’m giving it a solid chance and I’ll post my thoughts on the tech after I’ve solidified on the matter.

Anywho, here’s my first app. It’s a simple Tic-Tac-Toe game, which took longer, and is uglier than it should be, since I haven’t quite figured out what I’m doing yet. Not that that’s ever stopped me from posting before.

Amazing eh?

The MXML File:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx         = "http://www.adobe.com/2006/mxml"
	layout           = "absolute"
	width            = "220"
	height           = "190"
	creationComplete = "reset(this)"
>
	<mx:Script source = "TicTacToe.as" />
</mx:Application>

My Tile Class

package components {
	import flash.events.MouseEvent;
	import mx.controls.Button;

	public class Tile extends Button {
		public function Tile(x:int,y:int,click:Function) {
			super();
			this.x     = x;
			this.y     = y;
			this.label = "";
			this.addEventListener(MouseEvent.CLICK,click);
		}
		public function belongsTo(player:String):Boolean {
			return this.label == player;
		}
		public function isEmpty():Boolean {
			return belongsTo("");
		}
	}
}

And finally, my actual game code:

import components.*;

import mx.controls.Alert;

private const START_X:int     = 90;
private const START_Y:int     = 80;
private const TILE_SIZE:int   = 50;
private const TILE_BUFFER:int = 5;
private const BOARD_SIZE:int  = 3;

private const PLAYER_X:String = "X";
private const PLAYER_O:String = "O";

private var turn:String;
private var container:DisplayObjectContainer;
private var board:Array;

private function isValidMove(tile:Tile):Boolean {
	return(tile.label == ""); 
}

private function takeTurn(tile:Tile):void {
	tile.label = turn;
	if(turn == PLAYER_X) {
		turn = PLAYER_O;
	} else {
		turn = PLAYER_X;
	}
}

private function toggle(e:MouseEvent):void {
	var tile:Tile = Tile(e.target);

	if(!isValidMove(tile)) {
		return;
	}

	takeTurn(tile);

	if(playerWon(PLAYER_X)) {
		endGame("Yay, " + PLAYER_X + "  won!");
	}
	if(playerWon(PLAYER_O)) {
		endGame("Yay, " + PLAYER_O + "  won!");
	}
	if(!movesAreAvailable()) {
		endGame("Everybody loses. Losers.");
	}
}

private function endGame(message:String):void {
	Alert.show(message);
	reset(container);	
}

private function movesAreAvailable():Boolean {
	var i:int, j:int;
	for(i = 0; i < BOARD_SIZE; i++) {
		for(j = 0; j < BOARD_SIZE; j++) {
			if(board[i][j].isEmpty()) {
				return true;
			}
		}
	}
	return false;
}

private function playerWon(player:String):Boolean {
	var i:int, j:int;
	var status:Boolean;

	for(i = 0; i < BOARD_SIZE; i++) {
		status = true;
		for(j = 0; j < BOARD_SIZE; j++) {
			status = status && board[i][j].belongsTo(player);
		}
		if(status) {
			return status;
		}
	}

	for(i = 0; i < BOARD_SIZE; i++) {
		status = true;
		for(j = 0; j < BOARD_SIZE; j++) {
			status = status && board[j][i].belongsTo(player);
		}
		if(status) {
			return status;
		}
	}

	status = true;
	for(i = 0; i < BOARD_SIZE; i++) {
		status = status && board[i][i].belongsTo(player);
	}
	if(status) {
		return status;
	}

	status = true;
	for(i = 0; i < BOARD_SIZE; i++) {
		status = status && board[i][BOARD_SIZE - (i + 1)].belongsTo(player);
	}
	return status;
}

private function reset(applicationContainer:DisplayObjectContainer):void {
	var tile:Tile;

	board     = new Array(BOARD_SIZE);
	container = applicationContainer;
	turn      = PLAYER_X;

	while(container.numChildren) {
		container.removeChildAt(0);
	}

	for(var i:int = 0; i < BOARD_SIZE; i++) {
		board[i] = new Array(BOARD_SIZE);
		for(var j:int = 0; j < BOARD_SIZE; j++) {
			board[i][j] = new Tile(
				START_X + j * (TILE_SIZE + TILE_BUFFER),
				START_Y + i * (TILE_SIZE + TILE_BUFFER),
				toggle
			);
			container.addChild(board[i][j]);
		}
	}
}

You can also just download it

On a side note, big thanks to Alex Gorbatchev for my new syntax highlighter plugin and a round of applause for Mark Walters for the AS3 extension to said excellent plugin.

Project Euler: Problem 19 in Ruby

Although it felt dirty, I used Ruby’s baked-in date class. I’d written some day-of-week code when I first started coding, before I knew better, and it’s annoying. Besides, this was my last problem to do before level 1. That’s right…

LEVEL 1!!!!

Bravo, thejoezack! Now that you have solved 25 problems you have achieved what 79.52% of members have failed to do and have advanced to level 1. Good luck as you continue.”

I’m proud. I found a few of the problems to be really hard and it feels really good to have finally hit a milestone. I’ve actually had a much easier time with the problems as I’ve gone on, as I’ve learned a lot about solving these problems and perhaps even problem solving in general. Kudos and thanks, Project Euler!

Oh yeah…and here’s my solution:

Problem #19

How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

require 'date'

start = Date.new 1901, 1, 1
total = 0

(100 * 12 - 1).times do |i|
  total += 1 if (start >> i).wday == 0
end

puts total

Project Euler: Problem 22 in Ruby

Cake. I really hate hard-coding that ascii value in there, but it made it easier for me to get it working in different versions of Ruby.

Problem #22

What is the total of all the name scores in the file?

def convert word
  total = 0
  word.each_byte do |i|
    total += i - 64
  end
  total
end

file  = File.new("files/names.txt", "r")
names = eval("[" + file.gets + "]").sort
total = 0

file.close

names.each_with_index do |name, i|
  total += convert(name) * (i + 1)
end

puts total

Project Euler: Problem 21 in Ruby

Pretty standard Project Euler solution. You only need to check up to the square of each number, and you can cache each calculation as you go along.

Problem 21

Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n).
If d(a) = b and d(b) = a, where a ≠ b, then a and b are an amicable pair and each of a and b are called amicable numbers.

Evaluate the sum of all the amicable numbers under 10000.

def d(n)
  total = 1
  (2..Math.sqrt(n)).each do |i|
    if n % i == 0
      total += n / i + i
    end
  end
  total
end

def amicable?(a, repo)
  repo[a] = b = d(a)
  a != b and a == repo[b]
end

repo  = {}
total = 0

10_000.times do |i|
  if amicable?(i, repo)
    total += (i + repo[i])
  end
end

puts total

Project Euler: Problem 48 in Ruby

I realized the other day, that you can sort the Project Euler problems by difficulty. For the most part it sticks pretty closely to the problem number, but this one was an outlier. Most of the solutions didn’t actually trim out the extraneous characters, but I thought that was the “hardest” part of this problem since I actually had to check the docs.

Problem #48

Find the last ten digits of the series, 1^(1) + 2^(2) + 3^(3) + … + 1000^(1000).

sum = 0

(1..1_000).each do |i|
  sum += i**i
end

puts (sum % 10**10).to_s[-10, 10]

Project Euler: Problem 20 in Ruby

I cheesed out on this one, pretty much just did what the problem called for. No magic. Looking through the forums, however, it was pretty much par for the course.

Problem #20

Find the sum of the digits in the number 100!

product, sum = 1, 0

100.times do |i|
  product *= i + 1
end

while product > 0
  sum += (product /= 10) % 10
end

puts sum